tapv2: multiple improvements
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/input_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   return vl_socket_client_connect
92     (&vam->socket_client_main, (char *) vam->socket_name,
93      "vpp_api_test(s)", 0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 void
103 vl_socket_client_read_reply (socket_client_main_t * scm)
104 {
105 };
106 #endif
107
108
109 f64
110 vat_time_now (vat_main_t * vam)
111 {
112 #if VPP_API_TEST_BUILTIN
113   return vlib_time_now (vam->vlib_main);
114 #else
115   return clib_time_now (&vam->clib_time);
116 #endif
117 }
118
119 void
120 errmsg (char *fmt, ...)
121 {
122   vat_main_t *vam = &vat_main;
123   va_list va;
124   u8 *s;
125
126   va_start (va, fmt);
127   s = va_format (0, fmt, &va);
128   va_end (va);
129
130   vec_add1 (s, 0);
131
132 #if VPP_API_TEST_BUILTIN
133   vlib_cli_output (vam->vlib_main, (char *) s);
134 #else
135   {
136     if (vam->ifp != stdin)
137       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
138                vam->input_line_number);
139     fformat (vam->ofp, (char *) s);
140     fflush (vam->ofp);
141   }
142 #endif
143
144   vec_free (s);
145 }
146
147 #if VPP_API_TEST_BUILTIN == 0
148 static uword
149 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
150 {
151   vat_main_t *vam = va_arg (*args, vat_main_t *);
152   u32 *result = va_arg (*args, u32 *);
153   u8 *if_name;
154   uword *p;
155
156   if (!unformat (input, "%s", &if_name))
157     return 0;
158
159   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
160   if (p == 0)
161     return 0;
162   *result = p[0];
163   return 1;
164 }
165
166 /* Parse an IP4 address %d.%d.%d.%d. */
167 uword
168 unformat_ip4_address (unformat_input_t * input, va_list * args)
169 {
170   u8 *result = va_arg (*args, u8 *);
171   unsigned a[4];
172
173   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
174     return 0;
175
176   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
177     return 0;
178
179   result[0] = a[0];
180   result[1] = a[1];
181   result[2] = a[2];
182   result[3] = a[3];
183
184   return 1;
185 }
186
187 uword
188 unformat_ethernet_address (unformat_input_t * input, va_list * args)
189 {
190   u8 *result = va_arg (*args, u8 *);
191   u32 i, a[6];
192
193   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
194                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
195     return 0;
196
197   /* Check range. */
198   for (i = 0; i < 6; i++)
199     if (a[i] >= (1 << 8))
200       return 0;
201
202   for (i = 0; i < 6; i++)
203     result[i] = a[i];
204
205   return 1;
206 }
207
208 /* Returns ethernet type as an int in host byte order. */
209 uword
210 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
211                                         va_list * args)
212 {
213   u16 *result = va_arg (*args, u16 *);
214   int type;
215
216   /* Numeric type. */
217   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
218     {
219       if (type >= (1 << 16))
220         return 0;
221       *result = type;
222       return 1;
223     }
224   return 0;
225 }
226
227 /* Parse an IP6 address. */
228 uword
229 unformat_ip6_address (unformat_input_t * input, va_list * args)
230 {
231   ip6_address_t *result = va_arg (*args, ip6_address_t *);
232   u16 hex_quads[8];
233   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
234   uword c, n_colon, double_colon_index;
235
236   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
237   double_colon_index = ARRAY_LEN (hex_quads);
238   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
239     {
240       hex_digit = 16;
241       if (c >= '0' && c <= '9')
242         hex_digit = c - '0';
243       else if (c >= 'a' && c <= 'f')
244         hex_digit = c + 10 - 'a';
245       else if (c >= 'A' && c <= 'F')
246         hex_digit = c + 10 - 'A';
247       else if (c == ':' && n_colon < 2)
248         n_colon++;
249       else
250         {
251           unformat_put_input (input);
252           break;
253         }
254
255       /* Too many hex quads. */
256       if (n_hex_quads >= ARRAY_LEN (hex_quads))
257         return 0;
258
259       if (hex_digit < 16)
260         {
261           hex_quad = (hex_quad << 4) | hex_digit;
262
263           /* Hex quad must fit in 16 bits. */
264           if (n_hex_digits >= 4)
265             return 0;
266
267           n_colon = 0;
268           n_hex_digits++;
269         }
270
271       /* Save position of :: */
272       if (n_colon == 2)
273         {
274           /* More than one :: ? */
275           if (double_colon_index < ARRAY_LEN (hex_quads))
276             return 0;
277           double_colon_index = n_hex_quads;
278         }
279
280       if (n_colon > 0 && n_hex_digits > 0)
281         {
282           hex_quads[n_hex_quads++] = hex_quad;
283           hex_quad = 0;
284           n_hex_digits = 0;
285         }
286     }
287
288   if (n_hex_digits > 0)
289     hex_quads[n_hex_quads++] = hex_quad;
290
291   {
292     word i;
293
294     /* Expand :: to appropriate number of zero hex quads. */
295     if (double_colon_index < ARRAY_LEN (hex_quads))
296       {
297         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
298
299         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
300           hex_quads[n_zero + i] = hex_quads[i];
301
302         for (i = 0; i < n_zero; i++)
303           hex_quads[double_colon_index + i] = 0;
304
305         n_hex_quads = ARRAY_LEN (hex_quads);
306       }
307
308     /* Too few hex quads given. */
309     if (n_hex_quads < ARRAY_LEN (hex_quads))
310       return 0;
311
312     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
313       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
314
315     return 1;
316   }
317 }
318
319 uword
320 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
321 {
322   u32 *r = va_arg (*args, u32 *);
323
324   if (0);
325 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
326   foreach_ipsec_policy_action
327 #undef _
328     else
329     return 0;
330   return 1;
331 }
332
333 uword
334 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
335 {
336   u32 *r = va_arg (*args, u32 *);
337
338   if (0);
339 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
340   foreach_ipsec_crypto_alg
341 #undef _
342     else
343     return 0;
344   return 1;
345 }
346
347 u8 *
348 format_ipsec_crypto_alg (u8 * s, va_list * args)
349 {
350   u32 i = va_arg (*args, u32);
351   u8 *t = 0;
352
353   switch (i)
354     {
355 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
356       foreach_ipsec_crypto_alg
357 #undef _
358     default:
359       return format (s, "unknown");
360     }
361   return format (s, "%s", t);
362 }
363
364 uword
365 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
366 {
367   u32 *r = va_arg (*args, u32 *);
368
369   if (0);
370 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
371   foreach_ipsec_integ_alg
372 #undef _
373     else
374     return 0;
375   return 1;
376 }
377
378 u8 *
379 format_ipsec_integ_alg (u8 * s, va_list * args)
380 {
381   u32 i = va_arg (*args, u32);
382   u8 *t = 0;
383
384   switch (i)
385     {
386 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
387       foreach_ipsec_integ_alg
388 #undef _
389     default:
390       return format (s, "unknown");
391     }
392   return format (s, "%s", t);
393 }
394
395 uword
396 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
397 {
398   u32 *r = va_arg (*args, u32 *);
399
400   if (0);
401 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
402   foreach_ikev2_auth_method
403 #undef _
404     else
405     return 0;
406   return 1;
407 }
408
409 uword
410 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
411 {
412   u32 *r = va_arg (*args, u32 *);
413
414   if (0);
415 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
416   foreach_ikev2_id_type
417 #undef _
418     else
419     return 0;
420   return 1;
421 }
422 #else /* VPP_API_TEST_BUILTIN == 1 */
423 static uword
424 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
425 {
426   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
427   vnet_main_t *vnm = vnet_get_main ();
428   u32 *result = va_arg (*args, u32 *);
429   u32 sw_if_index;
430
431   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
432     return 0;
433
434   *result = sw_if_index;
435   return 1;
436 }
437 #endif /* VPP_API_TEST_BUILTIN */
438
439 static uword
440 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
441 {
442   u8 *r = va_arg (*args, u8 *);
443
444   if (unformat (input, "kbps"))
445     *r = SSE2_QOS_RATE_KBPS;
446   else if (unformat (input, "pps"))
447     *r = SSE2_QOS_RATE_PPS;
448   else
449     return 0;
450   return 1;
451 }
452
453 static uword
454 unformat_policer_round_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "closest"))
459     *r = SSE2_QOS_ROUND_TO_CLOSEST;
460   else if (unformat (input, "up"))
461     *r = SSE2_QOS_ROUND_TO_UP;
462   else if (unformat (input, "down"))
463     *r = SSE2_QOS_ROUND_TO_DOWN;
464   else
465     return 0;
466   return 1;
467 }
468
469 static uword
470 unformat_policer_type (unformat_input_t * input, va_list * args)
471 {
472   u8 *r = va_arg (*args, u8 *);
473
474   if (unformat (input, "1r2c"))
475     *r = SSE2_QOS_POLICER_TYPE_1R2C;
476   else if (unformat (input, "1r3c"))
477     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
478   else if (unformat (input, "2r3c-2698"))
479     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
480   else if (unformat (input, "2r3c-4115"))
481     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
482   else if (unformat (input, "2r3c-mef5cf1"))
483     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_dscp (unformat_input_t * input, va_list * va)
491 {
492   u8 *r = va_arg (*va, u8 *);
493
494   if (0);
495 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
496   foreach_vnet_dscp
497 #undef _
498     else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_policer_action_type (unformat_input_t * input, va_list * va)
505 {
506   sse2_qos_pol_action_params_st *a
507     = va_arg (*va, sse2_qos_pol_action_params_st *);
508
509   if (unformat (input, "drop"))
510     a->action_type = SSE2_QOS_ACTION_DROP;
511   else if (unformat (input, "transmit"))
512     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
513   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
514     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
515   else
516     return 0;
517   return 1;
518 }
519
520 static uword
521 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
522 {
523   u32 *r = va_arg (*va, u32 *);
524   u32 tid;
525
526   if (unformat (input, "ip4"))
527     tid = POLICER_CLASSIFY_TABLE_IP4;
528   else if (unformat (input, "ip6"))
529     tid = POLICER_CLASSIFY_TABLE_IP6;
530   else if (unformat (input, "l2"))
531     tid = POLICER_CLASSIFY_TABLE_L2;
532   else
533     return 0;
534
535   *r = tid;
536   return 1;
537 }
538
539 static uword
540 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = FLOW_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = FLOW_CLASSIFY_TABLE_IP6;
549   else
550     return 0;
551
552   *r = tid;
553   return 1;
554 }
555
556 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
557 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
558 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
559 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
560
561 #if (VPP_API_TEST_BUILTIN==0)
562 uword
563 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
564 {
565   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
566   mfib_itf_attribute_t attr;
567
568   old = *iflags;
569   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
570   {
571     if (unformat (input, mfib_itf_flag_long_names[attr]))
572       *iflags |= (1 << attr);
573   }
574   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
575   {
576     if (unformat (input, mfib_itf_flag_names[attr]))
577       *iflags |= (1 << attr);
578   }
579
580   return (old == *iflags ? 0 : 1);
581 }
582
583 uword
584 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
585 {
586   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
587   mfib_entry_attribute_t attr;
588
589   old = *eflags;
590   FOR_EACH_MFIB_ATTRIBUTE (attr)
591   {
592     if (unformat (input, mfib_flag_long_names[attr]))
593       *eflags |= (1 << attr);
594   }
595   FOR_EACH_MFIB_ATTRIBUTE (attr)
596   {
597     if (unformat (input, mfib_flag_names[attr]))
598       *eflags |= (1 << attr);
599   }
600
601   return (old == *eflags ? 0 : 1);
602 }
603
604 u8 *
605 format_ip4_address (u8 * s, va_list * args)
606 {
607   u8 *a = va_arg (*args, u8 *);
608   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
609 }
610
611 u8 *
612 format_ip6_address (u8 * s, va_list * args)
613 {
614   ip6_address_t *a = va_arg (*args, ip6_address_t *);
615   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
616
617   i_max_n_zero = ARRAY_LEN (a->as_u16);
618   max_n_zeros = 0;
619   i_first_zero = i_max_n_zero;
620   n_zeros = 0;
621   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
622     {
623       u32 is_zero = a->as_u16[i] == 0;
624       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
625         {
626           i_first_zero = i;
627           n_zeros = 0;
628         }
629       n_zeros += is_zero;
630       if ((!is_zero && n_zeros > max_n_zeros)
631           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
632         {
633           i_max_n_zero = i_first_zero;
634           max_n_zeros = n_zeros;
635           i_first_zero = ARRAY_LEN (a->as_u16);
636           n_zeros = 0;
637         }
638     }
639
640   last_double_colon = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       if (i == i_max_n_zero && max_n_zeros > 1)
644         {
645           s = format (s, "::");
646           i += max_n_zeros - 1;
647           last_double_colon = 1;
648         }
649       else
650         {
651           s = format (s, "%s%x",
652                       (last_double_colon || i == 0) ? "" : ":",
653                       clib_net_to_host_u16 (a->as_u16[i]));
654           last_double_colon = 0;
655         }
656     }
657
658   return s;
659 }
660
661 /* Format an IP46 address. */
662 u8 *
663 format_ip46_address (u8 * s, va_list * args)
664 {
665   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
666   ip46_type_t type = va_arg (*args, ip46_type_t);
667   int is_ip4 = 1;
668
669   switch (type)
670     {
671     case IP46_TYPE_ANY:
672       is_ip4 = ip46_address_is_ip4 (ip46);
673       break;
674     case IP46_TYPE_IP4:
675       is_ip4 = 1;
676       break;
677     case IP46_TYPE_IP6:
678       is_ip4 = 0;
679       break;
680     }
681
682   return is_ip4 ?
683     format (s, "%U", format_ip4_address, &ip46->ip4) :
684     format (s, "%U", format_ip6_address, &ip46->ip6);
685 }
686
687 u8 *
688 format_ethernet_address (u8 * s, va_list * args)
689 {
690   u8 *a = va_arg (*args, u8 *);
691
692   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
693                  a[0], a[1], a[2], a[3], a[4], a[5]);
694 }
695 #endif
696
697 static void
698 increment_v4_address (ip4_address_t * a)
699 {
700   u32 v;
701
702   v = ntohl (a->as_u32) + 1;
703   a->as_u32 = ntohl (v);
704 }
705
706 static void
707 increment_v6_address (ip6_address_t * a)
708 {
709   u64 v0, v1;
710
711   v0 = clib_net_to_host_u64 (a->as_u64[0]);
712   v1 = clib_net_to_host_u64 (a->as_u64[1]);
713
714   v1 += 1;
715   if (v1 == 0)
716     v0 += 1;
717   a->as_u64[0] = clib_net_to_host_u64 (v0);
718   a->as_u64[1] = clib_net_to_host_u64 (v1);
719 }
720
721 static void
722 increment_mac_address (u8 * mac)
723 {
724   u64 tmp = *((u64 *) mac);
725   tmp = clib_net_to_host_u64 (tmp);
726   tmp += 1 << 16;               /* skip unused (least significant) octets */
727   tmp = clib_host_to_net_u64 (tmp);
728
729   clib_memcpy (mac, &tmp, 6);
730 }
731
732 static void vl_api_create_loopback_reply_t_handler
733   (vl_api_create_loopback_reply_t * mp)
734 {
735   vat_main_t *vam = &vat_main;
736   i32 retval = ntohl (mp->retval);
737
738   vam->retval = retval;
739   vam->regenerate_interface_table = 1;
740   vam->sw_if_index = ntohl (mp->sw_if_index);
741   vam->result_ready = 1;
742 }
743
744 static void vl_api_create_loopback_reply_t_handler_json
745   (vl_api_create_loopback_reply_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   vat_json_node_t node;
749
750   vat_json_init_object (&node);
751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
753
754   vat_json_print (vam->ofp, &node);
755   vat_json_free (&node);
756   vam->retval = ntohl (mp->retval);
757   vam->result_ready = 1;
758 }
759
760 static void vl_api_create_loopback_instance_reply_t_handler
761   (vl_api_create_loopback_instance_reply_t * mp)
762 {
763   vat_main_t *vam = &vat_main;
764   i32 retval = ntohl (mp->retval);
765
766   vam->retval = retval;
767   vam->regenerate_interface_table = 1;
768   vam->sw_if_index = ntohl (mp->sw_if_index);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_instance_reply_t_handler_json
773   (vl_api_create_loopback_instance_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   vat_json_node_t node;
777
778   vat_json_init_object (&node);
779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
780   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
781
782   vat_json_print (vam->ofp, &node);
783   vat_json_free (&node);
784   vam->retval = ntohl (mp->retval);
785   vam->result_ready = 1;
786 }
787
788 static void vl_api_af_packet_create_reply_t_handler
789   (vl_api_af_packet_create_reply_t * mp)
790 {
791   vat_main_t *vam = &vat_main;
792   i32 retval = ntohl (mp->retval);
793
794   vam->retval = retval;
795   vam->regenerate_interface_table = 1;
796   vam->sw_if_index = ntohl (mp->sw_if_index);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_af_packet_create_reply_t_handler_json
801   (vl_api_af_packet_create_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   vat_json_node_t node;
805
806   vat_json_init_object (&node);
807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
808   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
809
810   vat_json_print (vam->ofp, &node);
811   vat_json_free (&node);
812
813   vam->retval = ntohl (mp->retval);
814   vam->result_ready = 1;
815 }
816
817 static void vl_api_create_vlan_subif_reply_t_handler
818   (vl_api_create_vlan_subif_reply_t * mp)
819 {
820   vat_main_t *vam = &vat_main;
821   i32 retval = ntohl (mp->retval);
822
823   vam->retval = retval;
824   vam->regenerate_interface_table = 1;
825   vam->sw_if_index = ntohl (mp->sw_if_index);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_vlan_subif_reply_t_handler_json
830   (vl_api_create_vlan_subif_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   vat_json_node_t node;
834
835   vat_json_init_object (&node);
836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
838
839   vat_json_print (vam->ofp, &node);
840   vat_json_free (&node);
841
842   vam->retval = ntohl (mp->retval);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_subif_reply_t_handler
847   (vl_api_create_subif_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   i32 retval = ntohl (mp->retval);
851
852   vam->retval = retval;
853   vam->regenerate_interface_table = 1;
854   vam->sw_if_index = ntohl (mp->sw_if_index);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_subif_reply_t_handler_json
859   (vl_api_create_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   vat_json_node_t node;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
867
868   vat_json_print (vam->ofp, &node);
869   vat_json_free (&node);
870
871   vam->retval = ntohl (mp->retval);
872   vam->result_ready = 1;
873 }
874
875 static void vl_api_interface_name_renumber_reply_t_handler
876   (vl_api_interface_name_renumber_reply_t * mp)
877 {
878   vat_main_t *vam = &vat_main;
879   i32 retval = ntohl (mp->retval);
880
881   vam->retval = retval;
882   vam->regenerate_interface_table = 1;
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_interface_name_renumber_reply_t_handler_json
887   (vl_api_interface_name_renumber_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891
892   vat_json_init_object (&node);
893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
894
895   vat_json_print (vam->ofp, &node);
896   vat_json_free (&node);
897
898   vam->retval = ntohl (mp->retval);
899   vam->result_ready = 1;
900 }
901
902 /*
903  * Special-case: build the interface table, maintain
904  * the next loopback sw_if_index vbl.
905  */
906 static void vl_api_sw_interface_details_t_handler
907   (vl_api_sw_interface_details_t * mp)
908 {
909   vat_main_t *vam = &vat_main;
910   u8 *s = format (0, "%s%c", mp->interface_name, 0);
911
912   hash_set_mem (vam->sw_if_index_by_interface_name, s,
913                 ntohl (mp->sw_if_index));
914
915   /* In sub interface case, fill the sub interface table entry */
916   if (mp->sw_if_index != mp->sup_sw_if_index)
917     {
918       sw_interface_subif_t *sub = NULL;
919
920       vec_add2 (vam->sw_if_subif_table, sub, 1);
921
922       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
923       strncpy ((char *) sub->interface_name, (char *) s,
924                vec_len (sub->interface_name));
925       sub->sw_if_index = ntohl (mp->sw_if_index);
926       sub->sub_id = ntohl (mp->sub_id);
927
928       sub->sub_dot1ad = mp->sub_dot1ad;
929       sub->sub_number_of_tags = mp->sub_number_of_tags;
930       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
931       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
932       sub->sub_exact_match = mp->sub_exact_match;
933       sub->sub_default = mp->sub_default;
934       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
935       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
936
937       /* vlan tag rewrite */
938       sub->vtr_op = ntohl (mp->vtr_op);
939       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
940       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
941       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
942     }
943 }
944
945 static void vl_api_sw_interface_details_t_handler_json
946   (vl_api_sw_interface_details_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   vat_json_node_t *node = NULL;
950
951   if (VAT_JSON_ARRAY != vam->json_tree.type)
952     {
953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
954       vat_json_init_array (&vam->json_tree);
955     }
956   node = vat_json_array_add (&vam->json_tree);
957
958   vat_json_init_object (node);
959   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
960   vat_json_object_add_uint (node, "sup_sw_if_index",
961                             ntohl (mp->sup_sw_if_index));
962   vat_json_object_add_uint (node, "l2_address_length",
963                             ntohl (mp->l2_address_length));
964   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
965                              sizeof (mp->l2_address));
966   vat_json_object_add_string_copy (node, "interface_name",
967                                    mp->interface_name);
968   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
969   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
970   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
971   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
972   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
973   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
974   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
975   vat_json_object_add_uint (node, "sub_number_of_tags",
976                             mp->sub_number_of_tags);
977   vat_json_object_add_uint (node, "sub_outer_vlan_id",
978                             ntohs (mp->sub_outer_vlan_id));
979   vat_json_object_add_uint (node, "sub_inner_vlan_id",
980                             ntohs (mp->sub_inner_vlan_id));
981   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
982   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
983   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
984                             mp->sub_outer_vlan_id_any);
985   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
986                             mp->sub_inner_vlan_id_any);
987   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
988   vat_json_object_add_uint (node, "vtr_push_dot1q",
989                             ntohl (mp->vtr_push_dot1q));
990   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
991   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
992   if (mp->sub_dot1ah)
993     {
994       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
995                                        format (0, "%U",
996                                                format_ethernet_address,
997                                                &mp->b_dmac));
998       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
999                                        format (0, "%U",
1000                                                format_ethernet_address,
1001                                                &mp->b_smac));
1002       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1003       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1004     }
1005 }
1006
1007 #if VPP_API_TEST_BUILTIN == 0
1008 static void vl_api_sw_interface_event_t_handler
1009   (vl_api_sw_interface_event_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   if (vam->interface_event_display)
1013     errmsg ("interface flags: sw_if_index %d %s %s",
1014             ntohl (mp->sw_if_index),
1015             mp->admin_up_down ? "admin-up" : "admin-down",
1016             mp->link_up_down ? "link-up" : "link-down");
1017 }
1018 #endif
1019
1020 static void vl_api_sw_interface_event_t_handler_json
1021   (vl_api_sw_interface_event_t * mp)
1022 {
1023   /* JSON output not supported */
1024 }
1025
1026 static void
1027 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031
1032   vam->retval = retval;
1033   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1034   vam->result_ready = 1;
1035 }
1036
1037 static void
1038 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1039 {
1040   vat_main_t *vam = &vat_main;
1041   vat_json_node_t node;
1042   api_main_t *am = &api_main;
1043   void *oldheap;
1044   u8 *reply;
1045
1046   vat_json_init_object (&node);
1047   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1048   vat_json_object_add_uint (&node, "reply_in_shmem",
1049                             ntohl (mp->reply_in_shmem));
1050   /* Toss the shared-memory original... */
1051   pthread_mutex_lock (&am->vlib_rp->mutex);
1052   oldheap = svm_push_data_heap (am->vlib_rp);
1053
1054   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1055   vec_free (reply);
1056
1057   svm_pop_heap (oldheap);
1058   pthread_mutex_unlock (&am->vlib_rp->mutex);
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void
1068 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072   u32 length = ntohl (mp->length);
1073
1074   vec_reset_length (vam->cmd_reply);
1075
1076   vam->retval = retval;
1077   if (retval == 0)
1078     {
1079       vec_validate (vam->cmd_reply, length);
1080       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1081       vam->cmd_reply[length] = 0;
1082     }
1083   vam->result_ready = 1;
1084 }
1085
1086 static void
1087 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1088 {
1089   vat_main_t *vam = &vat_main;
1090   vat_json_node_t node;
1091
1092   vec_reset_length (vam->cmd_reply);
1093
1094   vat_json_init_object (&node);
1095   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1096   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void vl_api_classify_add_del_table_reply_t_handler
1106   (vl_api_classify_add_del_table_reply_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   i32 retval = ntohl (mp->retval);
1110   if (vam->async_mode)
1111     {
1112       vam->async_errors += (retval < 0);
1113     }
1114   else
1115     {
1116       vam->retval = retval;
1117       if (retval == 0 &&
1118           ((mp->new_table_index != 0xFFFFFFFF) ||
1119            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1120            (mp->match_n_vectors != 0xFFFFFFFF)))
1121         /*
1122          * Note: this is just barely thread-safe, depends on
1123          * the main thread spinning waiting for an answer...
1124          */
1125         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1126                 ntohl (mp->new_table_index),
1127                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1128       vam->result_ready = 1;
1129     }
1130 }
1131
1132 static void vl_api_classify_add_del_table_reply_t_handler_json
1133   (vl_api_classify_add_del_table_reply_t * mp)
1134 {
1135   vat_main_t *vam = &vat_main;
1136   vat_json_node_t node;
1137
1138   vat_json_init_object (&node);
1139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1140   vat_json_object_add_uint (&node, "new_table_index",
1141                             ntohl (mp->new_table_index));
1142   vat_json_object_add_uint (&node, "skip_n_vectors",
1143                             ntohl (mp->skip_n_vectors));
1144   vat_json_object_add_uint (&node, "match_n_vectors",
1145                             ntohl (mp->match_n_vectors));
1146
1147   vat_json_print (vam->ofp, &node);
1148   vat_json_free (&node);
1149
1150   vam->retval = ntohl (mp->retval);
1151   vam->result_ready = 1;
1152 }
1153
1154 static void vl_api_get_node_index_reply_t_handler
1155   (vl_api_get_node_index_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   i32 retval = ntohl (mp->retval);
1159   if (vam->async_mode)
1160     {
1161       vam->async_errors += (retval < 0);
1162     }
1163   else
1164     {
1165       vam->retval = retval;
1166       if (retval == 0)
1167         errmsg ("node index %d", ntohl (mp->node_index));
1168       vam->result_ready = 1;
1169     }
1170 }
1171
1172 static void vl_api_get_node_index_reply_t_handler_json
1173   (vl_api_get_node_index_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177
1178   vat_json_init_object (&node);
1179   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1180   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1181
1182   vat_json_print (vam->ofp, &node);
1183   vat_json_free (&node);
1184
1185   vam->retval = ntohl (mp->retval);
1186   vam->result_ready = 1;
1187 }
1188
1189 static void vl_api_get_next_index_reply_t_handler
1190   (vl_api_get_next_index_reply_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   i32 retval = ntohl (mp->retval);
1194   if (vam->async_mode)
1195     {
1196       vam->async_errors += (retval < 0);
1197     }
1198   else
1199     {
1200       vam->retval = retval;
1201       if (retval == 0)
1202         errmsg ("next node index %d", ntohl (mp->next_index));
1203       vam->result_ready = 1;
1204     }
1205 }
1206
1207 static void vl_api_get_next_index_reply_t_handler_json
1208   (vl_api_get_next_index_reply_t * mp)
1209 {
1210   vat_main_t *vam = &vat_main;
1211   vat_json_node_t node;
1212
1213   vat_json_init_object (&node);
1214   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1215   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1216
1217   vat_json_print (vam->ofp, &node);
1218   vat_json_free (&node);
1219
1220   vam->retval = ntohl (mp->retval);
1221   vam->result_ready = 1;
1222 }
1223
1224 static void vl_api_add_node_next_reply_t_handler
1225   (vl_api_add_node_next_reply_t * mp)
1226 {
1227   vat_main_t *vam = &vat_main;
1228   i32 retval = ntohl (mp->retval);
1229   if (vam->async_mode)
1230     {
1231       vam->async_errors += (retval < 0);
1232     }
1233   else
1234     {
1235       vam->retval = retval;
1236       if (retval == 0)
1237         errmsg ("next index %d", ntohl (mp->next_index));
1238       vam->result_ready = 1;
1239     }
1240 }
1241
1242 static void vl_api_add_node_next_reply_t_handler_json
1243   (vl_api_add_node_next_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   vat_json_node_t node;
1247
1248   vat_json_init_object (&node);
1249   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1250   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1251
1252   vat_json_print (vam->ofp, &node);
1253   vat_json_free (&node);
1254
1255   vam->retval = ntohl (mp->retval);
1256   vam->result_ready = 1;
1257 }
1258
1259 static void vl_api_show_version_reply_t_handler
1260   (vl_api_show_version_reply_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   i32 retval = ntohl (mp->retval);
1264
1265   if (retval >= 0)
1266     {
1267       errmsg ("        program: %s", mp->program);
1268       errmsg ("        version: %s", mp->version);
1269       errmsg ("     build date: %s", mp->build_date);
1270       errmsg ("build directory: %s", mp->build_directory);
1271     }
1272   vam->retval = retval;
1273   vam->result_ready = 1;
1274 }
1275
1276 static void vl_api_show_version_reply_t_handler_json
1277   (vl_api_show_version_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t node;
1281
1282   vat_json_init_object (&node);
1283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1284   vat_json_object_add_string_copy (&node, "program", mp->program);
1285   vat_json_object_add_string_copy (&node, "version", mp->version);
1286   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1287   vat_json_object_add_string_copy (&node, "build_directory",
1288                                    mp->build_directory);
1289
1290   vat_json_print (vam->ofp, &node);
1291   vat_json_free (&node);
1292
1293   vam->retval = ntohl (mp->retval);
1294   vam->result_ready = 1;
1295 }
1296
1297 static void
1298 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1299 {
1300   u32 sw_if_index = ntohl (mp->sw_if_index);
1301   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1302           mp->mac_ip ? "mac/ip binding" : "address resolution",
1303           ntohl (mp->pid), format_ip4_address, &mp->address,
1304           format_ethernet_address, mp->new_mac, sw_if_index);
1305 }
1306
1307 static void
1308 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1309 {
1310   /* JSON output not supported */
1311 }
1312
1313 static void
1314 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1315 {
1316   u32 sw_if_index = ntohl (mp->sw_if_index);
1317   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1318           mp->mac_ip ? "mac/ip binding" : "address resolution",
1319           ntohl (mp->pid), format_ip6_address, mp->address,
1320           format_ethernet_address, mp->new_mac, sw_if_index);
1321 }
1322
1323 static void
1324 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1325 {
1326   /* JSON output not supported */
1327 }
1328
1329 static void
1330 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1331 {
1332   u32 n_macs = ntohl (mp->n_macs);
1333   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1334           ntohl (mp->pid), mp->client_index, n_macs);
1335   int i;
1336   for (i = 0; i < n_macs; i++)
1337     {
1338       vl_api_mac_entry_t *mac = &mp->mac[i];
1339       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1340               i + 1, ntohl (mac->sw_if_index),
1341               format_ethernet_address, mac->mac_addr, mac->is_del);
1342       if (i == 1000)
1343         break;
1344     }
1345 }
1346
1347 static void
1348 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1349 {
1350   /* JSON output not supported */
1351 }
1352
1353 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1354 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1355
1356 /*
1357  * Special-case: build the bridge domain table, maintain
1358  * the next bd id vbl.
1359  */
1360 static void vl_api_bridge_domain_details_t_handler
1361   (vl_api_bridge_domain_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1365   int i;
1366
1367   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1368          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1369
1370   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1371          ntohl (mp->bd_id), mp->learn, mp->forward,
1372          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1373
1374   if (n_sw_ifs)
1375     {
1376       vl_api_bridge_domain_sw_if_t *sw_ifs;
1377       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1378              "Interface Name");
1379
1380       sw_ifs = mp->sw_if_details;
1381       for (i = 0; i < n_sw_ifs; i++)
1382         {
1383           u8 *sw_if_name = 0;
1384           u32 sw_if_index;
1385           hash_pair_t *p;
1386
1387           sw_if_index = ntohl (sw_ifs->sw_if_index);
1388
1389           /* *INDENT-OFF* */
1390           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1391                              ({
1392                                if ((u32) p->value[0] == sw_if_index)
1393                                  {
1394                                    sw_if_name = (u8 *)(p->key);
1395                                    break;
1396                                  }
1397                              }));
1398           /* *INDENT-ON* */
1399           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1400                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1401                  "sw_if_index not found!");
1402
1403           sw_ifs++;
1404         }
1405     }
1406 }
1407
1408 static void vl_api_bridge_domain_details_t_handler_json
1409   (vl_api_bridge_domain_details_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t *node, *array = NULL;
1413   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1414
1415   if (VAT_JSON_ARRAY != vam->json_tree.type)
1416     {
1417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1418       vat_json_init_array (&vam->json_tree);
1419     }
1420   node = vat_json_array_add (&vam->json_tree);
1421
1422   vat_json_init_object (node);
1423   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1424   vat_json_object_add_uint (node, "flood", mp->flood);
1425   vat_json_object_add_uint (node, "forward", mp->forward);
1426   vat_json_object_add_uint (node, "learn", mp->learn);
1427   vat_json_object_add_uint (node, "bvi_sw_if_index",
1428                             ntohl (mp->bvi_sw_if_index));
1429   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1430   array = vat_json_object_add (node, "sw_if");
1431   vat_json_init_array (array);
1432
1433
1434
1435   if (n_sw_ifs)
1436     {
1437       vl_api_bridge_domain_sw_if_t *sw_ifs;
1438       int i;
1439
1440       sw_ifs = mp->sw_if_details;
1441       for (i = 0; i < n_sw_ifs; i++)
1442         {
1443           node = vat_json_array_add (array);
1444           vat_json_init_object (node);
1445           vat_json_object_add_uint (node, "sw_if_index",
1446                                     ntohl (sw_ifs->sw_if_index));
1447           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1448           sw_ifs++;
1449         }
1450     }
1451 }
1452
1453 static void vl_api_control_ping_reply_t_handler
1454   (vl_api_control_ping_reply_t * mp)
1455 {
1456   vat_main_t *vam = &vat_main;
1457   i32 retval = ntohl (mp->retval);
1458   if (vam->async_mode)
1459     {
1460       vam->async_errors += (retval < 0);
1461     }
1462   else
1463     {
1464       vam->retval = retval;
1465       vam->result_ready = 1;
1466     }
1467   vam->socket_client_main.control_pings_outstanding--;
1468 }
1469
1470 static void vl_api_control_ping_reply_t_handler_json
1471   (vl_api_control_ping_reply_t * mp)
1472 {
1473   vat_main_t *vam = &vat_main;
1474   i32 retval = ntohl (mp->retval);
1475
1476   if (VAT_JSON_NONE != vam->json_tree.type)
1477     {
1478       vat_json_print (vam->ofp, &vam->json_tree);
1479       vat_json_free (&vam->json_tree);
1480       vam->json_tree.type = VAT_JSON_NONE;
1481     }
1482   else
1483     {
1484       /* just print [] */
1485       vat_json_init_array (&vam->json_tree);
1486       vat_json_print (vam->ofp, &vam->json_tree);
1487       vam->json_tree.type = VAT_JSON_NONE;
1488     }
1489
1490   vam->retval = retval;
1491   vam->result_ready = 1;
1492 }
1493
1494 static void
1495   vl_api_bridge_domain_set_mac_age_reply_t_handler
1496   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   i32 retval = ntohl (mp->retval);
1500   if (vam->async_mode)
1501     {
1502       vam->async_errors += (retval < 0);
1503     }
1504   else
1505     {
1506       vam->retval = retval;
1507       vam->result_ready = 1;
1508     }
1509 }
1510
1511 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1512   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t node;
1516
1517   vat_json_init_object (&node);
1518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void
1528 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->result_ready = 1;
1540     }
1541 }
1542
1543 static void vl_api_l2_flags_reply_t_handler_json
1544   (vl_api_l2_flags_reply_t * mp)
1545 {
1546   vat_main_t *vam = &vat_main;
1547   vat_json_node_t node;
1548
1549   vat_json_init_object (&node);
1550   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1551   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1552                             ntohl (mp->resulting_feature_bitmap));
1553
1554   vat_json_print (vam->ofp, &node);
1555   vat_json_free (&node);
1556
1557   vam->retval = ntohl (mp->retval);
1558   vam->result_ready = 1;
1559 }
1560
1561 static void vl_api_bridge_flags_reply_t_handler
1562   (vl_api_bridge_flags_reply_t * mp)
1563 {
1564   vat_main_t *vam = &vat_main;
1565   i32 retval = ntohl (mp->retval);
1566   if (vam->async_mode)
1567     {
1568       vam->async_errors += (retval < 0);
1569     }
1570   else
1571     {
1572       vam->retval = retval;
1573       vam->result_ready = 1;
1574     }
1575 }
1576
1577 static void vl_api_bridge_flags_reply_t_handler_json
1578   (vl_api_bridge_flags_reply_t * mp)
1579 {
1580   vat_main_t *vam = &vat_main;
1581   vat_json_node_t node;
1582
1583   vat_json_init_object (&node);
1584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1585   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1586                             ntohl (mp->resulting_feature_bitmap));
1587
1588   vat_json_print (vam->ofp, &node);
1589   vat_json_free (&node);
1590
1591   vam->retval = ntohl (mp->retval);
1592   vam->result_ready = 1;
1593 }
1594
1595 static void vl_api_tap_connect_reply_t_handler
1596   (vl_api_tap_connect_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600   if (vam->async_mode)
1601     {
1602       vam->async_errors += (retval < 0);
1603     }
1604   else
1605     {
1606       vam->retval = retval;
1607       vam->sw_if_index = ntohl (mp->sw_if_index);
1608       vam->result_ready = 1;
1609     }
1610
1611 }
1612
1613 static void vl_api_tap_connect_reply_t_handler_json
1614   (vl_api_tap_connect_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1622
1623   vat_json_print (vam->ofp, &node);
1624   vat_json_free (&node);
1625
1626   vam->retval = ntohl (mp->retval);
1627   vam->result_ready = 1;
1628
1629 }
1630
1631 static void
1632 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->sw_if_index = ntohl (mp->sw_if_index);
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_tap_modify_reply_t_handler_json
1649   (vl_api_tap_modify_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void
1666 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_tap_delete_reply_t_handler_json
1682   (vl_api_tap_delete_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void
1698 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->sw_if_index = ntohl (mp->sw_if_index);
1710       vam->result_ready = 1;
1711     }
1712
1713 }
1714
1715 static void vl_api_tap_create_v2_reply_t_handler_json
1716   (vl_api_tap_create_v2_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730
1731 }
1732
1733 static void
1734 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_tap_delete_v2_reply_t_handler_json
1750   (vl_api_tap_delete_v2_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757
1758   vat_json_print (vam->ofp, &node);
1759   vat_json_free (&node);
1760
1761   vam->retval = ntohl (mp->retval);
1762   vam->result_ready = 1;
1763 }
1764
1765 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1766   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1767 {
1768   vat_main_t *vam = &vat_main;
1769   i32 retval = ntohl (mp->retval);
1770   if (vam->async_mode)
1771     {
1772       vam->async_errors += (retval < 0);
1773     }
1774   else
1775     {
1776       vam->retval = retval;
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1782   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1790                             ntohl (mp->sw_if_index));
1791
1792   vat_json_print (vam->ofp, &node);
1793   vat_json_free (&node);
1794
1795   vam->retval = ntohl (mp->retval);
1796   vam->result_ready = 1;
1797 }
1798
1799 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1800   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   i32 retval = ntohl (mp->retval);
1804   if (vam->async_mode)
1805     {
1806       vam->async_errors += (retval < 0);
1807     }
1808   else
1809     {
1810       vam->retval = retval;
1811       vam->sw_if_index = ntohl (mp->sw_if_index);
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1817   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831 }
1832
1833 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1834   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   i32 retval = ntohl (mp->retval);
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1850   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "fwd_entry_index",
1858                             clib_net_to_host_u32 (mp->fwd_entry_index));
1859
1860   vat_json_print (vam->ofp, &node);
1861   vat_json_free (&node);
1862
1863   vam->retval = ntohl (mp->retval);
1864   vam->result_ready = 1;
1865 }
1866
1867 u8 *
1868 format_lisp_transport_protocol (u8 * s, va_list * args)
1869 {
1870   u32 proto = va_arg (*args, u32);
1871
1872   switch (proto)
1873     {
1874     case 1:
1875       return format (s, "udp");
1876     case 2:
1877       return format (s, "api");
1878     default:
1879       return 0;
1880     }
1881   return 0;
1882 }
1883
1884 static void vl_api_one_get_transport_protocol_reply_t_handler
1885   (vl_api_one_get_transport_protocol_reply_t * mp)
1886 {
1887   vat_main_t *vam = &vat_main;
1888   i32 retval = ntohl (mp->retval);
1889   if (vam->async_mode)
1890     {
1891       vam->async_errors += (retval < 0);
1892     }
1893   else
1894     {
1895       u32 proto = mp->protocol;
1896       print (vam->ofp, "Transport protocol: %U",
1897              format_lisp_transport_protocol, proto);
1898       vam->retval = retval;
1899       vam->result_ready = 1;
1900     }
1901 }
1902
1903 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1904   (vl_api_one_get_transport_protocol_reply_t * mp)
1905 {
1906   vat_main_t *vam = &vat_main;
1907   vat_json_node_t node;
1908   u8 *s;
1909
1910   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1911   vec_add1 (s, 0);
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1916
1917   vec_free (s);
1918   vat_json_print (vam->ofp, &node);
1919   vat_json_free (&node);
1920
1921   vam->retval = ntohl (mp->retval);
1922   vam->result_ready = 1;
1923 }
1924
1925 static void vl_api_one_add_del_locator_set_reply_t_handler
1926   (vl_api_one_add_del_locator_set_reply_t * mp)
1927 {
1928   vat_main_t *vam = &vat_main;
1929   i32 retval = ntohl (mp->retval);
1930   if (vam->async_mode)
1931     {
1932       vam->async_errors += (retval < 0);
1933     }
1934   else
1935     {
1936       vam->retval = retval;
1937       vam->result_ready = 1;
1938     }
1939 }
1940
1941 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1942   (vl_api_one_add_del_locator_set_reply_t * mp)
1943 {
1944   vat_main_t *vam = &vat_main;
1945   vat_json_node_t node;
1946
1947   vat_json_init_object (&node);
1948   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1949   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1950
1951   vat_json_print (vam->ofp, &node);
1952   vat_json_free (&node);
1953
1954   vam->retval = ntohl (mp->retval);
1955   vam->result_ready = 1;
1956 }
1957
1958 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1959   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   i32 retval = ntohl (mp->retval);
1963   if (vam->async_mode)
1964     {
1965       vam->async_errors += (retval < 0);
1966     }
1967   else
1968     {
1969       vam->retval = retval;
1970       vam->sw_if_index = ntohl (mp->sw_if_index);
1971       vam->result_ready = 1;
1972     }
1973 }
1974
1975 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1976   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   vat_json_node_t node;
1980
1981   vat_json_init_object (&node);
1982   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1983   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1984
1985   vat_json_print (vam->ofp, &node);
1986   vat_json_free (&node);
1987
1988   vam->retval = ntohl (mp->retval);
1989   vam->result_ready = 1;
1990 }
1991
1992 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1993   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   i32 retval = ntohl (mp->retval);
1997   if (vam->async_mode)
1998     {
1999       vam->async_errors += (retval < 0);
2000     }
2001   else
2002     {
2003       vam->retval = retval;
2004       vam->sw_if_index = ntohl (mp->sw_if_index);
2005       vam->result_ready = 1;
2006     }
2007 }
2008
2009 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2010   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2011 {
2012   vat_main_t *vam = &vat_main;
2013   vat_json_node_t node;
2014
2015   vat_json_init_object (&node);
2016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2017   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2018
2019   vat_json_print (vam->ofp, &node);
2020   vat_json_free (&node);
2021
2022   vam->retval = ntohl (mp->retval);
2023   vam->result_ready = 1;
2024 }
2025
2026 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2027   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2028 {
2029   vat_main_t *vam = &vat_main;
2030   i32 retval = ntohl (mp->retval);
2031   if (vam->async_mode)
2032     {
2033       vam->async_errors += (retval < 0);
2034     }
2035   else
2036     {
2037       vam->retval = retval;
2038       vam->sw_if_index = ntohl (mp->sw_if_index);
2039       vam->result_ready = 1;
2040     }
2041 }
2042
2043 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2044   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047   vat_json_node_t node;
2048
2049   vat_json_init_object (&node);
2050   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2051   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2052
2053   vat_json_print (vam->ofp, &node);
2054   vat_json_free (&node);
2055
2056   vam->retval = ntohl (mp->retval);
2057   vam->result_ready = 1;
2058 }
2059
2060 static void vl_api_gre_add_del_tunnel_reply_t_handler
2061   (vl_api_gre_add_del_tunnel_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->sw_if_index = ntohl (mp->sw_if_index);
2073       vam->result_ready = 1;
2074     }
2075 }
2076
2077 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2078   (vl_api_gre_add_del_tunnel_reply_t * mp)
2079 {
2080   vat_main_t *vam = &vat_main;
2081   vat_json_node_t node;
2082
2083   vat_json_init_object (&node);
2084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2085   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_create_vhost_user_if_reply_t_handler
2095   (vl_api_create_vhost_user_if_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_create_vhost_user_if_reply_t_handler_json
2112   (vl_api_create_vhost_user_if_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static clib_error_t *
2129 receive_fd_msg (int socket_fd, int *my_fd)
2130 {
2131   char msgbuf[16];
2132   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2133   struct msghdr mh = { 0 };
2134   struct iovec iov[1];
2135   ssize_t size;
2136   struct ucred *cr = 0;
2137   struct cmsghdr *cmsg;
2138   pid_t pid __attribute__ ((unused));
2139   uid_t uid __attribute__ ((unused));
2140   gid_t gid __attribute__ ((unused));
2141
2142   iov[0].iov_base = msgbuf;
2143   iov[0].iov_len = 5;
2144   mh.msg_iov = iov;
2145   mh.msg_iovlen = 1;
2146   mh.msg_control = ctl;
2147   mh.msg_controllen = sizeof (ctl);
2148
2149   memset (ctl, 0, sizeof (ctl));
2150
2151   /* receive the incoming message */
2152   size = recvmsg (socket_fd, &mh, 0);
2153   if (size != 5)
2154     {
2155       return (size == 0) ? clib_error_return (0, "disconnected") :
2156         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2157                                 socket_fd);
2158     }
2159
2160   cmsg = CMSG_FIRSTHDR (&mh);
2161   while (cmsg)
2162     {
2163       if (cmsg->cmsg_level == SOL_SOCKET)
2164         {
2165           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2166             {
2167               cr = (struct ucred *) CMSG_DATA (cmsg);
2168               uid = cr->uid;
2169               gid = cr->gid;
2170               pid = cr->pid;
2171             }
2172           else if (cmsg->cmsg_type == SCM_RIGHTS)
2173             {
2174               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2175             }
2176         }
2177       cmsg = CMSG_NXTHDR (&mh, cmsg);
2178     }
2179   return 0;
2180 }
2181
2182 static void vl_api_memfd_segment_create_reply_t_handler
2183   (vl_api_memfd_segment_create_reply_t * mp)
2184 {
2185   /* Dont bother in the builtin version */
2186 #if VPP_API_TEST_BUILTIN == 0
2187   vat_main_t *vam = &vat_main;
2188   api_main_t *am = &api_main;
2189   socket_client_main_t *scm = &vam->socket_client_main;
2190   int my_fd = -1;
2191   clib_error_t *error;
2192   memfd_private_t memfd;
2193   i32 retval = ntohl (mp->retval);
2194
2195   if (retval == 0)
2196     {
2197       error = receive_fd_msg (scm->socket_fd, &my_fd);
2198       if (error)
2199         {
2200           retval = -99;
2201           goto out;
2202         }
2203
2204       memset (&memfd, 0, sizeof (memfd));
2205       memfd.fd = my_fd;
2206
2207       vam->client_index_invalid = 1;
2208
2209       /* Note: this closes memfd.fd */
2210       retval = memfd_slave_init (&memfd);
2211       if (retval)
2212         clib_warning ("WARNING: segment map returned %d", retval);
2213
2214       /* Pivot to the memory client segment that vpp just created */
2215
2216       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2217
2218       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2219
2220       vl_client_install_client_message_handlers ();
2221
2222       vl_client_connect_to_vlib_no_map ("pvt",
2223                                         "vpp_api_test(p)",
2224                                         32 /* input_queue_length */ );
2225       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2226
2227       vl_socket_client_enable_disable (&vam->socket_client_main,
2228                                        0 /* disable socket */ );
2229     }
2230
2231 out:
2232   if (vam->async_mode)
2233     {
2234       vam->async_errors += (retval < 0);
2235     }
2236   else
2237     {
2238       vam->retval = retval;
2239       vam->result_ready = 1;
2240     }
2241 #endif
2242 }
2243
2244 static void vl_api_memfd_segment_create_reply_t_handler_json
2245   (vl_api_memfd_segment_create_reply_t * mp)
2246 {
2247   clib_warning ("no");
2248 }
2249
2250 static void vl_api_dns_resolve_name_reply_t_handler
2251   (vl_api_dns_resolve_name_reply_t * mp)
2252 {
2253   vat_main_t *vam = &vat_main;
2254   i32 retval = ntohl (mp->retval);
2255   if (vam->async_mode)
2256     {
2257       vam->async_errors += (retval < 0);
2258     }
2259   else
2260     {
2261       vam->retval = retval;
2262       vam->result_ready = 1;
2263
2264       if (retval == 0)
2265         {
2266           if (mp->ip4_set)
2267             clib_warning ("ip4 address %U", format_ip4_address,
2268                           (ip4_address_t *) mp->ip4_address);
2269           if (mp->ip6_set)
2270             clib_warning ("ip6 address %U", format_ip6_address,
2271                           (ip6_address_t *) mp->ip6_address);
2272         }
2273       else
2274         clib_warning ("retval %d", retval);
2275     }
2276 }
2277
2278 static void vl_api_dns_resolve_name_reply_t_handler_json
2279   (vl_api_dns_resolve_name_reply_t * mp)
2280 {
2281   clib_warning ("not implemented");
2282 }
2283
2284 static void vl_api_dns_resolve_ip_reply_t_handler
2285   (vl_api_dns_resolve_ip_reply_t * mp)
2286 {
2287   vat_main_t *vam = &vat_main;
2288   i32 retval = ntohl (mp->retval);
2289   if (vam->async_mode)
2290     {
2291       vam->async_errors += (retval < 0);
2292     }
2293   else
2294     {
2295       vam->retval = retval;
2296       vam->result_ready = 1;
2297
2298       if (retval == 0)
2299         {
2300           clib_warning ("canonical name %s", mp->name);
2301         }
2302       else
2303         clib_warning ("retval %d", retval);
2304     }
2305 }
2306
2307 static void vl_api_dns_resolve_ip_reply_t_handler_json
2308   (vl_api_dns_resolve_ip_reply_t * mp)
2309 {
2310   clib_warning ("not implemented");
2311 }
2312
2313
2314 static void vl_api_ip_address_details_t_handler
2315   (vl_api_ip_address_details_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   static ip_address_details_t empty_ip_address_details = { {0} };
2319   ip_address_details_t *address = NULL;
2320   ip_details_t *current_ip_details = NULL;
2321   ip_details_t *details = NULL;
2322
2323   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2324
2325   if (!details || vam->current_sw_if_index >= vec_len (details)
2326       || !details[vam->current_sw_if_index].present)
2327     {
2328       errmsg ("ip address details arrived but not stored");
2329       errmsg ("ip_dump should be called first");
2330       return;
2331     }
2332
2333   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2334
2335 #define addresses (current_ip_details->addr)
2336
2337   vec_validate_init_empty (addresses, vec_len (addresses),
2338                            empty_ip_address_details);
2339
2340   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2341
2342   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2343   address->prefix_length = mp->prefix_length;
2344 #undef addresses
2345 }
2346
2347 static void vl_api_ip_address_details_t_handler_json
2348   (vl_api_ip_address_details_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   vat_json_node_t *node = NULL;
2352   struct in6_addr ip6;
2353   struct in_addr ip4;
2354
2355   if (VAT_JSON_ARRAY != vam->json_tree.type)
2356     {
2357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2358       vat_json_init_array (&vam->json_tree);
2359     }
2360   node = vat_json_array_add (&vam->json_tree);
2361
2362   vat_json_init_object (node);
2363   if (vam->is_ipv6)
2364     {
2365       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2366       vat_json_object_add_ip6 (node, "ip", ip6);
2367     }
2368   else
2369     {
2370       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2371       vat_json_object_add_ip4 (node, "ip", ip4);
2372     }
2373   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2374 }
2375
2376 static void
2377 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   static ip_details_t empty_ip_details = { 0 };
2381   ip_details_t *ip = NULL;
2382   u32 sw_if_index = ~0;
2383
2384   sw_if_index = ntohl (mp->sw_if_index);
2385
2386   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2387                            sw_if_index, empty_ip_details);
2388
2389   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2390                          sw_if_index);
2391
2392   ip->present = 1;
2393 }
2394
2395 static void
2396 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399
2400   if (VAT_JSON_ARRAY != vam->json_tree.type)
2401     {
2402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2403       vat_json_init_array (&vam->json_tree);
2404     }
2405   vat_json_array_add_uint (&vam->json_tree,
2406                            clib_net_to_host_u32 (mp->sw_if_index));
2407 }
2408
2409 static void vl_api_map_domain_details_t_handler_json
2410   (vl_api_map_domain_details_t * mp)
2411 {
2412   vat_json_node_t *node = NULL;
2413   vat_main_t *vam = &vat_main;
2414   struct in6_addr ip6;
2415   struct in_addr ip4;
2416
2417   if (VAT_JSON_ARRAY != vam->json_tree.type)
2418     {
2419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2420       vat_json_init_array (&vam->json_tree);
2421     }
2422
2423   node = vat_json_array_add (&vam->json_tree);
2424   vat_json_init_object (node);
2425
2426   vat_json_object_add_uint (node, "domain_index",
2427                             clib_net_to_host_u32 (mp->domain_index));
2428   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2429   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2430   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2431   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2432   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2433   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2434   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2435   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2436   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2437   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2438   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2439   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2440   vat_json_object_add_uint (node, "flags", mp->flags);
2441   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2442   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2443 }
2444
2445 static void vl_api_map_domain_details_t_handler
2446   (vl_api_map_domain_details_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449
2450   if (mp->is_translation)
2451     {
2452       print (vam->ofp,
2453              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2454              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2455              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2456              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2457              clib_net_to_host_u32 (mp->domain_index));
2458     }
2459   else
2460     {
2461       print (vam->ofp,
2462              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2463              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2464              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2465              format_ip6_address, mp->ip6_src,
2466              clib_net_to_host_u32 (mp->domain_index));
2467     }
2468   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2469          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2470          mp->is_translation ? "map-t" : "");
2471 }
2472
2473 static void vl_api_map_rule_details_t_handler_json
2474   (vl_api_map_rule_details_t * mp)
2475 {
2476   struct in6_addr ip6;
2477   vat_json_node_t *node = NULL;
2478   vat_main_t *vam = &vat_main;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485
2486   node = vat_json_array_add (&vam->json_tree);
2487   vat_json_init_object (node);
2488
2489   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2490   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2491   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2492 }
2493
2494 static void
2495 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2499          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2500 }
2501
2502 static void
2503 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2504 {
2505   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2506           "router_addr %U host_mac %U",
2507           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2508           format_ip4_address, &mp->host_address,
2509           format_ip4_address, &mp->router_address,
2510           format_ethernet_address, mp->host_mac);
2511 }
2512
2513 static void vl_api_dhcp_compl_event_t_handler_json
2514   (vl_api_dhcp_compl_event_t * mp)
2515 {
2516   /* JSON output not supported */
2517 }
2518
2519 static void
2520 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2521                               u32 counter)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   static u64 default_counter = 0;
2525
2526   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2527                            NULL);
2528   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2529                            sw_if_index, default_counter);
2530   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2531 }
2532
2533 static void
2534 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2535                                 interface_counter_t counter)
2536 {
2537   vat_main_t *vam = &vat_main;
2538   static interface_counter_t default_counter = { 0, };
2539
2540   vec_validate_init_empty (vam->combined_interface_counters,
2541                            vnet_counter_type, NULL);
2542   vec_validate_init_empty (vam->combined_interface_counters
2543                            [vnet_counter_type], sw_if_index, default_counter);
2544   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2545 }
2546
2547 static void vl_api_vnet_interface_simple_counters_t_handler
2548   (vl_api_vnet_interface_simple_counters_t * mp)
2549 {
2550   /* not supported */
2551 }
2552
2553 static void vl_api_vnet_interface_combined_counters_t_handler
2554   (vl_api_vnet_interface_combined_counters_t * mp)
2555 {
2556   /* not supported */
2557 }
2558
2559 static void vl_api_vnet_interface_simple_counters_t_handler_json
2560   (vl_api_vnet_interface_simple_counters_t * mp)
2561 {
2562   u64 *v_packets;
2563   u64 packets;
2564   u32 count;
2565   u32 first_sw_if_index;
2566   int i;
2567
2568   count = ntohl (mp->count);
2569   first_sw_if_index = ntohl (mp->first_sw_if_index);
2570
2571   v_packets = (u64 *) & mp->data;
2572   for (i = 0; i < count; i++)
2573     {
2574       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2575       set_simple_interface_counter (mp->vnet_counter_type,
2576                                     first_sw_if_index + i, packets);
2577       v_packets++;
2578     }
2579 }
2580
2581 static void vl_api_vnet_interface_combined_counters_t_handler_json
2582   (vl_api_vnet_interface_combined_counters_t * mp)
2583 {
2584   interface_counter_t counter;
2585   vlib_counter_t *v;
2586   u32 first_sw_if_index;
2587   int i;
2588   u32 count;
2589
2590   count = ntohl (mp->count);
2591   first_sw_if_index = ntohl (mp->first_sw_if_index);
2592
2593   v = (vlib_counter_t *) & mp->data;
2594   for (i = 0; i < count; i++)
2595     {
2596       counter.packets =
2597         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2598       counter.bytes =
2599         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2600       set_combined_interface_counter (mp->vnet_counter_type,
2601                                       first_sw_if_index + i, counter);
2602       v++;
2603     }
2604 }
2605
2606 static u32
2607 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u32 i;
2611
2612   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2613     {
2614       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2615         {
2616           return i;
2617         }
2618     }
2619   return ~0;
2620 }
2621
2622 static u32
2623 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2624 {
2625   vat_main_t *vam = &vat_main;
2626   u32 i;
2627
2628   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2629     {
2630       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2631         {
2632           return i;
2633         }
2634     }
2635   return ~0;
2636 }
2637
2638 static void vl_api_vnet_ip4_fib_counters_t_handler
2639   (vl_api_vnet_ip4_fib_counters_t * mp)
2640 {
2641   /* not supported */
2642 }
2643
2644 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2645   (vl_api_vnet_ip4_fib_counters_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   vl_api_ip4_fib_counter_t *v;
2649   ip4_fib_counter_t *counter;
2650   struct in_addr ip4;
2651   u32 vrf_id;
2652   u32 vrf_index;
2653   u32 count;
2654   int i;
2655
2656   vrf_id = ntohl (mp->vrf_id);
2657   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2658   if (~0 == vrf_index)
2659     {
2660       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2661       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2662       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2663       vec_validate (vam->ip4_fib_counters, vrf_index);
2664       vam->ip4_fib_counters[vrf_index] = NULL;
2665     }
2666
2667   vec_free (vam->ip4_fib_counters[vrf_index]);
2668   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2669   count = ntohl (mp->count);
2670   for (i = 0; i < count; i++)
2671     {
2672       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2673       counter = &vam->ip4_fib_counters[vrf_index][i];
2674       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2675       counter->address = ip4;
2676       counter->address_length = v->address_length;
2677       counter->packets = clib_net_to_host_u64 (v->packets);
2678       counter->bytes = clib_net_to_host_u64 (v->bytes);
2679       v++;
2680     }
2681 }
2682
2683 static void vl_api_vnet_ip4_nbr_counters_t_handler
2684   (vl_api_vnet_ip4_nbr_counters_t * mp)
2685 {
2686   /* not supported */
2687 }
2688
2689 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2690   (vl_api_vnet_ip4_nbr_counters_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693   vl_api_ip4_nbr_counter_t *v;
2694   ip4_nbr_counter_t *counter;
2695   u32 sw_if_index;
2696   u32 count;
2697   int i;
2698
2699   sw_if_index = ntohl (mp->sw_if_index);
2700   count = ntohl (mp->count);
2701   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2702
2703   if (mp->begin)
2704     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2705
2706   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2707   for (i = 0; i < count; i++)
2708     {
2709       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2710       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2711       counter->address.s_addr = v->address;
2712       counter->packets = clib_net_to_host_u64 (v->packets);
2713       counter->bytes = clib_net_to_host_u64 (v->bytes);
2714       counter->linkt = v->link_type;
2715       v++;
2716     }
2717 }
2718
2719 static void vl_api_vnet_ip6_fib_counters_t_handler
2720   (vl_api_vnet_ip6_fib_counters_t * mp)
2721 {
2722   /* not supported */
2723 }
2724
2725 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2726   (vl_api_vnet_ip6_fib_counters_t * mp)
2727 {
2728   vat_main_t *vam = &vat_main;
2729   vl_api_ip6_fib_counter_t *v;
2730   ip6_fib_counter_t *counter;
2731   struct in6_addr ip6;
2732   u32 vrf_id;
2733   u32 vrf_index;
2734   u32 count;
2735   int i;
2736
2737   vrf_id = ntohl (mp->vrf_id);
2738   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2739   if (~0 == vrf_index)
2740     {
2741       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2742       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2743       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2744       vec_validate (vam->ip6_fib_counters, vrf_index);
2745       vam->ip6_fib_counters[vrf_index] = NULL;
2746     }
2747
2748   vec_free (vam->ip6_fib_counters[vrf_index]);
2749   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2750   count = ntohl (mp->count);
2751   for (i = 0; i < count; i++)
2752     {
2753       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2754       counter = &vam->ip6_fib_counters[vrf_index][i];
2755       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2756       counter->address = ip6;
2757       counter->address_length = v->address_length;
2758       counter->packets = clib_net_to_host_u64 (v->packets);
2759       counter->bytes = clib_net_to_host_u64 (v->bytes);
2760       v++;
2761     }
2762 }
2763
2764 static void vl_api_vnet_ip6_nbr_counters_t_handler
2765   (vl_api_vnet_ip6_nbr_counters_t * mp)
2766 {
2767   /* not supported */
2768 }
2769
2770 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2771   (vl_api_vnet_ip6_nbr_counters_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   vl_api_ip6_nbr_counter_t *v;
2775   ip6_nbr_counter_t *counter;
2776   struct in6_addr ip6;
2777   u32 sw_if_index;
2778   u32 count;
2779   int i;
2780
2781   sw_if_index = ntohl (mp->sw_if_index);
2782   count = ntohl (mp->count);
2783   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2784
2785   if (mp->begin)
2786     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2787
2788   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2789   for (i = 0; i < count; i++)
2790     {
2791       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2792       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2793       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2794       counter->address = ip6;
2795       counter->packets = clib_net_to_host_u64 (v->packets);
2796       counter->bytes = clib_net_to_host_u64 (v->bytes);
2797       v++;
2798     }
2799 }
2800
2801 static void vl_api_get_first_msg_id_reply_t_handler
2802   (vl_api_get_first_msg_id_reply_t * mp)
2803 {
2804   vat_main_t *vam = &vat_main;
2805   i32 retval = ntohl (mp->retval);
2806
2807   if (vam->async_mode)
2808     {
2809       vam->async_errors += (retval < 0);
2810     }
2811   else
2812     {
2813       vam->retval = retval;
2814       vam->result_ready = 1;
2815     }
2816   if (retval >= 0)
2817     {
2818       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2819     }
2820 }
2821
2822 static void vl_api_get_first_msg_id_reply_t_handler_json
2823   (vl_api_get_first_msg_id_reply_t * mp)
2824 {
2825   vat_main_t *vam = &vat_main;
2826   vat_json_node_t node;
2827
2828   vat_json_init_object (&node);
2829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2830   vat_json_object_add_uint (&node, "first_msg_id",
2831                             (uint) ntohs (mp->first_msg_id));
2832
2833   vat_json_print (vam->ofp, &node);
2834   vat_json_free (&node);
2835
2836   vam->retval = ntohl (mp->retval);
2837   vam->result_ready = 1;
2838 }
2839
2840 static void vl_api_get_node_graph_reply_t_handler
2841   (vl_api_get_node_graph_reply_t * mp)
2842 {
2843   vat_main_t *vam = &vat_main;
2844   api_main_t *am = &api_main;
2845   i32 retval = ntohl (mp->retval);
2846   u8 *pvt_copy, *reply;
2847   void *oldheap;
2848   vlib_node_t *node;
2849   int i;
2850
2851   if (vam->async_mode)
2852     {
2853       vam->async_errors += (retval < 0);
2854     }
2855   else
2856     {
2857       vam->retval = retval;
2858       vam->result_ready = 1;
2859     }
2860
2861   /* "Should never happen..." */
2862   if (retval != 0)
2863     return;
2864
2865   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2866   pvt_copy = vec_dup (reply);
2867
2868   /* Toss the shared-memory original... */
2869   pthread_mutex_lock (&am->vlib_rp->mutex);
2870   oldheap = svm_push_data_heap (am->vlib_rp);
2871
2872   vec_free (reply);
2873
2874   svm_pop_heap (oldheap);
2875   pthread_mutex_unlock (&am->vlib_rp->mutex);
2876
2877   if (vam->graph_nodes)
2878     {
2879       hash_free (vam->graph_node_index_by_name);
2880
2881       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2882         {
2883           node = vam->graph_nodes[i];
2884           vec_free (node->name);
2885           vec_free (node->next_nodes);
2886           vec_free (node);
2887         }
2888       vec_free (vam->graph_nodes);
2889     }
2890
2891   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2892   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2893   vec_free (pvt_copy);
2894
2895   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2896     {
2897       node = vam->graph_nodes[i];
2898       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2899     }
2900 }
2901
2902 static void vl_api_get_node_graph_reply_t_handler_json
2903   (vl_api_get_node_graph_reply_t * mp)
2904 {
2905   vat_main_t *vam = &vat_main;
2906   api_main_t *am = &api_main;
2907   void *oldheap;
2908   vat_json_node_t node;
2909   u8 *reply;
2910
2911   /* $$$$ make this real? */
2912   vat_json_init_object (&node);
2913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2914   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2915
2916   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2917
2918   /* Toss the shared-memory original... */
2919   pthread_mutex_lock (&am->vlib_rp->mutex);
2920   oldheap = svm_push_data_heap (am->vlib_rp);
2921
2922   vec_free (reply);
2923
2924   svm_pop_heap (oldheap);
2925   pthread_mutex_unlock (&am->vlib_rp->mutex);
2926
2927   vat_json_print (vam->ofp, &node);
2928   vat_json_free (&node);
2929
2930   vam->retval = ntohl (mp->retval);
2931   vam->result_ready = 1;
2932 }
2933
2934 static void
2935 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   u8 *s = 0;
2939
2940   if (mp->local)
2941     {
2942       s = format (s, "%=16d%=16d%=16d",
2943                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2944     }
2945   else
2946     {
2947       s = format (s, "%=16U%=16d%=16d",
2948                   mp->is_ipv6 ? format_ip6_address :
2949                   format_ip4_address,
2950                   mp->ip_address, mp->priority, mp->weight);
2951     }
2952
2953   print (vam->ofp, "%v", s);
2954   vec_free (s);
2955 }
2956
2957 static void
2958 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   vat_json_node_t *node = NULL;
2962   struct in6_addr ip6;
2963   struct in_addr ip4;
2964
2965   if (VAT_JSON_ARRAY != vam->json_tree.type)
2966     {
2967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2968       vat_json_init_array (&vam->json_tree);
2969     }
2970   node = vat_json_array_add (&vam->json_tree);
2971   vat_json_init_object (node);
2972
2973   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2974   vat_json_object_add_uint (node, "priority", mp->priority);
2975   vat_json_object_add_uint (node, "weight", mp->weight);
2976
2977   if (mp->local)
2978     vat_json_object_add_uint (node, "sw_if_index",
2979                               clib_net_to_host_u32 (mp->sw_if_index));
2980   else
2981     {
2982       if (mp->is_ipv6)
2983         {
2984           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2985           vat_json_object_add_ip6 (node, "address", ip6);
2986         }
2987       else
2988         {
2989           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2990           vat_json_object_add_ip4 (node, "address", ip4);
2991         }
2992     }
2993 }
2994
2995 static void
2996 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2997                                           mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   u8 *ls_name = 0;
3001
3002   ls_name = format (0, "%s", mp->ls_name);
3003
3004   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3005          ls_name);
3006   vec_free (ls_name);
3007 }
3008
3009 static void
3010   vl_api_one_locator_set_details_t_handler_json
3011   (vl_api_one_locator_set_details_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vat_json_node_t *node = 0;
3015   u8 *ls_name = 0;
3016
3017   ls_name = format (0, "%s", mp->ls_name);
3018   vec_add1 (ls_name, 0);
3019
3020   if (VAT_JSON_ARRAY != vam->json_tree.type)
3021     {
3022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3023       vat_json_init_array (&vam->json_tree);
3024     }
3025   node = vat_json_array_add (&vam->json_tree);
3026
3027   vat_json_init_object (node);
3028   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3029   vat_json_object_add_uint (node, "ls_index",
3030                             clib_net_to_host_u32 (mp->ls_index));
3031   vec_free (ls_name);
3032 }
3033
3034 typedef struct
3035 {
3036   u32 spi;
3037   u8 si;
3038 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3039
3040 uword
3041 unformat_nsh_address (unformat_input_t * input, va_list * args)
3042 {
3043   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3044   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3045 }
3046
3047 u8 *
3048 format_nsh_address_vat (u8 * s, va_list * args)
3049 {
3050   nsh_t *a = va_arg (*args, nsh_t *);
3051   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3052 }
3053
3054 static u8 *
3055 format_lisp_flat_eid (u8 * s, va_list * args)
3056 {
3057   u32 type = va_arg (*args, u32);
3058   u8 *eid = va_arg (*args, u8 *);
3059   u32 eid_len = va_arg (*args, u32);
3060
3061   switch (type)
3062     {
3063     case 0:
3064       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3065     case 1:
3066       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3067     case 2:
3068       return format (s, "%U", format_ethernet_address, eid);
3069     case 3:
3070       return format (s, "%U", format_nsh_address_vat, eid);
3071     }
3072   return 0;
3073 }
3074
3075 static u8 *
3076 format_lisp_eid_vat (u8 * s, va_list * args)
3077 {
3078   u32 type = va_arg (*args, u32);
3079   u8 *eid = va_arg (*args, u8 *);
3080   u32 eid_len = va_arg (*args, u32);
3081   u8 *seid = va_arg (*args, u8 *);
3082   u32 seid_len = va_arg (*args, u32);
3083   u32 is_src_dst = va_arg (*args, u32);
3084
3085   if (is_src_dst)
3086     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3087
3088   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3089
3090   return s;
3091 }
3092
3093 static void
3094 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097   u8 *s = 0, *eid = 0;
3098
3099   if (~0 == mp->locator_set_index)
3100     s = format (0, "action: %d", mp->action);
3101   else
3102     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3103
3104   eid = format (0, "%U", format_lisp_eid_vat,
3105                 mp->eid_type,
3106                 mp->eid,
3107                 mp->eid_prefix_len,
3108                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3109   vec_add1 (eid, 0);
3110
3111   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3112          clib_net_to_host_u32 (mp->vni),
3113          eid,
3114          mp->is_local ? "local" : "remote",
3115          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3116          clib_net_to_host_u16 (mp->key_id), mp->key);
3117
3118   vec_free (s);
3119   vec_free (eid);
3120 }
3121
3122 static void
3123 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3124                                              * mp)
3125 {
3126   vat_main_t *vam = &vat_main;
3127   vat_json_node_t *node = 0;
3128   u8 *eid = 0;
3129
3130   if (VAT_JSON_ARRAY != vam->json_tree.type)
3131     {
3132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133       vat_json_init_array (&vam->json_tree);
3134     }
3135   node = vat_json_array_add (&vam->json_tree);
3136
3137   vat_json_init_object (node);
3138   if (~0 == mp->locator_set_index)
3139     vat_json_object_add_uint (node, "action", mp->action);
3140   else
3141     vat_json_object_add_uint (node, "locator_set_index",
3142                               clib_net_to_host_u32 (mp->locator_set_index));
3143
3144   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3145   if (mp->eid_type == 3)
3146     {
3147       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3148       vat_json_init_object (nsh_json);
3149       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3150       vat_json_object_add_uint (nsh_json, "spi",
3151                                 clib_net_to_host_u32 (nsh->spi));
3152       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3153     }
3154   else
3155     {
3156       eid = format (0, "%U", format_lisp_eid_vat,
3157                     mp->eid_type,
3158                     mp->eid,
3159                     mp->eid_prefix_len,
3160                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3161       vec_add1 (eid, 0);
3162       vat_json_object_add_string_copy (node, "eid", eid);
3163       vec_free (eid);
3164     }
3165   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3166   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3167   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3168
3169   if (mp->key_id)
3170     {
3171       vat_json_object_add_uint (node, "key_id",
3172                                 clib_net_to_host_u16 (mp->key_id));
3173       vat_json_object_add_string_copy (node, "key", mp->key);
3174     }
3175 }
3176
3177 static void
3178 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   u8 *seid = 0, *deid = 0;
3182   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3183
3184   deid = format (0, "%U", format_lisp_eid_vat,
3185                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3186
3187   seid = format (0, "%U", format_lisp_eid_vat,
3188                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3189
3190   vec_add1 (deid, 0);
3191   vec_add1 (seid, 0);
3192
3193   if (mp->is_ip4)
3194     format_ip_address_fcn = format_ip4_address;
3195   else
3196     format_ip_address_fcn = format_ip6_address;
3197
3198
3199   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3200          clib_net_to_host_u32 (mp->vni),
3201          seid, deid,
3202          format_ip_address_fcn, mp->lloc,
3203          format_ip_address_fcn, mp->rloc,
3204          clib_net_to_host_u32 (mp->pkt_count),
3205          clib_net_to_host_u32 (mp->bytes));
3206
3207   vec_free (deid);
3208   vec_free (seid);
3209 }
3210
3211 static void
3212 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3213 {
3214   struct in6_addr ip6;
3215   struct in_addr ip4;
3216   vat_main_t *vam = &vat_main;
3217   vat_json_node_t *node = 0;
3218   u8 *deid = 0, *seid = 0;
3219
3220   if (VAT_JSON_ARRAY != vam->json_tree.type)
3221     {
3222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3223       vat_json_init_array (&vam->json_tree);
3224     }
3225   node = vat_json_array_add (&vam->json_tree);
3226
3227   vat_json_init_object (node);
3228   deid = format (0, "%U", format_lisp_eid_vat,
3229                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3230
3231   seid = format (0, "%U", format_lisp_eid_vat,
3232                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3233
3234   vec_add1 (deid, 0);
3235   vec_add1 (seid, 0);
3236
3237   vat_json_object_add_string_copy (node, "seid", seid);
3238   vat_json_object_add_string_copy (node, "deid", deid);
3239   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3240
3241   if (mp->is_ip4)
3242     {
3243       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3244       vat_json_object_add_ip4 (node, "lloc", ip4);
3245       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3246       vat_json_object_add_ip4 (node, "rloc", ip4);
3247     }
3248   else
3249     {
3250       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3251       vat_json_object_add_ip6 (node, "lloc", ip6);
3252       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3253       vat_json_object_add_ip6 (node, "rloc", ip6);
3254     }
3255   vat_json_object_add_uint (node, "pkt_count",
3256                             clib_net_to_host_u32 (mp->pkt_count));
3257   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3258
3259   vec_free (deid);
3260   vec_free (seid);
3261 }
3262
3263 static void
3264   vl_api_one_eid_table_map_details_t_handler
3265   (vl_api_one_eid_table_map_details_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268
3269   u8 *line = format (0, "%=10d%=10d",
3270                      clib_net_to_host_u32 (mp->vni),
3271                      clib_net_to_host_u32 (mp->dp_table));
3272   print (vam->ofp, "%v", line);
3273   vec_free (line);
3274 }
3275
3276 static void
3277   vl_api_one_eid_table_map_details_t_handler_json
3278   (vl_api_one_eid_table_map_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t *node = NULL;
3282
3283   if (VAT_JSON_ARRAY != vam->json_tree.type)
3284     {
3285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3286       vat_json_init_array (&vam->json_tree);
3287     }
3288   node = vat_json_array_add (&vam->json_tree);
3289   vat_json_init_object (node);
3290   vat_json_object_add_uint (node, "dp_table",
3291                             clib_net_to_host_u32 (mp->dp_table));
3292   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3293 }
3294
3295 static void
3296   vl_api_one_eid_table_vni_details_t_handler
3297   (vl_api_one_eid_table_vni_details_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300
3301   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3302   print (vam->ofp, "%v", line);
3303   vec_free (line);
3304 }
3305
3306 static void
3307   vl_api_one_eid_table_vni_details_t_handler_json
3308   (vl_api_one_eid_table_vni_details_t * mp)
3309 {
3310   vat_main_t *vam = &vat_main;
3311   vat_json_node_t *node = NULL;
3312
3313   if (VAT_JSON_ARRAY != vam->json_tree.type)
3314     {
3315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3316       vat_json_init_array (&vam->json_tree);
3317     }
3318   node = vat_json_array_add (&vam->json_tree);
3319   vat_json_init_object (node);
3320   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3321 }
3322
3323 static void
3324   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3325   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328   int retval = clib_net_to_host_u32 (mp->retval);
3329
3330   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3331   print (vam->ofp, "fallback threshold value: %d", mp->value);
3332
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335 }
3336
3337 static void
3338   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3339   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3340 {
3341   vat_main_t *vam = &vat_main;
3342   vat_json_node_t _node, *node = &_node;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3346   vat_json_init_object (node);
3347   vat_json_object_add_uint (node, "value", mp->value);
3348
3349   vat_json_print (vam->ofp, node);
3350   vat_json_free (node);
3351
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354 }
3355
3356 static void
3357   vl_api_show_one_map_register_state_reply_t_handler
3358   (vl_api_show_one_map_register_state_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   int retval = clib_net_to_host_u32 (mp->retval);
3362
3363   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3364
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_show_one_map_register_state_reply_t_handler_json
3371   (vl_api_show_one_map_register_state_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t _node, *node = &_node;
3375   int retval = clib_net_to_host_u32 (mp->retval);
3376
3377   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3378
3379   vat_json_init_object (node);
3380   vat_json_object_add_string_copy (node, "state", s);
3381
3382   vat_json_print (vam->ofp, node);
3383   vat_json_free (node);
3384
3385   vam->retval = retval;
3386   vam->result_ready = 1;
3387   vec_free (s);
3388 }
3389
3390 static void
3391   vl_api_show_one_rloc_probe_state_reply_t_handler
3392   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395   int retval = clib_net_to_host_u32 (mp->retval);
3396
3397   if (retval)
3398     goto end;
3399
3400   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3401 end:
3402   vam->retval = retval;
3403   vam->result_ready = 1;
3404 }
3405
3406 static void
3407   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3408   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411   vat_json_node_t _node, *node = &_node;
3412   int retval = clib_net_to_host_u32 (mp->retval);
3413
3414   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3415   vat_json_init_object (node);
3416   vat_json_object_add_string_copy (node, "state", s);
3417
3418   vat_json_print (vam->ofp, node);
3419   vat_json_free (node);
3420
3421   vam->retval = retval;
3422   vam->result_ready = 1;
3423   vec_free (s);
3424 }
3425
3426 static void
3427   vl_api_show_one_stats_enable_disable_reply_t_handler
3428   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   int retval = clib_net_to_host_u32 (mp->retval);
3432
3433   if (retval)
3434     goto end;
3435
3436   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3437 end:
3438   vam->retval = retval;
3439   vam->result_ready = 1;
3440 }
3441
3442 static void
3443   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3444   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447   vat_json_node_t _node, *node = &_node;
3448   int retval = clib_net_to_host_u32 (mp->retval);
3449
3450   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3451   vat_json_init_object (node);
3452   vat_json_object_add_string_copy (node, "state", s);
3453
3454   vat_json_print (vam->ofp, node);
3455   vat_json_free (node);
3456
3457   vam->retval = retval;
3458   vam->result_ready = 1;
3459   vec_free (s);
3460 }
3461
3462 static void
3463 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3464 {
3465   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3466   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3467   e->vni = clib_net_to_host_u32 (e->vni);
3468 }
3469
3470 static void
3471   gpe_fwd_entries_get_reply_t_net_to_host
3472   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473 {
3474   u32 i;
3475
3476   mp->count = clib_net_to_host_u32 (mp->count);
3477   for (i = 0; i < mp->count; i++)
3478     {
3479       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3480     }
3481 }
3482
3483 static u8 *
3484 format_gpe_encap_mode (u8 * s, va_list * args)
3485 {
3486   u32 mode = va_arg (*args, u32);
3487
3488   switch (mode)
3489     {
3490     case 0:
3491       return format (s, "lisp");
3492     case 1:
3493       return format (s, "vxlan");
3494     }
3495   return 0;
3496 }
3497
3498 static void
3499   vl_api_gpe_get_encap_mode_reply_t_handler
3500   (vl_api_gpe_get_encap_mode_reply_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503
3504   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3505   vam->retval = ntohl (mp->retval);
3506   vam->result_ready = 1;
3507 }
3508
3509 static void
3510   vl_api_gpe_get_encap_mode_reply_t_handler_json
3511   (vl_api_gpe_get_encap_mode_reply_t * mp)
3512 {
3513   vat_main_t *vam = &vat_main;
3514   vat_json_node_t node;
3515
3516   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3517   vec_add1 (encap_mode, 0);
3518
3519   vat_json_init_object (&node);
3520   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3521
3522   vec_free (encap_mode);
3523   vat_json_print (vam->ofp, &node);
3524   vat_json_free (&node);
3525
3526   vam->retval = ntohl (mp->retval);
3527   vam->result_ready = 1;
3528 }
3529
3530 static void
3531   vl_api_gpe_fwd_entry_path_details_t_handler
3532   (vl_api_gpe_fwd_entry_path_details_t * mp)
3533 {
3534   vat_main_t *vam = &vat_main;
3535   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3536
3537   if (mp->lcl_loc.is_ip4)
3538     format_ip_address_fcn = format_ip4_address;
3539   else
3540     format_ip_address_fcn = format_ip6_address;
3541
3542   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3543          format_ip_address_fcn, &mp->lcl_loc,
3544          format_ip_address_fcn, &mp->rmt_loc);
3545 }
3546
3547 static void
3548 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3549 {
3550   struct in6_addr ip6;
3551   struct in_addr ip4;
3552
3553   if (loc->is_ip4)
3554     {
3555       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3556       vat_json_object_add_ip4 (n, "address", ip4);
3557     }
3558   else
3559     {
3560       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3561       vat_json_object_add_ip6 (n, "address", ip6);
3562     }
3563   vat_json_object_add_uint (n, "weight", loc->weight);
3564 }
3565
3566 static void
3567   vl_api_gpe_fwd_entry_path_details_t_handler_json
3568   (vl_api_gpe_fwd_entry_path_details_t * mp)
3569 {
3570   vat_main_t *vam = &vat_main;
3571   vat_json_node_t *node = NULL;
3572   vat_json_node_t *loc_node;
3573
3574   if (VAT_JSON_ARRAY != vam->json_tree.type)
3575     {
3576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3577       vat_json_init_array (&vam->json_tree);
3578     }
3579   node = vat_json_array_add (&vam->json_tree);
3580   vat_json_init_object (node);
3581
3582   loc_node = vat_json_object_add (node, "local_locator");
3583   vat_json_init_object (loc_node);
3584   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3585
3586   loc_node = vat_json_object_add (node, "remote_locator");
3587   vat_json_init_object (loc_node);
3588   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3589 }
3590
3591 static void
3592   vl_api_gpe_fwd_entries_get_reply_t_handler
3593   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   u32 i;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598   vl_api_gpe_fwd_entry_t *e;
3599
3600   if (retval)
3601     goto end;
3602
3603   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3604
3605   for (i = 0; i < mp->count; i++)
3606     {
3607       e = &mp->entries[i];
3608       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3609              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3610              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3611     }
3612
3613 end:
3614   vam->retval = retval;
3615   vam->result_ready = 1;
3616 }
3617
3618 static void
3619   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3620   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3621 {
3622   u8 *s = 0;
3623   vat_main_t *vam = &vat_main;
3624   vat_json_node_t *e = 0, root;
3625   u32 i;
3626   int retval = clib_net_to_host_u32 (mp->retval);
3627   vl_api_gpe_fwd_entry_t *fwd;
3628
3629   if (retval)
3630     goto end;
3631
3632   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3633   vat_json_init_array (&root);
3634
3635   for (i = 0; i < mp->count; i++)
3636     {
3637       e = vat_json_array_add (&root);
3638       fwd = &mp->entries[i];
3639
3640       vat_json_init_object (e);
3641       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3642       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3643       vat_json_object_add_int (e, "vni", fwd->vni);
3644       vat_json_object_add_int (e, "action", fwd->action);
3645
3646       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3647                   fwd->leid_prefix_len);
3648       vec_add1 (s, 0);
3649       vat_json_object_add_string_copy (e, "leid", s);
3650       vec_free (s);
3651
3652       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3653                   fwd->reid_prefix_len);
3654       vec_add1 (s, 0);
3655       vat_json_object_add_string_copy (e, "reid", s);
3656       vec_free (s);
3657     }
3658
3659   vat_json_print (vam->ofp, &root);
3660   vat_json_free (&root);
3661
3662 end:
3663   vam->retval = retval;
3664   vam->result_ready = 1;
3665 }
3666
3667 static void
3668   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3669   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3670 {
3671   vat_main_t *vam = &vat_main;
3672   u32 i, n;
3673   int retval = clib_net_to_host_u32 (mp->retval);
3674   vl_api_gpe_native_fwd_rpath_t *r;
3675
3676   if (retval)
3677     goto end;
3678
3679   n = clib_net_to_host_u32 (mp->count);
3680
3681   for (i = 0; i < n; i++)
3682     {
3683       r = &mp->entries[i];
3684       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3685              clib_net_to_host_u32 (r->fib_index),
3686              clib_net_to_host_u32 (r->nh_sw_if_index),
3687              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3688     }
3689
3690 end:
3691   vam->retval = retval;
3692   vam->result_ready = 1;
3693 }
3694
3695 static void
3696   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3697   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3698 {
3699   vat_main_t *vam = &vat_main;
3700   vat_json_node_t root, *e;
3701   u32 i, n;
3702   int retval = clib_net_to_host_u32 (mp->retval);
3703   vl_api_gpe_native_fwd_rpath_t *r;
3704   u8 *s;
3705
3706   if (retval)
3707     goto end;
3708
3709   n = clib_net_to_host_u32 (mp->count);
3710   vat_json_init_array (&root);
3711
3712   for (i = 0; i < n; i++)
3713     {
3714       e = vat_json_array_add (&root);
3715       vat_json_init_object (e);
3716       r = &mp->entries[i];
3717       s =
3718         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3719                 r->nh_addr);
3720       vec_add1 (s, 0);
3721       vat_json_object_add_string_copy (e, "ip4", s);
3722       vec_free (s);
3723
3724       vat_json_object_add_uint (e, "fib_index",
3725                                 clib_net_to_host_u32 (r->fib_index));
3726       vat_json_object_add_uint (e, "nh_sw_if_index",
3727                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3728     }
3729
3730   vat_json_print (vam->ofp, &root);
3731   vat_json_free (&root);
3732
3733 end:
3734   vam->retval = retval;
3735   vam->result_ready = 1;
3736 }
3737
3738 static void
3739   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3740   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3741 {
3742   vat_main_t *vam = &vat_main;
3743   u32 i, n;
3744   int retval = clib_net_to_host_u32 (mp->retval);
3745
3746   if (retval)
3747     goto end;
3748
3749   n = clib_net_to_host_u32 (mp->count);
3750
3751   for (i = 0; i < n; i++)
3752     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3753
3754 end:
3755   vam->retval = retval;
3756   vam->result_ready = 1;
3757 }
3758
3759 static void
3760   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3761   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3762 {
3763   vat_main_t *vam = &vat_main;
3764   vat_json_node_t root;
3765   u32 i, n;
3766   int retval = clib_net_to_host_u32 (mp->retval);
3767
3768   if (retval)
3769     goto end;
3770
3771   n = clib_net_to_host_u32 (mp->count);
3772   vat_json_init_array (&root);
3773
3774   for (i = 0; i < n; i++)
3775     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786   vl_api_one_ndp_entries_get_reply_t_handler
3787   (vl_api_one_ndp_entries_get_reply_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   u32 i, n;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3800            format_ethernet_address, mp->entries[i].mac);
3801
3802 end:
3803   vam->retval = retval;
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_one_ndp_entries_get_reply_t_handler_json
3809   (vl_api_one_ndp_entries_get_reply_t * mp)
3810 {
3811   u8 *s = 0;
3812   vat_main_t *vam = &vat_main;
3813   vat_json_node_t *e = 0, root;
3814   u32 i, n;
3815   int retval = clib_net_to_host_u32 (mp->retval);
3816   vl_api_one_ndp_entry_t *arp_entry;
3817
3818   if (retval)
3819     goto end;
3820
3821   n = clib_net_to_host_u32 (mp->count);
3822   vat_json_init_array (&root);
3823
3824   for (i = 0; i < n; i++)
3825     {
3826       e = vat_json_array_add (&root);
3827       arp_entry = &mp->entries[i];
3828
3829       vat_json_init_object (e);
3830       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3831       vec_add1 (s, 0);
3832
3833       vat_json_object_add_string_copy (e, "mac", s);
3834       vec_free (s);
3835
3836       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip6", s);
3839       vec_free (s);
3840     }
3841
3842   vat_json_print (vam->ofp, &root);
3843   vat_json_free (&root);
3844
3845 end:
3846   vam->retval = retval;
3847   vam->result_ready = 1;
3848 }
3849
3850 static void
3851   vl_api_one_l2_arp_entries_get_reply_t_handler
3852   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3853 {
3854   vat_main_t *vam = &vat_main;
3855   u32 i, n;
3856   int retval = clib_net_to_host_u32 (mp->retval);
3857
3858   if (retval)
3859     goto end;
3860
3861   n = clib_net_to_host_u32 (mp->count);
3862
3863   for (i = 0; i < n; i++)
3864     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3865            format_ethernet_address, mp->entries[i].mac);
3866
3867 end:
3868   vam->retval = retval;
3869   vam->result_ready = 1;
3870 }
3871
3872 static void
3873   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3874   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3875 {
3876   u8 *s = 0;
3877   vat_main_t *vam = &vat_main;
3878   vat_json_node_t *e = 0, root;
3879   u32 i, n;
3880   int retval = clib_net_to_host_u32 (mp->retval);
3881   vl_api_one_l2_arp_entry_t *arp_entry;
3882
3883   if (retval)
3884     goto end;
3885
3886   n = clib_net_to_host_u32 (mp->count);
3887   vat_json_init_array (&root);
3888
3889   for (i = 0; i < n; i++)
3890     {
3891       e = vat_json_array_add (&root);
3892       arp_entry = &mp->entries[i];
3893
3894       vat_json_init_object (e);
3895       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3896       vec_add1 (s, 0);
3897
3898       vat_json_object_add_string_copy (e, "mac", s);
3899       vec_free (s);
3900
3901       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3902       vec_add1 (s, 0);
3903       vat_json_object_add_string_copy (e, "ip4", s);
3904       vec_free (s);
3905     }
3906
3907   vat_json_print (vam->ofp, &root);
3908   vat_json_free (&root);
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921
3922   if (retval)
3923     goto end;
3924
3925   n = clib_net_to_host_u32 (mp->count);
3926
3927   for (i = 0; i < n; i++)
3928     {
3929       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3930     }
3931
3932 end:
3933   vam->retval = retval;
3934   vam->result_ready = 1;
3935 }
3936
3937 static void
3938   vl_api_one_ndp_bd_get_reply_t_handler_json
3939   (vl_api_one_ndp_bd_get_reply_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942   vat_json_node_t root;
3943   u32 i, n;
3944   int retval = clib_net_to_host_u32 (mp->retval);
3945
3946   if (retval)
3947     goto end;
3948
3949   n = clib_net_to_host_u32 (mp->count);
3950   vat_json_init_array (&root);
3951
3952   for (i = 0; i < n; i++)
3953     {
3954       vat_json_array_add_uint (&root,
3955                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3956     }
3957
3958   vat_json_print (vam->ofp, &root);
3959   vat_json_free (&root);
3960
3961 end:
3962   vam->retval = retval;
3963   vam->result_ready = 1;
3964 }
3965
3966 static void
3967   vl_api_one_l2_arp_bd_get_reply_t_handler
3968   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3969 {
3970   vat_main_t *vam = &vat_main;
3971   u32 i, n;
3972   int retval = clib_net_to_host_u32 (mp->retval);
3973
3974   if (retval)
3975     goto end;
3976
3977   n = clib_net_to_host_u32 (mp->count);
3978
3979   for (i = 0; i < n; i++)
3980     {
3981       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3982     }
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3992 {
3993   vat_main_t *vam = &vat_main;
3994   vat_json_node_t root;
3995   u32 i, n;
3996   int retval = clib_net_to_host_u32 (mp->retval);
3997
3998   if (retval)
3999     goto end;
4000
4001   n = clib_net_to_host_u32 (mp->count);
4002   vat_json_init_array (&root);
4003
4004   for (i = 0; i < n; i++)
4005     {
4006       vat_json_array_add_uint (&root,
4007                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4008     }
4009
4010   vat_json_print (vam->ofp, &root);
4011   vat_json_free (&root);
4012
4013 end:
4014   vam->retval = retval;
4015   vam->result_ready = 1;
4016 }
4017
4018 static void
4019   vl_api_one_adjacencies_get_reply_t_handler
4020   (vl_api_one_adjacencies_get_reply_t * mp)
4021 {
4022   vat_main_t *vam = &vat_main;
4023   u32 i, n;
4024   int retval = clib_net_to_host_u32 (mp->retval);
4025   vl_api_one_adjacency_t *a;
4026
4027   if (retval)
4028     goto end;
4029
4030   n = clib_net_to_host_u32 (mp->count);
4031
4032   for (i = 0; i < n; i++)
4033     {
4034       a = &mp->adjacencies[i];
4035       print (vam->ofp, "%U %40U",
4036              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4037              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4038     }
4039
4040 end:
4041   vam->retval = retval;
4042   vam->result_ready = 1;
4043 }
4044
4045 static void
4046   vl_api_one_adjacencies_get_reply_t_handler_json
4047   (vl_api_one_adjacencies_get_reply_t * mp)
4048 {
4049   u8 *s = 0;
4050   vat_main_t *vam = &vat_main;
4051   vat_json_node_t *e = 0, root;
4052   u32 i, n;
4053   int retval = clib_net_to_host_u32 (mp->retval);
4054   vl_api_one_adjacency_t *a;
4055
4056   if (retval)
4057     goto end;
4058
4059   n = clib_net_to_host_u32 (mp->count);
4060   vat_json_init_array (&root);
4061
4062   for (i = 0; i < n; i++)
4063     {
4064       e = vat_json_array_add (&root);
4065       a = &mp->adjacencies[i];
4066
4067       vat_json_init_object (e);
4068       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4069                   a->leid_prefix_len);
4070       vec_add1 (s, 0);
4071       vat_json_object_add_string_copy (e, "leid", s);
4072       vec_free (s);
4073
4074       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4075                   a->reid_prefix_len);
4076       vec_add1 (s, 0);
4077       vat_json_object_add_string_copy (e, "reid", s);
4078       vec_free (s);
4079     }
4080
4081   vat_json_print (vam->ofp, &root);
4082   vat_json_free (&root);
4083
4084 end:
4085   vam->retval = retval;
4086   vam->result_ready = 1;
4087 }
4088
4089 static void
4090 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093
4094   print (vam->ofp, "%=20U",
4095          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4096          mp->ip_address);
4097 }
4098
4099 static void
4100   vl_api_one_map_server_details_t_handler_json
4101   (vl_api_one_map_server_details_t * mp)
4102 {
4103   vat_main_t *vam = &vat_main;
4104   vat_json_node_t *node = NULL;
4105   struct in6_addr ip6;
4106   struct in_addr ip4;
4107
4108   if (VAT_JSON_ARRAY != vam->json_tree.type)
4109     {
4110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4111       vat_json_init_array (&vam->json_tree);
4112     }
4113   node = vat_json_array_add (&vam->json_tree);
4114
4115   vat_json_init_object (node);
4116   if (mp->is_ipv6)
4117     {
4118       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4119       vat_json_object_add_ip6 (node, "map-server", ip6);
4120     }
4121   else
4122     {
4123       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4124       vat_json_object_add_ip4 (node, "map-server", ip4);
4125     }
4126 }
4127
4128 static void
4129 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4130                                            * mp)
4131 {
4132   vat_main_t *vam = &vat_main;
4133
4134   print (vam->ofp, "%=20U",
4135          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4136          mp->ip_address);
4137 }
4138
4139 static void
4140   vl_api_one_map_resolver_details_t_handler_json
4141   (vl_api_one_map_resolver_details_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   vat_json_node_t *node = NULL;
4145   struct in6_addr ip6;
4146   struct in_addr ip4;
4147
4148   if (VAT_JSON_ARRAY != vam->json_tree.type)
4149     {
4150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4151       vat_json_init_array (&vam->json_tree);
4152     }
4153   node = vat_json_array_add (&vam->json_tree);
4154
4155   vat_json_init_object (node);
4156   if (mp->is_ipv6)
4157     {
4158       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4159       vat_json_object_add_ip6 (node, "map resolver", ip6);
4160     }
4161   else
4162     {
4163       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4164       vat_json_object_add_ip4 (node, "map resolver", ip4);
4165     }
4166 }
4167
4168 static void
4169 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4170 {
4171   vat_main_t *vam = &vat_main;
4172   i32 retval = ntohl (mp->retval);
4173
4174   if (0 <= retval)
4175     {
4176       print (vam->ofp, "feature: %s\ngpe: %s",
4177              mp->feature_status ? "enabled" : "disabled",
4178              mp->gpe_status ? "enabled" : "disabled");
4179     }
4180
4181   vam->retval = retval;
4182   vam->result_ready = 1;
4183 }
4184
4185 static void
4186   vl_api_show_one_status_reply_t_handler_json
4187   (vl_api_show_one_status_reply_t * mp)
4188 {
4189   vat_main_t *vam = &vat_main;
4190   vat_json_node_t node;
4191   u8 *gpe_status = NULL;
4192   u8 *feature_status = NULL;
4193
4194   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4195   feature_status = format (0, "%s",
4196                            mp->feature_status ? "enabled" : "disabled");
4197   vec_add1 (gpe_status, 0);
4198   vec_add1 (feature_status, 0);
4199
4200   vat_json_init_object (&node);
4201   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4202   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4203
4204   vec_free (gpe_status);
4205   vec_free (feature_status);
4206
4207   vat_json_print (vam->ofp, &node);
4208   vat_json_free (&node);
4209
4210   vam->retval = ntohl (mp->retval);
4211   vam->result_ready = 1;
4212 }
4213
4214 static void
4215   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4216   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4217 {
4218   vat_main_t *vam = &vat_main;
4219   i32 retval = ntohl (mp->retval);
4220
4221   if (retval >= 0)
4222     {
4223       print (vam->ofp, "%=20s", mp->locator_set_name);
4224     }
4225
4226   vam->retval = retval;
4227   vam->result_ready = 1;
4228 }
4229
4230 static void
4231   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4232   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4233 {
4234   vat_main_t *vam = &vat_main;
4235   vat_json_node_t *node = NULL;
4236
4237   if (VAT_JSON_ARRAY != vam->json_tree.type)
4238     {
4239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4240       vat_json_init_array (&vam->json_tree);
4241     }
4242   node = vat_json_array_add (&vam->json_tree);
4243
4244   vat_json_init_object (node);
4245   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4246
4247   vat_json_print (vam->ofp, node);
4248   vat_json_free (node);
4249
4250   vam->retval = ntohl (mp->retval);
4251   vam->result_ready = 1;
4252 }
4253
4254 static u8 *
4255 format_lisp_map_request_mode (u8 * s, va_list * args)
4256 {
4257   u32 mode = va_arg (*args, u32);
4258
4259   switch (mode)
4260     {
4261     case 0:
4262       return format (0, "dst-only");
4263     case 1:
4264       return format (0, "src-dst");
4265     }
4266   return 0;
4267 }
4268
4269 static void
4270   vl_api_show_one_map_request_mode_reply_t_handler
4271   (vl_api_show_one_map_request_mode_reply_t * mp)
4272 {
4273   vat_main_t *vam = &vat_main;
4274   i32 retval = ntohl (mp->retval);
4275
4276   if (0 <= retval)
4277     {
4278       u32 mode = mp->mode;
4279       print (vam->ofp, "map_request_mode: %U",
4280              format_lisp_map_request_mode, mode);
4281     }
4282
4283   vam->retval = retval;
4284   vam->result_ready = 1;
4285 }
4286
4287 static void
4288   vl_api_show_one_map_request_mode_reply_t_handler_json
4289   (vl_api_show_one_map_request_mode_reply_t * mp)
4290 {
4291   vat_main_t *vam = &vat_main;
4292   vat_json_node_t node;
4293   u8 *s = 0;
4294   u32 mode;
4295
4296   mode = mp->mode;
4297   s = format (0, "%U", format_lisp_map_request_mode, mode);
4298   vec_add1 (s, 0);
4299
4300   vat_json_init_object (&node);
4301   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4302   vat_json_print (vam->ofp, &node);
4303   vat_json_free (&node);
4304
4305   vec_free (s);
4306   vam->retval = ntohl (mp->retval);
4307   vam->result_ready = 1;
4308 }
4309
4310 static void
4311   vl_api_one_show_xtr_mode_reply_t_handler
4312   (vl_api_one_show_xtr_mode_reply_t * mp)
4313 {
4314   vat_main_t *vam = &vat_main;
4315   i32 retval = ntohl (mp->retval);
4316
4317   if (0 <= retval)
4318     {
4319       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4320     }
4321
4322   vam->retval = retval;
4323   vam->result_ready = 1;
4324 }
4325
4326 static void
4327   vl_api_one_show_xtr_mode_reply_t_handler_json
4328   (vl_api_one_show_xtr_mode_reply_t * mp)
4329 {
4330   vat_main_t *vam = &vat_main;
4331   vat_json_node_t node;
4332   u8 *status = 0;
4333
4334   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4335   vec_add1 (status, 0);
4336
4337   vat_json_init_object (&node);
4338   vat_json_object_add_string_copy (&node, "status", status);
4339
4340   vec_free (status);
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   vam->retval = ntohl (mp->retval);
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_one_show_pitr_mode_reply_t_handler
4351   (vl_api_one_show_pitr_mode_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   i32 retval = ntohl (mp->retval);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4359     }
4360
4361   vam->retval = retval;
4362   vam->result_ready = 1;
4363 }
4364
4365 static void
4366   vl_api_one_show_pitr_mode_reply_t_handler_json
4367   (vl_api_one_show_pitr_mode_reply_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   vat_json_node_t node;
4371   u8 *status = 0;
4372
4373   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4374   vec_add1 (status, 0);
4375
4376   vat_json_init_object (&node);
4377   vat_json_object_add_string_copy (&node, "status", status);
4378
4379   vec_free (status);
4380
4381   vat_json_print (vam->ofp, &node);
4382   vat_json_free (&node);
4383
4384   vam->retval = ntohl (mp->retval);
4385   vam->result_ready = 1;
4386 }
4387
4388 static void
4389   vl_api_one_show_petr_mode_reply_t_handler
4390   (vl_api_one_show_petr_mode_reply_t * mp)
4391 {
4392   vat_main_t *vam = &vat_main;
4393   i32 retval = ntohl (mp->retval);
4394
4395   if (0 <= retval)
4396     {
4397       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_one_show_petr_mode_reply_t_handler_json
4406   (vl_api_one_show_petr_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *status = 0;
4411
4412   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4413   vec_add1 (status, 0);
4414
4415   vat_json_init_object (&node);
4416   vat_json_object_add_string_copy (&node, "status", status);
4417
4418   vec_free (status);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_show_one_use_petr_reply_t_handler
4429   (vl_api_show_one_use_petr_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4437       if (mp->status)
4438         {
4439           print (vam->ofp, "Proxy-ETR address; %U",
4440                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4441                  mp->address);
4442         }
4443     }
4444
4445   vam->retval = retval;
4446   vam->result_ready = 1;
4447 }
4448
4449 static void
4450   vl_api_show_one_use_petr_reply_t_handler_json
4451   (vl_api_show_one_use_petr_reply_t * mp)
4452 {
4453   vat_main_t *vam = &vat_main;
4454   vat_json_node_t node;
4455   u8 *status = 0;
4456   struct in_addr ip4;
4457   struct in6_addr ip6;
4458
4459   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4460   vec_add1 (status, 0);
4461
4462   vat_json_init_object (&node);
4463   vat_json_object_add_string_copy (&node, "status", status);
4464   if (mp->status)
4465     {
4466       if (mp->is_ip4)
4467         {
4468           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4469           vat_json_object_add_ip6 (&node, "address", ip6);
4470         }
4471       else
4472         {
4473           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4474           vat_json_object_add_ip4 (&node, "address", ip4);
4475         }
4476     }
4477
4478   vec_free (status);
4479
4480   vat_json_print (vam->ofp, &node);
4481   vat_json_free (&node);
4482
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void
4488   vl_api_show_one_nsh_mapping_reply_t_handler
4489   (vl_api_show_one_nsh_mapping_reply_t * mp)
4490 {
4491   vat_main_t *vam = &vat_main;
4492   i32 retval = ntohl (mp->retval);
4493
4494   if (0 <= retval)
4495     {
4496       print (vam->ofp, "%-20s%-16s",
4497              mp->is_set ? "set" : "not-set",
4498              mp->is_set ? (char *) mp->locator_set_name : "");
4499     }
4500
4501   vam->retval = retval;
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_show_one_nsh_mapping_reply_t_handler_json
4507   (vl_api_show_one_nsh_mapping_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   vat_json_node_t node;
4511   u8 *status = 0;
4512
4513   status = format (0, "%s", mp->is_set ? "yes" : "no");
4514   vec_add1 (status, 0);
4515
4516   vat_json_init_object (&node);
4517   vat_json_object_add_string_copy (&node, "is_set", status);
4518   if (mp->is_set)
4519     {
4520       vat_json_object_add_string_copy (&node, "locator_set",
4521                                        mp->locator_set_name);
4522     }
4523
4524   vec_free (status);
4525
4526   vat_json_print (vam->ofp, &node);
4527   vat_json_free (&node);
4528
4529   vam->retval = ntohl (mp->retval);
4530   vam->result_ready = 1;
4531 }
4532
4533 static void
4534   vl_api_show_one_map_register_ttl_reply_t_handler
4535   (vl_api_show_one_map_register_ttl_reply_t * mp)
4536 {
4537   vat_main_t *vam = &vat_main;
4538   i32 retval = ntohl (mp->retval);
4539
4540   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4541
4542   if (0 <= retval)
4543     {
4544       print (vam->ofp, "ttl: %u", mp->ttl);
4545     }
4546
4547   vam->retval = retval;
4548   vam->result_ready = 1;
4549 }
4550
4551 static void
4552   vl_api_show_one_map_register_ttl_reply_t_handler_json
4553   (vl_api_show_one_map_register_ttl_reply_t * mp)
4554 {
4555   vat_main_t *vam = &vat_main;
4556   vat_json_node_t node;
4557
4558   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4559   vat_json_init_object (&node);
4560   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4561
4562   vat_json_print (vam->ofp, &node);
4563   vat_json_free (&node);
4564
4565   vam->retval = ntohl (mp->retval);
4566   vam->result_ready = 1;
4567 }
4568
4569 static void
4570 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4571 {
4572   vat_main_t *vam = &vat_main;
4573   i32 retval = ntohl (mp->retval);
4574
4575   if (0 <= retval)
4576     {
4577       print (vam->ofp, "%-20s%-16s",
4578              mp->status ? "enabled" : "disabled",
4579              mp->status ? (char *) mp->locator_set_name : "");
4580     }
4581
4582   vam->retval = retval;
4583   vam->result_ready = 1;
4584 }
4585
4586 static void
4587 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4588 {
4589   vat_main_t *vam = &vat_main;
4590   vat_json_node_t node;
4591   u8 *status = 0;
4592
4593   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4594   vec_add1 (status, 0);
4595
4596   vat_json_init_object (&node);
4597   vat_json_object_add_string_copy (&node, "status", status);
4598   if (mp->status)
4599     {
4600       vat_json_object_add_string_copy (&node, "locator_set",
4601                                        mp->locator_set_name);
4602     }
4603
4604   vec_free (status);
4605
4606   vat_json_print (vam->ofp, &node);
4607   vat_json_free (&node);
4608
4609   vam->retval = ntohl (mp->retval);
4610   vam->result_ready = 1;
4611 }
4612
4613 static u8 *
4614 format_policer_type (u8 * s, va_list * va)
4615 {
4616   u32 i = va_arg (*va, u32);
4617
4618   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4619     s = format (s, "1r2c");
4620   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4621     s = format (s, "1r3c");
4622   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4623     s = format (s, "2r3c-2698");
4624   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4625     s = format (s, "2r3c-4115");
4626   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4627     s = format (s, "2r3c-mef5cf1");
4628   else
4629     s = format (s, "ILLEGAL");
4630   return s;
4631 }
4632
4633 static u8 *
4634 format_policer_rate_type (u8 * s, va_list * va)
4635 {
4636   u32 i = va_arg (*va, u32);
4637
4638   if (i == SSE2_QOS_RATE_KBPS)
4639     s = format (s, "kbps");
4640   else if (i == SSE2_QOS_RATE_PPS)
4641     s = format (s, "pps");
4642   else
4643     s = format (s, "ILLEGAL");
4644   return s;
4645 }
4646
4647 static u8 *
4648 format_policer_round_type (u8 * s, va_list * va)
4649 {
4650   u32 i = va_arg (*va, u32);
4651
4652   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4653     s = format (s, "closest");
4654   else if (i == SSE2_QOS_ROUND_TO_UP)
4655     s = format (s, "up");
4656   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4657     s = format (s, "down");
4658   else
4659     s = format (s, "ILLEGAL");
4660   return s;
4661 }
4662
4663 static u8 *
4664 format_policer_action_type (u8 * s, va_list * va)
4665 {
4666   u32 i = va_arg (*va, u32);
4667
4668   if (i == SSE2_QOS_ACTION_DROP)
4669     s = format (s, "drop");
4670   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4671     s = format (s, "transmit");
4672   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4673     s = format (s, "mark-and-transmit");
4674   else
4675     s = format (s, "ILLEGAL");
4676   return s;
4677 }
4678
4679 static u8 *
4680 format_dscp (u8 * s, va_list * va)
4681 {
4682   u32 i = va_arg (*va, u32);
4683   char *t = 0;
4684
4685   switch (i)
4686     {
4687 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4688       foreach_vnet_dscp
4689 #undef _
4690     default:
4691       return format (s, "ILLEGAL");
4692     }
4693   s = format (s, "%s", t);
4694   return s;
4695 }
4696
4697 static void
4698 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4699 {
4700   vat_main_t *vam = &vat_main;
4701   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4702
4703   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4704     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4705   else
4706     conform_dscp_str = format (0, "");
4707
4708   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4709     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4710   else
4711     exceed_dscp_str = format (0, "");
4712
4713   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4714     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4715   else
4716     violate_dscp_str = format (0, "");
4717
4718   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4719          "rate type %U, round type %U, %s rate, %s color-aware, "
4720          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4721          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4722          "conform action %U%s, exceed action %U%s, violate action %U%s",
4723          mp->name,
4724          format_policer_type, mp->type,
4725          ntohl (mp->cir),
4726          ntohl (mp->eir),
4727          clib_net_to_host_u64 (mp->cb),
4728          clib_net_to_host_u64 (mp->eb),
4729          format_policer_rate_type, mp->rate_type,
4730          format_policer_round_type, mp->round_type,
4731          mp->single_rate ? "single" : "dual",
4732          mp->color_aware ? "is" : "not",
4733          ntohl (mp->cir_tokens_per_period),
4734          ntohl (mp->pir_tokens_per_period),
4735          ntohl (mp->scale),
4736          ntohl (mp->current_limit),
4737          ntohl (mp->current_bucket),
4738          ntohl (mp->extended_limit),
4739          ntohl (mp->extended_bucket),
4740          clib_net_to_host_u64 (mp->last_update_time),
4741          format_policer_action_type, mp->conform_action_type,
4742          conform_dscp_str,
4743          format_policer_action_type, mp->exceed_action_type,
4744          exceed_dscp_str,
4745          format_policer_action_type, mp->violate_action_type,
4746          violate_dscp_str);
4747
4748   vec_free (conform_dscp_str);
4749   vec_free (exceed_dscp_str);
4750   vec_free (violate_dscp_str);
4751 }
4752
4753 static void vl_api_policer_details_t_handler_json
4754   (vl_api_policer_details_t * mp)
4755 {
4756   vat_main_t *vam = &vat_main;
4757   vat_json_node_t *node;
4758   u8 *rate_type_str, *round_type_str, *type_str;
4759   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4760
4761   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4762   round_type_str =
4763     format (0, "%U", format_policer_round_type, mp->round_type);
4764   type_str = format (0, "%U", format_policer_type, mp->type);
4765   conform_action_str = format (0, "%U", format_policer_action_type,
4766                                mp->conform_action_type);
4767   exceed_action_str = format (0, "%U", format_policer_action_type,
4768                               mp->exceed_action_type);
4769   violate_action_str = format (0, "%U", format_policer_action_type,
4770                                mp->violate_action_type);
4771
4772   if (VAT_JSON_ARRAY != vam->json_tree.type)
4773     {
4774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4775       vat_json_init_array (&vam->json_tree);
4776     }
4777   node = vat_json_array_add (&vam->json_tree);
4778
4779   vat_json_init_object (node);
4780   vat_json_object_add_string_copy (node, "name", mp->name);
4781   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4782   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4783   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4784   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4785   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4786   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4787   vat_json_object_add_string_copy (node, "type", type_str);
4788   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4789   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4790   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4791   vat_json_object_add_uint (node, "cir_tokens_per_period",
4792                             ntohl (mp->cir_tokens_per_period));
4793   vat_json_object_add_uint (node, "eir_tokens_per_period",
4794                             ntohl (mp->pir_tokens_per_period));
4795   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4796   vat_json_object_add_uint (node, "current_bucket",
4797                             ntohl (mp->current_bucket));
4798   vat_json_object_add_uint (node, "extended_limit",
4799                             ntohl (mp->extended_limit));
4800   vat_json_object_add_uint (node, "extended_bucket",
4801                             ntohl (mp->extended_bucket));
4802   vat_json_object_add_uint (node, "last_update_time",
4803                             ntohl (mp->last_update_time));
4804   vat_json_object_add_string_copy (node, "conform_action",
4805                                    conform_action_str);
4806   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4807     {
4808       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4809       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4810       vec_free (dscp_str);
4811     }
4812   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4813   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4814     {
4815       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4816       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4817       vec_free (dscp_str);
4818     }
4819   vat_json_object_add_string_copy (node, "violate_action",
4820                                    violate_action_str);
4821   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4822     {
4823       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4824       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4825       vec_free (dscp_str);
4826     }
4827
4828   vec_free (rate_type_str);
4829   vec_free (round_type_str);
4830   vec_free (type_str);
4831   vec_free (conform_action_str);
4832   vec_free (exceed_action_str);
4833   vec_free (violate_action_str);
4834 }
4835
4836 static void
4837 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4838                                            mp)
4839 {
4840   vat_main_t *vam = &vat_main;
4841   int i, count = ntohl (mp->count);
4842
4843   if (count > 0)
4844     print (vam->ofp, "classify table ids (%d) : ", count);
4845   for (i = 0; i < count; i++)
4846     {
4847       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4848       print (vam->ofp, (i < count - 1) ? "," : "");
4849     }
4850   vam->retval = ntohl (mp->retval);
4851   vam->result_ready = 1;
4852 }
4853
4854 static void
4855   vl_api_classify_table_ids_reply_t_handler_json
4856   (vl_api_classify_table_ids_reply_t * mp)
4857 {
4858   vat_main_t *vam = &vat_main;
4859   int i, count = ntohl (mp->count);
4860
4861   if (count > 0)
4862     {
4863       vat_json_node_t node;
4864
4865       vat_json_init_object (&node);
4866       for (i = 0; i < count; i++)
4867         {
4868           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4869         }
4870       vat_json_print (vam->ofp, &node);
4871       vat_json_free (&node);
4872     }
4873   vam->retval = ntohl (mp->retval);
4874   vam->result_ready = 1;
4875 }
4876
4877 static void
4878   vl_api_classify_table_by_interface_reply_t_handler
4879   (vl_api_classify_table_by_interface_reply_t * mp)
4880 {
4881   vat_main_t *vam = &vat_main;
4882   u32 table_id;
4883
4884   table_id = ntohl (mp->l2_table_id);
4885   if (table_id != ~0)
4886     print (vam->ofp, "l2 table id : %d", table_id);
4887   else
4888     print (vam->ofp, "l2 table id : No input ACL tables configured");
4889   table_id = ntohl (mp->ip4_table_id);
4890   if (table_id != ~0)
4891     print (vam->ofp, "ip4 table id : %d", table_id);
4892   else
4893     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4894   table_id = ntohl (mp->ip6_table_id);
4895   if (table_id != ~0)
4896     print (vam->ofp, "ip6 table id : %d", table_id);
4897   else
4898     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4899   vam->retval = ntohl (mp->retval);
4900   vam->result_ready = 1;
4901 }
4902
4903 static void
4904   vl_api_classify_table_by_interface_reply_t_handler_json
4905   (vl_api_classify_table_by_interface_reply_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t node;
4909
4910   vat_json_init_object (&node);
4911
4912   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4913   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4914   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4915
4916   vat_json_print (vam->ofp, &node);
4917   vat_json_free (&node);
4918
4919   vam->retval = ntohl (mp->retval);
4920   vam->result_ready = 1;
4921 }
4922
4923 static void vl_api_policer_add_del_reply_t_handler
4924   (vl_api_policer_add_del_reply_t * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927   i32 retval = ntohl (mp->retval);
4928   if (vam->async_mode)
4929     {
4930       vam->async_errors += (retval < 0);
4931     }
4932   else
4933     {
4934       vam->retval = retval;
4935       vam->result_ready = 1;
4936       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4937         /*
4938          * Note: this is just barely thread-safe, depends on
4939          * the main thread spinning waiting for an answer...
4940          */
4941         errmsg ("policer index %d", ntohl (mp->policer_index));
4942     }
4943 }
4944
4945 static void vl_api_policer_add_del_reply_t_handler_json
4946   (vl_api_policer_add_del_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   vat_json_init_object (&node);
4952   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4953   vat_json_object_add_uint (&node, "policer_index",
4954                             ntohl (mp->policer_index));
4955
4956   vat_json_print (vam->ofp, &node);
4957   vat_json_free (&node);
4958
4959   vam->retval = ntohl (mp->retval);
4960   vam->result_ready = 1;
4961 }
4962
4963 /* Format hex dump. */
4964 u8 *
4965 format_hex_bytes (u8 * s, va_list * va)
4966 {
4967   u8 *bytes = va_arg (*va, u8 *);
4968   int n_bytes = va_arg (*va, int);
4969   uword i;
4970
4971   /* Print short or long form depending on byte count. */
4972   uword short_form = n_bytes <= 32;
4973   u32 indent = format_get_indent (s);
4974
4975   if (n_bytes == 0)
4976     return s;
4977
4978   for (i = 0; i < n_bytes; i++)
4979     {
4980       if (!short_form && (i % 32) == 0)
4981         s = format (s, "%08x: ", i);
4982       s = format (s, "%02x", bytes[i]);
4983       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4984         s = format (s, "\n%U", format_white_space, indent);
4985     }
4986
4987   return s;
4988 }
4989
4990 static void
4991 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4992                                             * mp)
4993 {
4994   vat_main_t *vam = &vat_main;
4995   i32 retval = ntohl (mp->retval);
4996   if (retval == 0)
4997     {
4998       print (vam->ofp, "classify table info :");
4999       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5000              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5001              ntohl (mp->miss_next_index));
5002       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5003              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5004              ntohl (mp->match_n_vectors));
5005       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5006              ntohl (mp->mask_length));
5007     }
5008   vam->retval = retval;
5009   vam->result_ready = 1;
5010 }
5011
5012 static void
5013   vl_api_classify_table_info_reply_t_handler_json
5014   (vl_api_classify_table_info_reply_t * mp)
5015 {
5016   vat_main_t *vam = &vat_main;
5017   vat_json_node_t node;
5018
5019   i32 retval = ntohl (mp->retval);
5020   if (retval == 0)
5021     {
5022       vat_json_init_object (&node);
5023
5024       vat_json_object_add_int (&node, "sessions",
5025                                ntohl (mp->active_sessions));
5026       vat_json_object_add_int (&node, "nexttbl",
5027                                ntohl (mp->next_table_index));
5028       vat_json_object_add_int (&node, "nextnode",
5029                                ntohl (mp->miss_next_index));
5030       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5031       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5032       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5033       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5034                       ntohl (mp->mask_length), 0);
5035       vat_json_object_add_string_copy (&node, "mask", s);
5036
5037       vat_json_print (vam->ofp, &node);
5038       vat_json_free (&node);
5039     }
5040   vam->retval = ntohl (mp->retval);
5041   vam->result_ready = 1;
5042 }
5043
5044 static void
5045 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5046                                            mp)
5047 {
5048   vat_main_t *vam = &vat_main;
5049
5050   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5051          ntohl (mp->hit_next_index), ntohl (mp->advance),
5052          ntohl (mp->opaque_index));
5053   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5054          ntohl (mp->match_length));
5055 }
5056
5057 static void
5058   vl_api_classify_session_details_t_handler_json
5059   (vl_api_classify_session_details_t * mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062   vat_json_node_t *node = NULL;
5063
5064   if (VAT_JSON_ARRAY != vam->json_tree.type)
5065     {
5066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5067       vat_json_init_array (&vam->json_tree);
5068     }
5069   node = vat_json_array_add (&vam->json_tree);
5070
5071   vat_json_init_object (node);
5072   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5073   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5074   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5075   u8 *s =
5076     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5077             0);
5078   vat_json_object_add_string_copy (node, "match", s);
5079 }
5080
5081 static void vl_api_pg_create_interface_reply_t_handler
5082   (vl_api_pg_create_interface_reply_t * mp)
5083 {
5084   vat_main_t *vam = &vat_main;
5085
5086   vam->retval = ntohl (mp->retval);
5087   vam->result_ready = 1;
5088 }
5089
5090 static void vl_api_pg_create_interface_reply_t_handler_json
5091   (vl_api_pg_create_interface_reply_t * mp)
5092 {
5093   vat_main_t *vam = &vat_main;
5094   vat_json_node_t node;
5095
5096   i32 retval = ntohl (mp->retval);
5097   if (retval == 0)
5098     {
5099       vat_json_init_object (&node);
5100
5101       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5102
5103       vat_json_print (vam->ofp, &node);
5104       vat_json_free (&node);
5105     }
5106   vam->retval = ntohl (mp->retval);
5107   vam->result_ready = 1;
5108 }
5109
5110 static void vl_api_policer_classify_details_t_handler
5111   (vl_api_policer_classify_details_t * mp)
5112 {
5113   vat_main_t *vam = &vat_main;
5114
5115   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5116          ntohl (mp->table_index));
5117 }
5118
5119 static void vl_api_policer_classify_details_t_handler_json
5120   (vl_api_policer_classify_details_t * mp)
5121 {
5122   vat_main_t *vam = &vat_main;
5123   vat_json_node_t *node;
5124
5125   if (VAT_JSON_ARRAY != vam->json_tree.type)
5126     {
5127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5128       vat_json_init_array (&vam->json_tree);
5129     }
5130   node = vat_json_array_add (&vam->json_tree);
5131
5132   vat_json_init_object (node);
5133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5134   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5135 }
5136
5137 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5138   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5139 {
5140   vat_main_t *vam = &vat_main;
5141   i32 retval = ntohl (mp->retval);
5142   if (vam->async_mode)
5143     {
5144       vam->async_errors += (retval < 0);
5145     }
5146   else
5147     {
5148       vam->retval = retval;
5149       vam->sw_if_index = ntohl (mp->sw_if_index);
5150       vam->result_ready = 1;
5151     }
5152 }
5153
5154 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5155   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5156 {
5157   vat_main_t *vam = &vat_main;
5158   vat_json_node_t node;
5159
5160   vat_json_init_object (&node);
5161   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5162   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5163
5164   vat_json_print (vam->ofp, &node);
5165   vat_json_free (&node);
5166
5167   vam->retval = ntohl (mp->retval);
5168   vam->result_ready = 1;
5169 }
5170
5171 static void vl_api_flow_classify_details_t_handler
5172   (vl_api_flow_classify_details_t * mp)
5173 {
5174   vat_main_t *vam = &vat_main;
5175
5176   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5177          ntohl (mp->table_index));
5178 }
5179
5180 static void vl_api_flow_classify_details_t_handler_json
5181   (vl_api_flow_classify_details_t * mp)
5182 {
5183   vat_main_t *vam = &vat_main;
5184   vat_json_node_t *node;
5185
5186   if (VAT_JSON_ARRAY != vam->json_tree.type)
5187     {
5188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5189       vat_json_init_array (&vam->json_tree);
5190     }
5191   node = vat_json_array_add (&vam->json_tree);
5192
5193   vat_json_init_object (node);
5194   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5195   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5196 }
5197
5198 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5199 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5200 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5201 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5202 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5203 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5204 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5205 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5206 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5207 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5208 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5209 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5210 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5211 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5212 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5213 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5214 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5215 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5216 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5217 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5218 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5219 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5220
5221 /*
5222  * Generate boilerplate reply handlers, which
5223  * dig the return value out of the xxx_reply_t API message,
5224  * stick it into vam->retval, and set vam->result_ready
5225  *
5226  * Could also do this by pointing N message decode slots at
5227  * a single function, but that could break in subtle ways.
5228  */
5229
5230 #define foreach_standard_reply_retval_handler           \
5231 _(sw_interface_set_flags_reply)                         \
5232 _(sw_interface_add_del_address_reply)                   \
5233 _(sw_interface_set_rx_mode_reply)                       \
5234 _(sw_interface_set_table_reply)                         \
5235 _(sw_interface_set_mpls_enable_reply)                   \
5236 _(sw_interface_set_vpath_reply)                         \
5237 _(sw_interface_set_vxlan_bypass_reply)                  \
5238 _(sw_interface_set_geneve_bypass_reply)                 \
5239 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5240 _(sw_interface_set_l2_bridge_reply)                     \
5241 _(bridge_domain_add_del_reply)                          \
5242 _(sw_interface_set_l2_xconnect_reply)                   \
5243 _(l2fib_add_del_reply)                                  \
5244 _(l2fib_flush_int_reply)                                \
5245 _(l2fib_flush_bd_reply)                                 \
5246 _(ip_add_del_route_reply)                               \
5247 _(ip_table_add_del_reply)                               \
5248 _(ip_mroute_add_del_reply)                              \
5249 _(mpls_route_add_del_reply)                             \
5250 _(mpls_table_add_del_reply)                             \
5251 _(mpls_ip_bind_unbind_reply)                            \
5252 _(bier_route_add_del_reply)                             \
5253 _(bier_table_add_del_reply)                             \
5254 _(proxy_arp_add_del_reply)                              \
5255 _(proxy_arp_intfc_enable_disable_reply)                 \
5256 _(sw_interface_set_unnumbered_reply)                    \
5257 _(ip_neighbor_add_del_reply)                            \
5258 _(oam_add_del_reply)                                    \
5259 _(reset_fib_reply)                                      \
5260 _(dhcp_proxy_config_reply)                              \
5261 _(dhcp_proxy_set_vss_reply)                             \
5262 _(dhcp_client_config_reply)                             \
5263 _(set_ip_flow_hash_reply)                               \
5264 _(sw_interface_ip6_enable_disable_reply)                \
5265 _(sw_interface_ip6_set_link_local_address_reply)        \
5266 _(ip6nd_proxy_add_del_reply)                            \
5267 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5268 _(sw_interface_ip6nd_ra_config_reply)                   \
5269 _(set_arp_neighbor_limit_reply)                         \
5270 _(l2_patch_add_del_reply)                               \
5271 _(sr_policy_add_reply)                                  \
5272 _(sr_policy_mod_reply)                                  \
5273 _(sr_policy_del_reply)                                  \
5274 _(sr_localsid_add_del_reply)                            \
5275 _(sr_steering_add_del_reply)                            \
5276 _(classify_add_del_session_reply)                       \
5277 _(classify_set_interface_ip_table_reply)                \
5278 _(classify_set_interface_l2_tables_reply)               \
5279 _(l2tpv3_set_tunnel_cookies_reply)                      \
5280 _(l2tpv3_interface_enable_disable_reply)                \
5281 _(l2tpv3_set_lookup_key_reply)                          \
5282 _(l2_fib_clear_table_reply)                             \
5283 _(l2_interface_efp_filter_reply)                        \
5284 _(l2_interface_vlan_tag_rewrite_reply)                  \
5285 _(modify_vhost_user_if_reply)                           \
5286 _(delete_vhost_user_if_reply)                           \
5287 _(want_ip4_arp_events_reply)                            \
5288 _(want_ip6_nd_events_reply)                             \
5289 _(want_l2_macs_events_reply)                            \
5290 _(input_acl_set_interface_reply)                        \
5291 _(ipsec_spd_add_del_reply)                              \
5292 _(ipsec_interface_add_del_spd_reply)                    \
5293 _(ipsec_spd_add_del_entry_reply)                        \
5294 _(ipsec_sad_add_del_entry_reply)                        \
5295 _(ipsec_sa_set_key_reply)                               \
5296 _(ipsec_tunnel_if_add_del_reply)                        \
5297 _(ipsec_tunnel_if_set_key_reply)                        \
5298 _(ipsec_tunnel_if_set_sa_reply)                         \
5299 _(ikev2_profile_add_del_reply)                          \
5300 _(ikev2_profile_set_auth_reply)                         \
5301 _(ikev2_profile_set_id_reply)                           \
5302 _(ikev2_profile_set_ts_reply)                           \
5303 _(ikev2_set_local_key_reply)                            \
5304 _(ikev2_set_responder_reply)                            \
5305 _(ikev2_set_ike_transforms_reply)                       \
5306 _(ikev2_set_esp_transforms_reply)                       \
5307 _(ikev2_set_sa_lifetime_reply)                          \
5308 _(ikev2_initiate_sa_init_reply)                         \
5309 _(ikev2_initiate_del_ike_sa_reply)                      \
5310 _(ikev2_initiate_del_child_sa_reply)                    \
5311 _(ikev2_initiate_rekey_child_sa_reply)                  \
5312 _(delete_loopback_reply)                                \
5313 _(bd_ip_mac_add_del_reply)                              \
5314 _(map_del_domain_reply)                                 \
5315 _(map_add_del_rule_reply)                               \
5316 _(want_interface_events_reply)                          \
5317 _(want_stats_reply)                                     \
5318 _(cop_interface_enable_disable_reply)                   \
5319 _(cop_whitelist_enable_disable_reply)                   \
5320 _(sw_interface_clear_stats_reply)                       \
5321 _(ioam_enable_reply)                                    \
5322 _(ioam_disable_reply)                                   \
5323 _(one_add_del_locator_reply)                            \
5324 _(one_add_del_local_eid_reply)                          \
5325 _(one_add_del_remote_mapping_reply)                     \
5326 _(one_add_del_adjacency_reply)                          \
5327 _(one_add_del_map_resolver_reply)                       \
5328 _(one_add_del_map_server_reply)                         \
5329 _(one_enable_disable_reply)                             \
5330 _(one_rloc_probe_enable_disable_reply)                  \
5331 _(one_map_register_enable_disable_reply)                \
5332 _(one_map_register_set_ttl_reply)                       \
5333 _(one_set_transport_protocol_reply)                     \
5334 _(one_map_register_fallback_threshold_reply)            \
5335 _(one_pitr_set_locator_set_reply)                       \
5336 _(one_map_request_mode_reply)                           \
5337 _(one_add_del_map_request_itr_rlocs_reply)              \
5338 _(one_eid_table_add_del_map_reply)                      \
5339 _(one_use_petr_reply)                                   \
5340 _(one_stats_enable_disable_reply)                       \
5341 _(one_add_del_l2_arp_entry_reply)                       \
5342 _(one_add_del_ndp_entry_reply)                          \
5343 _(one_stats_flush_reply)                                \
5344 _(one_enable_disable_xtr_mode_reply)                    \
5345 _(one_enable_disable_pitr_mode_reply)                   \
5346 _(one_enable_disable_petr_mode_reply)                   \
5347 _(gpe_enable_disable_reply)                             \
5348 _(gpe_set_encap_mode_reply)                             \
5349 _(gpe_add_del_iface_reply)                              \
5350 _(gpe_add_del_native_fwd_rpath_reply)                   \
5351 _(af_packet_delete_reply)                               \
5352 _(policer_classify_set_interface_reply)                 \
5353 _(netmap_create_reply)                                  \
5354 _(netmap_delete_reply)                                  \
5355 _(set_ipfix_exporter_reply)                             \
5356 _(set_ipfix_classify_stream_reply)                      \
5357 _(ipfix_classify_table_add_del_reply)                   \
5358 _(flow_classify_set_interface_reply)                    \
5359 _(sw_interface_span_enable_disable_reply)               \
5360 _(pg_capture_reply)                                     \
5361 _(pg_enable_disable_reply)                              \
5362 _(ip_source_and_port_range_check_add_del_reply)         \
5363 _(ip_source_and_port_range_check_interface_add_del_reply)\
5364 _(delete_subif_reply)                                   \
5365 _(l2_interface_pbb_tag_rewrite_reply)                   \
5366 _(punt_reply)                                           \
5367 _(feature_enable_disable_reply)                         \
5368 _(sw_interface_tag_add_del_reply)                       \
5369 _(sw_interface_set_mtu_reply)                           \
5370 _(p2p_ethernet_add_reply)                               \
5371 _(p2p_ethernet_del_reply)                               \
5372 _(lldp_config_reply)                                    \
5373 _(sw_interface_set_lldp_reply)                          \
5374 _(tcp_configure_src_addresses_reply)                    \
5375 _(dns_enable_disable_reply)                             \
5376 _(dns_name_server_add_del_reply)                        \
5377 _(session_rule_add_del_reply)                           \
5378 _(ip_container_proxy_add_del_reply)
5379
5380 #define _(n)                                    \
5381     static void vl_api_##n##_t_handler          \
5382     (vl_api_##n##_t * mp)                       \
5383     {                                           \
5384         vat_main_t * vam = &vat_main;           \
5385         i32 retval = ntohl(mp->retval);         \
5386         if (vam->async_mode) {                  \
5387             vam->async_errors += (retval < 0);  \
5388         } else {                                \
5389             vam->retval = retval;               \
5390             vam->result_ready = 1;              \
5391         }                                       \
5392     }
5393 foreach_standard_reply_retval_handler;
5394 #undef _
5395
5396 #define _(n)                                    \
5397     static void vl_api_##n##_t_handler_json     \
5398     (vl_api_##n##_t * mp)                       \
5399     {                                           \
5400         vat_main_t * vam = &vat_main;           \
5401         vat_json_node_t node;                   \
5402         vat_json_init_object(&node);            \
5403         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5404         vat_json_print(vam->ofp, &node);        \
5405         vam->retval = ntohl(mp->retval);        \
5406         vam->result_ready = 1;                  \
5407     }
5408 foreach_standard_reply_retval_handler;
5409 #undef _
5410
5411 /*
5412  * Table of message reply handlers, must include boilerplate handlers
5413  * we just generated
5414  */
5415
5416 #define foreach_vpe_api_reply_msg                                       \
5417 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5418 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5419 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5420 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5421 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5422 _(CLI_REPLY, cli_reply)                                                 \
5423 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5424 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5425   sw_interface_add_del_address_reply)                                   \
5426 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5427 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5428 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5429 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5430 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5431 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5432 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5433 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5434   sw_interface_set_l2_xconnect_reply)                                   \
5435 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5436   sw_interface_set_l2_bridge_reply)                                     \
5437 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5438 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5439 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5440 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5441 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5442 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5443 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5444 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5445 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5446 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5447 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5448 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5449 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5450 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5451 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5452 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5453 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5454 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5455 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5456 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5457 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5458 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5459 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5460 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5461 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5462   proxy_arp_intfc_enable_disable_reply)                                 \
5463 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5464 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5465   sw_interface_set_unnumbered_reply)                                    \
5466 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5467 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5468 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5469 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5470 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5471 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5472 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5473 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5474 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5475 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5476 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5477   sw_interface_ip6_enable_disable_reply)                                \
5478 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5479   sw_interface_ip6_set_link_local_address_reply)                        \
5480 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5481 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5482 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5483   sw_interface_ip6nd_ra_prefix_reply)                                   \
5484 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5485   sw_interface_ip6nd_ra_config_reply)                                   \
5486 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5487 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5488 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5489 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5490 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5491 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5492 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5493 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5494 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5495 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5496 classify_set_interface_ip_table_reply)                                  \
5497 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5498   classify_set_interface_l2_tables_reply)                               \
5499 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5500 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5501 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5502 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5503 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5504   l2tpv3_interface_enable_disable_reply)                                \
5505 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5506 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5507 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5508 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5509 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5510 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5511 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5512 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5513 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5514 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5515 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5516 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5517 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5518 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5519 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5520 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5521 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5522 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5523 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5524 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5525 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5526 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5527 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5528 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5529 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5530 _(L2_MACS_EVENT, l2_macs_event)                                         \
5531 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5532 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5533 _(IP_DETAILS, ip_details)                                               \
5534 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5535 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5536 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5537 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5538 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5539 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5540 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5541 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5542 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5543 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5544 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5545 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5546 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5547 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5548 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5549 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5550 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5551 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5552 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5553 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5554 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5555 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5556 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5557 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5558 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5559 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5560 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5561 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5562 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5563 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5564 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5565 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5566 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5567 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5568 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5569 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5570 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5571 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5572 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5573 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5574 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5575 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5576 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5577 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5578 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5579 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5580 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5581 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5582   one_map_register_enable_disable_reply)                                \
5583 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5584 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5585 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5586 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5587   one_map_register_fallback_threshold_reply)                            \
5588 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5589   one_rloc_probe_enable_disable_reply)                                  \
5590 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5591 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5592 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5593 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5594 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5595 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5596 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5597 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5598 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5599 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5600 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5601 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5602 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5603 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5604 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5605 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5606   show_one_stats_enable_disable_reply)                                  \
5607 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5608 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5609 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5610 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5611 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5612 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5613 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5614 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5615   one_enable_disable_pitr_mode_reply)                                   \
5616 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5617   one_enable_disable_petr_mode_reply)                                   \
5618 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5619 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5620 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5621 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5622 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5623 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5624 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5625 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5626 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5627 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5628 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5629 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5630   gpe_add_del_native_fwd_rpath_reply)                                   \
5631 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5632   gpe_fwd_entry_path_details)                                           \
5633 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5634 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5635   one_add_del_map_request_itr_rlocs_reply)                              \
5636 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5637   one_get_map_request_itr_rlocs_reply)                                  \
5638 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5639 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5640 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5641 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5642 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5643 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5644   show_one_map_register_state_reply)                                    \
5645 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5646 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5647   show_one_map_register_fallback_threshold_reply)                       \
5648 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5649 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5650 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5651 _(POLICER_DETAILS, policer_details)                                     \
5652 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5653 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5654 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5655 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5656 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5657 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5658 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5659 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5660 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5661 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5662 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5663 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5664 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5665 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5666 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5667 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5668 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5669 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5670 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5671 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5672 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5673 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5674 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5675 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5676 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5677  ip_source_and_port_range_check_add_del_reply)                          \
5678 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5679  ip_source_and_port_range_check_interface_add_del_reply)                \
5680 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5681 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5682 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5683 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5684 _(PUNT_REPLY, punt_reply)                                               \
5685 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5686 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5687 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5688 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5689 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5690 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5691 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5692 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5693 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5694 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5695 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5696 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5697 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5698 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5699 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5700 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5701 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5702 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5703 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5704 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5705 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5706
5707 #define foreach_standalone_reply_msg                                    \
5708 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5709 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5710 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5711 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5712 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5713 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5714 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5715 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5716
5717 typedef struct
5718 {
5719   u8 *name;
5720   u32 value;
5721 } name_sort_t;
5722
5723
5724 #define STR_VTR_OP_CASE(op)     \
5725     case L2_VTR_ ## op:         \
5726         return "" # op;
5727
5728 static const char *
5729 str_vtr_op (u32 vtr_op)
5730 {
5731   switch (vtr_op)
5732     {
5733       STR_VTR_OP_CASE (DISABLED);
5734       STR_VTR_OP_CASE (PUSH_1);
5735       STR_VTR_OP_CASE (PUSH_2);
5736       STR_VTR_OP_CASE (POP_1);
5737       STR_VTR_OP_CASE (POP_2);
5738       STR_VTR_OP_CASE (TRANSLATE_1_1);
5739       STR_VTR_OP_CASE (TRANSLATE_1_2);
5740       STR_VTR_OP_CASE (TRANSLATE_2_1);
5741       STR_VTR_OP_CASE (TRANSLATE_2_2);
5742     }
5743
5744   return "UNKNOWN";
5745 }
5746
5747 static int
5748 dump_sub_interface_table (vat_main_t * vam)
5749 {
5750   const sw_interface_subif_t *sub = NULL;
5751
5752   if (vam->json_output)
5753     {
5754       clib_warning
5755         ("JSON output supported only for VPE API calls and dump_stats_table");
5756       return -99;
5757     }
5758
5759   print (vam->ofp,
5760          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5761          "Interface", "sw_if_index",
5762          "sub id", "dot1ad", "tags", "outer id",
5763          "inner id", "exact", "default", "outer any", "inner any");
5764
5765   vec_foreach (sub, vam->sw_if_subif_table)
5766   {
5767     print (vam->ofp,
5768            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5769            sub->interface_name,
5770            sub->sw_if_index,
5771            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5772            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5773            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5774            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5775     if (sub->vtr_op != L2_VTR_DISABLED)
5776       {
5777         print (vam->ofp,
5778                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5779                "tag1: %d tag2: %d ]",
5780                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5781                sub->vtr_tag1, sub->vtr_tag2);
5782       }
5783   }
5784
5785   return 0;
5786 }
5787
5788 static int
5789 name_sort_cmp (void *a1, void *a2)
5790 {
5791   name_sort_t *n1 = a1;
5792   name_sort_t *n2 = a2;
5793
5794   return strcmp ((char *) n1->name, (char *) n2->name);
5795 }
5796
5797 static int
5798 dump_interface_table (vat_main_t * vam)
5799 {
5800   hash_pair_t *p;
5801   name_sort_t *nses = 0, *ns;
5802
5803   if (vam->json_output)
5804     {
5805       clib_warning
5806         ("JSON output supported only for VPE API calls and dump_stats_table");
5807       return -99;
5808     }
5809
5810   /* *INDENT-OFF* */
5811   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5812   ({
5813     vec_add2 (nses, ns, 1);
5814     ns->name = (u8 *)(p->key);
5815     ns->value = (u32) p->value[0];
5816   }));
5817   /* *INDENT-ON* */
5818
5819   vec_sort_with_function (nses, name_sort_cmp);
5820
5821   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5822   vec_foreach (ns, nses)
5823   {
5824     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5825   }
5826   vec_free (nses);
5827   return 0;
5828 }
5829
5830 static int
5831 dump_ip_table (vat_main_t * vam, int is_ipv6)
5832 {
5833   const ip_details_t *det = NULL;
5834   const ip_address_details_t *address = NULL;
5835   u32 i = ~0;
5836
5837   print (vam->ofp, "%-12s", "sw_if_index");
5838
5839   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5840   {
5841     i++;
5842     if (!det->present)
5843       {
5844         continue;
5845       }
5846     print (vam->ofp, "%-12d", i);
5847     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5848     if (!det->addr)
5849       {
5850         continue;
5851       }
5852     vec_foreach (address, det->addr)
5853     {
5854       print (vam->ofp,
5855              "            %-30U%-13d",
5856              is_ipv6 ? format_ip6_address : format_ip4_address,
5857              address->ip, address->prefix_length);
5858     }
5859   }
5860
5861   return 0;
5862 }
5863
5864 static int
5865 dump_ipv4_table (vat_main_t * vam)
5866 {
5867   if (vam->json_output)
5868     {
5869       clib_warning
5870         ("JSON output supported only for VPE API calls and dump_stats_table");
5871       return -99;
5872     }
5873
5874   return dump_ip_table (vam, 0);
5875 }
5876
5877 static int
5878 dump_ipv6_table (vat_main_t * vam)
5879 {
5880   if (vam->json_output)
5881     {
5882       clib_warning
5883         ("JSON output supported only for VPE API calls and dump_stats_table");
5884       return -99;
5885     }
5886
5887   return dump_ip_table (vam, 1);
5888 }
5889
5890 static char *
5891 counter_type_to_str (u8 counter_type, u8 is_combined)
5892 {
5893   if (!is_combined)
5894     {
5895       switch (counter_type)
5896         {
5897         case VNET_INTERFACE_COUNTER_DROP:
5898           return "drop";
5899         case VNET_INTERFACE_COUNTER_PUNT:
5900           return "punt";
5901         case VNET_INTERFACE_COUNTER_IP4:
5902           return "ip4";
5903         case VNET_INTERFACE_COUNTER_IP6:
5904           return "ip6";
5905         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5906           return "rx-no-buf";
5907         case VNET_INTERFACE_COUNTER_RX_MISS:
5908           return "rx-miss";
5909         case VNET_INTERFACE_COUNTER_RX_ERROR:
5910           return "rx-error";
5911         case VNET_INTERFACE_COUNTER_TX_ERROR:
5912           return "tx-error";
5913         default:
5914           return "INVALID-COUNTER-TYPE";
5915         }
5916     }
5917   else
5918     {
5919       switch (counter_type)
5920         {
5921         case VNET_INTERFACE_COUNTER_RX:
5922           return "rx";
5923         case VNET_INTERFACE_COUNTER_TX:
5924           return "tx";
5925         default:
5926           return "INVALID-COUNTER-TYPE";
5927         }
5928     }
5929 }
5930
5931 static int
5932 dump_stats_table (vat_main_t * vam)
5933 {
5934   vat_json_node_t node;
5935   vat_json_node_t *msg_array;
5936   vat_json_node_t *msg;
5937   vat_json_node_t *counter_array;
5938   vat_json_node_t *counter;
5939   interface_counter_t c;
5940   u64 packets;
5941   ip4_fib_counter_t *c4;
5942   ip6_fib_counter_t *c6;
5943   ip4_nbr_counter_t *n4;
5944   ip6_nbr_counter_t *n6;
5945   int i, j;
5946
5947   if (!vam->json_output)
5948     {
5949       clib_warning ("dump_stats_table supported only in JSON format");
5950       return -99;
5951     }
5952
5953   vat_json_init_object (&node);
5954
5955   /* interface counters */
5956   msg_array = vat_json_object_add (&node, "interface_counters");
5957   vat_json_init_array (msg_array);
5958   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5959     {
5960       msg = vat_json_array_add (msg_array);
5961       vat_json_init_object (msg);
5962       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5963                                        (u8 *) counter_type_to_str (i, 0));
5964       vat_json_object_add_int (msg, "is_combined", 0);
5965       counter_array = vat_json_object_add (msg, "data");
5966       vat_json_init_array (counter_array);
5967       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5968         {
5969           packets = vam->simple_interface_counters[i][j];
5970           vat_json_array_add_uint (counter_array, packets);
5971         }
5972     }
5973   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5974     {
5975       msg = vat_json_array_add (msg_array);
5976       vat_json_init_object (msg);
5977       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5978                                        (u8 *) counter_type_to_str (i, 1));
5979       vat_json_object_add_int (msg, "is_combined", 1);
5980       counter_array = vat_json_object_add (msg, "data");
5981       vat_json_init_array (counter_array);
5982       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5983         {
5984           c = vam->combined_interface_counters[i][j];
5985           counter = vat_json_array_add (counter_array);
5986           vat_json_init_object (counter);
5987           vat_json_object_add_uint (counter, "packets", c.packets);
5988           vat_json_object_add_uint (counter, "bytes", c.bytes);
5989         }
5990     }
5991
5992   /* ip4 fib counters */
5993   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5994   vat_json_init_array (msg_array);
5995   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5996     {
5997       msg = vat_json_array_add (msg_array);
5998       vat_json_init_object (msg);
5999       vat_json_object_add_uint (msg, "vrf_id",
6000                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6001       counter_array = vat_json_object_add (msg, "c");
6002       vat_json_init_array (counter_array);
6003       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6004         {
6005           counter = vat_json_array_add (counter_array);
6006           vat_json_init_object (counter);
6007           c4 = &vam->ip4_fib_counters[i][j];
6008           vat_json_object_add_ip4 (counter, "address", c4->address);
6009           vat_json_object_add_uint (counter, "address_length",
6010                                     c4->address_length);
6011           vat_json_object_add_uint (counter, "packets", c4->packets);
6012           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6013         }
6014     }
6015
6016   /* ip6 fib counters */
6017   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6018   vat_json_init_array (msg_array);
6019   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6020     {
6021       msg = vat_json_array_add (msg_array);
6022       vat_json_init_object (msg);
6023       vat_json_object_add_uint (msg, "vrf_id",
6024                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6025       counter_array = vat_json_object_add (msg, "c");
6026       vat_json_init_array (counter_array);
6027       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6028         {
6029           counter = vat_json_array_add (counter_array);
6030           vat_json_init_object (counter);
6031           c6 = &vam->ip6_fib_counters[i][j];
6032           vat_json_object_add_ip6 (counter, "address", c6->address);
6033           vat_json_object_add_uint (counter, "address_length",
6034                                     c6->address_length);
6035           vat_json_object_add_uint (counter, "packets", c6->packets);
6036           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6037         }
6038     }
6039
6040   /* ip4 nbr counters */
6041   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6042   vat_json_init_array (msg_array);
6043   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6044     {
6045       msg = vat_json_array_add (msg_array);
6046       vat_json_init_object (msg);
6047       vat_json_object_add_uint (msg, "sw_if_index", i);
6048       counter_array = vat_json_object_add (msg, "c");
6049       vat_json_init_array (counter_array);
6050       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6051         {
6052           counter = vat_json_array_add (counter_array);
6053           vat_json_init_object (counter);
6054           n4 = &vam->ip4_nbr_counters[i][j];
6055           vat_json_object_add_ip4 (counter, "address", n4->address);
6056           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6057           vat_json_object_add_uint (counter, "packets", n4->packets);
6058           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6059         }
6060     }
6061
6062   /* ip6 nbr counters */
6063   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6064   vat_json_init_array (msg_array);
6065   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6066     {
6067       msg = vat_json_array_add (msg_array);
6068       vat_json_init_object (msg);
6069       vat_json_object_add_uint (msg, "sw_if_index", i);
6070       counter_array = vat_json_object_add (msg, "c");
6071       vat_json_init_array (counter_array);
6072       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6073         {
6074           counter = vat_json_array_add (counter_array);
6075           vat_json_init_object (counter);
6076           n6 = &vam->ip6_nbr_counters[i][j];
6077           vat_json_object_add_ip6 (counter, "address", n6->address);
6078           vat_json_object_add_uint (counter, "packets", n6->packets);
6079           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6080         }
6081     }
6082
6083   vat_json_print (vam->ofp, &node);
6084   vat_json_free (&node);
6085
6086   return 0;
6087 }
6088
6089 /*
6090  * Pass CLI buffers directly in the CLI_INBAND API message,
6091  * instead of an additional shared memory area.
6092  */
6093 static int
6094 exec_inband (vat_main_t * vam)
6095 {
6096   vl_api_cli_inband_t *mp;
6097   unformat_input_t *i = vam->input;
6098   int ret;
6099
6100   if (vec_len (i->buffer) == 0)
6101     return -1;
6102
6103   if (vam->exec_mode == 0 && unformat (i, "mode"))
6104     {
6105       vam->exec_mode = 1;
6106       return 0;
6107     }
6108   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6109     {
6110       vam->exec_mode = 0;
6111       return 0;
6112     }
6113
6114   /*
6115    * In order for the CLI command to work, it
6116    * must be a vector ending in \n, not a C-string ending
6117    * in \n\0.
6118    */
6119   u32 len = vec_len (vam->input->buffer);
6120   M2 (CLI_INBAND, mp, len);
6121   clib_memcpy (mp->cmd, vam->input->buffer, len);
6122   mp->length = htonl (len);
6123
6124   S (mp);
6125   W (ret);
6126   /* json responses may or may not include a useful reply... */
6127   if (vec_len (vam->cmd_reply))
6128     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6129   return ret;
6130 }
6131
6132 int
6133 exec (vat_main_t * vam)
6134 {
6135   return exec_inband (vam);
6136 }
6137
6138 static int
6139 api_create_loopback (vat_main_t * vam)
6140 {
6141   unformat_input_t *i = vam->input;
6142   vl_api_create_loopback_t *mp;
6143   vl_api_create_loopback_instance_t *mp_lbi;
6144   u8 mac_address[6];
6145   u8 mac_set = 0;
6146   u8 is_specified = 0;
6147   u32 user_instance = 0;
6148   int ret;
6149
6150   memset (mac_address, 0, sizeof (mac_address));
6151
6152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6153     {
6154       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6155         mac_set = 1;
6156       if (unformat (i, "instance %d", &user_instance))
6157         is_specified = 1;
6158       else
6159         break;
6160     }
6161
6162   if (is_specified)
6163     {
6164       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6165       mp_lbi->is_specified = is_specified;
6166       if (is_specified)
6167         mp_lbi->user_instance = htonl (user_instance);
6168       if (mac_set)
6169         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6170       S (mp_lbi);
6171     }
6172   else
6173     {
6174       /* Construct the API message */
6175       M (CREATE_LOOPBACK, mp);
6176       if (mac_set)
6177         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6178       S (mp);
6179     }
6180
6181   W (ret);
6182   return ret;
6183 }
6184
6185 static int
6186 api_delete_loopback (vat_main_t * vam)
6187 {
6188   unformat_input_t *i = vam->input;
6189   vl_api_delete_loopback_t *mp;
6190   u32 sw_if_index = ~0;
6191   int ret;
6192
6193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6194     {
6195       if (unformat (i, "sw_if_index %d", &sw_if_index))
6196         ;
6197       else
6198         break;
6199     }
6200
6201   if (sw_if_index == ~0)
6202     {
6203       errmsg ("missing sw_if_index");
6204       return -99;
6205     }
6206
6207   /* Construct the API message */
6208   M (DELETE_LOOPBACK, mp);
6209   mp->sw_if_index = ntohl (sw_if_index);
6210
6211   S (mp);
6212   W (ret);
6213   return ret;
6214 }
6215
6216 static int
6217 api_want_stats (vat_main_t * vam)
6218 {
6219   unformat_input_t *i = vam->input;
6220   vl_api_want_stats_t *mp;
6221   int enable = -1;
6222   int ret;
6223
6224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6225     {
6226       if (unformat (i, "enable"))
6227         enable = 1;
6228       else if (unformat (i, "disable"))
6229         enable = 0;
6230       else
6231         break;
6232     }
6233
6234   if (enable == -1)
6235     {
6236       errmsg ("missing enable|disable");
6237       return -99;
6238     }
6239
6240   M (WANT_STATS, mp);
6241   mp->enable_disable = enable;
6242
6243   S (mp);
6244   W (ret);
6245   return ret;
6246 }
6247
6248 static int
6249 api_want_interface_events (vat_main_t * vam)
6250 {
6251   unformat_input_t *i = vam->input;
6252   vl_api_want_interface_events_t *mp;
6253   int enable = -1;
6254   int ret;
6255
6256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6257     {
6258       if (unformat (i, "enable"))
6259         enable = 1;
6260       else if (unformat (i, "disable"))
6261         enable = 0;
6262       else
6263         break;
6264     }
6265
6266   if (enable == -1)
6267     {
6268       errmsg ("missing enable|disable");
6269       return -99;
6270     }
6271
6272   M (WANT_INTERFACE_EVENTS, mp);
6273   mp->enable_disable = enable;
6274
6275   vam->interface_event_display = enable;
6276
6277   S (mp);
6278   W (ret);
6279   return ret;
6280 }
6281
6282
6283 /* Note: non-static, called once to set up the initial intfc table */
6284 int
6285 api_sw_interface_dump (vat_main_t * vam)
6286 {
6287   vl_api_sw_interface_dump_t *mp;
6288   vl_api_control_ping_t *mp_ping;
6289   hash_pair_t *p;
6290   name_sort_t *nses = 0, *ns;
6291   sw_interface_subif_t *sub = NULL;
6292   int ret;
6293
6294   /* Toss the old name table */
6295   /* *INDENT-OFF* */
6296   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6297   ({
6298     vec_add2 (nses, ns, 1);
6299     ns->name = (u8 *)(p->key);
6300     ns->value = (u32) p->value[0];
6301   }));
6302   /* *INDENT-ON* */
6303
6304   hash_free (vam->sw_if_index_by_interface_name);
6305
6306   vec_foreach (ns, nses) vec_free (ns->name);
6307
6308   vec_free (nses);
6309
6310   vec_foreach (sub, vam->sw_if_subif_table)
6311   {
6312     vec_free (sub->interface_name);
6313   }
6314   vec_free (vam->sw_if_subif_table);
6315
6316   /* recreate the interface name hash table */
6317   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6318
6319   /* Get list of ethernets */
6320   M (SW_INTERFACE_DUMP, mp);
6321   mp->name_filter_valid = 1;
6322   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6323   S (mp);
6324
6325   /* and local / loopback interfaces */
6326   M (SW_INTERFACE_DUMP, mp);
6327   mp->name_filter_valid = 1;
6328   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6329   S (mp);
6330
6331   /* and packet-generator interfaces */
6332   M (SW_INTERFACE_DUMP, mp);
6333   mp->name_filter_valid = 1;
6334   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6335   S (mp);
6336
6337   /* and vxlan-gpe tunnel interfaces */
6338   M (SW_INTERFACE_DUMP, mp);
6339   mp->name_filter_valid = 1;
6340   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6341            sizeof (mp->name_filter) - 1);
6342   S (mp);
6343
6344   /* and vxlan tunnel interfaces */
6345   M (SW_INTERFACE_DUMP, mp);
6346   mp->name_filter_valid = 1;
6347   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6348   S (mp);
6349
6350   /* and geneve tunnel interfaces */
6351   M (SW_INTERFACE_DUMP, mp);
6352   mp->name_filter_valid = 1;
6353   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6354   S (mp);
6355
6356   /* and host (af_packet) interfaces */
6357   M (SW_INTERFACE_DUMP, mp);
6358   mp->name_filter_valid = 1;
6359   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6360   S (mp);
6361
6362   /* and l2tpv3 tunnel interfaces */
6363   M (SW_INTERFACE_DUMP, mp);
6364   mp->name_filter_valid = 1;
6365   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6366            sizeof (mp->name_filter) - 1);
6367   S (mp);
6368
6369   /* and GRE tunnel interfaces */
6370   M (SW_INTERFACE_DUMP, mp);
6371   mp->name_filter_valid = 1;
6372   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6373   S (mp);
6374
6375   /* and LISP-GPE interfaces */
6376   M (SW_INTERFACE_DUMP, mp);
6377   mp->name_filter_valid = 1;
6378   strncpy ((char *) mp->name_filter, "lisp_gpe",
6379            sizeof (mp->name_filter) - 1);
6380   S (mp);
6381
6382   /* and IPSEC tunnel interfaces */
6383   M (SW_INTERFACE_DUMP, mp);
6384   mp->name_filter_valid = 1;
6385   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6386   S (mp);
6387
6388   /* Use a control ping for synchronization */
6389   MPING (CONTROL_PING, mp_ping);
6390   S (mp_ping);
6391
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_flags (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_flags_t *mp;
6401   u32 sw_if_index;
6402   u8 sw_if_index_set = 0;
6403   u8 admin_up = 0;
6404   int ret;
6405
6406   /* Parse args required to build the message */
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "admin-up"))
6410         admin_up = 1;
6411       else if (unformat (i, "admin-down"))
6412         admin_up = 0;
6413       else
6414         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6415         sw_if_index_set = 1;
6416       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6417         sw_if_index_set = 1;
6418       else
6419         break;
6420     }
6421
6422   if (sw_if_index_set == 0)
6423     {
6424       errmsg ("missing interface name or sw_if_index");
6425       return -99;
6426     }
6427
6428   /* Construct the API message */
6429   M (SW_INTERFACE_SET_FLAGS, mp);
6430   mp->sw_if_index = ntohl (sw_if_index);
6431   mp->admin_up_down = admin_up;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply, return the good/bad news... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_rx_mode (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_rx_mode_t *mp;
6446   u32 sw_if_index;
6447   u8 sw_if_index_set = 0;
6448   int ret;
6449   u8 queue_id_valid = 0;
6450   u32 queue_id;
6451   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6452
6453   /* Parse args required to build the message */
6454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6455     {
6456       if (unformat (i, "queue %d", &queue_id))
6457         queue_id_valid = 1;
6458       else if (unformat (i, "polling"))
6459         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6460       else if (unformat (i, "interrupt"))
6461         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6462       else if (unformat (i, "adaptive"))
6463         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6464       else
6465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6466         sw_if_index_set = 1;
6467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6468         sw_if_index_set = 1;
6469       else
6470         break;
6471     }
6472
6473   if (sw_if_index_set == 0)
6474     {
6475       errmsg ("missing interface name or sw_if_index");
6476       return -99;
6477     }
6478   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6479     {
6480       errmsg ("missing rx-mode");
6481       return -99;
6482     }
6483
6484   /* Construct the API message */
6485   M (SW_INTERFACE_SET_RX_MODE, mp);
6486   mp->sw_if_index = ntohl (sw_if_index);
6487   mp->mode = mode;
6488   mp->queue_id_valid = queue_id_valid;
6489   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6490
6491   /* send it... */
6492   S (mp);
6493
6494   /* Wait for a reply, return the good/bad news... */
6495   W (ret);
6496   return ret;
6497 }
6498
6499 static int
6500 api_sw_interface_clear_stats (vat_main_t * vam)
6501 {
6502   unformat_input_t *i = vam->input;
6503   vl_api_sw_interface_clear_stats_t *mp;
6504   u32 sw_if_index;
6505   u8 sw_if_index_set = 0;
6506   int ret;
6507
6508   /* Parse args required to build the message */
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6512         sw_if_index_set = 1;
6513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6514         sw_if_index_set = 1;
6515       else
6516         break;
6517     }
6518
6519   /* Construct the API message */
6520   M (SW_INTERFACE_CLEAR_STATS, mp);
6521
6522   if (sw_if_index_set == 1)
6523     mp->sw_if_index = ntohl (sw_if_index);
6524   else
6525     mp->sw_if_index = ~0;
6526
6527   /* send it... */
6528   S (mp);
6529
6530   /* Wait for a reply, return the good/bad news... */
6531   W (ret);
6532   return ret;
6533 }
6534
6535 static int
6536 api_sw_interface_add_del_address (vat_main_t * vam)
6537 {
6538   unformat_input_t *i = vam->input;
6539   vl_api_sw_interface_add_del_address_t *mp;
6540   u32 sw_if_index;
6541   u8 sw_if_index_set = 0;
6542   u8 is_add = 1, del_all = 0;
6543   u32 address_length = 0;
6544   u8 v4_address_set = 0;
6545   u8 v6_address_set = 0;
6546   ip4_address_t v4address;
6547   ip6_address_t v6address;
6548   int ret;
6549
6550   /* Parse args required to build the message */
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "del-all"))
6554         del_all = 1;
6555       else if (unformat (i, "del"))
6556         is_add = 0;
6557       else
6558         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6559         sw_if_index_set = 1;
6560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "%U/%d",
6563                          unformat_ip4_address, &v4address, &address_length))
6564         v4_address_set = 1;
6565       else if (unformat (i, "%U/%d",
6566                          unformat_ip6_address, &v6address, &address_length))
6567         v6_address_set = 1;
6568       else
6569         break;
6570     }
6571
6572   if (sw_if_index_set == 0)
6573     {
6574       errmsg ("missing interface name or sw_if_index");
6575       return -99;
6576     }
6577   if (v4_address_set && v6_address_set)
6578     {
6579       errmsg ("both v4 and v6 addresses set");
6580       return -99;
6581     }
6582   if (!v4_address_set && !v6_address_set && !del_all)
6583     {
6584       errmsg ("no addresses set");
6585       return -99;
6586     }
6587
6588   /* Construct the API message */
6589   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6590
6591   mp->sw_if_index = ntohl (sw_if_index);
6592   mp->is_add = is_add;
6593   mp->del_all = del_all;
6594   if (v6_address_set)
6595     {
6596       mp->is_ipv6 = 1;
6597       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6598     }
6599   else
6600     {
6601       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6602     }
6603   mp->address_length = address_length;
6604
6605   /* send it... */
6606   S (mp);
6607
6608   /* Wait for a reply, return good/bad news  */
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_set_mpls_enable_t *mp;
6618   u32 sw_if_index;
6619   u8 sw_if_index_set = 0;
6620   u8 enable = 1;
6621   int ret;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6627         sw_if_index_set = 1;
6628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "disable"))
6631         enable = 0;
6632       else if (unformat (i, "dis"))
6633         enable = 0;
6634       else
6635         break;
6636     }
6637
6638   if (sw_if_index_set == 0)
6639     {
6640       errmsg ("missing interface name or sw_if_index");
6641       return -99;
6642     }
6643
6644   /* Construct the API message */
6645   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6646
6647   mp->sw_if_index = ntohl (sw_if_index);
6648   mp->enable = enable;
6649
6650   /* send it... */
6651   S (mp);
6652
6653   /* Wait for a reply... */
6654   W (ret);
6655   return ret;
6656 }
6657
6658 static int
6659 api_sw_interface_set_table (vat_main_t * vam)
6660 {
6661   unformat_input_t *i = vam->input;
6662   vl_api_sw_interface_set_table_t *mp;
6663   u32 sw_if_index, vrf_id = 0;
6664   u8 sw_if_index_set = 0;
6665   u8 is_ipv6 = 0;
6666   int ret;
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6672         sw_if_index_set = 1;
6673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6674         sw_if_index_set = 1;
6675       else if (unformat (i, "vrf %d", &vrf_id))
6676         ;
6677       else if (unformat (i, "ipv6"))
6678         is_ipv6 = 1;
6679       else
6680         break;
6681     }
6682
6683   if (sw_if_index_set == 0)
6684     {
6685       errmsg ("missing interface name or sw_if_index");
6686       return -99;
6687     }
6688
6689   /* Construct the API message */
6690   M (SW_INTERFACE_SET_TABLE, mp);
6691
6692   mp->sw_if_index = ntohl (sw_if_index);
6693   mp->is_ipv6 = is_ipv6;
6694   mp->vrf_id = ntohl (vrf_id);
6695
6696   /* send it... */
6697   S (mp);
6698
6699   /* Wait for a reply... */
6700   W (ret);
6701   return ret;
6702 }
6703
6704 static void vl_api_sw_interface_get_table_reply_t_handler
6705   (vl_api_sw_interface_get_table_reply_t * mp)
6706 {
6707   vat_main_t *vam = &vat_main;
6708
6709   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6710
6711   vam->retval = ntohl (mp->retval);
6712   vam->result_ready = 1;
6713
6714 }
6715
6716 static void vl_api_sw_interface_get_table_reply_t_handler_json
6717   (vl_api_sw_interface_get_table_reply_t * mp)
6718 {
6719   vat_main_t *vam = &vat_main;
6720   vat_json_node_t node;
6721
6722   vat_json_init_object (&node);
6723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6724   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6725
6726   vat_json_print (vam->ofp, &node);
6727   vat_json_free (&node);
6728
6729   vam->retval = ntohl (mp->retval);
6730   vam->result_ready = 1;
6731 }
6732
6733 static int
6734 api_sw_interface_get_table (vat_main_t * vam)
6735 {
6736   unformat_input_t *i = vam->input;
6737   vl_api_sw_interface_get_table_t *mp;
6738   u32 sw_if_index;
6739   u8 sw_if_index_set = 0;
6740   u8 is_ipv6 = 0;
6741   int ret;
6742
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "ipv6"))
6750         is_ipv6 = 1;
6751       else
6752         break;
6753     }
6754
6755   if (sw_if_index_set == 0)
6756     {
6757       errmsg ("missing interface name or sw_if_index");
6758       return -99;
6759     }
6760
6761   M (SW_INTERFACE_GET_TABLE, mp);
6762   mp->sw_if_index = htonl (sw_if_index);
6763   mp->is_ipv6 = is_ipv6;
6764
6765   S (mp);
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_sw_interface_set_vpath (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_sw_interface_set_vpath_t *mp;
6775   u32 sw_if_index = 0;
6776   u8 sw_if_index_set = 0;
6777   u8 is_enable = 0;
6778   int ret;
6779
6780   /* Parse args required to build the message */
6781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6782     {
6783       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6784         sw_if_index_set = 1;
6785       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6786         sw_if_index_set = 1;
6787       else if (unformat (i, "enable"))
6788         is_enable = 1;
6789       else if (unformat (i, "disable"))
6790         is_enable = 0;
6791       else
6792         break;
6793     }
6794
6795   if (sw_if_index_set == 0)
6796     {
6797       errmsg ("missing interface name or sw_if_index");
6798       return -99;
6799     }
6800
6801   /* Construct the API message */
6802   M (SW_INTERFACE_SET_VPATH, mp);
6803
6804   mp->sw_if_index = ntohl (sw_if_index);
6805   mp->enable = is_enable;
6806
6807   /* send it... */
6808   S (mp);
6809
6810   /* Wait for a reply... */
6811   W (ret);
6812   return ret;
6813 }
6814
6815 static int
6816 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6817 {
6818   unformat_input_t *i = vam->input;
6819   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6820   u32 sw_if_index = 0;
6821   u8 sw_if_index_set = 0;
6822   u8 is_enable = 1;
6823   u8 is_ipv6 = 0;
6824   int ret;
6825
6826   /* Parse args required to build the message */
6827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6828     {
6829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6832         sw_if_index_set = 1;
6833       else if (unformat (i, "enable"))
6834         is_enable = 1;
6835       else if (unformat (i, "disable"))
6836         is_enable = 0;
6837       else if (unformat (i, "ip4"))
6838         is_ipv6 = 0;
6839       else if (unformat (i, "ip6"))
6840         is_ipv6 = 1;
6841       else
6842         break;
6843     }
6844
6845   if (sw_if_index_set == 0)
6846     {
6847       errmsg ("missing interface name or sw_if_index");
6848       return -99;
6849     }
6850
6851   /* Construct the API message */
6852   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6853
6854   mp->sw_if_index = ntohl (sw_if_index);
6855   mp->enable = is_enable;
6856   mp->is_ipv6 = is_ipv6;
6857
6858   /* send it... */
6859   S (mp);
6860
6861   /* Wait for a reply... */
6862   W (ret);
6863   return ret;
6864 }
6865
6866 static int
6867 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6868 {
6869   unformat_input_t *i = vam->input;
6870   vl_api_sw_interface_set_geneve_bypass_t *mp;
6871   u32 sw_if_index = 0;
6872   u8 sw_if_index_set = 0;
6873   u8 is_enable = 1;
6874   u8 is_ipv6 = 0;
6875   int ret;
6876
6877   /* Parse args required to build the message */
6878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879     {
6880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6881         sw_if_index_set = 1;
6882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6883         sw_if_index_set = 1;
6884       else if (unformat (i, "enable"))
6885         is_enable = 1;
6886       else if (unformat (i, "disable"))
6887         is_enable = 0;
6888       else if (unformat (i, "ip4"))
6889         is_ipv6 = 0;
6890       else if (unformat (i, "ip6"))
6891         is_ipv6 = 1;
6892       else
6893         break;
6894     }
6895
6896   if (sw_if_index_set == 0)
6897     {
6898       errmsg ("missing interface name or sw_if_index");
6899       return -99;
6900     }
6901
6902   /* Construct the API message */
6903   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6904
6905   mp->sw_if_index = ntohl (sw_if_index);
6906   mp->enable = is_enable;
6907   mp->is_ipv6 = is_ipv6;
6908
6909   /* send it... */
6910   S (mp);
6911
6912   /* Wait for a reply... */
6913   W (ret);
6914   return ret;
6915 }
6916
6917 static int
6918 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6919 {
6920   unformat_input_t *i = vam->input;
6921   vl_api_sw_interface_set_l2_xconnect_t *mp;
6922   u32 rx_sw_if_index;
6923   u8 rx_sw_if_index_set = 0;
6924   u32 tx_sw_if_index;
6925   u8 tx_sw_if_index_set = 0;
6926   u8 enable = 1;
6927   int ret;
6928
6929   /* Parse args required to build the message */
6930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6931     {
6932       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6933         rx_sw_if_index_set = 1;
6934       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6935         tx_sw_if_index_set = 1;
6936       else if (unformat (i, "rx"))
6937         {
6938           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6939             {
6940               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6941                             &rx_sw_if_index))
6942                 rx_sw_if_index_set = 1;
6943             }
6944           else
6945             break;
6946         }
6947       else if (unformat (i, "tx"))
6948         {
6949           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950             {
6951               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6952                             &tx_sw_if_index))
6953                 tx_sw_if_index_set = 1;
6954             }
6955           else
6956             break;
6957         }
6958       else if (unformat (i, "enable"))
6959         enable = 1;
6960       else if (unformat (i, "disable"))
6961         enable = 0;
6962       else
6963         break;
6964     }
6965
6966   if (rx_sw_if_index_set == 0)
6967     {
6968       errmsg ("missing rx interface name or rx_sw_if_index");
6969       return -99;
6970     }
6971
6972   if (enable && (tx_sw_if_index_set == 0))
6973     {
6974       errmsg ("missing tx interface name or tx_sw_if_index");
6975       return -99;
6976     }
6977
6978   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6979
6980   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6981   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6982   mp->enable = enable;
6983
6984   S (mp);
6985   W (ret);
6986   return ret;
6987 }
6988
6989 static int
6990 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6991 {
6992   unformat_input_t *i = vam->input;
6993   vl_api_sw_interface_set_l2_bridge_t *mp;
6994   u32 rx_sw_if_index;
6995   u8 rx_sw_if_index_set = 0;
6996   u32 bd_id;
6997   u8 bd_id_set = 0;
6998   u8 bvi = 0;
6999   u32 shg = 0;
7000   u8 enable = 1;
7001   int ret;
7002
7003   /* Parse args required to build the message */
7004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7005     {
7006       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7007         rx_sw_if_index_set = 1;
7008       else if (unformat (i, "bd_id %d", &bd_id))
7009         bd_id_set = 1;
7010       else
7011         if (unformat
7012             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7013         rx_sw_if_index_set = 1;
7014       else if (unformat (i, "shg %d", &shg))
7015         ;
7016       else if (unformat (i, "bvi"))
7017         bvi = 1;
7018       else if (unformat (i, "enable"))
7019         enable = 1;
7020       else if (unformat (i, "disable"))
7021         enable = 0;
7022       else
7023         break;
7024     }
7025
7026   if (rx_sw_if_index_set == 0)
7027     {
7028       errmsg ("missing rx interface name or sw_if_index");
7029       return -99;
7030     }
7031
7032   if (enable && (bd_id_set == 0))
7033     {
7034       errmsg ("missing bridge domain");
7035       return -99;
7036     }
7037
7038   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7039
7040   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7041   mp->bd_id = ntohl (bd_id);
7042   mp->shg = (u8) shg;
7043   mp->bvi = bvi;
7044   mp->enable = enable;
7045
7046   S (mp);
7047   W (ret);
7048   return ret;
7049 }
7050
7051 static int
7052 api_bridge_domain_dump (vat_main_t * vam)
7053 {
7054   unformat_input_t *i = vam->input;
7055   vl_api_bridge_domain_dump_t *mp;
7056   vl_api_control_ping_t *mp_ping;
7057   u32 bd_id = ~0;
7058   int ret;
7059
7060   /* Parse args required to build the message */
7061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7062     {
7063       if (unformat (i, "bd_id %d", &bd_id))
7064         ;
7065       else
7066         break;
7067     }
7068
7069   M (BRIDGE_DOMAIN_DUMP, mp);
7070   mp->bd_id = ntohl (bd_id);
7071   S (mp);
7072
7073   /* Use a control ping for synchronization */
7074   MPING (CONTROL_PING, mp_ping);
7075   S (mp_ping);
7076
7077   W (ret);
7078   return ret;
7079 }
7080
7081 static int
7082 api_bridge_domain_add_del (vat_main_t * vam)
7083 {
7084   unformat_input_t *i = vam->input;
7085   vl_api_bridge_domain_add_del_t *mp;
7086   u32 bd_id = ~0;
7087   u8 is_add = 1;
7088   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7089   u8 *bd_tag = NULL;
7090   u32 mac_age = 0;
7091   int ret;
7092
7093   /* Parse args required to build the message */
7094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7095     {
7096       if (unformat (i, "bd_id %d", &bd_id))
7097         ;
7098       else if (unformat (i, "flood %d", &flood))
7099         ;
7100       else if (unformat (i, "uu-flood %d", &uu_flood))
7101         ;
7102       else if (unformat (i, "forward %d", &forward))
7103         ;
7104       else if (unformat (i, "learn %d", &learn))
7105         ;
7106       else if (unformat (i, "arp-term %d", &arp_term))
7107         ;
7108       else if (unformat (i, "mac-age %d", &mac_age))
7109         ;
7110       else if (unformat (i, "bd-tag %s", &bd_tag))
7111         ;
7112       else if (unformat (i, "del"))
7113         {
7114           is_add = 0;
7115           flood = uu_flood = forward = learn = 0;
7116         }
7117       else
7118         break;
7119     }
7120
7121   if (bd_id == ~0)
7122     {
7123       errmsg ("missing bridge domain");
7124       ret = -99;
7125       goto done;
7126     }
7127
7128   if (mac_age > 255)
7129     {
7130       errmsg ("mac age must be less than 256 ");
7131       ret = -99;
7132       goto done;
7133     }
7134
7135   if ((bd_tag) && (vec_len (bd_tag) > 63))
7136     {
7137       errmsg ("bd-tag cannot be longer than 63");
7138       ret = -99;
7139       goto done;
7140     }
7141
7142   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7143
7144   mp->bd_id = ntohl (bd_id);
7145   mp->flood = flood;
7146   mp->uu_flood = uu_flood;
7147   mp->forward = forward;
7148   mp->learn = learn;
7149   mp->arp_term = arp_term;
7150   mp->is_add = is_add;
7151   mp->mac_age = (u8) mac_age;
7152   if (bd_tag)
7153     {
7154       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7155       mp->bd_tag[vec_len (bd_tag)] = 0;
7156     }
7157   S (mp);
7158   W (ret);
7159
7160 done:
7161   vec_free (bd_tag);
7162   return ret;
7163 }
7164
7165 static int
7166 api_l2fib_flush_bd (vat_main_t * vam)
7167 {
7168   unformat_input_t *i = vam->input;
7169   vl_api_l2fib_flush_bd_t *mp;
7170   u32 bd_id = ~0;
7171   int ret;
7172
7173   /* Parse args required to build the message */
7174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7175     {
7176       if (unformat (i, "bd_id %d", &bd_id));
7177       else
7178         break;
7179     }
7180
7181   if (bd_id == ~0)
7182     {
7183       errmsg ("missing bridge domain");
7184       return -99;
7185     }
7186
7187   M (L2FIB_FLUSH_BD, mp);
7188
7189   mp->bd_id = htonl (bd_id);
7190
7191   S (mp);
7192   W (ret);
7193   return ret;
7194 }
7195
7196 static int
7197 api_l2fib_flush_int (vat_main_t * vam)
7198 {
7199   unformat_input_t *i = vam->input;
7200   vl_api_l2fib_flush_int_t *mp;
7201   u32 sw_if_index = ~0;
7202   int ret;
7203
7204   /* Parse args required to build the message */
7205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7206     {
7207       if (unformat (i, "sw_if_index %d", &sw_if_index));
7208       else
7209         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7210       else
7211         break;
7212     }
7213
7214   if (sw_if_index == ~0)
7215     {
7216       errmsg ("missing interface name or sw_if_index");
7217       return -99;
7218     }
7219
7220   M (L2FIB_FLUSH_INT, mp);
7221
7222   mp->sw_if_index = ntohl (sw_if_index);
7223
7224   S (mp);
7225   W (ret);
7226   return ret;
7227 }
7228
7229 static int
7230 api_l2fib_add_del (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_l2fib_add_del_t *mp;
7234   f64 timeout;
7235   u8 mac[6] = { 0 };
7236   u8 mac_set = 0;
7237   u32 bd_id;
7238   u8 bd_id_set = 0;
7239   u32 sw_if_index = ~0;
7240   u8 sw_if_index_set = 0;
7241   u8 is_add = 1;
7242   u8 static_mac = 0;
7243   u8 filter_mac = 0;
7244   u8 bvi_mac = 0;
7245   int count = 1;
7246   f64 before = 0;
7247   int j;
7248
7249   /* Parse args required to build the message */
7250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7251     {
7252       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7253         mac_set = 1;
7254       else if (unformat (i, "bd_id %d", &bd_id))
7255         bd_id_set = 1;
7256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7257         sw_if_index_set = 1;
7258       else if (unformat (i, "sw_if"))
7259         {
7260           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261             {
7262               if (unformat
7263                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7264                 sw_if_index_set = 1;
7265             }
7266           else
7267             break;
7268         }
7269       else if (unformat (i, "static"))
7270         static_mac = 1;
7271       else if (unformat (i, "filter"))
7272         {
7273           filter_mac = 1;
7274           static_mac = 1;
7275         }
7276       else if (unformat (i, "bvi"))
7277         {
7278           bvi_mac = 1;
7279           static_mac = 1;
7280         }
7281       else if (unformat (i, "del"))
7282         is_add = 0;
7283       else if (unformat (i, "count %d", &count))
7284         ;
7285       else
7286         break;
7287     }
7288
7289   if (mac_set == 0)
7290     {
7291       errmsg ("missing mac address");
7292       return -99;
7293     }
7294
7295   if (bd_id_set == 0)
7296     {
7297       errmsg ("missing bridge domain");
7298       return -99;
7299     }
7300
7301   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7302     {
7303       errmsg ("missing interface name or sw_if_index");
7304       return -99;
7305     }
7306
7307   if (count > 1)
7308     {
7309       /* Turn on async mode */
7310       vam->async_mode = 1;
7311       vam->async_errors = 0;
7312       before = vat_time_now (vam);
7313     }
7314
7315   for (j = 0; j < count; j++)
7316     {
7317       M (L2FIB_ADD_DEL, mp);
7318
7319       clib_memcpy (mp->mac, mac, 6);
7320       mp->bd_id = ntohl (bd_id);
7321       mp->is_add = is_add;
7322
7323       if (is_add)
7324         {
7325           mp->sw_if_index = ntohl (sw_if_index);
7326           mp->static_mac = static_mac;
7327           mp->filter_mac = filter_mac;
7328           mp->bvi_mac = bvi_mac;
7329         }
7330       increment_mac_address (mac);
7331       /* send it... */
7332       S (mp);
7333     }
7334
7335   if (count > 1)
7336     {
7337       vl_api_control_ping_t *mp_ping;
7338       f64 after;
7339
7340       /* Shut off async mode */
7341       vam->async_mode = 0;
7342
7343       MPING (CONTROL_PING, mp_ping);
7344       S (mp_ping);
7345
7346       timeout = vat_time_now (vam) + 1.0;
7347       while (vat_time_now (vam) < timeout)
7348         if (vam->result_ready == 1)
7349           goto out;
7350       vam->retval = -99;
7351
7352     out:
7353       if (vam->retval == -99)
7354         errmsg ("timeout");
7355
7356       if (vam->async_errors > 0)
7357         {
7358           errmsg ("%d asynchronous errors", vam->async_errors);
7359           vam->retval = -98;
7360         }
7361       vam->async_errors = 0;
7362       after = vat_time_now (vam);
7363
7364       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7365              count, after - before, count / (after - before));
7366     }
7367   else
7368     {
7369       int ret;
7370
7371       /* Wait for a reply... */
7372       W (ret);
7373       return ret;
7374     }
7375   /* Return the good/bad news */
7376   return (vam->retval);
7377 }
7378
7379 static int
7380 api_bridge_domain_set_mac_age (vat_main_t * vam)
7381 {
7382   unformat_input_t *i = vam->input;
7383   vl_api_bridge_domain_set_mac_age_t *mp;
7384   u32 bd_id = ~0;
7385   u32 mac_age = 0;
7386   int ret;
7387
7388   /* Parse args required to build the message */
7389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7390     {
7391       if (unformat (i, "bd_id %d", &bd_id));
7392       else if (unformat (i, "mac-age %d", &mac_age));
7393       else
7394         break;
7395     }
7396
7397   if (bd_id == ~0)
7398     {
7399       errmsg ("missing bridge domain");
7400       return -99;
7401     }
7402
7403   if (mac_age > 255)
7404     {
7405       errmsg ("mac age must be less than 256 ");
7406       return -99;
7407     }
7408
7409   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7410
7411   mp->bd_id = htonl (bd_id);
7412   mp->mac_age = (u8) mac_age;
7413
7414   S (mp);
7415   W (ret);
7416   return ret;
7417 }
7418
7419 static int
7420 api_l2_flags (vat_main_t * vam)
7421 {
7422   unformat_input_t *i = vam->input;
7423   vl_api_l2_flags_t *mp;
7424   u32 sw_if_index;
7425   u32 flags = 0;
7426   u8 sw_if_index_set = 0;
7427   u8 is_set = 0;
7428   int ret;
7429
7430   /* Parse args required to build the message */
7431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7432     {
7433       if (unformat (i, "sw_if_index %d", &sw_if_index))
7434         sw_if_index_set = 1;
7435       else if (unformat (i, "sw_if"))
7436         {
7437           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7438             {
7439               if (unformat
7440                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7441                 sw_if_index_set = 1;
7442             }
7443           else
7444             break;
7445         }
7446       else if (unformat (i, "learn"))
7447         flags |= L2_LEARN;
7448       else if (unformat (i, "forward"))
7449         flags |= L2_FWD;
7450       else if (unformat (i, "flood"))
7451         flags |= L2_FLOOD;
7452       else if (unformat (i, "uu-flood"))
7453         flags |= L2_UU_FLOOD;
7454       else if (unformat (i, "arp-term"))
7455         flags |= L2_ARP_TERM;
7456       else if (unformat (i, "off"))
7457         is_set = 0;
7458       else if (unformat (i, "disable"))
7459         is_set = 0;
7460       else
7461         break;
7462     }
7463
7464   if (sw_if_index_set == 0)
7465     {
7466       errmsg ("missing interface name or sw_if_index");
7467       return -99;
7468     }
7469
7470   M (L2_FLAGS, mp);
7471
7472   mp->sw_if_index = ntohl (sw_if_index);
7473   mp->feature_bitmap = ntohl (flags);
7474   mp->is_set = is_set;
7475
7476   S (mp);
7477   W (ret);
7478   return ret;
7479 }
7480
7481 static int
7482 api_bridge_flags (vat_main_t * vam)
7483 {
7484   unformat_input_t *i = vam->input;
7485   vl_api_bridge_flags_t *mp;
7486   u32 bd_id;
7487   u8 bd_id_set = 0;
7488   u8 is_set = 1;
7489   u32 flags = 0;
7490   int ret;
7491
7492   /* Parse args required to build the message */
7493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7494     {
7495       if (unformat (i, "bd_id %d", &bd_id))
7496         bd_id_set = 1;
7497       else if (unformat (i, "learn"))
7498         flags |= L2_LEARN;
7499       else if (unformat (i, "forward"))
7500         flags |= L2_FWD;
7501       else if (unformat (i, "flood"))
7502         flags |= L2_FLOOD;
7503       else if (unformat (i, "uu-flood"))
7504         flags |= L2_UU_FLOOD;
7505       else if (unformat (i, "arp-term"))
7506         flags |= L2_ARP_TERM;
7507       else if (unformat (i, "off"))
7508         is_set = 0;
7509       else if (unformat (i, "disable"))
7510         is_set = 0;
7511       else
7512         break;
7513     }
7514
7515   if (bd_id_set == 0)
7516     {
7517       errmsg ("missing bridge domain");
7518       return -99;
7519     }
7520
7521   M (BRIDGE_FLAGS, mp);
7522
7523   mp->bd_id = ntohl (bd_id);
7524   mp->feature_bitmap = ntohl (flags);
7525   mp->is_set = is_set;
7526
7527   S (mp);
7528   W (ret);
7529   return ret;
7530 }
7531
7532 static int
7533 api_bd_ip_mac_add_del (vat_main_t * vam)
7534 {
7535   unformat_input_t *i = vam->input;
7536   vl_api_bd_ip_mac_add_del_t *mp;
7537   u32 bd_id;
7538   u8 is_ipv6 = 0;
7539   u8 is_add = 1;
7540   u8 bd_id_set = 0;
7541   u8 ip_set = 0;
7542   u8 mac_set = 0;
7543   ip4_address_t v4addr;
7544   ip6_address_t v6addr;
7545   u8 macaddr[6];
7546   int ret;
7547
7548
7549   /* Parse args required to build the message */
7550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7551     {
7552       if (unformat (i, "bd_id %d", &bd_id))
7553         {
7554           bd_id_set++;
7555         }
7556       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7557         {
7558           ip_set++;
7559         }
7560       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7561         {
7562           ip_set++;
7563           is_ipv6++;
7564         }
7565       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7566         {
7567           mac_set++;
7568         }
7569       else if (unformat (i, "del"))
7570         is_add = 0;
7571       else
7572         break;
7573     }
7574
7575   if (bd_id_set == 0)
7576     {
7577       errmsg ("missing bridge domain");
7578       return -99;
7579     }
7580   else if (ip_set == 0)
7581     {
7582       errmsg ("missing IP address");
7583       return -99;
7584     }
7585   else if (mac_set == 0)
7586     {
7587       errmsg ("missing MAC address");
7588       return -99;
7589     }
7590
7591   M (BD_IP_MAC_ADD_DEL, mp);
7592
7593   mp->bd_id = ntohl (bd_id);
7594   mp->is_ipv6 = is_ipv6;
7595   mp->is_add = is_add;
7596   if (is_ipv6)
7597     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7598   else
7599     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7600   clib_memcpy (mp->mac_address, macaddr, 6);
7601   S (mp);
7602   W (ret);
7603   return ret;
7604 }
7605
7606 static int
7607 api_tap_connect (vat_main_t * vam)
7608 {
7609   unformat_input_t *i = vam->input;
7610   vl_api_tap_connect_t *mp;
7611   u8 mac_address[6];
7612   u8 random_mac = 1;
7613   u8 name_set = 0;
7614   u8 *tap_name;
7615   u8 *tag = 0;
7616   ip4_address_t ip4_address;
7617   u32 ip4_mask_width;
7618   int ip4_address_set = 0;
7619   ip6_address_t ip6_address;
7620   u32 ip6_mask_width;
7621   int ip6_address_set = 0;
7622   int ret;
7623
7624   memset (mac_address, 0, sizeof (mac_address));
7625
7626   /* Parse args required to build the message */
7627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7628     {
7629       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7630         {
7631           random_mac = 0;
7632         }
7633       else if (unformat (i, "random-mac"))
7634         random_mac = 1;
7635       else if (unformat (i, "tapname %s", &tap_name))
7636         name_set = 1;
7637       else if (unformat (i, "tag %s", &tag))
7638         ;
7639       else if (unformat (i, "address %U/%d",
7640                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7641         ip4_address_set = 1;
7642       else if (unformat (i, "address %U/%d",
7643                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7644         ip6_address_set = 1;
7645       else
7646         break;
7647     }
7648
7649   if (name_set == 0)
7650     {
7651       errmsg ("missing tap name");
7652       return -99;
7653     }
7654   if (vec_len (tap_name) > 63)
7655     {
7656       errmsg ("tap name too long");
7657       return -99;
7658     }
7659   vec_add1 (tap_name, 0);
7660
7661   if (vec_len (tag) > 63)
7662     {
7663       errmsg ("tag too long");
7664       return -99;
7665     }
7666
7667   /* Construct the API message */
7668   M (TAP_CONNECT, mp);
7669
7670   mp->use_random_mac = random_mac;
7671   clib_memcpy (mp->mac_address, mac_address, 6);
7672   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7673   if (tag)
7674     clib_memcpy (mp->tag, tag, vec_len (tag));
7675
7676   if (ip4_address_set)
7677     {
7678       mp->ip4_address_set = 1;
7679       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7680       mp->ip4_mask_width = ip4_mask_width;
7681     }
7682   if (ip6_address_set)
7683     {
7684       mp->ip6_address_set = 1;
7685       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7686       mp->ip6_mask_width = ip6_mask_width;
7687     }
7688
7689   vec_free (tap_name);
7690   vec_free (tag);
7691
7692   /* send it... */
7693   S (mp);
7694
7695   /* Wait for a reply... */
7696   W (ret);
7697   return ret;
7698 }
7699
7700 static int
7701 api_tap_modify (vat_main_t * vam)
7702 {
7703   unformat_input_t *i = vam->input;
7704   vl_api_tap_modify_t *mp;
7705   u8 mac_address[6];
7706   u8 random_mac = 1;
7707   u8 name_set = 0;
7708   u8 *tap_name;
7709   u32 sw_if_index = ~0;
7710   u8 sw_if_index_set = 0;
7711   int ret;
7712
7713   memset (mac_address, 0, sizeof (mac_address));
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7719         sw_if_index_set = 1;
7720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7721         sw_if_index_set = 1;
7722       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7723         {
7724           random_mac = 0;
7725         }
7726       else if (unformat (i, "random-mac"))
7727         random_mac = 1;
7728       else if (unformat (i, "tapname %s", &tap_name))
7729         name_set = 1;
7730       else
7731         break;
7732     }
7733
7734   if (sw_if_index_set == 0)
7735     {
7736       errmsg ("missing vpp interface name");
7737       return -99;
7738     }
7739   if (name_set == 0)
7740     {
7741       errmsg ("missing tap name");
7742       return -99;
7743     }
7744   if (vec_len (tap_name) > 63)
7745     {
7746       errmsg ("tap name too long");
7747     }
7748   vec_add1 (tap_name, 0);
7749
7750   /* Construct the API message */
7751   M (TAP_MODIFY, mp);
7752
7753   mp->use_random_mac = random_mac;
7754   mp->sw_if_index = ntohl (sw_if_index);
7755   clib_memcpy (mp->mac_address, mac_address, 6);
7756   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7757   vec_free (tap_name);
7758
7759   /* send it... */
7760   S (mp);
7761
7762   /* Wait for a reply... */
7763   W (ret);
7764   return ret;
7765 }
7766
7767 static int
7768 api_tap_delete (vat_main_t * vam)
7769 {
7770   unformat_input_t *i = vam->input;
7771   vl_api_tap_delete_t *mp;
7772   u32 sw_if_index = ~0;
7773   u8 sw_if_index_set = 0;
7774   int ret;
7775
7776   /* Parse args required to build the message */
7777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778     {
7779       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7780         sw_if_index_set = 1;
7781       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7782         sw_if_index_set = 1;
7783       else
7784         break;
7785     }
7786
7787   if (sw_if_index_set == 0)
7788     {
7789       errmsg ("missing vpp interface name");
7790       return -99;
7791     }
7792
7793   /* Construct the API message */
7794   M (TAP_DELETE, mp);
7795
7796   mp->sw_if_index = ntohl (sw_if_index);
7797
7798   /* send it... */
7799   S (mp);
7800
7801   /* Wait for a reply... */
7802   W (ret);
7803   return ret;
7804 }
7805
7806 static int
7807 api_tap_create_v2 (vat_main_t * vam)
7808 {
7809   unformat_input_t *i = vam->input;
7810   vl_api_tap_create_v2_t *mp;
7811   u8 mac_address[6];
7812   u8 random_mac = 1;
7813   u32 id = ~0;
7814   u8 *host_if_name = 0;
7815   u8 *host_ns = 0;
7816   u8 host_mac_addr[6];
7817   u8 host_mac_addr_set = 0;
7818   u8 *host_bridge = 0;
7819   ip4_address_t host_ip4_addr;
7820   u32 host_ip4_prefix_len = 0;
7821   ip6_address_t host_ip6_addr;
7822   u32 host_ip6_prefix_len = 0;
7823   int ret;
7824   int rx_ring_sz = 0, tx_ring_sz = 0;
7825
7826   memset (mac_address, 0, sizeof (mac_address));
7827
7828   /* Parse args required to build the message */
7829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7832         {
7833           random_mac = 0;
7834         }
7835       else if (unformat (i, "id %s", &id))
7836         ;
7837       else if (unformat (i, "host-if-name %s", &host_if_name))
7838         ;
7839       else if (unformat (i, "host-ns %s", &host_ns))
7840         ;
7841       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7842                          host_mac_addr))
7843         host_mac_addr_set = 1;
7844       else if (unformat (i, "host-bridge %s", &host_bridge))
7845         ;
7846       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7847                          &host_ip4_addr, &host_ip4_prefix_len))
7848         ;
7849       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7850                          &host_ip6_addr, &host_ip6_prefix_len))
7851         ;
7852       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7853         ;
7854       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7855         ;
7856       else
7857         break;
7858     }
7859
7860   if (vec_len (host_if_name) > 63)
7861     {
7862       errmsg ("tap name too long. ");
7863       return -99;
7864     }
7865   if (vec_len (host_ns) > 63)
7866     {
7867       errmsg ("host name space too long. ");
7868       return -99;
7869     }
7870   if (vec_len (host_bridge) > 63)
7871     {
7872       errmsg ("host bridge name too long. ");
7873       return -99;
7874     }
7875   if (host_ip4_prefix_len > 32)
7876     {
7877       errmsg ("host ip4 prefix length not valid. ");
7878       return -99;
7879     }
7880   if (host_ip6_prefix_len > 128)
7881     {
7882       errmsg ("host ip6 prefix length not valid. ");
7883       return -99;
7884     }
7885   if (!is_pow2 (rx_ring_sz))
7886     {
7887       errmsg ("rx ring size must be power of 2. ");
7888       return -99;
7889     }
7890   if (rx_ring_sz > 32768)
7891     {
7892       errmsg ("rx ring size must be 32768 or lower. ");
7893       return -99;
7894     }
7895   if (!is_pow2 (tx_ring_sz))
7896     {
7897       errmsg ("tx ring size must be power of 2. ");
7898       return -99;
7899     }
7900   if (tx_ring_sz > 32768)
7901     {
7902       errmsg ("tx ring size must be 32768 or lower. ");
7903       return -99;
7904     }
7905
7906   /* Construct the API message */
7907   M (TAP_CREATE_V2, mp);
7908
7909   mp->use_random_mac = random_mac;
7910
7911   mp->id = id;
7912   mp->host_namespace_set = host_ns != 0;
7913   mp->host_bridge_set = host_bridge != 0;
7914   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7915   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7916   mp->rx_ring_sz = rx_ring_sz;
7917   mp->tx_ring_sz = tx_ring_sz;
7918
7919   if (random_mac)
7920     clib_memcpy (mp->mac_address, mac_address, 6);
7921   if (host_mac_addr_set)
7922     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7923   if (host_if_name)
7924     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7925   if (host_ns)
7926     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7927   if (host_bridge)
7928     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7929   if (host_ip4_prefix_len)
7930     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7931   if (host_ip4_prefix_len)
7932     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7933
7934
7935   vec_free (host_ns);
7936   vec_free (host_if_name);
7937   vec_free (host_bridge);
7938
7939   /* send it... */
7940   S (mp);
7941
7942   /* Wait for a reply... */
7943   W (ret);
7944   return ret;
7945 }
7946
7947 static int
7948 api_tap_delete_v2 (vat_main_t * vam)
7949 {
7950   unformat_input_t *i = vam->input;
7951   vl_api_tap_delete_v2_t *mp;
7952   u32 sw_if_index = ~0;
7953   u8 sw_if_index_set = 0;
7954   int ret;
7955
7956   /* Parse args required to build the message */
7957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7958     {
7959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7960         sw_if_index_set = 1;
7961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7962         sw_if_index_set = 1;
7963       else
7964         break;
7965     }
7966
7967   if (sw_if_index_set == 0)
7968     {
7969       errmsg ("missing vpp interface name. ");
7970       return -99;
7971     }
7972
7973   /* Construct the API message */
7974   M (TAP_DELETE_V2, mp);
7975
7976   mp->sw_if_index = ntohl (sw_if_index);
7977
7978   /* send it... */
7979   S (mp);
7980
7981   /* Wait for a reply... */
7982   W (ret);
7983   return ret;
7984 }
7985
7986 static int
7987 api_ip_table_add_del (vat_main_t * vam)
7988 {
7989   unformat_input_t *i = vam->input;
7990   vl_api_ip_table_add_del_t *mp;
7991   u32 table_id = ~0;
7992   u8 is_ipv6 = 0;
7993   u8 is_add = 1;
7994   int ret = 0;
7995
7996   /* Parse args required to build the message */
7997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7998     {
7999       if (unformat (i, "ipv6"))
8000         is_ipv6 = 1;
8001       else if (unformat (i, "del"))
8002         is_add = 0;
8003       else if (unformat (i, "add"))
8004         is_add = 1;
8005       else if (unformat (i, "table %d", &table_id))
8006         ;
8007       else
8008         {
8009           clib_warning ("parse error '%U'", format_unformat_error, i);
8010           return -99;
8011         }
8012     }
8013
8014   if (~0 == table_id)
8015     {
8016       errmsg ("missing table-ID");
8017       return -99;
8018     }
8019
8020   /* Construct the API message */
8021   M (IP_TABLE_ADD_DEL, mp);
8022
8023   mp->table_id = ntohl (table_id);
8024   mp->is_ipv6 = is_ipv6;
8025   mp->is_add = is_add;
8026
8027   /* send it... */
8028   S (mp);
8029
8030   /* Wait for a reply... */
8031   W (ret);
8032
8033   return ret;
8034 }
8035
8036 static int
8037 api_ip_add_del_route (vat_main_t * vam)
8038 {
8039   unformat_input_t *i = vam->input;
8040   vl_api_ip_add_del_route_t *mp;
8041   u32 sw_if_index = ~0, vrf_id = 0;
8042   u8 is_ipv6 = 0;
8043   u8 is_local = 0, is_drop = 0;
8044   u8 is_unreach = 0, is_prohibit = 0;
8045   u8 create_vrf_if_needed = 0;
8046   u8 is_add = 1;
8047   u32 next_hop_weight = 1;
8048   u8 is_multipath = 0;
8049   u8 address_set = 0;
8050   u8 address_length_set = 0;
8051   u32 next_hop_table_id = 0;
8052   u32 resolve_attempts = 0;
8053   u32 dst_address_length = 0;
8054   u8 next_hop_set = 0;
8055   ip4_address_t v4_dst_address, v4_next_hop_address;
8056   ip6_address_t v6_dst_address, v6_next_hop_address;
8057   int count = 1;
8058   int j;
8059   f64 before = 0;
8060   u32 random_add_del = 0;
8061   u32 *random_vector = 0;
8062   uword *random_hash;
8063   u32 random_seed = 0xdeaddabe;
8064   u32 classify_table_index = ~0;
8065   u8 is_classify = 0;
8066   u8 resolve_host = 0, resolve_attached = 0;
8067   mpls_label_t *next_hop_out_label_stack = NULL;
8068   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8069   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8070
8071   /* Parse args required to build the message */
8072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8073     {
8074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8075         ;
8076       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8077         ;
8078       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8079         {
8080           address_set = 1;
8081           is_ipv6 = 0;
8082         }
8083       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8084         {
8085           address_set = 1;
8086           is_ipv6 = 1;
8087         }
8088       else if (unformat (i, "/%d", &dst_address_length))
8089         {
8090           address_length_set = 1;
8091         }
8092
8093       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8094                                          &v4_next_hop_address))
8095         {
8096           next_hop_set = 1;
8097         }
8098       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8099                                          &v6_next_hop_address))
8100         {
8101           next_hop_set = 1;
8102         }
8103       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8104         ;
8105       else if (unformat (i, "weight %d", &next_hop_weight))
8106         ;
8107       else if (unformat (i, "drop"))
8108         {
8109           is_drop = 1;
8110         }
8111       else if (unformat (i, "null-send-unreach"))
8112         {
8113           is_unreach = 1;
8114         }
8115       else if (unformat (i, "null-send-prohibit"))
8116         {
8117           is_prohibit = 1;
8118         }
8119       else if (unformat (i, "local"))
8120         {
8121           is_local = 1;
8122         }
8123       else if (unformat (i, "classify %d", &classify_table_index))
8124         {
8125           is_classify = 1;
8126         }
8127       else if (unformat (i, "del"))
8128         is_add = 0;
8129       else if (unformat (i, "add"))
8130         is_add = 1;
8131       else if (unformat (i, "resolve-via-host"))
8132         resolve_host = 1;
8133       else if (unformat (i, "resolve-via-attached"))
8134         resolve_attached = 1;
8135       else if (unformat (i, "multipath"))
8136         is_multipath = 1;
8137       else if (unformat (i, "vrf %d", &vrf_id))
8138         ;
8139       else if (unformat (i, "create-vrf"))
8140         create_vrf_if_needed = 1;
8141       else if (unformat (i, "count %d", &count))
8142         ;
8143       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8144         ;
8145       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8146         ;
8147       else if (unformat (i, "out-label %d", &next_hop_out_label))
8148         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8149       else if (unformat (i, "via-label %d", &next_hop_via_label))
8150         ;
8151       else if (unformat (i, "random"))
8152         random_add_del = 1;
8153       else if (unformat (i, "seed %d", &random_seed))
8154         ;
8155       else
8156         {
8157           clib_warning ("parse error '%U'", format_unformat_error, i);
8158           return -99;
8159         }
8160     }
8161
8162   if (!next_hop_set && !is_drop && !is_local &&
8163       !is_classify && !is_unreach && !is_prohibit &&
8164       MPLS_LABEL_INVALID == next_hop_via_label)
8165     {
8166       errmsg
8167         ("next hop / local / drop / unreach / prohibit / classify not set");
8168       return -99;
8169     }
8170
8171   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8172     {
8173       errmsg ("next hop and next-hop via label set");
8174       return -99;
8175     }
8176   if (address_set == 0)
8177     {
8178       errmsg ("missing addresses");
8179       return -99;
8180     }
8181
8182   if (address_length_set == 0)
8183     {
8184       errmsg ("missing address length");
8185       return -99;
8186     }
8187
8188   /* Generate a pile of unique, random routes */
8189   if (random_add_del)
8190     {
8191       u32 this_random_address;
8192       random_hash = hash_create (count, sizeof (uword));
8193
8194       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8195       for (j = 0; j <= count; j++)
8196         {
8197           do
8198             {
8199               this_random_address = random_u32 (&random_seed);
8200               this_random_address =
8201                 clib_host_to_net_u32 (this_random_address);
8202             }
8203           while (hash_get (random_hash, this_random_address));
8204           vec_add1 (random_vector, this_random_address);
8205           hash_set (random_hash, this_random_address, 1);
8206         }
8207       hash_free (random_hash);
8208       v4_dst_address.as_u32 = random_vector[0];
8209     }
8210
8211   if (count > 1)
8212     {
8213       /* Turn on async mode */
8214       vam->async_mode = 1;
8215       vam->async_errors = 0;
8216       before = vat_time_now (vam);
8217     }
8218
8219   for (j = 0; j < count; j++)
8220     {
8221       /* Construct the API message */
8222       M2 (IP_ADD_DEL_ROUTE, mp,
8223           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8224
8225       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8226       mp->table_id = ntohl (vrf_id);
8227       mp->create_vrf_if_needed = create_vrf_if_needed;
8228
8229       mp->is_add = is_add;
8230       mp->is_drop = is_drop;
8231       mp->is_unreach = is_unreach;
8232       mp->is_prohibit = is_prohibit;
8233       mp->is_ipv6 = is_ipv6;
8234       mp->is_local = is_local;
8235       mp->is_classify = is_classify;
8236       mp->is_multipath = is_multipath;
8237       mp->is_resolve_host = resolve_host;
8238       mp->is_resolve_attached = resolve_attached;
8239       mp->next_hop_weight = next_hop_weight;
8240       mp->dst_address_length = dst_address_length;
8241       mp->next_hop_table_id = ntohl (next_hop_table_id);
8242       mp->classify_table_index = ntohl (classify_table_index);
8243       mp->next_hop_via_label = ntohl (next_hop_via_label);
8244       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8245       if (0 != mp->next_hop_n_out_labels)
8246         {
8247           memcpy (mp->next_hop_out_label_stack,
8248                   next_hop_out_label_stack,
8249                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8250           vec_free (next_hop_out_label_stack);
8251         }
8252
8253       if (is_ipv6)
8254         {
8255           clib_memcpy (mp->dst_address, &v6_dst_address,
8256                        sizeof (v6_dst_address));
8257           if (next_hop_set)
8258             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8259                          sizeof (v6_next_hop_address));
8260           increment_v6_address (&v6_dst_address);
8261         }
8262       else
8263         {
8264           clib_memcpy (mp->dst_address, &v4_dst_address,
8265                        sizeof (v4_dst_address));
8266           if (next_hop_set)
8267             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8268                          sizeof (v4_next_hop_address));
8269           if (random_add_del)
8270             v4_dst_address.as_u32 = random_vector[j + 1];
8271           else
8272             increment_v4_address (&v4_dst_address);
8273         }
8274       /* send it... */
8275       S (mp);
8276       /* If we receive SIGTERM, stop now... */
8277       if (vam->do_exit)
8278         break;
8279     }
8280
8281   /* When testing multiple add/del ops, use a control-ping to sync */
8282   if (count > 1)
8283     {
8284       vl_api_control_ping_t *mp_ping;
8285       f64 after;
8286       f64 timeout;
8287
8288       /* Shut off async mode */
8289       vam->async_mode = 0;
8290
8291       MPING (CONTROL_PING, mp_ping);
8292       S (mp_ping);
8293
8294       timeout = vat_time_now (vam) + 1.0;
8295       while (vat_time_now (vam) < timeout)
8296         if (vam->result_ready == 1)
8297           goto out;
8298       vam->retval = -99;
8299
8300     out:
8301       if (vam->retval == -99)
8302         errmsg ("timeout");
8303
8304       if (vam->async_errors > 0)
8305         {
8306           errmsg ("%d asynchronous errors", vam->async_errors);
8307           vam->retval = -98;
8308         }
8309       vam->async_errors = 0;
8310       after = vat_time_now (vam);
8311
8312       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8313       if (j > 0)
8314         count = j;
8315
8316       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8317              count, after - before, count / (after - before));
8318     }
8319   else
8320     {
8321       int ret;
8322
8323       /* Wait for a reply... */
8324       W (ret);
8325       return ret;
8326     }
8327
8328   /* Return the good/bad news */
8329   return (vam->retval);
8330 }
8331
8332 static int
8333 api_ip_mroute_add_del (vat_main_t * vam)
8334 {
8335   unformat_input_t *i = vam->input;
8336   vl_api_ip_mroute_add_del_t *mp;
8337   u32 sw_if_index = ~0, vrf_id = 0;
8338   u8 is_ipv6 = 0;
8339   u8 is_local = 0;
8340   u8 create_vrf_if_needed = 0;
8341   u8 is_add = 1;
8342   u8 address_set = 0;
8343   u32 grp_address_length = 0;
8344   ip4_address_t v4_grp_address, v4_src_address;
8345   ip6_address_t v6_grp_address, v6_src_address;
8346   mfib_itf_flags_t iflags = 0;
8347   mfib_entry_flags_t eflags = 0;
8348   int ret;
8349
8350   /* Parse args required to build the message */
8351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8352     {
8353       if (unformat (i, "sw_if_index %d", &sw_if_index))
8354         ;
8355       else if (unformat (i, "%U %U",
8356                          unformat_ip4_address, &v4_src_address,
8357                          unformat_ip4_address, &v4_grp_address))
8358         {
8359           grp_address_length = 64;
8360           address_set = 1;
8361           is_ipv6 = 0;
8362         }
8363       else if (unformat (i, "%U %U",
8364                          unformat_ip6_address, &v6_src_address,
8365                          unformat_ip6_address, &v6_grp_address))
8366         {
8367           grp_address_length = 256;
8368           address_set = 1;
8369           is_ipv6 = 1;
8370         }
8371       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8372         {
8373           memset (&v4_src_address, 0, sizeof (v4_src_address));
8374           grp_address_length = 32;
8375           address_set = 1;
8376           is_ipv6 = 0;
8377         }
8378       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8379         {
8380           memset (&v6_src_address, 0, sizeof (v6_src_address));
8381           grp_address_length = 128;
8382           address_set = 1;
8383           is_ipv6 = 1;
8384         }
8385       else if (unformat (i, "/%d", &grp_address_length))
8386         ;
8387       else if (unformat (i, "local"))
8388         {
8389           is_local = 1;
8390         }
8391       else if (unformat (i, "del"))
8392         is_add = 0;
8393       else if (unformat (i, "add"))
8394         is_add = 1;
8395       else if (unformat (i, "vrf %d", &vrf_id))
8396         ;
8397       else if (unformat (i, "create-vrf"))
8398         create_vrf_if_needed = 1;
8399       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8400         ;
8401       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8402         ;
8403       else
8404         {
8405           clib_warning ("parse error '%U'", format_unformat_error, i);
8406           return -99;
8407         }
8408     }
8409
8410   if (address_set == 0)
8411     {
8412       errmsg ("missing addresses\n");
8413       return -99;
8414     }
8415
8416   /* Construct the API message */
8417   M (IP_MROUTE_ADD_DEL, mp);
8418
8419   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8420   mp->table_id = ntohl (vrf_id);
8421   mp->create_vrf_if_needed = create_vrf_if_needed;
8422
8423   mp->is_add = is_add;
8424   mp->is_ipv6 = is_ipv6;
8425   mp->is_local = is_local;
8426   mp->itf_flags = ntohl (iflags);
8427   mp->entry_flags = ntohl (eflags);
8428   mp->grp_address_length = grp_address_length;
8429   mp->grp_address_length = ntohs (mp->grp_address_length);
8430
8431   if (is_ipv6)
8432     {
8433       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8434       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8435     }
8436   else
8437     {
8438       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8439       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8440
8441     }
8442
8443   /* send it... */
8444   S (mp);
8445   /* Wait for a reply... */
8446   W (ret);
8447   return ret;
8448 }
8449
8450 static int
8451 api_mpls_table_add_del (vat_main_t * vam)
8452 {
8453   unformat_input_t *i = vam->input;
8454   vl_api_mpls_table_add_del_t *mp;
8455   u32 table_id = ~0;
8456   u8 is_add = 1;
8457   int ret = 0;
8458
8459   /* Parse args required to build the message */
8460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8461     {
8462       if (unformat (i, "table %d", &table_id))
8463         ;
8464       else if (unformat (i, "del"))
8465         is_add = 0;
8466       else if (unformat (i, "add"))
8467         is_add = 1;
8468       else
8469         {
8470           clib_warning ("parse error '%U'", format_unformat_error, i);
8471           return -99;
8472         }
8473     }
8474
8475   if (~0 == table_id)
8476     {
8477       errmsg ("missing table-ID");
8478       return -99;
8479     }
8480
8481   /* Construct the API message */
8482   M (MPLS_TABLE_ADD_DEL, mp);
8483
8484   mp->mt_table_id = ntohl (table_id);
8485   mp->mt_is_add = is_add;
8486
8487   /* send it... */
8488   S (mp);
8489
8490   /* Wait for a reply... */
8491   W (ret);
8492
8493   return ret;
8494 }
8495
8496 static int
8497 api_mpls_route_add_del (vat_main_t * vam)
8498 {
8499   unformat_input_t *i = vam->input;
8500   vl_api_mpls_route_add_del_t *mp;
8501   u32 sw_if_index = ~0, table_id = 0;
8502   u8 create_table_if_needed = 0;
8503   u8 is_add = 1;
8504   u32 next_hop_weight = 1;
8505   u8 is_multipath = 0;
8506   u32 next_hop_table_id = 0;
8507   u8 next_hop_set = 0;
8508   ip4_address_t v4_next_hop_address = {
8509     .as_u32 = 0,
8510   };
8511   ip6_address_t v6_next_hop_address = { {0} };
8512   int count = 1;
8513   int j;
8514   f64 before = 0;
8515   u32 classify_table_index = ~0;
8516   u8 is_classify = 0;
8517   u8 resolve_host = 0, resolve_attached = 0;
8518   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8519   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8520   mpls_label_t *next_hop_out_label_stack = NULL;
8521   mpls_label_t local_label = MPLS_LABEL_INVALID;
8522   u8 is_eos = 0;
8523   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8524
8525   /* Parse args required to build the message */
8526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8527     {
8528       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8529         ;
8530       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8531         ;
8532       else if (unformat (i, "%d", &local_label))
8533         ;
8534       else if (unformat (i, "eos"))
8535         is_eos = 1;
8536       else if (unformat (i, "non-eos"))
8537         is_eos = 0;
8538       else if (unformat (i, "via %U", unformat_ip4_address,
8539                          &v4_next_hop_address))
8540         {
8541           next_hop_set = 1;
8542           next_hop_proto = DPO_PROTO_IP4;
8543         }
8544       else if (unformat (i, "via %U", unformat_ip6_address,
8545                          &v6_next_hop_address))
8546         {
8547           next_hop_set = 1;
8548           next_hop_proto = DPO_PROTO_IP6;
8549         }
8550       else if (unformat (i, "weight %d", &next_hop_weight))
8551         ;
8552       else if (unformat (i, "create-table"))
8553         create_table_if_needed = 1;
8554       else if (unformat (i, "classify %d", &classify_table_index))
8555         {
8556           is_classify = 1;
8557         }
8558       else if (unformat (i, "del"))
8559         is_add = 0;
8560       else if (unformat (i, "add"))
8561         is_add = 1;
8562       else if (unformat (i, "resolve-via-host"))
8563         resolve_host = 1;
8564       else if (unformat (i, "resolve-via-attached"))
8565         resolve_attached = 1;
8566       else if (unformat (i, "multipath"))
8567         is_multipath = 1;
8568       else if (unformat (i, "count %d", &count))
8569         ;
8570       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8571         {
8572           next_hop_set = 1;
8573           next_hop_proto = DPO_PROTO_IP4;
8574         }
8575       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8576         {
8577           next_hop_set = 1;
8578           next_hop_proto = DPO_PROTO_IP6;
8579         }
8580       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8581         ;
8582       else if (unformat (i, "via-label %d", &next_hop_via_label))
8583         ;
8584       else if (unformat (i, "out-label %d", &next_hop_out_label))
8585         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8586       else
8587         {
8588           clib_warning ("parse error '%U'", format_unformat_error, i);
8589           return -99;
8590         }
8591     }
8592
8593   if (!next_hop_set && !is_classify)
8594     {
8595       errmsg ("next hop / classify not set");
8596       return -99;
8597     }
8598
8599   if (MPLS_LABEL_INVALID == local_label)
8600     {
8601       errmsg ("missing label");
8602       return -99;
8603     }
8604
8605   if (count > 1)
8606     {
8607       /* Turn on async mode */
8608       vam->async_mode = 1;
8609       vam->async_errors = 0;
8610       before = vat_time_now (vam);
8611     }
8612
8613   for (j = 0; j < count; j++)
8614     {
8615       /* Construct the API message */
8616       M2 (MPLS_ROUTE_ADD_DEL, mp,
8617           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8618
8619       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8620       mp->mr_table_id = ntohl (table_id);
8621       mp->mr_create_table_if_needed = create_table_if_needed;
8622
8623       mp->mr_is_add = is_add;
8624       mp->mr_next_hop_proto = next_hop_proto;
8625       mp->mr_is_classify = is_classify;
8626       mp->mr_is_multipath = is_multipath;
8627       mp->mr_is_resolve_host = resolve_host;
8628       mp->mr_is_resolve_attached = resolve_attached;
8629       mp->mr_next_hop_weight = next_hop_weight;
8630       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8631       mp->mr_classify_table_index = ntohl (classify_table_index);
8632       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8633       mp->mr_label = ntohl (local_label);
8634       mp->mr_eos = is_eos;
8635
8636       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8637       if (0 != mp->mr_next_hop_n_out_labels)
8638         {
8639           memcpy (mp->mr_next_hop_out_label_stack,
8640                   next_hop_out_label_stack,
8641                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8642           vec_free (next_hop_out_label_stack);
8643         }
8644
8645       if (next_hop_set)
8646         {
8647           if (DPO_PROTO_IP4 == next_hop_proto)
8648             {
8649               clib_memcpy (mp->mr_next_hop,
8650                            &v4_next_hop_address,
8651                            sizeof (v4_next_hop_address));
8652             }
8653           else if (DPO_PROTO_IP6 == next_hop_proto)
8654
8655             {
8656               clib_memcpy (mp->mr_next_hop,
8657                            &v6_next_hop_address,
8658                            sizeof (v6_next_hop_address));
8659             }
8660         }
8661       local_label++;
8662
8663       /* send it... */
8664       S (mp);
8665       /* If we receive SIGTERM, stop now... */
8666       if (vam->do_exit)
8667         break;
8668     }
8669
8670   /* When testing multiple add/del ops, use a control-ping to sync */
8671   if (count > 1)
8672     {
8673       vl_api_control_ping_t *mp_ping;
8674       f64 after;
8675       f64 timeout;
8676
8677       /* Shut off async mode */
8678       vam->async_mode = 0;
8679
8680       MPING (CONTROL_PING, mp_ping);
8681       S (mp_ping);
8682
8683       timeout = vat_time_now (vam) + 1.0;
8684       while (vat_time_now (vam) < timeout)
8685         if (vam->result_ready == 1)
8686           goto out;
8687       vam->retval = -99;
8688
8689     out:
8690       if (vam->retval == -99)
8691         errmsg ("timeout");
8692
8693       if (vam->async_errors > 0)
8694         {
8695           errmsg ("%d asynchronous errors", vam->async_errors);
8696           vam->retval = -98;
8697         }
8698       vam->async_errors = 0;
8699       after = vat_time_now (vam);
8700
8701       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8702       if (j > 0)
8703         count = j;
8704
8705       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8706              count, after - before, count / (after - before));
8707     }
8708   else
8709     {
8710       int ret;
8711
8712       /* Wait for a reply... */
8713       W (ret);
8714       return ret;
8715     }
8716
8717   /* Return the good/bad news */
8718   return (vam->retval);
8719 }
8720
8721 static int
8722 api_mpls_ip_bind_unbind (vat_main_t * vam)
8723 {
8724   unformat_input_t *i = vam->input;
8725   vl_api_mpls_ip_bind_unbind_t *mp;
8726   u32 ip_table_id = 0;
8727   u8 create_table_if_needed = 0;
8728   u8 is_bind = 1;
8729   u8 is_ip4 = 1;
8730   ip4_address_t v4_address;
8731   ip6_address_t v6_address;
8732   u32 address_length;
8733   u8 address_set = 0;
8734   mpls_label_t local_label = MPLS_LABEL_INVALID;
8735   int ret;
8736
8737   /* Parse args required to build the message */
8738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8739     {
8740       if (unformat (i, "%U/%d", unformat_ip4_address,
8741                     &v4_address, &address_length))
8742         {
8743           is_ip4 = 1;
8744           address_set = 1;
8745         }
8746       else if (unformat (i, "%U/%d", unformat_ip6_address,
8747                          &v6_address, &address_length))
8748         {
8749           is_ip4 = 0;
8750           address_set = 1;
8751         }
8752       else if (unformat (i, "%d", &local_label))
8753         ;
8754       else if (unformat (i, "create-table"))
8755         create_table_if_needed = 1;
8756       else if (unformat (i, "table-id %d", &ip_table_id))
8757         ;
8758       else if (unformat (i, "unbind"))
8759         is_bind = 0;
8760       else if (unformat (i, "bind"))
8761         is_bind = 1;
8762       else
8763         {
8764           clib_warning ("parse error '%U'", format_unformat_error, i);
8765           return -99;
8766         }
8767     }
8768
8769   if (!address_set)
8770     {
8771       errmsg ("IP addres not set");
8772       return -99;
8773     }
8774
8775   if (MPLS_LABEL_INVALID == local_label)
8776     {
8777       errmsg ("missing label");
8778       return -99;
8779     }
8780
8781   /* Construct the API message */
8782   M (MPLS_IP_BIND_UNBIND, mp);
8783
8784   mp->mb_create_table_if_needed = create_table_if_needed;
8785   mp->mb_is_bind = is_bind;
8786   mp->mb_is_ip4 = is_ip4;
8787   mp->mb_ip_table_id = ntohl (ip_table_id);
8788   mp->mb_mpls_table_id = 0;
8789   mp->mb_label = ntohl (local_label);
8790   mp->mb_address_length = address_length;
8791
8792   if (is_ip4)
8793     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8794   else
8795     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8796
8797   /* send it... */
8798   S (mp);
8799
8800   /* Wait for a reply... */
8801   W (ret);
8802   return ret;
8803 }
8804
8805 static int
8806 api_bier_table_add_del (vat_main_t * vam)
8807 {
8808   unformat_input_t *i = vam->input;
8809   vl_api_bier_table_add_del_t *mp;
8810   u8 is_add = 1;
8811   u32 set = 0, sub_domain = 0, hdr_len = 3;
8812   mpls_label_t local_label = MPLS_LABEL_INVALID;
8813   int ret;
8814
8815   /* Parse args required to build the message */
8816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8817     {
8818       if (unformat (i, "sub-domain %d", &sub_domain))
8819         ;
8820       else if (unformat (i, "set %d", &set))
8821         ;
8822       else if (unformat (i, "label %d", &local_label))
8823         ;
8824       else if (unformat (i, "hdr-len %d", &hdr_len))
8825         ;
8826       else if (unformat (i, "add"))
8827         is_add = 1;
8828       else if (unformat (i, "del"))
8829         is_add = 0;
8830       else
8831         {
8832           clib_warning ("parse error '%U'", format_unformat_error, i);
8833           return -99;
8834         }
8835     }
8836
8837   if (MPLS_LABEL_INVALID == local_label)
8838     {
8839       errmsg ("missing label\n");
8840       return -99;
8841     }
8842
8843   /* Construct the API message */
8844   M (BIER_TABLE_ADD_DEL, mp);
8845
8846   mp->bt_is_add = is_add;
8847   mp->bt_label = ntohl (local_label);
8848   mp->bt_tbl_id.bt_set = set;
8849   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8850   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8851
8852   /* send it... */
8853   S (mp);
8854
8855   /* Wait for a reply... */
8856   W (ret);
8857
8858   return (ret);
8859 }
8860
8861 static int
8862 api_bier_route_add_del (vat_main_t * vam)
8863 {
8864   unformat_input_t *i = vam->input;
8865   vl_api_bier_route_add_del_t *mp;
8866   u8 is_add = 1;
8867   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8868   ip4_address_t v4_next_hop_address;
8869   ip6_address_t v6_next_hop_address;
8870   u8 next_hop_set = 0;
8871   u8 next_hop_proto_is_ip4 = 1;
8872   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8873   int ret;
8874
8875   /* Parse args required to build the message */
8876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8877     {
8878       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8879         {
8880           next_hop_proto_is_ip4 = 1;
8881           next_hop_set = 1;
8882         }
8883       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8884         {
8885           next_hop_proto_is_ip4 = 0;
8886           next_hop_set = 1;
8887         }
8888       if (unformat (i, "sub-domain %d", &sub_domain))
8889         ;
8890       else if (unformat (i, "set %d", &set))
8891         ;
8892       else if (unformat (i, "hdr-len %d", &hdr_len))
8893         ;
8894       else if (unformat (i, "bp %d", &bp))
8895         ;
8896       else if (unformat (i, "add"))
8897         is_add = 1;
8898       else if (unformat (i, "del"))
8899         is_add = 0;
8900       else if (unformat (i, "out-label %d", &next_hop_out_label))
8901         ;
8902       else
8903         {
8904           clib_warning ("parse error '%U'", format_unformat_error, i);
8905           return -99;
8906         }
8907     }
8908
8909   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8910     {
8911       errmsg ("next hop / label set\n");
8912       return -99;
8913     }
8914   if (0 == bp)
8915     {
8916       errmsg ("bit=position not set\n");
8917       return -99;
8918     }
8919
8920   /* Construct the API message */
8921   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8922
8923   mp->br_is_add = is_add;
8924   mp->br_tbl_id.bt_set = set;
8925   mp->br_tbl_id.bt_sub_domain = sub_domain;
8926   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8927   mp->br_bp = ntohs (bp);
8928   mp->br_n_paths = 1;
8929   mp->br_paths[0].n_labels = 1;
8930   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8931   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8932
8933   if (next_hop_proto_is_ip4)
8934     {
8935       clib_memcpy (mp->br_paths[0].next_hop,
8936                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8937     }
8938   else
8939     {
8940       clib_memcpy (mp->br_paths[0].next_hop,
8941                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8942     }
8943
8944   /* send it... */
8945   S (mp);
8946
8947   /* Wait for a reply... */
8948   W (ret);
8949
8950   return (ret);
8951 }
8952
8953 static int
8954 api_proxy_arp_add_del (vat_main_t * vam)
8955 {
8956   unformat_input_t *i = vam->input;
8957   vl_api_proxy_arp_add_del_t *mp;
8958   u32 vrf_id = 0;
8959   u8 is_add = 1;
8960   ip4_address_t lo, hi;
8961   u8 range_set = 0;
8962   int ret;
8963
8964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8965     {
8966       if (unformat (i, "vrf %d", &vrf_id))
8967         ;
8968       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8969                          unformat_ip4_address, &hi))
8970         range_set = 1;
8971       else if (unformat (i, "del"))
8972         is_add = 0;
8973       else
8974         {
8975           clib_warning ("parse error '%U'", format_unformat_error, i);
8976           return -99;
8977         }
8978     }
8979
8980   if (range_set == 0)
8981     {
8982       errmsg ("address range not set");
8983       return -99;
8984     }
8985
8986   M (PROXY_ARP_ADD_DEL, mp);
8987
8988   mp->vrf_id = ntohl (vrf_id);
8989   mp->is_add = is_add;
8990   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8991   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8992
8993   S (mp);
8994   W (ret);
8995   return ret;
8996 }
8997
8998 static int
8999 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9000 {
9001   unformat_input_t *i = vam->input;
9002   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9003   u32 sw_if_index;
9004   u8 enable = 1;
9005   u8 sw_if_index_set = 0;
9006   int ret;
9007
9008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9009     {
9010       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9011         sw_if_index_set = 1;
9012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9013         sw_if_index_set = 1;
9014       else if (unformat (i, "enable"))
9015         enable = 1;
9016       else if (unformat (i, "disable"))
9017         enable = 0;
9018       else
9019         {
9020           clib_warning ("parse error '%U'", format_unformat_error, i);
9021           return -99;
9022         }
9023     }
9024
9025   if (sw_if_index_set == 0)
9026     {
9027       errmsg ("missing interface name or sw_if_index");
9028       return -99;
9029     }
9030
9031   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9032
9033   mp->sw_if_index = ntohl (sw_if_index);
9034   mp->enable_disable = enable;
9035
9036   S (mp);
9037   W (ret);
9038   return ret;
9039 }
9040
9041 static int
9042 api_mpls_tunnel_add_del (vat_main_t * vam)
9043 {
9044   unformat_input_t *i = vam->input;
9045   vl_api_mpls_tunnel_add_del_t *mp;
9046
9047   u8 is_add = 1;
9048   u8 l2_only = 0;
9049   u32 sw_if_index = ~0;
9050   u32 next_hop_sw_if_index = ~0;
9051   u32 next_hop_proto_is_ip4 = 1;
9052
9053   u32 next_hop_table_id = 0;
9054   ip4_address_t v4_next_hop_address = {
9055     .as_u32 = 0,
9056   };
9057   ip6_address_t v6_next_hop_address = { {0} };
9058   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9059   int ret;
9060
9061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9062     {
9063       if (unformat (i, "add"))
9064         is_add = 1;
9065       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9066         is_add = 0;
9067       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9068         ;
9069       else if (unformat (i, "via %U",
9070                          unformat_ip4_address, &v4_next_hop_address))
9071         {
9072           next_hop_proto_is_ip4 = 1;
9073         }
9074       else if (unformat (i, "via %U",
9075                          unformat_ip6_address, &v6_next_hop_address))
9076         {
9077           next_hop_proto_is_ip4 = 0;
9078         }
9079       else if (unformat (i, "l2-only"))
9080         l2_only = 1;
9081       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9082         ;
9083       else if (unformat (i, "out-label %d", &next_hop_out_label))
9084         vec_add1 (labels, ntohl (next_hop_out_label));
9085       else
9086         {
9087           clib_warning ("parse error '%U'", format_unformat_error, i);
9088           return -99;
9089         }
9090     }
9091
9092   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9093
9094   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9095   mp->mt_sw_if_index = ntohl (sw_if_index);
9096   mp->mt_is_add = is_add;
9097   mp->mt_l2_only = l2_only;
9098   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9099   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9100
9101   mp->mt_next_hop_n_out_labels = vec_len (labels);
9102
9103   if (0 != mp->mt_next_hop_n_out_labels)
9104     {
9105       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9106                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9107       vec_free (labels);
9108     }
9109
9110   if (next_hop_proto_is_ip4)
9111     {
9112       clib_memcpy (mp->mt_next_hop,
9113                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9114     }
9115   else
9116     {
9117       clib_memcpy (mp->mt_next_hop,
9118                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9119     }
9120
9121   S (mp);
9122   W (ret);
9123   return ret;
9124 }
9125
9126 static int
9127 api_sw_interface_set_unnumbered (vat_main_t * vam)
9128 {
9129   unformat_input_t *i = vam->input;
9130   vl_api_sw_interface_set_unnumbered_t *mp;
9131   u32 sw_if_index;
9132   u32 unnum_sw_index = ~0;
9133   u8 is_add = 1;
9134   u8 sw_if_index_set = 0;
9135   int ret;
9136
9137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9138     {
9139       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9140         sw_if_index_set = 1;
9141       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9142         sw_if_index_set = 1;
9143       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9144         ;
9145       else if (unformat (i, "del"))
9146         is_add = 0;
9147       else
9148         {
9149           clib_warning ("parse error '%U'", format_unformat_error, i);
9150           return -99;
9151         }
9152     }
9153
9154   if (sw_if_index_set == 0)
9155     {
9156       errmsg ("missing interface name or sw_if_index");
9157       return -99;
9158     }
9159
9160   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9161
9162   mp->sw_if_index = ntohl (sw_if_index);
9163   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9164   mp->is_add = is_add;
9165
9166   S (mp);
9167   W (ret);
9168   return ret;
9169 }
9170
9171 static int
9172 api_ip_neighbor_add_del (vat_main_t * vam)
9173 {
9174   unformat_input_t *i = vam->input;
9175   vl_api_ip_neighbor_add_del_t *mp;
9176   u32 sw_if_index;
9177   u8 sw_if_index_set = 0;
9178   u8 is_add = 1;
9179   u8 is_static = 0;
9180   u8 is_no_fib_entry = 0;
9181   u8 mac_address[6];
9182   u8 mac_set = 0;
9183   u8 v4_address_set = 0;
9184   u8 v6_address_set = 0;
9185   ip4_address_t v4address;
9186   ip6_address_t v6address;
9187   int ret;
9188
9189   memset (mac_address, 0, sizeof (mac_address));
9190
9191   /* Parse args required to build the message */
9192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9193     {
9194       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9195         {
9196           mac_set = 1;
9197         }
9198       else if (unformat (i, "del"))
9199         is_add = 0;
9200       else
9201         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9202         sw_if_index_set = 1;
9203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9204         sw_if_index_set = 1;
9205       else if (unformat (i, "is_static"))
9206         is_static = 1;
9207       else if (unformat (i, "no-fib-entry"))
9208         is_no_fib_entry = 1;
9209       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9210         v4_address_set = 1;
9211       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9212         v6_address_set = 1;
9213       else
9214         {
9215           clib_warning ("parse error '%U'", format_unformat_error, i);
9216           return -99;
9217         }
9218     }
9219
9220   if (sw_if_index_set == 0)
9221     {
9222       errmsg ("missing interface name or sw_if_index");
9223       return -99;
9224     }
9225   if (v4_address_set && v6_address_set)
9226     {
9227       errmsg ("both v4 and v6 addresses set");
9228       return -99;
9229     }
9230   if (!v4_address_set && !v6_address_set)
9231     {
9232       errmsg ("no address set");
9233       return -99;
9234     }
9235
9236   /* Construct the API message */
9237   M (IP_NEIGHBOR_ADD_DEL, mp);
9238
9239   mp->sw_if_index = ntohl (sw_if_index);
9240   mp->is_add = is_add;
9241   mp->is_static = is_static;
9242   mp->is_no_adj_fib = is_no_fib_entry;
9243   if (mac_set)
9244     clib_memcpy (mp->mac_address, mac_address, 6);
9245   if (v6_address_set)
9246     {
9247       mp->is_ipv6 = 1;
9248       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9249     }
9250   else
9251     {
9252       /* mp->is_ipv6 = 0; via memset in M macro above */
9253       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9254     }
9255
9256   /* send it... */
9257   S (mp);
9258
9259   /* Wait for a reply, return good/bad news  */
9260   W (ret);
9261   return ret;
9262 }
9263
9264 static int
9265 api_create_vlan_subif (vat_main_t * vam)
9266 {
9267   unformat_input_t *i = vam->input;
9268   vl_api_create_vlan_subif_t *mp;
9269   u32 sw_if_index;
9270   u8 sw_if_index_set = 0;
9271   u32 vlan_id;
9272   u8 vlan_id_set = 0;
9273   int ret;
9274
9275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9276     {
9277       if (unformat (i, "sw_if_index %d", &sw_if_index))
9278         sw_if_index_set = 1;
9279       else
9280         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9281         sw_if_index_set = 1;
9282       else if (unformat (i, "vlan %d", &vlan_id))
9283         vlan_id_set = 1;
9284       else
9285         {
9286           clib_warning ("parse error '%U'", format_unformat_error, i);
9287           return -99;
9288         }
9289     }
9290
9291   if (sw_if_index_set == 0)
9292     {
9293       errmsg ("missing interface name or sw_if_index");
9294       return -99;
9295     }
9296
9297   if (vlan_id_set == 0)
9298     {
9299       errmsg ("missing vlan_id");
9300       return -99;
9301     }
9302   M (CREATE_VLAN_SUBIF, mp);
9303
9304   mp->sw_if_index = ntohl (sw_if_index);
9305   mp->vlan_id = ntohl (vlan_id);
9306
9307   S (mp);
9308   W (ret);
9309   return ret;
9310 }
9311
9312 #define foreach_create_subif_bit                \
9313 _(no_tags)                                      \
9314 _(one_tag)                                      \
9315 _(two_tags)                                     \
9316 _(dot1ad)                                       \
9317 _(exact_match)                                  \
9318 _(default_sub)                                  \
9319 _(outer_vlan_id_any)                            \
9320 _(inner_vlan_id_any)
9321
9322 static int
9323 api_create_subif (vat_main_t * vam)
9324 {
9325   unformat_input_t *i = vam->input;
9326   vl_api_create_subif_t *mp;
9327   u32 sw_if_index;
9328   u8 sw_if_index_set = 0;
9329   u32 sub_id;
9330   u8 sub_id_set = 0;
9331   u32 no_tags = 0;
9332   u32 one_tag = 0;
9333   u32 two_tags = 0;
9334   u32 dot1ad = 0;
9335   u32 exact_match = 0;
9336   u32 default_sub = 0;
9337   u32 outer_vlan_id_any = 0;
9338   u32 inner_vlan_id_any = 0;
9339   u32 tmp;
9340   u16 outer_vlan_id = 0;
9341   u16 inner_vlan_id = 0;
9342   int ret;
9343
9344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9345     {
9346       if (unformat (i, "sw_if_index %d", &sw_if_index))
9347         sw_if_index_set = 1;
9348       else
9349         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9350         sw_if_index_set = 1;
9351       else if (unformat (i, "sub_id %d", &sub_id))
9352         sub_id_set = 1;
9353       else if (unformat (i, "outer_vlan_id %d", &tmp))
9354         outer_vlan_id = tmp;
9355       else if (unformat (i, "inner_vlan_id %d", &tmp))
9356         inner_vlan_id = tmp;
9357
9358 #define _(a) else if (unformat (i, #a)) a = 1 ;
9359       foreach_create_subif_bit
9360 #undef _
9361         else
9362         {
9363           clib_warning ("parse error '%U'", format_unformat_error, i);
9364           return -99;
9365         }
9366     }
9367
9368   if (sw_if_index_set == 0)
9369     {
9370       errmsg ("missing interface name or sw_if_index");
9371       return -99;
9372     }
9373
9374   if (sub_id_set == 0)
9375     {
9376       errmsg ("missing sub_id");
9377       return -99;
9378     }
9379   M (CREATE_SUBIF, mp);
9380
9381   mp->sw_if_index = ntohl (sw_if_index);
9382   mp->sub_id = ntohl (sub_id);
9383
9384 #define _(a) mp->a = a;
9385   foreach_create_subif_bit;
9386 #undef _
9387
9388   mp->outer_vlan_id = ntohs (outer_vlan_id);
9389   mp->inner_vlan_id = ntohs (inner_vlan_id);
9390
9391   S (mp);
9392   W (ret);
9393   return ret;
9394 }
9395
9396 static int
9397 api_oam_add_del (vat_main_t * vam)
9398 {
9399   unformat_input_t *i = vam->input;
9400   vl_api_oam_add_del_t *mp;
9401   u32 vrf_id = 0;
9402   u8 is_add = 1;
9403   ip4_address_t src, dst;
9404   u8 src_set = 0;
9405   u8 dst_set = 0;
9406   int ret;
9407
9408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9409     {
9410       if (unformat (i, "vrf %d", &vrf_id))
9411         ;
9412       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9413         src_set = 1;
9414       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9415         dst_set = 1;
9416       else if (unformat (i, "del"))
9417         is_add = 0;
9418       else
9419         {
9420           clib_warning ("parse error '%U'", format_unformat_error, i);
9421           return -99;
9422         }
9423     }
9424
9425   if (src_set == 0)
9426     {
9427       errmsg ("missing src addr");
9428       return -99;
9429     }
9430
9431   if (dst_set == 0)
9432     {
9433       errmsg ("missing dst addr");
9434       return -99;
9435     }
9436
9437   M (OAM_ADD_DEL, mp);
9438
9439   mp->vrf_id = ntohl (vrf_id);
9440   mp->is_add = is_add;
9441   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9442   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9443
9444   S (mp);
9445   W (ret);
9446   return ret;
9447 }
9448
9449 static int
9450 api_reset_fib (vat_main_t * vam)
9451 {
9452   unformat_input_t *i = vam->input;
9453   vl_api_reset_fib_t *mp;
9454   u32 vrf_id = 0;
9455   u8 is_ipv6 = 0;
9456   u8 vrf_id_set = 0;
9457
9458   int ret;
9459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9460     {
9461       if (unformat (i, "vrf %d", &vrf_id))
9462         vrf_id_set = 1;
9463       else if (unformat (i, "ipv6"))
9464         is_ipv6 = 1;
9465       else
9466         {
9467           clib_warning ("parse error '%U'", format_unformat_error, i);
9468           return -99;
9469         }
9470     }
9471
9472   if (vrf_id_set == 0)
9473     {
9474       errmsg ("missing vrf id");
9475       return -99;
9476     }
9477
9478   M (RESET_FIB, mp);
9479
9480   mp->vrf_id = ntohl (vrf_id);
9481   mp->is_ipv6 = is_ipv6;
9482
9483   S (mp);
9484   W (ret);
9485   return ret;
9486 }
9487
9488 static int
9489 api_dhcp_proxy_config (vat_main_t * vam)
9490 {
9491   unformat_input_t *i = vam->input;
9492   vl_api_dhcp_proxy_config_t *mp;
9493   u32 rx_vrf_id = 0;
9494   u32 server_vrf_id = 0;
9495   u8 is_add = 1;
9496   u8 v4_address_set = 0;
9497   u8 v6_address_set = 0;
9498   ip4_address_t v4address;
9499   ip6_address_t v6address;
9500   u8 v4_src_address_set = 0;
9501   u8 v6_src_address_set = 0;
9502   ip4_address_t v4srcaddress;
9503   ip6_address_t v6srcaddress;
9504   int ret;
9505
9506   /* Parse args required to build the message */
9507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9508     {
9509       if (unformat (i, "del"))
9510         is_add = 0;
9511       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9512         ;
9513       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9514         ;
9515       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9516         v4_address_set = 1;
9517       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9518         v6_address_set = 1;
9519       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9520         v4_src_address_set = 1;
9521       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9522         v6_src_address_set = 1;
9523       else
9524         break;
9525     }
9526
9527   if (v4_address_set && v6_address_set)
9528     {
9529       errmsg ("both v4 and v6 server addresses set");
9530       return -99;
9531     }
9532   if (!v4_address_set && !v6_address_set)
9533     {
9534       errmsg ("no server addresses set");
9535       return -99;
9536     }
9537
9538   if (v4_src_address_set && v6_src_address_set)
9539     {
9540       errmsg ("both v4 and v6  src addresses set");
9541       return -99;
9542     }
9543   if (!v4_src_address_set && !v6_src_address_set)
9544     {
9545       errmsg ("no src addresses set");
9546       return -99;
9547     }
9548
9549   if (!(v4_src_address_set && v4_address_set) &&
9550       !(v6_src_address_set && v6_address_set))
9551     {
9552       errmsg ("no matching server and src addresses set");
9553       return -99;
9554     }
9555
9556   /* Construct the API message */
9557   M (DHCP_PROXY_CONFIG, mp);
9558
9559   mp->is_add = is_add;
9560   mp->rx_vrf_id = ntohl (rx_vrf_id);
9561   mp->server_vrf_id = ntohl (server_vrf_id);
9562   if (v6_address_set)
9563     {
9564       mp->is_ipv6 = 1;
9565       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9566       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9567     }
9568   else
9569     {
9570       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9571       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9572     }
9573
9574   /* send it... */
9575   S (mp);
9576
9577   /* Wait for a reply, return good/bad news  */
9578   W (ret);
9579   return ret;
9580 }
9581
9582 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9583 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9584
9585 static void
9586 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9587 {
9588   vat_main_t *vam = &vat_main;
9589   u32 i, count = mp->count;
9590   vl_api_dhcp_server_t *s;
9591
9592   if (mp->is_ipv6)
9593     print (vam->ofp,
9594            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9595            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9596            ntohl (mp->rx_vrf_id),
9597            format_ip6_address, mp->dhcp_src_address,
9598            mp->vss_type, mp->vss_vpn_ascii_id,
9599            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9600   else
9601     print (vam->ofp,
9602            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9603            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9604            ntohl (mp->rx_vrf_id),
9605            format_ip4_address, mp->dhcp_src_address,
9606            mp->vss_type, mp->vss_vpn_ascii_id,
9607            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9608
9609   for (i = 0; i < count; i++)
9610     {
9611       s = &mp->servers[i];
9612
9613       if (mp->is_ipv6)
9614         print (vam->ofp,
9615                " Server Table-ID %d, Server Address %U",
9616                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9617       else
9618         print (vam->ofp,
9619                " Server Table-ID %d, Server Address %U",
9620                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9621     }
9622 }
9623
9624 static void vl_api_dhcp_proxy_details_t_handler_json
9625   (vl_api_dhcp_proxy_details_t * mp)
9626 {
9627   vat_main_t *vam = &vat_main;
9628   vat_json_node_t *node = NULL;
9629   u32 i, count = mp->count;
9630   struct in_addr ip4;
9631   struct in6_addr ip6;
9632   vl_api_dhcp_server_t *s;
9633
9634   if (VAT_JSON_ARRAY != vam->json_tree.type)
9635     {
9636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9637       vat_json_init_array (&vam->json_tree);
9638     }
9639   node = vat_json_array_add (&vam->json_tree);
9640
9641   vat_json_init_object (node);
9642   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9643   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9644                              sizeof (mp->vss_type));
9645   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9646                                    mp->vss_vpn_ascii_id);
9647   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9648   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9649
9650   if (mp->is_ipv6)
9651     {
9652       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9653       vat_json_object_add_ip6 (node, "src_address", ip6);
9654     }
9655   else
9656     {
9657       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9658       vat_json_object_add_ip4 (node, "src_address", ip4);
9659     }
9660
9661   for (i = 0; i < count; i++)
9662     {
9663       s = &mp->servers[i];
9664
9665       vat_json_object_add_uint (node, "server-table-id",
9666                                 ntohl (s->server_vrf_id));
9667
9668       if (mp->is_ipv6)
9669         {
9670           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9671           vat_json_object_add_ip4 (node, "src_address", ip4);
9672         }
9673       else
9674         {
9675           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9676           vat_json_object_add_ip6 (node, "server_address", ip6);
9677         }
9678     }
9679 }
9680
9681 static int
9682 api_dhcp_proxy_dump (vat_main_t * vam)
9683 {
9684   unformat_input_t *i = vam->input;
9685   vl_api_control_ping_t *mp_ping;
9686   vl_api_dhcp_proxy_dump_t *mp;
9687   u8 is_ipv6 = 0;
9688   int ret;
9689
9690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9691     {
9692       if (unformat (i, "ipv6"))
9693         is_ipv6 = 1;
9694       else
9695         {
9696           clib_warning ("parse error '%U'", format_unformat_error, i);
9697           return -99;
9698         }
9699     }
9700
9701   M (DHCP_PROXY_DUMP, mp);
9702
9703   mp->is_ip6 = is_ipv6;
9704   S (mp);
9705
9706   /* Use a control ping for synchronization */
9707   MPING (CONTROL_PING, mp_ping);
9708   S (mp_ping);
9709
9710   W (ret);
9711   return ret;
9712 }
9713
9714 static int
9715 api_dhcp_proxy_set_vss (vat_main_t * vam)
9716 {
9717   unformat_input_t *i = vam->input;
9718   vl_api_dhcp_proxy_set_vss_t *mp;
9719   u8 is_ipv6 = 0;
9720   u8 is_add = 1;
9721   u32 tbl_id = ~0;
9722   u8 vss_type = VSS_TYPE_DEFAULT;
9723   u8 *vpn_ascii_id = 0;
9724   u32 oui = 0;
9725   u32 fib_id = 0;
9726   int ret;
9727
9728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9729     {
9730       if (unformat (i, "tbl_id %d", &tbl_id))
9731         ;
9732       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9733         vss_type = VSS_TYPE_ASCII;
9734       else if (unformat (i, "fib_id %d", &fib_id))
9735         vss_type = VSS_TYPE_VPN_ID;
9736       else if (unformat (i, "oui %d", &oui))
9737         vss_type = VSS_TYPE_VPN_ID;
9738       else if (unformat (i, "ipv6"))
9739         is_ipv6 = 1;
9740       else if (unformat (i, "del"))
9741         is_add = 0;
9742       else
9743         break;
9744     }
9745
9746   if (tbl_id == ~0)
9747     {
9748       errmsg ("missing tbl_id ");
9749       vec_free (vpn_ascii_id);
9750       return -99;
9751     }
9752
9753   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9754     {
9755       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9756       vec_free (vpn_ascii_id);
9757       return -99;
9758     }
9759
9760   M (DHCP_PROXY_SET_VSS, mp);
9761   mp->tbl_id = ntohl (tbl_id);
9762   mp->vss_type = vss_type;
9763   if (vpn_ascii_id)
9764     {
9765       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9766       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9767     }
9768   mp->vpn_index = ntohl (fib_id);
9769   mp->oui = ntohl (oui);
9770   mp->is_ipv6 = is_ipv6;
9771   mp->is_add = is_add;
9772
9773   S (mp);
9774   W (ret);
9775
9776   vec_free (vpn_ascii_id);
9777   return ret;
9778 }
9779
9780 static int
9781 api_dhcp_client_config (vat_main_t * vam)
9782 {
9783   unformat_input_t *i = vam->input;
9784   vl_api_dhcp_client_config_t *mp;
9785   u32 sw_if_index;
9786   u8 sw_if_index_set = 0;
9787   u8 is_add = 1;
9788   u8 *hostname = 0;
9789   u8 disable_event = 0;
9790   int ret;
9791
9792   /* Parse args required to build the message */
9793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9794     {
9795       if (unformat (i, "del"))
9796         is_add = 0;
9797       else
9798         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9799         sw_if_index_set = 1;
9800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9801         sw_if_index_set = 1;
9802       else if (unformat (i, "hostname %s", &hostname))
9803         ;
9804       else if (unformat (i, "disable_event"))
9805         disable_event = 1;
9806       else
9807         break;
9808     }
9809
9810   if (sw_if_index_set == 0)
9811     {
9812       errmsg ("missing interface name or sw_if_index");
9813       return -99;
9814     }
9815
9816   if (vec_len (hostname) > 63)
9817     {
9818       errmsg ("hostname too long");
9819     }
9820   vec_add1 (hostname, 0);
9821
9822   /* Construct the API message */
9823   M (DHCP_CLIENT_CONFIG, mp);
9824
9825   mp->sw_if_index = htonl (sw_if_index);
9826   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9827   vec_free (hostname);
9828   mp->is_add = is_add;
9829   mp->want_dhcp_event = disable_event ? 0 : 1;
9830   mp->pid = htonl (getpid ());
9831
9832   /* send it... */
9833   S (mp);
9834
9835   /* Wait for a reply, return good/bad news  */
9836   W (ret);
9837   return ret;
9838 }
9839
9840 static int
9841 api_set_ip_flow_hash (vat_main_t * vam)
9842 {
9843   unformat_input_t *i = vam->input;
9844   vl_api_set_ip_flow_hash_t *mp;
9845   u32 vrf_id = 0;
9846   u8 is_ipv6 = 0;
9847   u8 vrf_id_set = 0;
9848   u8 src = 0;
9849   u8 dst = 0;
9850   u8 sport = 0;
9851   u8 dport = 0;
9852   u8 proto = 0;
9853   u8 reverse = 0;
9854   int ret;
9855
9856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9857     {
9858       if (unformat (i, "vrf %d", &vrf_id))
9859         vrf_id_set = 1;
9860       else if (unformat (i, "ipv6"))
9861         is_ipv6 = 1;
9862       else if (unformat (i, "src"))
9863         src = 1;
9864       else if (unformat (i, "dst"))
9865         dst = 1;
9866       else if (unformat (i, "sport"))
9867         sport = 1;
9868       else if (unformat (i, "dport"))
9869         dport = 1;
9870       else if (unformat (i, "proto"))
9871         proto = 1;
9872       else if (unformat (i, "reverse"))
9873         reverse = 1;
9874
9875       else
9876         {
9877           clib_warning ("parse error '%U'", format_unformat_error, i);
9878           return -99;
9879         }
9880     }
9881
9882   if (vrf_id_set == 0)
9883     {
9884       errmsg ("missing vrf id");
9885       return -99;
9886     }
9887
9888   M (SET_IP_FLOW_HASH, mp);
9889   mp->src = src;
9890   mp->dst = dst;
9891   mp->sport = sport;
9892   mp->dport = dport;
9893   mp->proto = proto;
9894   mp->reverse = reverse;
9895   mp->vrf_id = ntohl (vrf_id);
9896   mp->is_ipv6 = is_ipv6;
9897
9898   S (mp);
9899   W (ret);
9900   return ret;
9901 }
9902
9903 static int
9904 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9905 {
9906   unformat_input_t *i = vam->input;
9907   vl_api_sw_interface_ip6_enable_disable_t *mp;
9908   u32 sw_if_index;
9909   u8 sw_if_index_set = 0;
9910   u8 enable = 0;
9911   int ret;
9912
9913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9914     {
9915       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9916         sw_if_index_set = 1;
9917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9918         sw_if_index_set = 1;
9919       else if (unformat (i, "enable"))
9920         enable = 1;
9921       else if (unformat (i, "disable"))
9922         enable = 0;
9923       else
9924         {
9925           clib_warning ("parse error '%U'", format_unformat_error, i);
9926           return -99;
9927         }
9928     }
9929
9930   if (sw_if_index_set == 0)
9931     {
9932       errmsg ("missing interface name or sw_if_index");
9933       return -99;
9934     }
9935
9936   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9937
9938   mp->sw_if_index = ntohl (sw_if_index);
9939   mp->enable = enable;
9940
9941   S (mp);
9942   W (ret);
9943   return ret;
9944 }
9945
9946 static int
9947 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9948 {
9949   unformat_input_t *i = vam->input;
9950   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9951   u32 sw_if_index;
9952   u8 sw_if_index_set = 0;
9953   u8 v6_address_set = 0;
9954   ip6_address_t v6address;
9955   int ret;
9956
9957   /* Parse args required to build the message */
9958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9959     {
9960       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9961         sw_if_index_set = 1;
9962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9963         sw_if_index_set = 1;
9964       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9965         v6_address_set = 1;
9966       else
9967         break;
9968     }
9969
9970   if (sw_if_index_set == 0)
9971     {
9972       errmsg ("missing interface name or sw_if_index");
9973       return -99;
9974     }
9975   if (!v6_address_set)
9976     {
9977       errmsg ("no address set");
9978       return -99;
9979     }
9980
9981   /* Construct the API message */
9982   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9983
9984   mp->sw_if_index = ntohl (sw_if_index);
9985   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9986
9987   /* send it... */
9988   S (mp);
9989
9990   /* Wait for a reply, return good/bad news  */
9991   W (ret);
9992   return ret;
9993 }
9994
9995 static int
9996 api_ip6nd_proxy_add_del (vat_main_t * vam)
9997 {
9998   unformat_input_t *i = vam->input;
9999   vl_api_ip6nd_proxy_add_del_t *mp;
10000   u32 sw_if_index = ~0;
10001   u8 v6_address_set = 0;
10002   ip6_address_t v6address;
10003   u8 is_del = 0;
10004   int ret;
10005
10006   /* Parse args required to build the message */
10007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10008     {
10009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10010         ;
10011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10012         ;
10013       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10014         v6_address_set = 1;
10015       if (unformat (i, "del"))
10016         is_del = 1;
10017       else
10018         {
10019           clib_warning ("parse error '%U'", format_unformat_error, i);
10020           return -99;
10021         }
10022     }
10023
10024   if (sw_if_index == ~0)
10025     {
10026       errmsg ("missing interface name or sw_if_index");
10027       return -99;
10028     }
10029   if (!v6_address_set)
10030     {
10031       errmsg ("no address set");
10032       return -99;
10033     }
10034
10035   /* Construct the API message */
10036   M (IP6ND_PROXY_ADD_DEL, mp);
10037
10038   mp->is_del = is_del;
10039   mp->sw_if_index = ntohl (sw_if_index);
10040   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10041
10042   /* send it... */
10043   S (mp);
10044
10045   /* Wait for a reply, return good/bad news  */
10046   W (ret);
10047   return ret;
10048 }
10049
10050 static int
10051 api_ip6nd_proxy_dump (vat_main_t * vam)
10052 {
10053   vl_api_ip6nd_proxy_dump_t *mp;
10054   vl_api_control_ping_t *mp_ping;
10055   int ret;
10056
10057   M (IP6ND_PROXY_DUMP, mp);
10058
10059   S (mp);
10060
10061   /* Use a control ping for synchronization */
10062   MPING (CONTROL_PING, mp_ping);
10063   S (mp_ping);
10064
10065   W (ret);
10066   return ret;
10067 }
10068
10069 static void vl_api_ip6nd_proxy_details_t_handler
10070   (vl_api_ip6nd_proxy_details_t * mp)
10071 {
10072   vat_main_t *vam = &vat_main;
10073
10074   print (vam->ofp, "host %U sw_if_index %d",
10075          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10076 }
10077
10078 static void vl_api_ip6nd_proxy_details_t_handler_json
10079   (vl_api_ip6nd_proxy_details_t * mp)
10080 {
10081   vat_main_t *vam = &vat_main;
10082   struct in6_addr ip6;
10083   vat_json_node_t *node = NULL;
10084
10085   if (VAT_JSON_ARRAY != vam->json_tree.type)
10086     {
10087       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10088       vat_json_init_array (&vam->json_tree);
10089     }
10090   node = vat_json_array_add (&vam->json_tree);
10091
10092   vat_json_init_object (node);
10093   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10094
10095   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10096   vat_json_object_add_ip6 (node, "host", ip6);
10097 }
10098
10099 static int
10100 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10101 {
10102   unformat_input_t *i = vam->input;
10103   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10104   u32 sw_if_index;
10105   u8 sw_if_index_set = 0;
10106   u32 address_length = 0;
10107   u8 v6_address_set = 0;
10108   ip6_address_t v6address;
10109   u8 use_default = 0;
10110   u8 no_advertise = 0;
10111   u8 off_link = 0;
10112   u8 no_autoconfig = 0;
10113   u8 no_onlink = 0;
10114   u8 is_no = 0;
10115   u32 val_lifetime = 0;
10116   u32 pref_lifetime = 0;
10117   int ret;
10118
10119   /* Parse args required to build the message */
10120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10121     {
10122       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10123         sw_if_index_set = 1;
10124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10125         sw_if_index_set = 1;
10126       else if (unformat (i, "%U/%d",
10127                          unformat_ip6_address, &v6address, &address_length))
10128         v6_address_set = 1;
10129       else if (unformat (i, "val_life %d", &val_lifetime))
10130         ;
10131       else if (unformat (i, "pref_life %d", &pref_lifetime))
10132         ;
10133       else if (unformat (i, "def"))
10134         use_default = 1;
10135       else if (unformat (i, "noadv"))
10136         no_advertise = 1;
10137       else if (unformat (i, "offl"))
10138         off_link = 1;
10139       else if (unformat (i, "noauto"))
10140         no_autoconfig = 1;
10141       else if (unformat (i, "nolink"))
10142         no_onlink = 1;
10143       else if (unformat (i, "isno"))
10144         is_no = 1;
10145       else
10146         {
10147           clib_warning ("parse error '%U'", format_unformat_error, i);
10148           return -99;
10149         }
10150     }
10151
10152   if (sw_if_index_set == 0)
10153     {
10154       errmsg ("missing interface name or sw_if_index");
10155       return -99;
10156     }
10157   if (!v6_address_set)
10158     {
10159       errmsg ("no address set");
10160       return -99;
10161     }
10162
10163   /* Construct the API message */
10164   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10165
10166   mp->sw_if_index = ntohl (sw_if_index);
10167   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10168   mp->address_length = address_length;
10169   mp->use_default = use_default;
10170   mp->no_advertise = no_advertise;
10171   mp->off_link = off_link;
10172   mp->no_autoconfig = no_autoconfig;
10173   mp->no_onlink = no_onlink;
10174   mp->is_no = is_no;
10175   mp->val_lifetime = ntohl (val_lifetime);
10176   mp->pref_lifetime = ntohl (pref_lifetime);
10177
10178   /* send it... */
10179   S (mp);
10180
10181   /* Wait for a reply, return good/bad news  */
10182   W (ret);
10183   return ret;
10184 }
10185
10186 static int
10187 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10188 {
10189   unformat_input_t *i = vam->input;
10190   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10191   u32 sw_if_index;
10192   u8 sw_if_index_set = 0;
10193   u8 suppress = 0;
10194   u8 managed = 0;
10195   u8 other = 0;
10196   u8 ll_option = 0;
10197   u8 send_unicast = 0;
10198   u8 cease = 0;
10199   u8 is_no = 0;
10200   u8 default_router = 0;
10201   u32 max_interval = 0;
10202   u32 min_interval = 0;
10203   u32 lifetime = 0;
10204   u32 initial_count = 0;
10205   u32 initial_interval = 0;
10206   int ret;
10207
10208
10209   /* Parse args required to build the message */
10210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10211     {
10212       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10213         sw_if_index_set = 1;
10214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10215         sw_if_index_set = 1;
10216       else if (unformat (i, "maxint %d", &max_interval))
10217         ;
10218       else if (unformat (i, "minint %d", &min_interval))
10219         ;
10220       else if (unformat (i, "life %d", &lifetime))
10221         ;
10222       else if (unformat (i, "count %d", &initial_count))
10223         ;
10224       else if (unformat (i, "interval %d", &initial_interval))
10225         ;
10226       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10227         suppress = 1;
10228       else if (unformat (i, "managed"))
10229         managed = 1;
10230       else if (unformat (i, "other"))
10231         other = 1;
10232       else if (unformat (i, "ll"))
10233         ll_option = 1;
10234       else if (unformat (i, "send"))
10235         send_unicast = 1;
10236       else if (unformat (i, "cease"))
10237         cease = 1;
10238       else if (unformat (i, "isno"))
10239         is_no = 1;
10240       else if (unformat (i, "def"))
10241         default_router = 1;
10242       else
10243         {
10244           clib_warning ("parse error '%U'", format_unformat_error, i);
10245           return -99;
10246         }
10247     }
10248
10249   if (sw_if_index_set == 0)
10250     {
10251       errmsg ("missing interface name or sw_if_index");
10252       return -99;
10253     }
10254
10255   /* Construct the API message */
10256   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10257
10258   mp->sw_if_index = ntohl (sw_if_index);
10259   mp->max_interval = ntohl (max_interval);
10260   mp->min_interval = ntohl (min_interval);
10261   mp->lifetime = ntohl (lifetime);
10262   mp->initial_count = ntohl (initial_count);
10263   mp->initial_interval = ntohl (initial_interval);
10264   mp->suppress = suppress;
10265   mp->managed = managed;
10266   mp->other = other;
10267   mp->ll_option = ll_option;
10268   mp->send_unicast = send_unicast;
10269   mp->cease = cease;
10270   mp->is_no = is_no;
10271   mp->default_router = default_router;
10272
10273   /* send it... */
10274   S (mp);
10275
10276   /* Wait for a reply, return good/bad news  */
10277   W (ret);
10278   return ret;
10279 }
10280
10281 static int
10282 api_set_arp_neighbor_limit (vat_main_t * vam)
10283 {
10284   unformat_input_t *i = vam->input;
10285   vl_api_set_arp_neighbor_limit_t *mp;
10286   u32 arp_nbr_limit;
10287   u8 limit_set = 0;
10288   u8 is_ipv6 = 0;
10289   int ret;
10290
10291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10292     {
10293       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10294         limit_set = 1;
10295       else if (unformat (i, "ipv6"))
10296         is_ipv6 = 1;
10297       else
10298         {
10299           clib_warning ("parse error '%U'", format_unformat_error, i);
10300           return -99;
10301         }
10302     }
10303
10304   if (limit_set == 0)
10305     {
10306       errmsg ("missing limit value");
10307       return -99;
10308     }
10309
10310   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10311
10312   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10313   mp->is_ipv6 = is_ipv6;
10314
10315   S (mp);
10316   W (ret);
10317   return ret;
10318 }
10319
10320 static int
10321 api_l2_patch_add_del (vat_main_t * vam)
10322 {
10323   unformat_input_t *i = vam->input;
10324   vl_api_l2_patch_add_del_t *mp;
10325   u32 rx_sw_if_index;
10326   u8 rx_sw_if_index_set = 0;
10327   u32 tx_sw_if_index;
10328   u8 tx_sw_if_index_set = 0;
10329   u8 is_add = 1;
10330   int ret;
10331
10332   /* Parse args required to build the message */
10333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10334     {
10335       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10336         rx_sw_if_index_set = 1;
10337       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10338         tx_sw_if_index_set = 1;
10339       else if (unformat (i, "rx"))
10340         {
10341           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10342             {
10343               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10344                             &rx_sw_if_index))
10345                 rx_sw_if_index_set = 1;
10346             }
10347           else
10348             break;
10349         }
10350       else if (unformat (i, "tx"))
10351         {
10352           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10353             {
10354               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10355                             &tx_sw_if_index))
10356                 tx_sw_if_index_set = 1;
10357             }
10358           else
10359             break;
10360         }
10361       else if (unformat (i, "del"))
10362         is_add = 0;
10363       else
10364         break;
10365     }
10366
10367   if (rx_sw_if_index_set == 0)
10368     {
10369       errmsg ("missing rx interface name or rx_sw_if_index");
10370       return -99;
10371     }
10372
10373   if (tx_sw_if_index_set == 0)
10374     {
10375       errmsg ("missing tx interface name or tx_sw_if_index");
10376       return -99;
10377     }
10378
10379   M (L2_PATCH_ADD_DEL, mp);
10380
10381   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10382   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10383   mp->is_add = is_add;
10384
10385   S (mp);
10386   W (ret);
10387   return ret;
10388 }
10389
10390 u8 is_del;
10391 u8 localsid_addr[16];
10392 u8 end_psp;
10393 u8 behavior;
10394 u32 sw_if_index;
10395 u32 vlan_index;
10396 u32 fib_table;
10397 u8 nh_addr[16];
10398
10399 static int
10400 api_sr_localsid_add_del (vat_main_t * vam)
10401 {
10402   unformat_input_t *i = vam->input;
10403   vl_api_sr_localsid_add_del_t *mp;
10404
10405   u8 is_del;
10406   ip6_address_t localsid;
10407   u8 end_psp = 0;
10408   u8 behavior = ~0;
10409   u32 sw_if_index;
10410   u32 fib_table = ~(u32) 0;
10411   ip6_address_t next_hop;
10412
10413   bool nexthop_set = 0;
10414
10415   int ret;
10416
10417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10418     {
10419       if (unformat (i, "del"))
10420         is_del = 1;
10421       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10422       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10423         nexthop_set = 1;
10424       else if (unformat (i, "behavior %u", &behavior));
10425       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10426       else if (unformat (i, "fib-table %u", &fib_table));
10427       else if (unformat (i, "end.psp %u", &behavior));
10428       else
10429         break;
10430     }
10431
10432   M (SR_LOCALSID_ADD_DEL, mp);
10433
10434   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10435   if (nexthop_set)
10436     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10437   mp->behavior = behavior;
10438   mp->sw_if_index = ntohl (sw_if_index);
10439   mp->fib_table = ntohl (fib_table);
10440   mp->end_psp = end_psp;
10441   mp->is_del = is_del;
10442
10443   S (mp);
10444   W (ret);
10445   return ret;
10446 }
10447
10448 static int
10449 api_ioam_enable (vat_main_t * vam)
10450 {
10451   unformat_input_t *input = vam->input;
10452   vl_api_ioam_enable_t *mp;
10453   u32 id = 0;
10454   int has_trace_option = 0;
10455   int has_pot_option = 0;
10456   int has_seqno_option = 0;
10457   int has_analyse_option = 0;
10458   int ret;
10459
10460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10461     {
10462       if (unformat (input, "trace"))
10463         has_trace_option = 1;
10464       else if (unformat (input, "pot"))
10465         has_pot_option = 1;
10466       else if (unformat (input, "seqno"))
10467         has_seqno_option = 1;
10468       else if (unformat (input, "analyse"))
10469         has_analyse_option = 1;
10470       else
10471         break;
10472     }
10473   M (IOAM_ENABLE, mp);
10474   mp->id = htons (id);
10475   mp->seqno = has_seqno_option;
10476   mp->analyse = has_analyse_option;
10477   mp->pot_enable = has_pot_option;
10478   mp->trace_enable = has_trace_option;
10479
10480   S (mp);
10481   W (ret);
10482   return ret;
10483 }
10484
10485
10486 static int
10487 api_ioam_disable (vat_main_t * vam)
10488 {
10489   vl_api_ioam_disable_t *mp;
10490   int ret;
10491
10492   M (IOAM_DISABLE, mp);
10493   S (mp);
10494   W (ret);
10495   return ret;
10496 }
10497
10498 #define foreach_tcp_proto_field                 \
10499 _(src_port)                                     \
10500 _(dst_port)
10501
10502 #define foreach_udp_proto_field                 \
10503 _(src_port)                                     \
10504 _(dst_port)
10505
10506 #define foreach_ip4_proto_field                 \
10507 _(src_address)                                  \
10508 _(dst_address)                                  \
10509 _(tos)                                          \
10510 _(length)                                       \
10511 _(fragment_id)                                  \
10512 _(ttl)                                          \
10513 _(protocol)                                     \
10514 _(checksum)
10515
10516 typedef struct
10517 {
10518   u16 src_port, dst_port;
10519 } tcpudp_header_t;
10520
10521 #if VPP_API_TEST_BUILTIN == 0
10522 uword
10523 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10524 {
10525   u8 **maskp = va_arg (*args, u8 **);
10526   u8 *mask = 0;
10527   u8 found_something = 0;
10528   tcp_header_t *tcp;
10529
10530 #define _(a) u8 a=0;
10531   foreach_tcp_proto_field;
10532 #undef _
10533
10534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10535     {
10536       if (0);
10537 #define _(a) else if (unformat (input, #a)) a=1;
10538       foreach_tcp_proto_field
10539 #undef _
10540         else
10541         break;
10542     }
10543
10544 #define _(a) found_something += a;
10545   foreach_tcp_proto_field;
10546 #undef _
10547
10548   if (found_something == 0)
10549     return 0;
10550
10551   vec_validate (mask, sizeof (*tcp) - 1);
10552
10553   tcp = (tcp_header_t *) mask;
10554
10555 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10556   foreach_tcp_proto_field;
10557 #undef _
10558
10559   *maskp = mask;
10560   return 1;
10561 }
10562
10563 uword
10564 unformat_udp_mask (unformat_input_t * input, va_list * args)
10565 {
10566   u8 **maskp = va_arg (*args, u8 **);
10567   u8 *mask = 0;
10568   u8 found_something = 0;
10569   udp_header_t *udp;
10570
10571 #define _(a) u8 a=0;
10572   foreach_udp_proto_field;
10573 #undef _
10574
10575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10576     {
10577       if (0);
10578 #define _(a) else if (unformat (input, #a)) a=1;
10579       foreach_udp_proto_field
10580 #undef _
10581         else
10582         break;
10583     }
10584
10585 #define _(a) found_something += a;
10586   foreach_udp_proto_field;
10587 #undef _
10588
10589   if (found_something == 0)
10590     return 0;
10591
10592   vec_validate (mask, sizeof (*udp) - 1);
10593
10594   udp = (udp_header_t *) mask;
10595
10596 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10597   foreach_udp_proto_field;
10598 #undef _
10599
10600   *maskp = mask;
10601   return 1;
10602 }
10603
10604 uword
10605 unformat_l4_mask (unformat_input_t * input, va_list * args)
10606 {
10607   u8 **maskp = va_arg (*args, u8 **);
10608   u16 src_port = 0, dst_port = 0;
10609   tcpudp_header_t *tcpudp;
10610
10611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10612     {
10613       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10614         return 1;
10615       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10616         return 1;
10617       else if (unformat (input, "src_port"))
10618         src_port = 0xFFFF;
10619       else if (unformat (input, "dst_port"))
10620         dst_port = 0xFFFF;
10621       else
10622         return 0;
10623     }
10624
10625   if (!src_port && !dst_port)
10626     return 0;
10627
10628   u8 *mask = 0;
10629   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10630
10631   tcpudp = (tcpudp_header_t *) mask;
10632   tcpudp->src_port = src_port;
10633   tcpudp->dst_port = dst_port;
10634
10635   *maskp = mask;
10636
10637   return 1;
10638 }
10639
10640 uword
10641 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10642 {
10643   u8 **maskp = va_arg (*args, u8 **);
10644   u8 *mask = 0;
10645   u8 found_something = 0;
10646   ip4_header_t *ip;
10647
10648 #define _(a) u8 a=0;
10649   foreach_ip4_proto_field;
10650 #undef _
10651   u8 version = 0;
10652   u8 hdr_length = 0;
10653
10654
10655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10656     {
10657       if (unformat (input, "version"))
10658         version = 1;
10659       else if (unformat (input, "hdr_length"))
10660         hdr_length = 1;
10661       else if (unformat (input, "src"))
10662         src_address = 1;
10663       else if (unformat (input, "dst"))
10664         dst_address = 1;
10665       else if (unformat (input, "proto"))
10666         protocol = 1;
10667
10668 #define _(a) else if (unformat (input, #a)) a=1;
10669       foreach_ip4_proto_field
10670 #undef _
10671         else
10672         break;
10673     }
10674
10675 #define _(a) found_something += a;
10676   foreach_ip4_proto_field;
10677 #undef _
10678
10679   if (found_something == 0)
10680     return 0;
10681
10682   vec_validate (mask, sizeof (*ip) - 1);
10683
10684   ip = (ip4_header_t *) mask;
10685
10686 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10687   foreach_ip4_proto_field;
10688 #undef _
10689
10690   ip->ip_version_and_header_length = 0;
10691
10692   if (version)
10693     ip->ip_version_and_header_length |= 0xF0;
10694
10695   if (hdr_length)
10696     ip->ip_version_and_header_length |= 0x0F;
10697
10698   *maskp = mask;
10699   return 1;
10700 }
10701
10702 #define foreach_ip6_proto_field                 \
10703 _(src_address)                                  \
10704 _(dst_address)                                  \
10705 _(payload_length)                               \
10706 _(hop_limit)                                    \
10707 _(protocol)
10708
10709 uword
10710 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10711 {
10712   u8 **maskp = va_arg (*args, u8 **);
10713   u8 *mask = 0;
10714   u8 found_something = 0;
10715   ip6_header_t *ip;
10716   u32 ip_version_traffic_class_and_flow_label;
10717
10718 #define _(a) u8 a=0;
10719   foreach_ip6_proto_field;
10720 #undef _
10721   u8 version = 0;
10722   u8 traffic_class = 0;
10723   u8 flow_label = 0;
10724
10725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10726     {
10727       if (unformat (input, "version"))
10728         version = 1;
10729       else if (unformat (input, "traffic-class"))
10730         traffic_class = 1;
10731       else if (unformat (input, "flow-label"))
10732         flow_label = 1;
10733       else if (unformat (input, "src"))
10734         src_address = 1;
10735       else if (unformat (input, "dst"))
10736         dst_address = 1;
10737       else if (unformat (input, "proto"))
10738         protocol = 1;
10739
10740 #define _(a) else if (unformat (input, #a)) a=1;
10741       foreach_ip6_proto_field
10742 #undef _
10743         else
10744         break;
10745     }
10746
10747 #define _(a) found_something += a;
10748   foreach_ip6_proto_field;
10749 #undef _
10750
10751   if (found_something == 0)
10752     return 0;
10753
10754   vec_validate (mask, sizeof (*ip) - 1);
10755
10756   ip = (ip6_header_t *) mask;
10757
10758 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10759   foreach_ip6_proto_field;
10760 #undef _
10761
10762   ip_version_traffic_class_and_flow_label = 0;
10763
10764   if (version)
10765     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10766
10767   if (traffic_class)
10768     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10769
10770   if (flow_label)
10771     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10772
10773   ip->ip_version_traffic_class_and_flow_label =
10774     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10775
10776   *maskp = mask;
10777   return 1;
10778 }
10779
10780 uword
10781 unformat_l3_mask (unformat_input_t * input, va_list * args)
10782 {
10783   u8 **maskp = va_arg (*args, u8 **);
10784
10785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10786     {
10787       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10788         return 1;
10789       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10790         return 1;
10791       else
10792         break;
10793     }
10794   return 0;
10795 }
10796
10797 uword
10798 unformat_l2_mask (unformat_input_t * input, va_list * args)
10799 {
10800   u8 **maskp = va_arg (*args, u8 **);
10801   u8 *mask = 0;
10802   u8 src = 0;
10803   u8 dst = 0;
10804   u8 proto = 0;
10805   u8 tag1 = 0;
10806   u8 tag2 = 0;
10807   u8 ignore_tag1 = 0;
10808   u8 ignore_tag2 = 0;
10809   u8 cos1 = 0;
10810   u8 cos2 = 0;
10811   u8 dot1q = 0;
10812   u8 dot1ad = 0;
10813   int len = 14;
10814
10815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10816     {
10817       if (unformat (input, "src"))
10818         src = 1;
10819       else if (unformat (input, "dst"))
10820         dst = 1;
10821       else if (unformat (input, "proto"))
10822         proto = 1;
10823       else if (unformat (input, "tag1"))
10824         tag1 = 1;
10825       else if (unformat (input, "tag2"))
10826         tag2 = 1;
10827       else if (unformat (input, "ignore-tag1"))
10828         ignore_tag1 = 1;
10829       else if (unformat (input, "ignore-tag2"))
10830         ignore_tag2 = 1;
10831       else if (unformat (input, "cos1"))
10832         cos1 = 1;
10833       else if (unformat (input, "cos2"))
10834         cos2 = 1;
10835       else if (unformat (input, "dot1q"))
10836         dot1q = 1;
10837       else if (unformat (input, "dot1ad"))
10838         dot1ad = 1;
10839       else
10840         break;
10841     }
10842   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10843        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10844     return 0;
10845
10846   if (tag1 || ignore_tag1 || cos1 || dot1q)
10847     len = 18;
10848   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10849     len = 22;
10850
10851   vec_validate (mask, len - 1);
10852
10853   if (dst)
10854     memset (mask, 0xff, 6);
10855
10856   if (src)
10857     memset (mask + 6, 0xff, 6);
10858
10859   if (tag2 || dot1ad)
10860     {
10861       /* inner vlan tag */
10862       if (tag2)
10863         {
10864           mask[19] = 0xff;
10865           mask[18] = 0x0f;
10866         }
10867       if (cos2)
10868         mask[18] |= 0xe0;
10869       if (proto)
10870         mask[21] = mask[20] = 0xff;
10871       if (tag1)
10872         {
10873           mask[15] = 0xff;
10874           mask[14] = 0x0f;
10875         }
10876       if (cos1)
10877         mask[14] |= 0xe0;
10878       *maskp = mask;
10879       return 1;
10880     }
10881   if (tag1 | dot1q)
10882     {
10883       if (tag1)
10884         {
10885           mask[15] = 0xff;
10886           mask[14] = 0x0f;
10887         }
10888       if (cos1)
10889         mask[14] |= 0xe0;
10890       if (proto)
10891         mask[16] = mask[17] = 0xff;
10892
10893       *maskp = mask;
10894       return 1;
10895     }
10896   if (cos2)
10897     mask[18] |= 0xe0;
10898   if (cos1)
10899     mask[14] |= 0xe0;
10900   if (proto)
10901     mask[12] = mask[13] = 0xff;
10902
10903   *maskp = mask;
10904   return 1;
10905 }
10906
10907 uword
10908 unformat_classify_mask (unformat_input_t * input, va_list * args)
10909 {
10910   u8 **maskp = va_arg (*args, u8 **);
10911   u32 *skipp = va_arg (*args, u32 *);
10912   u32 *matchp = va_arg (*args, u32 *);
10913   u32 match;
10914   u8 *mask = 0;
10915   u8 *l2 = 0;
10916   u8 *l3 = 0;
10917   u8 *l4 = 0;
10918   int i;
10919
10920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10921     {
10922       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10923         ;
10924       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10925         ;
10926       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10927         ;
10928       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10929         ;
10930       else
10931         break;
10932     }
10933
10934   if (l4 && !l3)
10935     {
10936       vec_free (mask);
10937       vec_free (l2);
10938       vec_free (l4);
10939       return 0;
10940     }
10941
10942   if (mask || l2 || l3 || l4)
10943     {
10944       if (l2 || l3 || l4)
10945         {
10946           /* "With a free Ethernet header in every package" */
10947           if (l2 == 0)
10948             vec_validate (l2, 13);
10949           mask = l2;
10950           if (vec_len (l3))
10951             {
10952               vec_append (mask, l3);
10953               vec_free (l3);
10954             }
10955           if (vec_len (l4))
10956             {
10957               vec_append (mask, l4);
10958               vec_free (l4);
10959             }
10960         }
10961
10962       /* Scan forward looking for the first significant mask octet */
10963       for (i = 0; i < vec_len (mask); i++)
10964         if (mask[i])
10965           break;
10966
10967       /* compute (skip, match) params */
10968       *skipp = i / sizeof (u32x4);
10969       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10970
10971       /* Pad mask to an even multiple of the vector size */
10972       while (vec_len (mask) % sizeof (u32x4))
10973         vec_add1 (mask, 0);
10974
10975       match = vec_len (mask) / sizeof (u32x4);
10976
10977       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10978         {
10979           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10980           if (*tmp || *(tmp + 1))
10981             break;
10982           match--;
10983         }
10984       if (match == 0)
10985         clib_warning ("BUG: match 0");
10986
10987       _vec_len (mask) = match * sizeof (u32x4);
10988
10989       *matchp = match;
10990       *maskp = mask;
10991
10992       return 1;
10993     }
10994
10995   return 0;
10996 }
10997 #endif /* VPP_API_TEST_BUILTIN */
10998
10999 #define foreach_l2_next                         \
11000 _(drop, DROP)                                   \
11001 _(ethernet, ETHERNET_INPUT)                     \
11002 _(ip4, IP4_INPUT)                               \
11003 _(ip6, IP6_INPUT)
11004
11005 uword
11006 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11007 {
11008   u32 *miss_next_indexp = va_arg (*args, u32 *);
11009   u32 next_index = 0;
11010   u32 tmp;
11011
11012 #define _(n,N) \
11013   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11014   foreach_l2_next;
11015 #undef _
11016
11017   if (unformat (input, "%d", &tmp))
11018     {
11019       next_index = tmp;
11020       goto out;
11021     }
11022
11023   return 0;
11024
11025 out:
11026   *miss_next_indexp = next_index;
11027   return 1;
11028 }
11029
11030 #define foreach_ip_next                         \
11031 _(drop, DROP)                                   \
11032 _(local, LOCAL)                                 \
11033 _(rewrite, REWRITE)
11034
11035 uword
11036 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11037 {
11038   u32 *miss_next_indexp = va_arg (*args, u32 *);
11039   u32 next_index = 0;
11040   u32 tmp;
11041
11042 #define _(n,N) \
11043   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11044   foreach_ip_next;
11045 #undef _
11046
11047   if (unformat (input, "%d", &tmp))
11048     {
11049       next_index = tmp;
11050       goto out;
11051     }
11052
11053   return 0;
11054
11055 out:
11056   *miss_next_indexp = next_index;
11057   return 1;
11058 }
11059
11060 #define foreach_acl_next                        \
11061 _(deny, DENY)
11062
11063 uword
11064 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11065 {
11066   u32 *miss_next_indexp = va_arg (*args, u32 *);
11067   u32 next_index = 0;
11068   u32 tmp;
11069
11070 #define _(n,N) \
11071   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11072   foreach_acl_next;
11073 #undef _
11074
11075   if (unformat (input, "permit"))
11076     {
11077       next_index = ~0;
11078       goto out;
11079     }
11080   else if (unformat (input, "%d", &tmp))
11081     {
11082       next_index = tmp;
11083       goto out;
11084     }
11085
11086   return 0;
11087
11088 out:
11089   *miss_next_indexp = next_index;
11090   return 1;
11091 }
11092
11093 uword
11094 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11095 {
11096   u32 *r = va_arg (*args, u32 *);
11097
11098   if (unformat (input, "conform-color"))
11099     *r = POLICE_CONFORM;
11100   else if (unformat (input, "exceed-color"))
11101     *r = POLICE_EXCEED;
11102   else
11103     return 0;
11104
11105   return 1;
11106 }
11107
11108 static int
11109 api_classify_add_del_table (vat_main_t * vam)
11110 {
11111   unformat_input_t *i = vam->input;
11112   vl_api_classify_add_del_table_t *mp;
11113
11114   u32 nbuckets = 2;
11115   u32 skip = ~0;
11116   u32 match = ~0;
11117   int is_add = 1;
11118   int del_chain = 0;
11119   u32 table_index = ~0;
11120   u32 next_table_index = ~0;
11121   u32 miss_next_index = ~0;
11122   u32 memory_size = 32 << 20;
11123   u8 *mask = 0;
11124   u32 current_data_flag = 0;
11125   int current_data_offset = 0;
11126   int ret;
11127
11128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11129     {
11130       if (unformat (i, "del"))
11131         is_add = 0;
11132       else if (unformat (i, "del-chain"))
11133         {
11134           is_add = 0;
11135           del_chain = 1;
11136         }
11137       else if (unformat (i, "buckets %d", &nbuckets))
11138         ;
11139       else if (unformat (i, "memory_size %d", &memory_size))
11140         ;
11141       else if (unformat (i, "skip %d", &skip))
11142         ;
11143       else if (unformat (i, "match %d", &match))
11144         ;
11145       else if (unformat (i, "table %d", &table_index))
11146         ;
11147       else if (unformat (i, "mask %U", unformat_classify_mask,
11148                          &mask, &skip, &match))
11149         ;
11150       else if (unformat (i, "next-table %d", &next_table_index))
11151         ;
11152       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11153                          &miss_next_index))
11154         ;
11155       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11156                          &miss_next_index))
11157         ;
11158       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11159                          &miss_next_index))
11160         ;
11161       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11162         ;
11163       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11164         ;
11165       else
11166         break;
11167     }
11168
11169   if (is_add && mask == 0)
11170     {
11171       errmsg ("Mask required");
11172       return -99;
11173     }
11174
11175   if (is_add && skip == ~0)
11176     {
11177       errmsg ("skip count required");
11178       return -99;
11179     }
11180
11181   if (is_add && match == ~0)
11182     {
11183       errmsg ("match count required");
11184       return -99;
11185     }
11186
11187   if (!is_add && table_index == ~0)
11188     {
11189       errmsg ("table index required for delete");
11190       return -99;
11191     }
11192
11193   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11194
11195   mp->is_add = is_add;
11196   mp->del_chain = del_chain;
11197   mp->table_index = ntohl (table_index);
11198   mp->nbuckets = ntohl (nbuckets);
11199   mp->memory_size = ntohl (memory_size);
11200   mp->skip_n_vectors = ntohl (skip);
11201   mp->match_n_vectors = ntohl (match);
11202   mp->next_table_index = ntohl (next_table_index);
11203   mp->miss_next_index = ntohl (miss_next_index);
11204   mp->current_data_flag = ntohl (current_data_flag);
11205   mp->current_data_offset = ntohl (current_data_offset);
11206   clib_memcpy (mp->mask, mask, vec_len (mask));
11207
11208   vec_free (mask);
11209
11210   S (mp);
11211   W (ret);
11212   return ret;
11213 }
11214
11215 #if VPP_API_TEST_BUILTIN == 0
11216 uword
11217 unformat_l4_match (unformat_input_t * input, va_list * args)
11218 {
11219   u8 **matchp = va_arg (*args, u8 **);
11220
11221   u8 *proto_header = 0;
11222   int src_port = 0;
11223   int dst_port = 0;
11224
11225   tcpudp_header_t h;
11226
11227   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11228     {
11229       if (unformat (input, "src_port %d", &src_port))
11230         ;
11231       else if (unformat (input, "dst_port %d", &dst_port))
11232         ;
11233       else
11234         return 0;
11235     }
11236
11237   h.src_port = clib_host_to_net_u16 (src_port);
11238   h.dst_port = clib_host_to_net_u16 (dst_port);
11239   vec_validate (proto_header, sizeof (h) - 1);
11240   memcpy (proto_header, &h, sizeof (h));
11241
11242   *matchp = proto_header;
11243
11244   return 1;
11245 }
11246
11247 uword
11248 unformat_ip4_match (unformat_input_t * input, va_list * args)
11249 {
11250   u8 **matchp = va_arg (*args, u8 **);
11251   u8 *match = 0;
11252   ip4_header_t *ip;
11253   int version = 0;
11254   u32 version_val;
11255   int hdr_length = 0;
11256   u32 hdr_length_val;
11257   int src = 0, dst = 0;
11258   ip4_address_t src_val, dst_val;
11259   int proto = 0;
11260   u32 proto_val;
11261   int tos = 0;
11262   u32 tos_val;
11263   int length = 0;
11264   u32 length_val;
11265   int fragment_id = 0;
11266   u32 fragment_id_val;
11267   int ttl = 0;
11268   int ttl_val;
11269   int checksum = 0;
11270   u32 checksum_val;
11271
11272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11273     {
11274       if (unformat (input, "version %d", &version_val))
11275         version = 1;
11276       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11277         hdr_length = 1;
11278       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11279         src = 1;
11280       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11281         dst = 1;
11282       else if (unformat (input, "proto %d", &proto_val))
11283         proto = 1;
11284       else if (unformat (input, "tos %d", &tos_val))
11285         tos = 1;
11286       else if (unformat (input, "length %d", &length_val))
11287         length = 1;
11288       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11289         fragment_id = 1;
11290       else if (unformat (input, "ttl %d", &ttl_val))
11291         ttl = 1;
11292       else if (unformat (input, "checksum %d", &checksum_val))
11293         checksum = 1;
11294       else
11295         break;
11296     }
11297
11298   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11299       + ttl + checksum == 0)
11300     return 0;
11301
11302   /*
11303    * Aligned because we use the real comparison functions
11304    */
11305   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11306
11307   ip = (ip4_header_t *) match;
11308
11309   /* These are realistically matched in practice */
11310   if (src)
11311     ip->src_address.as_u32 = src_val.as_u32;
11312
11313   if (dst)
11314     ip->dst_address.as_u32 = dst_val.as_u32;
11315
11316   if (proto)
11317     ip->protocol = proto_val;
11318
11319
11320   /* These are not, but they're included for completeness */
11321   if (version)
11322     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11323
11324   if (hdr_length)
11325     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11326
11327   if (tos)
11328     ip->tos = tos_val;
11329
11330   if (length)
11331     ip->length = clib_host_to_net_u16 (length_val);
11332
11333   if (ttl)
11334     ip->ttl = ttl_val;
11335
11336   if (checksum)
11337     ip->checksum = clib_host_to_net_u16 (checksum_val);
11338
11339   *matchp = match;
11340   return 1;
11341 }
11342
11343 uword
11344 unformat_ip6_match (unformat_input_t * input, va_list * args)
11345 {
11346   u8 **matchp = va_arg (*args, u8 **);
11347   u8 *match = 0;
11348   ip6_header_t *ip;
11349   int version = 0;
11350   u32 version_val;
11351   u8 traffic_class = 0;
11352   u32 traffic_class_val = 0;
11353   u8 flow_label = 0;
11354   u8 flow_label_val;
11355   int src = 0, dst = 0;
11356   ip6_address_t src_val, dst_val;
11357   int proto = 0;
11358   u32 proto_val;
11359   int payload_length = 0;
11360   u32 payload_length_val;
11361   int hop_limit = 0;
11362   int hop_limit_val;
11363   u32 ip_version_traffic_class_and_flow_label;
11364
11365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11366     {
11367       if (unformat (input, "version %d", &version_val))
11368         version = 1;
11369       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11370         traffic_class = 1;
11371       else if (unformat (input, "flow_label %d", &flow_label_val))
11372         flow_label = 1;
11373       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11374         src = 1;
11375       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11376         dst = 1;
11377       else if (unformat (input, "proto %d", &proto_val))
11378         proto = 1;
11379       else if (unformat (input, "payload_length %d", &payload_length_val))
11380         payload_length = 1;
11381       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11382         hop_limit = 1;
11383       else
11384         break;
11385     }
11386
11387   if (version + traffic_class + flow_label + src + dst + proto +
11388       payload_length + hop_limit == 0)
11389     return 0;
11390
11391   /*
11392    * Aligned because we use the real comparison functions
11393    */
11394   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11395
11396   ip = (ip6_header_t *) match;
11397
11398   if (src)
11399     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11400
11401   if (dst)
11402     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11403
11404   if (proto)
11405     ip->protocol = proto_val;
11406
11407   ip_version_traffic_class_and_flow_label = 0;
11408
11409   if (version)
11410     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11411
11412   if (traffic_class)
11413     ip_version_traffic_class_and_flow_label |=
11414       (traffic_class_val & 0xFF) << 20;
11415
11416   if (flow_label)
11417     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11418
11419   ip->ip_version_traffic_class_and_flow_label =
11420     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11421
11422   if (payload_length)
11423     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11424
11425   if (hop_limit)
11426     ip->hop_limit = hop_limit_val;
11427
11428   *matchp = match;
11429   return 1;
11430 }
11431
11432 uword
11433 unformat_l3_match (unformat_input_t * input, va_list * args)
11434 {
11435   u8 **matchp = va_arg (*args, u8 **);
11436
11437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11438     {
11439       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11440         return 1;
11441       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11442         return 1;
11443       else
11444         break;
11445     }
11446   return 0;
11447 }
11448
11449 uword
11450 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11451 {
11452   u8 *tagp = va_arg (*args, u8 *);
11453   u32 tag;
11454
11455   if (unformat (input, "%d", &tag))
11456     {
11457       tagp[0] = (tag >> 8) & 0x0F;
11458       tagp[1] = tag & 0xFF;
11459       return 1;
11460     }
11461
11462   return 0;
11463 }
11464
11465 uword
11466 unformat_l2_match (unformat_input_t * input, va_list * args)
11467 {
11468   u8 **matchp = va_arg (*args, u8 **);
11469   u8 *match = 0;
11470   u8 src = 0;
11471   u8 src_val[6];
11472   u8 dst = 0;
11473   u8 dst_val[6];
11474   u8 proto = 0;
11475   u16 proto_val;
11476   u8 tag1 = 0;
11477   u8 tag1_val[2];
11478   u8 tag2 = 0;
11479   u8 tag2_val[2];
11480   int len = 14;
11481   u8 ignore_tag1 = 0;
11482   u8 ignore_tag2 = 0;
11483   u8 cos1 = 0;
11484   u8 cos2 = 0;
11485   u32 cos1_val = 0;
11486   u32 cos2_val = 0;
11487
11488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11489     {
11490       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11491         src = 1;
11492       else
11493         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11494         dst = 1;
11495       else if (unformat (input, "proto %U",
11496                          unformat_ethernet_type_host_byte_order, &proto_val))
11497         proto = 1;
11498       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11499         tag1 = 1;
11500       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11501         tag2 = 1;
11502       else if (unformat (input, "ignore-tag1"))
11503         ignore_tag1 = 1;
11504       else if (unformat (input, "ignore-tag2"))
11505         ignore_tag2 = 1;
11506       else if (unformat (input, "cos1 %d", &cos1_val))
11507         cos1 = 1;
11508       else if (unformat (input, "cos2 %d", &cos2_val))
11509         cos2 = 1;
11510       else
11511         break;
11512     }
11513   if ((src + dst + proto + tag1 + tag2 +
11514        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11515     return 0;
11516
11517   if (tag1 || ignore_tag1 || cos1)
11518     len = 18;
11519   if (tag2 || ignore_tag2 || cos2)
11520     len = 22;
11521
11522   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11523
11524   if (dst)
11525     clib_memcpy (match, dst_val, 6);
11526
11527   if (src)
11528     clib_memcpy (match + 6, src_val, 6);
11529
11530   if (tag2)
11531     {
11532       /* inner vlan tag */
11533       match[19] = tag2_val[1];
11534       match[18] = tag2_val[0];
11535       if (cos2)
11536         match[18] |= (cos2_val & 0x7) << 5;
11537       if (proto)
11538         {
11539           match[21] = proto_val & 0xff;
11540           match[20] = proto_val >> 8;
11541         }
11542       if (tag1)
11543         {
11544           match[15] = tag1_val[1];
11545           match[14] = tag1_val[0];
11546         }
11547       if (cos1)
11548         match[14] |= (cos1_val & 0x7) << 5;
11549       *matchp = match;
11550       return 1;
11551     }
11552   if (tag1)
11553     {
11554       match[15] = tag1_val[1];
11555       match[14] = tag1_val[0];
11556       if (proto)
11557         {
11558           match[17] = proto_val & 0xff;
11559           match[16] = proto_val >> 8;
11560         }
11561       if (cos1)
11562         match[14] |= (cos1_val & 0x7) << 5;
11563
11564       *matchp = match;
11565       return 1;
11566     }
11567   if (cos2)
11568     match[18] |= (cos2_val & 0x7) << 5;
11569   if (cos1)
11570     match[14] |= (cos1_val & 0x7) << 5;
11571   if (proto)
11572     {
11573       match[13] = proto_val & 0xff;
11574       match[12] = proto_val >> 8;
11575     }
11576
11577   *matchp = match;
11578   return 1;
11579 }
11580 #endif
11581
11582 uword
11583 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11584 {
11585   u8 **matchp = va_arg (*args, u8 **);
11586   u32 skip_n_vectors = va_arg (*args, u32);
11587   u32 match_n_vectors = va_arg (*args, u32);
11588
11589   u8 *match = 0;
11590   u8 *l2 = 0;
11591   u8 *l3 = 0;
11592   u8 *l4 = 0;
11593
11594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11595     {
11596       if (unformat (input, "hex %U", unformat_hex_string, &match))
11597         ;
11598       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11599         ;
11600       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11601         ;
11602       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11603         ;
11604       else
11605         break;
11606     }
11607
11608   if (l4 && !l3)
11609     {
11610       vec_free (match);
11611       vec_free (l2);
11612       vec_free (l4);
11613       return 0;
11614     }
11615
11616   if (match || l2 || l3 || l4)
11617     {
11618       if (l2 || l3 || l4)
11619         {
11620           /* "Win a free Ethernet header in every packet" */
11621           if (l2 == 0)
11622             vec_validate_aligned (l2, 13, sizeof (u32x4));
11623           match = l2;
11624           if (vec_len (l3))
11625             {
11626               vec_append_aligned (match, l3, sizeof (u32x4));
11627               vec_free (l3);
11628             }
11629           if (vec_len (l4))
11630             {
11631               vec_append_aligned (match, l4, sizeof (u32x4));
11632               vec_free (l4);
11633             }
11634         }
11635
11636       /* Make sure the vector is big enough even if key is all 0's */
11637       vec_validate_aligned
11638         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11639          sizeof (u32x4));
11640
11641       /* Set size, include skipped vectors */
11642       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11643
11644       *matchp = match;
11645
11646       return 1;
11647     }
11648
11649   return 0;
11650 }
11651
11652 static int
11653 api_classify_add_del_session (vat_main_t * vam)
11654 {
11655   unformat_input_t *i = vam->input;
11656   vl_api_classify_add_del_session_t *mp;
11657   int is_add = 1;
11658   u32 table_index = ~0;
11659   u32 hit_next_index = ~0;
11660   u32 opaque_index = ~0;
11661   u8 *match = 0;
11662   i32 advance = 0;
11663   u32 skip_n_vectors = 0;
11664   u32 match_n_vectors = 0;
11665   u32 action = 0;
11666   u32 metadata = 0;
11667   int ret;
11668
11669   /*
11670    * Warning: you have to supply skip_n and match_n
11671    * because the API client cant simply look at the classify
11672    * table object.
11673    */
11674
11675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11676     {
11677       if (unformat (i, "del"))
11678         is_add = 0;
11679       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11680                          &hit_next_index))
11681         ;
11682       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11683                          &hit_next_index))
11684         ;
11685       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11686                          &hit_next_index))
11687         ;
11688       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11689         ;
11690       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11691         ;
11692       else if (unformat (i, "opaque-index %d", &opaque_index))
11693         ;
11694       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11695         ;
11696       else if (unformat (i, "match_n %d", &match_n_vectors))
11697         ;
11698       else if (unformat (i, "match %U", api_unformat_classify_match,
11699                          &match, skip_n_vectors, match_n_vectors))
11700         ;
11701       else if (unformat (i, "advance %d", &advance))
11702         ;
11703       else if (unformat (i, "table-index %d", &table_index))
11704         ;
11705       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11706         action = 1;
11707       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11708         action = 2;
11709       else if (unformat (i, "action %d", &action))
11710         ;
11711       else if (unformat (i, "metadata %d", &metadata))
11712         ;
11713       else
11714         break;
11715     }
11716
11717   if (table_index == ~0)
11718     {
11719       errmsg ("Table index required");
11720       return -99;
11721     }
11722
11723   if (is_add && match == 0)
11724     {
11725       errmsg ("Match value required");
11726       return -99;
11727     }
11728
11729   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11730
11731   mp->is_add = is_add;
11732   mp->table_index = ntohl (table_index);
11733   mp->hit_next_index = ntohl (hit_next_index);
11734   mp->opaque_index = ntohl (opaque_index);
11735   mp->advance = ntohl (advance);
11736   mp->action = action;
11737   mp->metadata = ntohl (metadata);
11738   clib_memcpy (mp->match, match, vec_len (match));
11739   vec_free (match);
11740
11741   S (mp);
11742   W (ret);
11743   return ret;
11744 }
11745
11746 static int
11747 api_classify_set_interface_ip_table (vat_main_t * vam)
11748 {
11749   unformat_input_t *i = vam->input;
11750   vl_api_classify_set_interface_ip_table_t *mp;
11751   u32 sw_if_index;
11752   int sw_if_index_set;
11753   u32 table_index = ~0;
11754   u8 is_ipv6 = 0;
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, "table %d", &table_index))
11764         ;
11765       else
11766         {
11767           clib_warning ("parse error '%U'", format_unformat_error, i);
11768           return -99;
11769         }
11770     }
11771
11772   if (sw_if_index_set == 0)
11773     {
11774       errmsg ("missing interface name or sw_if_index");
11775       return -99;
11776     }
11777
11778
11779   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11780
11781   mp->sw_if_index = ntohl (sw_if_index);
11782   mp->table_index = ntohl (table_index);
11783   mp->is_ipv6 = is_ipv6;
11784
11785   S (mp);
11786   W (ret);
11787   return ret;
11788 }
11789
11790 static int
11791 api_classify_set_interface_l2_tables (vat_main_t * vam)
11792 {
11793   unformat_input_t *i = vam->input;
11794   vl_api_classify_set_interface_l2_tables_t *mp;
11795   u32 sw_if_index;
11796   int sw_if_index_set;
11797   u32 ip4_table_index = ~0;
11798   u32 ip6_table_index = ~0;
11799   u32 other_table_index = ~0;
11800   u32 is_input = 1;
11801   int ret;
11802
11803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11804     {
11805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11806         sw_if_index_set = 1;
11807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11808         sw_if_index_set = 1;
11809       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11810         ;
11811       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11812         ;
11813       else if (unformat (i, "other-table %d", &other_table_index))
11814         ;
11815       else if (unformat (i, "is-input %d", &is_input))
11816         ;
11817       else
11818         {
11819           clib_warning ("parse error '%U'", format_unformat_error, i);
11820           return -99;
11821         }
11822     }
11823
11824   if (sw_if_index_set == 0)
11825     {
11826       errmsg ("missing interface name or sw_if_index");
11827       return -99;
11828     }
11829
11830
11831   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11832
11833   mp->sw_if_index = ntohl (sw_if_index);
11834   mp->ip4_table_index = ntohl (ip4_table_index);
11835   mp->ip6_table_index = ntohl (ip6_table_index);
11836   mp->other_table_index = ntohl (other_table_index);
11837   mp->is_input = (u8) is_input;
11838
11839   S (mp);
11840   W (ret);
11841   return ret;
11842 }
11843
11844 static int
11845 api_set_ipfix_exporter (vat_main_t * vam)
11846 {
11847   unformat_input_t *i = vam->input;
11848   vl_api_set_ipfix_exporter_t *mp;
11849   ip4_address_t collector_address;
11850   u8 collector_address_set = 0;
11851   u32 collector_port = ~0;
11852   ip4_address_t src_address;
11853   u8 src_address_set = 0;
11854   u32 vrf_id = ~0;
11855   u32 path_mtu = ~0;
11856   u32 template_interval = ~0;
11857   u8 udp_checksum = 0;
11858   int ret;
11859
11860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11861     {
11862       if (unformat (i, "collector_address %U", unformat_ip4_address,
11863                     &collector_address))
11864         collector_address_set = 1;
11865       else if (unformat (i, "collector_port %d", &collector_port))
11866         ;
11867       else if (unformat (i, "src_address %U", unformat_ip4_address,
11868                          &src_address))
11869         src_address_set = 1;
11870       else if (unformat (i, "vrf_id %d", &vrf_id))
11871         ;
11872       else if (unformat (i, "path_mtu %d", &path_mtu))
11873         ;
11874       else if (unformat (i, "template_interval %d", &template_interval))
11875         ;
11876       else if (unformat (i, "udp_checksum"))
11877         udp_checksum = 1;
11878       else
11879         break;
11880     }
11881
11882   if (collector_address_set == 0)
11883     {
11884       errmsg ("collector_address required");
11885       return -99;
11886     }
11887
11888   if (src_address_set == 0)
11889     {
11890       errmsg ("src_address required");
11891       return -99;
11892     }
11893
11894   M (SET_IPFIX_EXPORTER, mp);
11895
11896   memcpy (mp->collector_address, collector_address.data,
11897           sizeof (collector_address.data));
11898   mp->collector_port = htons ((u16) collector_port);
11899   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11900   mp->vrf_id = htonl (vrf_id);
11901   mp->path_mtu = htonl (path_mtu);
11902   mp->template_interval = htonl (template_interval);
11903   mp->udp_checksum = udp_checksum;
11904
11905   S (mp);
11906   W (ret);
11907   return ret;
11908 }
11909
11910 static int
11911 api_set_ipfix_classify_stream (vat_main_t * vam)
11912 {
11913   unformat_input_t *i = vam->input;
11914   vl_api_set_ipfix_classify_stream_t *mp;
11915   u32 domain_id = 0;
11916   u32 src_port = UDP_DST_PORT_ipfix;
11917   int ret;
11918
11919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11920     {
11921       if (unformat (i, "domain %d", &domain_id))
11922         ;
11923       else if (unformat (i, "src_port %d", &src_port))
11924         ;
11925       else
11926         {
11927           errmsg ("unknown input `%U'", format_unformat_error, i);
11928           return -99;
11929         }
11930     }
11931
11932   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11933
11934   mp->domain_id = htonl (domain_id);
11935   mp->src_port = htons ((u16) src_port);
11936
11937   S (mp);
11938   W (ret);
11939   return ret;
11940 }
11941
11942 static int
11943 api_ipfix_classify_table_add_del (vat_main_t * vam)
11944 {
11945   unformat_input_t *i = vam->input;
11946   vl_api_ipfix_classify_table_add_del_t *mp;
11947   int is_add = -1;
11948   u32 classify_table_index = ~0;
11949   u8 ip_version = 0;
11950   u8 transport_protocol = 255;
11951   int ret;
11952
11953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11954     {
11955       if (unformat (i, "add"))
11956         is_add = 1;
11957       else if (unformat (i, "del"))
11958         is_add = 0;
11959       else if (unformat (i, "table %d", &classify_table_index))
11960         ;
11961       else if (unformat (i, "ip4"))
11962         ip_version = 4;
11963       else if (unformat (i, "ip6"))
11964         ip_version = 6;
11965       else if (unformat (i, "tcp"))
11966         transport_protocol = 6;
11967       else if (unformat (i, "udp"))
11968         transport_protocol = 17;
11969       else
11970         {
11971           errmsg ("unknown input `%U'", format_unformat_error, i);
11972           return -99;
11973         }
11974     }
11975
11976   if (is_add == -1)
11977     {
11978       errmsg ("expecting: add|del");
11979       return -99;
11980     }
11981   if (classify_table_index == ~0)
11982     {
11983       errmsg ("classifier table not specified");
11984       return -99;
11985     }
11986   if (ip_version == 0)
11987     {
11988       errmsg ("IP version not specified");
11989       return -99;
11990     }
11991
11992   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11993
11994   mp->is_add = is_add;
11995   mp->table_id = htonl (classify_table_index);
11996   mp->ip_version = ip_version;
11997   mp->transport_protocol = transport_protocol;
11998
11999   S (mp);
12000   W (ret);
12001   return ret;
12002 }
12003
12004 static int
12005 api_get_node_index (vat_main_t * vam)
12006 {
12007   unformat_input_t *i = vam->input;
12008   vl_api_get_node_index_t *mp;
12009   u8 *name = 0;
12010   int ret;
12011
12012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12013     {
12014       if (unformat (i, "node %s", &name))
12015         ;
12016       else
12017         break;
12018     }
12019   if (name == 0)
12020     {
12021       errmsg ("node name required");
12022       return -99;
12023     }
12024   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12025     {
12026       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12027       return -99;
12028     }
12029
12030   M (GET_NODE_INDEX, mp);
12031   clib_memcpy (mp->node_name, name, vec_len (name));
12032   vec_free (name);
12033
12034   S (mp);
12035   W (ret);
12036   return ret;
12037 }
12038
12039 static int
12040 api_get_next_index (vat_main_t * vam)
12041 {
12042   unformat_input_t *i = vam->input;
12043   vl_api_get_next_index_t *mp;
12044   u8 *node_name = 0, *next_node_name = 0;
12045   int ret;
12046
12047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12048     {
12049       if (unformat (i, "node-name %s", &node_name))
12050         ;
12051       else if (unformat (i, "next-node-name %s", &next_node_name))
12052         break;
12053     }
12054
12055   if (node_name == 0)
12056     {
12057       errmsg ("node name required");
12058       return -99;
12059     }
12060   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12061     {
12062       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12063       return -99;
12064     }
12065
12066   if (next_node_name == 0)
12067     {
12068       errmsg ("next node name required");
12069       return -99;
12070     }
12071   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12072     {
12073       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12074       return -99;
12075     }
12076
12077   M (GET_NEXT_INDEX, mp);
12078   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12079   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12080   vec_free (node_name);
12081   vec_free (next_node_name);
12082
12083   S (mp);
12084   W (ret);
12085   return ret;
12086 }
12087
12088 static int
12089 api_add_node_next (vat_main_t * vam)
12090 {
12091   unformat_input_t *i = vam->input;
12092   vl_api_add_node_next_t *mp;
12093   u8 *name = 0;
12094   u8 *next = 0;
12095   int ret;
12096
12097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12098     {
12099       if (unformat (i, "node %s", &name))
12100         ;
12101       else if (unformat (i, "next %s", &next))
12102         ;
12103       else
12104         break;
12105     }
12106   if (name == 0)
12107     {
12108       errmsg ("node name required");
12109       return -99;
12110     }
12111   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12112     {
12113       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12114       return -99;
12115     }
12116   if (next == 0)
12117     {
12118       errmsg ("next node required");
12119       return -99;
12120     }
12121   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12122     {
12123       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12124       return -99;
12125     }
12126
12127   M (ADD_NODE_NEXT, mp);
12128   clib_memcpy (mp->node_name, name, vec_len (name));
12129   clib_memcpy (mp->next_name, next, vec_len (next));
12130   vec_free (name);
12131   vec_free (next);
12132
12133   S (mp);
12134   W (ret);
12135   return ret;
12136 }
12137
12138 static int
12139 api_l2tpv3_create_tunnel (vat_main_t * vam)
12140 {
12141   unformat_input_t *i = vam->input;
12142   ip6_address_t client_address, our_address;
12143   int client_address_set = 0;
12144   int our_address_set = 0;
12145   u32 local_session_id = 0;
12146   u32 remote_session_id = 0;
12147   u64 local_cookie = 0;
12148   u64 remote_cookie = 0;
12149   u8 l2_sublayer_present = 0;
12150   vl_api_l2tpv3_create_tunnel_t *mp;
12151   int ret;
12152
12153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12154     {
12155       if (unformat (i, "client_address %U", unformat_ip6_address,
12156                     &client_address))
12157         client_address_set = 1;
12158       else if (unformat (i, "our_address %U", unformat_ip6_address,
12159                          &our_address))
12160         our_address_set = 1;
12161       else if (unformat (i, "local_session_id %d", &local_session_id))
12162         ;
12163       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12164         ;
12165       else if (unformat (i, "local_cookie %lld", &local_cookie))
12166         ;
12167       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12168         ;
12169       else if (unformat (i, "l2-sublayer-present"))
12170         l2_sublayer_present = 1;
12171       else
12172         break;
12173     }
12174
12175   if (client_address_set == 0)
12176     {
12177       errmsg ("client_address required");
12178       return -99;
12179     }
12180
12181   if (our_address_set == 0)
12182     {
12183       errmsg ("our_address required");
12184       return -99;
12185     }
12186
12187   M (L2TPV3_CREATE_TUNNEL, mp);
12188
12189   clib_memcpy (mp->client_address, client_address.as_u8,
12190                sizeof (mp->client_address));
12191
12192   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12193
12194   mp->local_session_id = ntohl (local_session_id);
12195   mp->remote_session_id = ntohl (remote_session_id);
12196   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12197   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12198   mp->l2_sublayer_present = l2_sublayer_present;
12199   mp->is_ipv6 = 1;
12200
12201   S (mp);
12202   W (ret);
12203   return ret;
12204 }
12205
12206 static int
12207 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12208 {
12209   unformat_input_t *i = vam->input;
12210   u32 sw_if_index;
12211   u8 sw_if_index_set = 0;
12212   u64 new_local_cookie = 0;
12213   u64 new_remote_cookie = 0;
12214   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12215   int ret;
12216
12217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12218     {
12219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12220         sw_if_index_set = 1;
12221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12222         sw_if_index_set = 1;
12223       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12224         ;
12225       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12226         ;
12227       else
12228         break;
12229     }
12230
12231   if (sw_if_index_set == 0)
12232     {
12233       errmsg ("missing interface name or sw_if_index");
12234       return -99;
12235     }
12236
12237   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12238
12239   mp->sw_if_index = ntohl (sw_if_index);
12240   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12241   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12242
12243   S (mp);
12244   W (ret);
12245   return ret;
12246 }
12247
12248 static int
12249 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12250 {
12251   unformat_input_t *i = vam->input;
12252   vl_api_l2tpv3_interface_enable_disable_t *mp;
12253   u32 sw_if_index;
12254   u8 sw_if_index_set = 0;
12255   u8 enable_disable = 1;
12256   int ret;
12257
12258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12259     {
12260       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12261         sw_if_index_set = 1;
12262       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12263         sw_if_index_set = 1;
12264       else if (unformat (i, "enable"))
12265         enable_disable = 1;
12266       else if (unformat (i, "disable"))
12267         enable_disable = 0;
12268       else
12269         break;
12270     }
12271
12272   if (sw_if_index_set == 0)
12273     {
12274       errmsg ("missing interface name or sw_if_index");
12275       return -99;
12276     }
12277
12278   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12279
12280   mp->sw_if_index = ntohl (sw_if_index);
12281   mp->enable_disable = enable_disable;
12282
12283   S (mp);
12284   W (ret);
12285   return ret;
12286 }
12287
12288 static int
12289 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12290 {
12291   unformat_input_t *i = vam->input;
12292   vl_api_l2tpv3_set_lookup_key_t *mp;
12293   u8 key = ~0;
12294   int ret;
12295
12296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12297     {
12298       if (unformat (i, "lookup_v6_src"))
12299         key = L2T_LOOKUP_SRC_ADDRESS;
12300       else if (unformat (i, "lookup_v6_dst"))
12301         key = L2T_LOOKUP_DST_ADDRESS;
12302       else if (unformat (i, "lookup_session_id"))
12303         key = L2T_LOOKUP_SESSION_ID;
12304       else
12305         break;
12306     }
12307
12308   if (key == (u8) ~ 0)
12309     {
12310       errmsg ("l2tp session lookup key unset");
12311       return -99;
12312     }
12313
12314   M (L2TPV3_SET_LOOKUP_KEY, mp);
12315
12316   mp->key = key;
12317
12318   S (mp);
12319   W (ret);
12320   return ret;
12321 }
12322
12323 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12324   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12325 {
12326   vat_main_t *vam = &vat_main;
12327
12328   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12329          format_ip6_address, mp->our_address,
12330          format_ip6_address, mp->client_address,
12331          clib_net_to_host_u32 (mp->sw_if_index));
12332
12333   print (vam->ofp,
12334          "   local cookies %016llx %016llx remote cookie %016llx",
12335          clib_net_to_host_u64 (mp->local_cookie[0]),
12336          clib_net_to_host_u64 (mp->local_cookie[1]),
12337          clib_net_to_host_u64 (mp->remote_cookie));
12338
12339   print (vam->ofp, "   local session-id %d remote session-id %d",
12340          clib_net_to_host_u32 (mp->local_session_id),
12341          clib_net_to_host_u32 (mp->remote_session_id));
12342
12343   print (vam->ofp, "   l2 specific sublayer %s\n",
12344          mp->l2_sublayer_present ? "preset" : "absent");
12345
12346 }
12347
12348 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12349   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12350 {
12351   vat_main_t *vam = &vat_main;
12352   vat_json_node_t *node = NULL;
12353   struct in6_addr addr;
12354
12355   if (VAT_JSON_ARRAY != vam->json_tree.type)
12356     {
12357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12358       vat_json_init_array (&vam->json_tree);
12359     }
12360   node = vat_json_array_add (&vam->json_tree);
12361
12362   vat_json_init_object (node);
12363
12364   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12365   vat_json_object_add_ip6 (node, "our_address", addr);
12366   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12367   vat_json_object_add_ip6 (node, "client_address", addr);
12368
12369   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12370   vat_json_init_array (lc);
12371   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12372   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12373   vat_json_object_add_uint (node, "remote_cookie",
12374                             clib_net_to_host_u64 (mp->remote_cookie));
12375
12376   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12377   vat_json_object_add_uint (node, "local_session_id",
12378                             clib_net_to_host_u32 (mp->local_session_id));
12379   vat_json_object_add_uint (node, "remote_session_id",
12380                             clib_net_to_host_u32 (mp->remote_session_id));
12381   vat_json_object_add_string_copy (node, "l2_sublayer",
12382                                    mp->l2_sublayer_present ? (u8 *) "present"
12383                                    : (u8 *) "absent");
12384 }
12385
12386 static int
12387 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12388 {
12389   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12390   vl_api_control_ping_t *mp_ping;
12391   int ret;
12392
12393   /* Get list of l2tpv3-tunnel interfaces */
12394   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12395   S (mp);
12396
12397   /* Use a control ping for synchronization */
12398   MPING (CONTROL_PING, mp_ping);
12399   S (mp_ping);
12400
12401   W (ret);
12402   return ret;
12403 }
12404
12405
12406 static void vl_api_sw_interface_tap_details_t_handler
12407   (vl_api_sw_interface_tap_details_t * mp)
12408 {
12409   vat_main_t *vam = &vat_main;
12410
12411   print (vam->ofp, "%-16s %d",
12412          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12413 }
12414
12415 static void vl_api_sw_interface_tap_details_t_handler_json
12416   (vl_api_sw_interface_tap_details_t * mp)
12417 {
12418   vat_main_t *vam = &vat_main;
12419   vat_json_node_t *node = NULL;
12420
12421   if (VAT_JSON_ARRAY != vam->json_tree.type)
12422     {
12423       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12424       vat_json_init_array (&vam->json_tree);
12425     }
12426   node = vat_json_array_add (&vam->json_tree);
12427
12428   vat_json_init_object (node);
12429   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12430   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12431 }
12432
12433 static int
12434 api_sw_interface_tap_dump (vat_main_t * vam)
12435 {
12436   vl_api_sw_interface_tap_dump_t *mp;
12437   vl_api_control_ping_t *mp_ping;
12438   int ret;
12439
12440   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12441   /* Get list of tap interfaces */
12442   M (SW_INTERFACE_TAP_DUMP, mp);
12443   S (mp);
12444
12445   /* Use a control ping for synchronization */
12446   MPING (CONTROL_PING, mp_ping);
12447   S (mp_ping);
12448
12449   W (ret);
12450   return ret;
12451 }
12452
12453 static void vl_api_sw_interface_tap_v2_details_t_handler
12454   (vl_api_sw_interface_tap_v2_details_t * mp)
12455 {
12456   vat_main_t *vam = &vat_main;
12457
12458   print (vam->ofp, "%-16s %d",
12459          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12460 }
12461
12462 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12463   (vl_api_sw_interface_tap_v2_details_t * mp)
12464 {
12465   vat_main_t *vam = &vat_main;
12466   vat_json_node_t *node = NULL;
12467
12468   if (VAT_JSON_ARRAY != vam->json_tree.type)
12469     {
12470       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12471       vat_json_init_array (&vam->json_tree);
12472     }
12473   node = vat_json_array_add (&vam->json_tree);
12474
12475   vat_json_init_object (node);
12476   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12477   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12478 }
12479
12480 static int
12481 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12482 {
12483   vl_api_sw_interface_tap_v2_dump_t *mp;
12484   vl_api_control_ping_t *mp_ping;
12485   int ret;
12486
12487   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12488   /* Get list of tap interfaces */
12489   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12490   S (mp);
12491
12492   /* Use a control ping for synchronization */
12493   MPING (CONTROL_PING, mp_ping);
12494   S (mp_ping);
12495
12496   W (ret);
12497   return ret;
12498 }
12499
12500 static uword unformat_vxlan_decap_next
12501   (unformat_input_t * input, va_list * args)
12502 {
12503   u32 *result = va_arg (*args, u32 *);
12504   u32 tmp;
12505
12506   if (unformat (input, "l2"))
12507     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12508   else if (unformat (input, "%d", &tmp))
12509     *result = tmp;
12510   else
12511     return 0;
12512   return 1;
12513 }
12514
12515 static int
12516 api_vxlan_add_del_tunnel (vat_main_t * vam)
12517 {
12518   unformat_input_t *line_input = vam->input;
12519   vl_api_vxlan_add_del_tunnel_t *mp;
12520   ip46_address_t src, dst;
12521   u8 is_add = 1;
12522   u8 ipv4_set = 0, ipv6_set = 0;
12523   u8 src_set = 0;
12524   u8 dst_set = 0;
12525   u8 grp_set = 0;
12526   u32 mcast_sw_if_index = ~0;
12527   u32 encap_vrf_id = 0;
12528   u32 decap_next_index = ~0;
12529   u32 vni = 0;
12530   int ret;
12531
12532   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12533   memset (&src, 0, sizeof src);
12534   memset (&dst, 0, sizeof dst);
12535
12536   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12537     {
12538       if (unformat (line_input, "del"))
12539         is_add = 0;
12540       else
12541         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12542         {
12543           ipv4_set = 1;
12544           src_set = 1;
12545         }
12546       else
12547         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12548         {
12549           ipv4_set = 1;
12550           dst_set = 1;
12551         }
12552       else
12553         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12554         {
12555           ipv6_set = 1;
12556           src_set = 1;
12557         }
12558       else
12559         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12560         {
12561           ipv6_set = 1;
12562           dst_set = 1;
12563         }
12564       else if (unformat (line_input, "group %U %U",
12565                          unformat_ip4_address, &dst.ip4,
12566                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12567         {
12568           grp_set = dst_set = 1;
12569           ipv4_set = 1;
12570         }
12571       else if (unformat (line_input, "group %U",
12572                          unformat_ip4_address, &dst.ip4))
12573         {
12574           grp_set = dst_set = 1;
12575           ipv4_set = 1;
12576         }
12577       else if (unformat (line_input, "group %U %U",
12578                          unformat_ip6_address, &dst.ip6,
12579                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12580         {
12581           grp_set = dst_set = 1;
12582           ipv6_set = 1;
12583         }
12584       else if (unformat (line_input, "group %U",
12585                          unformat_ip6_address, &dst.ip6))
12586         {
12587           grp_set = dst_set = 1;
12588           ipv6_set = 1;
12589         }
12590       else
12591         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12592         ;
12593       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12594         ;
12595       else if (unformat (line_input, "decap-next %U",
12596                          unformat_vxlan_decap_next, &decap_next_index))
12597         ;
12598       else if (unformat (line_input, "vni %d", &vni))
12599         ;
12600       else
12601         {
12602           errmsg ("parse error '%U'", format_unformat_error, line_input);
12603           return -99;
12604         }
12605     }
12606
12607   if (src_set == 0)
12608     {
12609       errmsg ("tunnel src address not specified");
12610       return -99;
12611     }
12612   if (dst_set == 0)
12613     {
12614       errmsg ("tunnel dst address not specified");
12615       return -99;
12616     }
12617
12618   if (grp_set && !ip46_address_is_multicast (&dst))
12619     {
12620       errmsg ("tunnel group address not multicast");
12621       return -99;
12622     }
12623   if (grp_set && mcast_sw_if_index == ~0)
12624     {
12625       errmsg ("tunnel nonexistent multicast device");
12626       return -99;
12627     }
12628   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12629     {
12630       errmsg ("tunnel dst address must be unicast");
12631       return -99;
12632     }
12633
12634
12635   if (ipv4_set && ipv6_set)
12636     {
12637       errmsg ("both IPv4 and IPv6 addresses specified");
12638       return -99;
12639     }
12640
12641   if ((vni == 0) || (vni >> 24))
12642     {
12643       errmsg ("vni not specified or out of range");
12644       return -99;
12645     }
12646
12647   M (VXLAN_ADD_DEL_TUNNEL, mp);
12648
12649   if (ipv6_set)
12650     {
12651       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12652       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12653     }
12654   else
12655     {
12656       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12657       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12658     }
12659   mp->encap_vrf_id = ntohl (encap_vrf_id);
12660   mp->decap_next_index = ntohl (decap_next_index);
12661   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12662   mp->vni = ntohl (vni);
12663   mp->is_add = is_add;
12664   mp->is_ipv6 = ipv6_set;
12665
12666   S (mp);
12667   W (ret);
12668   return ret;
12669 }
12670
12671 static void vl_api_vxlan_tunnel_details_t_handler
12672   (vl_api_vxlan_tunnel_details_t * mp)
12673 {
12674   vat_main_t *vam = &vat_main;
12675   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12676   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12677
12678   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12679          ntohl (mp->sw_if_index),
12680          format_ip46_address, &src, IP46_TYPE_ANY,
12681          format_ip46_address, &dst, IP46_TYPE_ANY,
12682          ntohl (mp->encap_vrf_id),
12683          ntohl (mp->decap_next_index), ntohl (mp->vni),
12684          ntohl (mp->mcast_sw_if_index));
12685 }
12686
12687 static void vl_api_vxlan_tunnel_details_t_handler_json
12688   (vl_api_vxlan_tunnel_details_t * mp)
12689 {
12690   vat_main_t *vam = &vat_main;
12691   vat_json_node_t *node = NULL;
12692
12693   if (VAT_JSON_ARRAY != vam->json_tree.type)
12694     {
12695       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12696       vat_json_init_array (&vam->json_tree);
12697     }
12698   node = vat_json_array_add (&vam->json_tree);
12699
12700   vat_json_init_object (node);
12701   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12702   if (mp->is_ipv6)
12703     {
12704       struct in6_addr ip6;
12705
12706       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12707       vat_json_object_add_ip6 (node, "src_address", ip6);
12708       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12709       vat_json_object_add_ip6 (node, "dst_address", ip6);
12710     }
12711   else
12712     {
12713       struct in_addr ip4;
12714
12715       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12716       vat_json_object_add_ip4 (node, "src_address", ip4);
12717       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12718       vat_json_object_add_ip4 (node, "dst_address", ip4);
12719     }
12720   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12721   vat_json_object_add_uint (node, "decap_next_index",
12722                             ntohl (mp->decap_next_index));
12723   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12724   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12725   vat_json_object_add_uint (node, "mcast_sw_if_index",
12726                             ntohl (mp->mcast_sw_if_index));
12727 }
12728
12729 static int
12730 api_vxlan_tunnel_dump (vat_main_t * vam)
12731 {
12732   unformat_input_t *i = vam->input;
12733   vl_api_vxlan_tunnel_dump_t *mp;
12734   vl_api_control_ping_t *mp_ping;
12735   u32 sw_if_index;
12736   u8 sw_if_index_set = 0;
12737   int ret;
12738
12739   /* Parse args required to build the message */
12740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12741     {
12742       if (unformat (i, "sw_if_index %d", &sw_if_index))
12743         sw_if_index_set = 1;
12744       else
12745         break;
12746     }
12747
12748   if (sw_if_index_set == 0)
12749     {
12750       sw_if_index = ~0;
12751     }
12752
12753   if (!vam->json_output)
12754     {
12755       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12756              "sw_if_index", "src_address", "dst_address",
12757              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12758     }
12759
12760   /* Get list of vxlan-tunnel interfaces */
12761   M (VXLAN_TUNNEL_DUMP, mp);
12762
12763   mp->sw_if_index = htonl (sw_if_index);
12764
12765   S (mp);
12766
12767   /* Use a control ping for synchronization */
12768   MPING (CONTROL_PING, mp_ping);
12769   S (mp_ping);
12770
12771   W (ret);
12772   return ret;
12773 }
12774
12775 static uword unformat_geneve_decap_next
12776   (unformat_input_t * input, va_list * args)
12777 {
12778   u32 *result = va_arg (*args, u32 *);
12779   u32 tmp;
12780
12781   if (unformat (input, "l2"))
12782     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12783   else if (unformat (input, "%d", &tmp))
12784     *result = tmp;
12785   else
12786     return 0;
12787   return 1;
12788 }
12789
12790 static int
12791 api_geneve_add_del_tunnel (vat_main_t * vam)
12792 {
12793   unformat_input_t *line_input = vam->input;
12794   vl_api_geneve_add_del_tunnel_t *mp;
12795   ip46_address_t src, dst;
12796   u8 is_add = 1;
12797   u8 ipv4_set = 0, ipv6_set = 0;
12798   u8 src_set = 0;
12799   u8 dst_set = 0;
12800   u8 grp_set = 0;
12801   u32 mcast_sw_if_index = ~0;
12802   u32 encap_vrf_id = 0;
12803   u32 decap_next_index = ~0;
12804   u32 vni = 0;
12805   int ret;
12806
12807   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12808   memset (&src, 0, sizeof src);
12809   memset (&dst, 0, sizeof dst);
12810
12811   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12812     {
12813       if (unformat (line_input, "del"))
12814         is_add = 0;
12815       else
12816         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12817         {
12818           ipv4_set = 1;
12819           src_set = 1;
12820         }
12821       else
12822         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12823         {
12824           ipv4_set = 1;
12825           dst_set = 1;
12826         }
12827       else
12828         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12829         {
12830           ipv6_set = 1;
12831           src_set = 1;
12832         }
12833       else
12834         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12835         {
12836           ipv6_set = 1;
12837           dst_set = 1;
12838         }
12839       else if (unformat (line_input, "group %U %U",
12840                          unformat_ip4_address, &dst.ip4,
12841                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12842         {
12843           grp_set = dst_set = 1;
12844           ipv4_set = 1;
12845         }
12846       else if (unformat (line_input, "group %U",
12847                          unformat_ip4_address, &dst.ip4))
12848         {
12849           grp_set = dst_set = 1;
12850           ipv4_set = 1;
12851         }
12852       else if (unformat (line_input, "group %U %U",
12853                          unformat_ip6_address, &dst.ip6,
12854                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12855         {
12856           grp_set = dst_set = 1;
12857           ipv6_set = 1;
12858         }
12859       else if (unformat (line_input, "group %U",
12860                          unformat_ip6_address, &dst.ip6))
12861         {
12862           grp_set = dst_set = 1;
12863           ipv6_set = 1;
12864         }
12865       else
12866         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12867         ;
12868       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12869         ;
12870       else if (unformat (line_input, "decap-next %U",
12871                          unformat_geneve_decap_next, &decap_next_index))
12872         ;
12873       else if (unformat (line_input, "vni %d", &vni))
12874         ;
12875       else
12876         {
12877           errmsg ("parse error '%U'", format_unformat_error, line_input);
12878           return -99;
12879         }
12880     }
12881
12882   if (src_set == 0)
12883     {
12884       errmsg ("tunnel src address not specified");
12885       return -99;
12886     }
12887   if (dst_set == 0)
12888     {
12889       errmsg ("tunnel dst address not specified");
12890       return -99;
12891     }
12892
12893   if (grp_set && !ip46_address_is_multicast (&dst))
12894     {
12895       errmsg ("tunnel group address not multicast");
12896       return -99;
12897     }
12898   if (grp_set && mcast_sw_if_index == ~0)
12899     {
12900       errmsg ("tunnel nonexistent multicast device");
12901       return -99;
12902     }
12903   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12904     {
12905       errmsg ("tunnel dst address must be unicast");
12906       return -99;
12907     }
12908
12909
12910   if (ipv4_set && ipv6_set)
12911     {
12912       errmsg ("both IPv4 and IPv6 addresses specified");
12913       return -99;
12914     }
12915
12916   if ((vni == 0) || (vni >> 24))
12917     {
12918       errmsg ("vni not specified or out of range");
12919       return -99;
12920     }
12921
12922   M (GENEVE_ADD_DEL_TUNNEL, mp);
12923
12924   if (ipv6_set)
12925     {
12926       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12927       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12928     }
12929   else
12930     {
12931       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12932       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12933     }
12934   mp->encap_vrf_id = ntohl (encap_vrf_id);
12935   mp->decap_next_index = ntohl (decap_next_index);
12936   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12937   mp->vni = ntohl (vni);
12938   mp->is_add = is_add;
12939   mp->is_ipv6 = ipv6_set;
12940
12941   S (mp);
12942   W (ret);
12943   return ret;
12944 }
12945
12946 static void vl_api_geneve_tunnel_details_t_handler
12947   (vl_api_geneve_tunnel_details_t * mp)
12948 {
12949   vat_main_t *vam = &vat_main;
12950   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12951   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12952
12953   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12954          ntohl (mp->sw_if_index),
12955          format_ip46_address, &src, IP46_TYPE_ANY,
12956          format_ip46_address, &dst, IP46_TYPE_ANY,
12957          ntohl (mp->encap_vrf_id),
12958          ntohl (mp->decap_next_index), ntohl (mp->vni),
12959          ntohl (mp->mcast_sw_if_index));
12960 }
12961
12962 static void vl_api_geneve_tunnel_details_t_handler_json
12963   (vl_api_geneve_tunnel_details_t * mp)
12964 {
12965   vat_main_t *vam = &vat_main;
12966   vat_json_node_t *node = NULL;
12967
12968   if (VAT_JSON_ARRAY != vam->json_tree.type)
12969     {
12970       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12971       vat_json_init_array (&vam->json_tree);
12972     }
12973   node = vat_json_array_add (&vam->json_tree);
12974
12975   vat_json_init_object (node);
12976   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12977   if (mp->is_ipv6)
12978     {
12979       struct in6_addr ip6;
12980
12981       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12982       vat_json_object_add_ip6 (node, "src_address", ip6);
12983       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12984       vat_json_object_add_ip6 (node, "dst_address", ip6);
12985     }
12986   else
12987     {
12988       struct in_addr ip4;
12989
12990       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12991       vat_json_object_add_ip4 (node, "src_address", ip4);
12992       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12993       vat_json_object_add_ip4 (node, "dst_address", ip4);
12994     }
12995   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12996   vat_json_object_add_uint (node, "decap_next_index",
12997                             ntohl (mp->decap_next_index));
12998   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12999   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13000   vat_json_object_add_uint (node, "mcast_sw_if_index",
13001                             ntohl (mp->mcast_sw_if_index));
13002 }
13003
13004 static int
13005 api_geneve_tunnel_dump (vat_main_t * vam)
13006 {
13007   unformat_input_t *i = vam->input;
13008   vl_api_geneve_tunnel_dump_t *mp;
13009   vl_api_control_ping_t *mp_ping;
13010   u32 sw_if_index;
13011   u8 sw_if_index_set = 0;
13012   int ret;
13013
13014   /* Parse args required to build the message */
13015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13016     {
13017       if (unformat (i, "sw_if_index %d", &sw_if_index))
13018         sw_if_index_set = 1;
13019       else
13020         break;
13021     }
13022
13023   if (sw_if_index_set == 0)
13024     {
13025       sw_if_index = ~0;
13026     }
13027
13028   if (!vam->json_output)
13029     {
13030       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13031              "sw_if_index", "local_address", "remote_address",
13032              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13033     }
13034
13035   /* Get list of geneve-tunnel interfaces */
13036   M (GENEVE_TUNNEL_DUMP, mp);
13037
13038   mp->sw_if_index = htonl (sw_if_index);
13039
13040   S (mp);
13041
13042   /* Use a control ping for synchronization */
13043   M (CONTROL_PING, mp_ping);
13044   S (mp_ping);
13045
13046   W (ret);
13047   return ret;
13048 }
13049
13050 static int
13051 api_gre_add_del_tunnel (vat_main_t * vam)
13052 {
13053   unformat_input_t *line_input = vam->input;
13054   vl_api_gre_add_del_tunnel_t *mp;
13055   ip4_address_t src4, dst4;
13056   ip6_address_t src6, dst6;
13057   u8 is_add = 1;
13058   u8 ipv4_set = 0;
13059   u8 ipv6_set = 0;
13060   u8 teb = 0;
13061   u8 src_set = 0;
13062   u8 dst_set = 0;
13063   u32 outer_fib_id = 0;
13064   int ret;
13065
13066   memset (&src4, 0, sizeof src4);
13067   memset (&dst4, 0, sizeof dst4);
13068   memset (&src6, 0, sizeof src6);
13069   memset (&dst6, 0, sizeof dst6);
13070
13071   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13072     {
13073       if (unformat (line_input, "del"))
13074         is_add = 0;
13075       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13076         {
13077           src_set = 1;
13078           ipv4_set = 1;
13079         }
13080       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13081         {
13082           dst_set = 1;
13083           ipv4_set = 1;
13084         }
13085       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13086         {
13087           src_set = 1;
13088           ipv6_set = 1;
13089         }
13090       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13091         {
13092           dst_set = 1;
13093           ipv6_set = 1;
13094         }
13095       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13096         ;
13097       else if (unformat (line_input, "teb"))
13098         teb = 1;
13099       else
13100         {
13101           errmsg ("parse error '%U'", format_unformat_error, line_input);
13102           return -99;
13103         }
13104     }
13105
13106   if (src_set == 0)
13107     {
13108       errmsg ("tunnel src address not specified");
13109       return -99;
13110     }
13111   if (dst_set == 0)
13112     {
13113       errmsg ("tunnel dst address not specified");
13114       return -99;
13115     }
13116   if (ipv4_set && ipv6_set)
13117     {
13118       errmsg ("both IPv4 and IPv6 addresses specified");
13119       return -99;
13120     }
13121
13122
13123   M (GRE_ADD_DEL_TUNNEL, mp);
13124
13125   if (ipv4_set)
13126     {
13127       clib_memcpy (&mp->src_address, &src4, 4);
13128       clib_memcpy (&mp->dst_address, &dst4, 4);
13129     }
13130   else
13131     {
13132       clib_memcpy (&mp->src_address, &src6, 16);
13133       clib_memcpy (&mp->dst_address, &dst6, 16);
13134     }
13135   mp->outer_fib_id = ntohl (outer_fib_id);
13136   mp->is_add = is_add;
13137   mp->teb = teb;
13138   mp->is_ipv6 = ipv6_set;
13139
13140   S (mp);
13141   W (ret);
13142   return ret;
13143 }
13144
13145 static void vl_api_gre_tunnel_details_t_handler
13146   (vl_api_gre_tunnel_details_t * mp)
13147 {
13148   vat_main_t *vam = &vat_main;
13149   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13150   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13151
13152   print (vam->ofp, "%11d%24U%24U%6d%14d",
13153          ntohl (mp->sw_if_index),
13154          format_ip46_address, &src, IP46_TYPE_ANY,
13155          format_ip46_address, &dst, IP46_TYPE_ANY,
13156          mp->teb, ntohl (mp->outer_fib_id));
13157 }
13158
13159 static void vl_api_gre_tunnel_details_t_handler_json
13160   (vl_api_gre_tunnel_details_t * mp)
13161 {
13162   vat_main_t *vam = &vat_main;
13163   vat_json_node_t *node = NULL;
13164   struct in_addr ip4;
13165   struct in6_addr ip6;
13166
13167   if (VAT_JSON_ARRAY != vam->json_tree.type)
13168     {
13169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13170       vat_json_init_array (&vam->json_tree);
13171     }
13172   node = vat_json_array_add (&vam->json_tree);
13173
13174   vat_json_init_object (node);
13175   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13176   if (!mp->is_ipv6)
13177     {
13178       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13179       vat_json_object_add_ip4 (node, "src_address", ip4);
13180       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13181       vat_json_object_add_ip4 (node, "dst_address", ip4);
13182     }
13183   else
13184     {
13185       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13186       vat_json_object_add_ip6 (node, "src_address", ip6);
13187       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13188       vat_json_object_add_ip6 (node, "dst_address", ip6);
13189     }
13190   vat_json_object_add_uint (node, "teb", mp->teb);
13191   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13192   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13193 }
13194
13195 static int
13196 api_gre_tunnel_dump (vat_main_t * vam)
13197 {
13198   unformat_input_t *i = vam->input;
13199   vl_api_gre_tunnel_dump_t *mp;
13200   vl_api_control_ping_t *mp_ping;
13201   u32 sw_if_index;
13202   u8 sw_if_index_set = 0;
13203   int ret;
13204
13205   /* Parse args required to build the message */
13206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13207     {
13208       if (unformat (i, "sw_if_index %d", &sw_if_index))
13209         sw_if_index_set = 1;
13210       else
13211         break;
13212     }
13213
13214   if (sw_if_index_set == 0)
13215     {
13216       sw_if_index = ~0;
13217     }
13218
13219   if (!vam->json_output)
13220     {
13221       print (vam->ofp, "%11s%24s%24s%6s%14s",
13222              "sw_if_index", "src_address", "dst_address", "teb",
13223              "outer_fib_id");
13224     }
13225
13226   /* Get list of gre-tunnel interfaces */
13227   M (GRE_TUNNEL_DUMP, mp);
13228
13229   mp->sw_if_index = htonl (sw_if_index);
13230
13231   S (mp);
13232
13233   /* Use a control ping for synchronization */
13234   MPING (CONTROL_PING, mp_ping);
13235   S (mp_ping);
13236
13237   W (ret);
13238   return ret;
13239 }
13240
13241 static int
13242 api_l2_fib_clear_table (vat_main_t * vam)
13243 {
13244 //  unformat_input_t * i = vam->input;
13245   vl_api_l2_fib_clear_table_t *mp;
13246   int ret;
13247
13248   M (L2_FIB_CLEAR_TABLE, mp);
13249
13250   S (mp);
13251   W (ret);
13252   return ret;
13253 }
13254
13255 static int
13256 api_l2_interface_efp_filter (vat_main_t * vam)
13257 {
13258   unformat_input_t *i = vam->input;
13259   vl_api_l2_interface_efp_filter_t *mp;
13260   u32 sw_if_index;
13261   u8 enable = 1;
13262   u8 sw_if_index_set = 0;
13263   int ret;
13264
13265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13266     {
13267       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13268         sw_if_index_set = 1;
13269       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13270         sw_if_index_set = 1;
13271       else if (unformat (i, "enable"))
13272         enable = 1;
13273       else if (unformat (i, "disable"))
13274         enable = 0;
13275       else
13276         {
13277           clib_warning ("parse error '%U'", format_unformat_error, i);
13278           return -99;
13279         }
13280     }
13281
13282   if (sw_if_index_set == 0)
13283     {
13284       errmsg ("missing sw_if_index");
13285       return -99;
13286     }
13287
13288   M (L2_INTERFACE_EFP_FILTER, mp);
13289
13290   mp->sw_if_index = ntohl (sw_if_index);
13291   mp->enable_disable = enable;
13292
13293   S (mp);
13294   W (ret);
13295   return ret;
13296 }
13297
13298 #define foreach_vtr_op                          \
13299 _("disable",  L2_VTR_DISABLED)                  \
13300 _("push-1",  L2_VTR_PUSH_1)                     \
13301 _("push-2",  L2_VTR_PUSH_2)                     \
13302 _("pop-1",  L2_VTR_POP_1)                       \
13303 _("pop-2",  L2_VTR_POP_2)                       \
13304 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13305 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13306 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13307 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13308
13309 static int
13310 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13311 {
13312   unformat_input_t *i = vam->input;
13313   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13314   u32 sw_if_index;
13315   u8 sw_if_index_set = 0;
13316   u8 vtr_op_set = 0;
13317   u32 vtr_op = 0;
13318   u32 push_dot1q = 1;
13319   u32 tag1 = ~0;
13320   u32 tag2 = ~0;
13321   int ret;
13322
13323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13324     {
13325       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13326         sw_if_index_set = 1;
13327       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13328         sw_if_index_set = 1;
13329       else if (unformat (i, "vtr_op %d", &vtr_op))
13330         vtr_op_set = 1;
13331 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13332       foreach_vtr_op
13333 #undef _
13334         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13335         ;
13336       else if (unformat (i, "tag1 %d", &tag1))
13337         ;
13338       else if (unformat (i, "tag2 %d", &tag2))
13339         ;
13340       else
13341         {
13342           clib_warning ("parse error '%U'", format_unformat_error, i);
13343           return -99;
13344         }
13345     }
13346
13347   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13348     {
13349       errmsg ("missing vtr operation or sw_if_index");
13350       return -99;
13351     }
13352
13353   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13354   mp->sw_if_index = ntohl (sw_if_index);
13355   mp->vtr_op = ntohl (vtr_op);
13356   mp->push_dot1q = ntohl (push_dot1q);
13357   mp->tag1 = ntohl (tag1);
13358   mp->tag2 = ntohl (tag2);
13359
13360   S (mp);
13361   W (ret);
13362   return ret;
13363 }
13364
13365 static int
13366 api_create_vhost_user_if (vat_main_t * vam)
13367 {
13368   unformat_input_t *i = vam->input;
13369   vl_api_create_vhost_user_if_t *mp;
13370   u8 *file_name;
13371   u8 is_server = 0;
13372   u8 file_name_set = 0;
13373   u32 custom_dev_instance = ~0;
13374   u8 hwaddr[6];
13375   u8 use_custom_mac = 0;
13376   u8 *tag = 0;
13377   int ret;
13378
13379   /* Shut up coverity */
13380   memset (hwaddr, 0, sizeof (hwaddr));
13381
13382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13383     {
13384       if (unformat (i, "socket %s", &file_name))
13385         {
13386           file_name_set = 1;
13387         }
13388       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13389         ;
13390       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13391         use_custom_mac = 1;
13392       else if (unformat (i, "server"))
13393         is_server = 1;
13394       else if (unformat (i, "tag %s", &tag))
13395         ;
13396       else
13397         break;
13398     }
13399
13400   if (file_name_set == 0)
13401     {
13402       errmsg ("missing socket file name");
13403       return -99;
13404     }
13405
13406   if (vec_len (file_name) > 255)
13407     {
13408       errmsg ("socket file name too long");
13409       return -99;
13410     }
13411   vec_add1 (file_name, 0);
13412
13413   M (CREATE_VHOST_USER_IF, mp);
13414
13415   mp->is_server = is_server;
13416   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13417   vec_free (file_name);
13418   if (custom_dev_instance != ~0)
13419     {
13420       mp->renumber = 1;
13421       mp->custom_dev_instance = ntohl (custom_dev_instance);
13422     }
13423   mp->use_custom_mac = use_custom_mac;
13424   clib_memcpy (mp->mac_address, hwaddr, 6);
13425   if (tag)
13426     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13427   vec_free (tag);
13428
13429   S (mp);
13430   W (ret);
13431   return ret;
13432 }
13433
13434 static int
13435 api_modify_vhost_user_if (vat_main_t * vam)
13436 {
13437   unformat_input_t *i = vam->input;
13438   vl_api_modify_vhost_user_if_t *mp;
13439   u8 *file_name;
13440   u8 is_server = 0;
13441   u8 file_name_set = 0;
13442   u32 custom_dev_instance = ~0;
13443   u8 sw_if_index_set = 0;
13444   u32 sw_if_index = (u32) ~ 0;
13445   int ret;
13446
13447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13448     {
13449       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13450         sw_if_index_set = 1;
13451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13452         sw_if_index_set = 1;
13453       else if (unformat (i, "socket %s", &file_name))
13454         {
13455           file_name_set = 1;
13456         }
13457       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13458         ;
13459       else if (unformat (i, "server"))
13460         is_server = 1;
13461       else
13462         break;
13463     }
13464
13465   if (sw_if_index_set == 0)
13466     {
13467       errmsg ("missing sw_if_index or interface name");
13468       return -99;
13469     }
13470
13471   if (file_name_set == 0)
13472     {
13473       errmsg ("missing socket file name");
13474       return -99;
13475     }
13476
13477   if (vec_len (file_name) > 255)
13478     {
13479       errmsg ("socket file name too long");
13480       return -99;
13481     }
13482   vec_add1 (file_name, 0);
13483
13484   M (MODIFY_VHOST_USER_IF, mp);
13485
13486   mp->sw_if_index = ntohl (sw_if_index);
13487   mp->is_server = is_server;
13488   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13489   vec_free (file_name);
13490   if (custom_dev_instance != ~0)
13491     {
13492       mp->renumber = 1;
13493       mp->custom_dev_instance = ntohl (custom_dev_instance);
13494     }
13495
13496   S (mp);
13497   W (ret);
13498   return ret;
13499 }
13500
13501 static int
13502 api_delete_vhost_user_if (vat_main_t * vam)
13503 {
13504   unformat_input_t *i = vam->input;
13505   vl_api_delete_vhost_user_if_t *mp;
13506   u32 sw_if_index = ~0;
13507   u8 sw_if_index_set = 0;
13508   int ret;
13509
13510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13511     {
13512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13513         sw_if_index_set = 1;
13514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13515         sw_if_index_set = 1;
13516       else
13517         break;
13518     }
13519
13520   if (sw_if_index_set == 0)
13521     {
13522       errmsg ("missing sw_if_index or interface name");
13523       return -99;
13524     }
13525
13526
13527   M (DELETE_VHOST_USER_IF, mp);
13528
13529   mp->sw_if_index = ntohl (sw_if_index);
13530
13531   S (mp);
13532   W (ret);
13533   return ret;
13534 }
13535
13536 static void vl_api_sw_interface_vhost_user_details_t_handler
13537   (vl_api_sw_interface_vhost_user_details_t * mp)
13538 {
13539   vat_main_t *vam = &vat_main;
13540
13541   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13542          (char *) mp->interface_name,
13543          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13544          clib_net_to_host_u64 (mp->features), mp->is_server,
13545          ntohl (mp->num_regions), (char *) mp->sock_filename);
13546   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13547 }
13548
13549 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13550   (vl_api_sw_interface_vhost_user_details_t * mp)
13551 {
13552   vat_main_t *vam = &vat_main;
13553   vat_json_node_t *node = NULL;
13554
13555   if (VAT_JSON_ARRAY != vam->json_tree.type)
13556     {
13557       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13558       vat_json_init_array (&vam->json_tree);
13559     }
13560   node = vat_json_array_add (&vam->json_tree);
13561
13562   vat_json_init_object (node);
13563   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13564   vat_json_object_add_string_copy (node, "interface_name",
13565                                    mp->interface_name);
13566   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13567                             ntohl (mp->virtio_net_hdr_sz));
13568   vat_json_object_add_uint (node, "features",
13569                             clib_net_to_host_u64 (mp->features));
13570   vat_json_object_add_uint (node, "is_server", mp->is_server);
13571   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13572   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13573   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13574 }
13575
13576 static int
13577 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13578 {
13579   vl_api_sw_interface_vhost_user_dump_t *mp;
13580   vl_api_control_ping_t *mp_ping;
13581   int ret;
13582   print (vam->ofp,
13583          "Interface name            idx hdr_sz features server regions filename");
13584
13585   /* Get list of vhost-user interfaces */
13586   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13587   S (mp);
13588
13589   /* Use a control ping for synchronization */
13590   MPING (CONTROL_PING, mp_ping);
13591   S (mp_ping);
13592
13593   W (ret);
13594   return ret;
13595 }
13596
13597 static int
13598 api_show_version (vat_main_t * vam)
13599 {
13600   vl_api_show_version_t *mp;
13601   int ret;
13602
13603   M (SHOW_VERSION, mp);
13604
13605   S (mp);
13606   W (ret);
13607   return ret;
13608 }
13609
13610
13611 static int
13612 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13613 {
13614   unformat_input_t *line_input = vam->input;
13615   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13616   ip4_address_t local4, remote4;
13617   ip6_address_t local6, remote6;
13618   u8 is_add = 1;
13619   u8 ipv4_set = 0, ipv6_set = 0;
13620   u8 local_set = 0;
13621   u8 remote_set = 0;
13622   u8 grp_set = 0;
13623   u32 mcast_sw_if_index = ~0;
13624   u32 encap_vrf_id = 0;
13625   u32 decap_vrf_id = 0;
13626   u8 protocol = ~0;
13627   u32 vni;
13628   u8 vni_set = 0;
13629   int ret;
13630
13631   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13632   memset (&local4, 0, sizeof local4);
13633   memset (&remote4, 0, sizeof remote4);
13634   memset (&local6, 0, sizeof local6);
13635   memset (&remote6, 0, sizeof remote6);
13636
13637   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13638     {
13639       if (unformat (line_input, "del"))
13640         is_add = 0;
13641       else if (unformat (line_input, "local %U",
13642                          unformat_ip4_address, &local4))
13643         {
13644           local_set = 1;
13645           ipv4_set = 1;
13646         }
13647       else if (unformat (line_input, "remote %U",
13648                          unformat_ip4_address, &remote4))
13649         {
13650           remote_set = 1;
13651           ipv4_set = 1;
13652         }
13653       else if (unformat (line_input, "local %U",
13654                          unformat_ip6_address, &local6))
13655         {
13656           local_set = 1;
13657           ipv6_set = 1;
13658         }
13659       else if (unformat (line_input, "remote %U",
13660                          unformat_ip6_address, &remote6))
13661         {
13662           remote_set = 1;
13663           ipv6_set = 1;
13664         }
13665       else if (unformat (line_input, "group %U %U",
13666                          unformat_ip4_address, &remote4,
13667                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13668         {
13669           grp_set = remote_set = 1;
13670           ipv4_set = 1;
13671         }
13672       else if (unformat (line_input, "group %U",
13673                          unformat_ip4_address, &remote4))
13674         {
13675           grp_set = remote_set = 1;
13676           ipv4_set = 1;
13677         }
13678       else if (unformat (line_input, "group %U %U",
13679                          unformat_ip6_address, &remote6,
13680                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13681         {
13682           grp_set = remote_set = 1;
13683           ipv6_set = 1;
13684         }
13685       else if (unformat (line_input, "group %U",
13686                          unformat_ip6_address, &remote6))
13687         {
13688           grp_set = remote_set = 1;
13689           ipv6_set = 1;
13690         }
13691       else
13692         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13693         ;
13694       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13695         ;
13696       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13697         ;
13698       else if (unformat (line_input, "vni %d", &vni))
13699         vni_set = 1;
13700       else if (unformat (line_input, "next-ip4"))
13701         protocol = 1;
13702       else if (unformat (line_input, "next-ip6"))
13703         protocol = 2;
13704       else if (unformat (line_input, "next-ethernet"))
13705         protocol = 3;
13706       else if (unformat (line_input, "next-nsh"))
13707         protocol = 4;
13708       else
13709         {
13710           errmsg ("parse error '%U'", format_unformat_error, line_input);
13711           return -99;
13712         }
13713     }
13714
13715   if (local_set == 0)
13716     {
13717       errmsg ("tunnel local address not specified");
13718       return -99;
13719     }
13720   if (remote_set == 0)
13721     {
13722       errmsg ("tunnel remote address not specified");
13723       return -99;
13724     }
13725   if (grp_set && mcast_sw_if_index == ~0)
13726     {
13727       errmsg ("tunnel nonexistent multicast device");
13728       return -99;
13729     }
13730   if (ipv4_set && ipv6_set)
13731     {
13732       errmsg ("both IPv4 and IPv6 addresses specified");
13733       return -99;
13734     }
13735
13736   if (vni_set == 0)
13737     {
13738       errmsg ("vni not specified");
13739       return -99;
13740     }
13741
13742   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13743
13744
13745   if (ipv6_set)
13746     {
13747       clib_memcpy (&mp->local, &local6, sizeof (local6));
13748       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13749     }
13750   else
13751     {
13752       clib_memcpy (&mp->local, &local4, sizeof (local4));
13753       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13754     }
13755
13756   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13757   mp->encap_vrf_id = ntohl (encap_vrf_id);
13758   mp->decap_vrf_id = ntohl (decap_vrf_id);
13759   mp->protocol = protocol;
13760   mp->vni = ntohl (vni);
13761   mp->is_add = is_add;
13762   mp->is_ipv6 = ipv6_set;
13763
13764   S (mp);
13765   W (ret);
13766   return ret;
13767 }
13768
13769 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13770   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13771 {
13772   vat_main_t *vam = &vat_main;
13773   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13774   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13775
13776   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13777          ntohl (mp->sw_if_index),
13778          format_ip46_address, &local, IP46_TYPE_ANY,
13779          format_ip46_address, &remote, IP46_TYPE_ANY,
13780          ntohl (mp->vni), mp->protocol,
13781          ntohl (mp->mcast_sw_if_index),
13782          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13783 }
13784
13785
13786 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13787   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13788 {
13789   vat_main_t *vam = &vat_main;
13790   vat_json_node_t *node = NULL;
13791   struct in_addr ip4;
13792   struct in6_addr ip6;
13793
13794   if (VAT_JSON_ARRAY != vam->json_tree.type)
13795     {
13796       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13797       vat_json_init_array (&vam->json_tree);
13798     }
13799   node = vat_json_array_add (&vam->json_tree);
13800
13801   vat_json_init_object (node);
13802   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13803   if (mp->is_ipv6)
13804     {
13805       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13806       vat_json_object_add_ip6 (node, "local", ip6);
13807       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13808       vat_json_object_add_ip6 (node, "remote", ip6);
13809     }
13810   else
13811     {
13812       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13813       vat_json_object_add_ip4 (node, "local", ip4);
13814       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13815       vat_json_object_add_ip4 (node, "remote", ip4);
13816     }
13817   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13818   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13819   vat_json_object_add_uint (node, "mcast_sw_if_index",
13820                             ntohl (mp->mcast_sw_if_index));
13821   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13822   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13823   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13824 }
13825
13826 static int
13827 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13828 {
13829   unformat_input_t *i = vam->input;
13830   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13831   vl_api_control_ping_t *mp_ping;
13832   u32 sw_if_index;
13833   u8 sw_if_index_set = 0;
13834   int ret;
13835
13836   /* Parse args required to build the message */
13837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13838     {
13839       if (unformat (i, "sw_if_index %d", &sw_if_index))
13840         sw_if_index_set = 1;
13841       else
13842         break;
13843     }
13844
13845   if (sw_if_index_set == 0)
13846     {
13847       sw_if_index = ~0;
13848     }
13849
13850   if (!vam->json_output)
13851     {
13852       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13853              "sw_if_index", "local", "remote", "vni",
13854              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13855     }
13856
13857   /* Get list of vxlan-tunnel interfaces */
13858   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13859
13860   mp->sw_if_index = htonl (sw_if_index);
13861
13862   S (mp);
13863
13864   /* Use a control ping for synchronization */
13865   MPING (CONTROL_PING, mp_ping);
13866   S (mp_ping);
13867
13868   W (ret);
13869   return ret;
13870 }
13871
13872 static void vl_api_l2_fib_table_details_t_handler
13873   (vl_api_l2_fib_table_details_t * mp)
13874 {
13875   vat_main_t *vam = &vat_main;
13876
13877   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13878          "       %d       %d     %d",
13879          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13880          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13881          mp->bvi_mac);
13882 }
13883
13884 static void vl_api_l2_fib_table_details_t_handler_json
13885   (vl_api_l2_fib_table_details_t * mp)
13886 {
13887   vat_main_t *vam = &vat_main;
13888   vat_json_node_t *node = NULL;
13889
13890   if (VAT_JSON_ARRAY != vam->json_tree.type)
13891     {
13892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13893       vat_json_init_array (&vam->json_tree);
13894     }
13895   node = vat_json_array_add (&vam->json_tree);
13896
13897   vat_json_init_object (node);
13898   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13899   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13900   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13901   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13902   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13903   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13904 }
13905
13906 static int
13907 api_l2_fib_table_dump (vat_main_t * vam)
13908 {
13909   unformat_input_t *i = vam->input;
13910   vl_api_l2_fib_table_dump_t *mp;
13911   vl_api_control_ping_t *mp_ping;
13912   u32 bd_id;
13913   u8 bd_id_set = 0;
13914   int ret;
13915
13916   /* Parse args required to build the message */
13917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13918     {
13919       if (unformat (i, "bd_id %d", &bd_id))
13920         bd_id_set = 1;
13921       else
13922         break;
13923     }
13924
13925   if (bd_id_set == 0)
13926     {
13927       errmsg ("missing bridge domain");
13928       return -99;
13929     }
13930
13931   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13932
13933   /* Get list of l2 fib entries */
13934   M (L2_FIB_TABLE_DUMP, mp);
13935
13936   mp->bd_id = ntohl (bd_id);
13937   S (mp);
13938
13939   /* Use a control ping for synchronization */
13940   MPING (CONTROL_PING, mp_ping);
13941   S (mp_ping);
13942
13943   W (ret);
13944   return ret;
13945 }
13946
13947
13948 static int
13949 api_interface_name_renumber (vat_main_t * vam)
13950 {
13951   unformat_input_t *line_input = vam->input;
13952   vl_api_interface_name_renumber_t *mp;
13953   u32 sw_if_index = ~0;
13954   u32 new_show_dev_instance = ~0;
13955   int ret;
13956
13957   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13958     {
13959       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13960                     &sw_if_index))
13961         ;
13962       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13963         ;
13964       else if (unformat (line_input, "new_show_dev_instance %d",
13965                          &new_show_dev_instance))
13966         ;
13967       else
13968         break;
13969     }
13970
13971   if (sw_if_index == ~0)
13972     {
13973       errmsg ("missing interface name or sw_if_index");
13974       return -99;
13975     }
13976
13977   if (new_show_dev_instance == ~0)
13978     {
13979       errmsg ("missing new_show_dev_instance");
13980       return -99;
13981     }
13982
13983   M (INTERFACE_NAME_RENUMBER, mp);
13984
13985   mp->sw_if_index = ntohl (sw_if_index);
13986   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13987
13988   S (mp);
13989   W (ret);
13990   return ret;
13991 }
13992
13993 static int
13994 api_want_ip4_arp_events (vat_main_t * vam)
13995 {
13996   unformat_input_t *line_input = vam->input;
13997   vl_api_want_ip4_arp_events_t *mp;
13998   ip4_address_t address;
13999   int address_set = 0;
14000   u32 enable_disable = 1;
14001   int ret;
14002
14003   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14004     {
14005       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14006         address_set = 1;
14007       else if (unformat (line_input, "del"))
14008         enable_disable = 0;
14009       else
14010         break;
14011     }
14012
14013   if (address_set == 0)
14014     {
14015       errmsg ("missing addresses");
14016       return -99;
14017     }
14018
14019   M (WANT_IP4_ARP_EVENTS, mp);
14020   mp->enable_disable = enable_disable;
14021   mp->pid = htonl (getpid ());
14022   mp->address = address.as_u32;
14023
14024   S (mp);
14025   W (ret);
14026   return ret;
14027 }
14028
14029 static int
14030 api_want_ip6_nd_events (vat_main_t * vam)
14031 {
14032   unformat_input_t *line_input = vam->input;
14033   vl_api_want_ip6_nd_events_t *mp;
14034   ip6_address_t address;
14035   int address_set = 0;
14036   u32 enable_disable = 1;
14037   int ret;
14038
14039   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14040     {
14041       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14042         address_set = 1;
14043       else if (unformat (line_input, "del"))
14044         enable_disable = 0;
14045       else
14046         break;
14047     }
14048
14049   if (address_set == 0)
14050     {
14051       errmsg ("missing addresses");
14052       return -99;
14053     }
14054
14055   M (WANT_IP6_ND_EVENTS, mp);
14056   mp->enable_disable = enable_disable;
14057   mp->pid = htonl (getpid ());
14058   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14059
14060   S (mp);
14061   W (ret);
14062   return ret;
14063 }
14064
14065 static int
14066 api_want_l2_macs_events (vat_main_t * vam)
14067 {
14068   unformat_input_t *line_input = vam->input;
14069   vl_api_want_l2_macs_events_t *mp;
14070   u8 enable_disable = 1;
14071   u32 scan_delay = 0;
14072   u32 max_macs_in_event = 0;
14073   u32 learn_limit = 0;
14074   int ret;
14075
14076   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14077     {
14078       if (unformat (line_input, "learn-limit %d", &learn_limit))
14079         ;
14080       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14081         ;
14082       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14083         ;
14084       else if (unformat (line_input, "disable"))
14085         enable_disable = 0;
14086       else
14087         break;
14088     }
14089
14090   M (WANT_L2_MACS_EVENTS, mp);
14091   mp->enable_disable = enable_disable;
14092   mp->pid = htonl (getpid ());
14093   mp->learn_limit = htonl (learn_limit);
14094   mp->scan_delay = (u8) scan_delay;
14095   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14096   S (mp);
14097   W (ret);
14098   return ret;
14099 }
14100
14101 static int
14102 api_input_acl_set_interface (vat_main_t * vam)
14103 {
14104   unformat_input_t *i = vam->input;
14105   vl_api_input_acl_set_interface_t *mp;
14106   u32 sw_if_index;
14107   int sw_if_index_set;
14108   u32 ip4_table_index = ~0;
14109   u32 ip6_table_index = ~0;
14110   u32 l2_table_index = ~0;
14111   u8 is_add = 1;
14112   int ret;
14113
14114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14115     {
14116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14117         sw_if_index_set = 1;
14118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14119         sw_if_index_set = 1;
14120       else if (unformat (i, "del"))
14121         is_add = 0;
14122       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14123         ;
14124       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14125         ;
14126       else if (unformat (i, "l2-table %d", &l2_table_index))
14127         ;
14128       else
14129         {
14130           clib_warning ("parse error '%U'", format_unformat_error, i);
14131           return -99;
14132         }
14133     }
14134
14135   if (sw_if_index_set == 0)
14136     {
14137       errmsg ("missing interface name or sw_if_index");
14138       return -99;
14139     }
14140
14141   M (INPUT_ACL_SET_INTERFACE, mp);
14142
14143   mp->sw_if_index = ntohl (sw_if_index);
14144   mp->ip4_table_index = ntohl (ip4_table_index);
14145   mp->ip6_table_index = ntohl (ip6_table_index);
14146   mp->l2_table_index = ntohl (l2_table_index);
14147   mp->is_add = is_add;
14148
14149   S (mp);
14150   W (ret);
14151   return ret;
14152 }
14153
14154 static int
14155 api_ip_address_dump (vat_main_t * vam)
14156 {
14157   unformat_input_t *i = vam->input;
14158   vl_api_ip_address_dump_t *mp;
14159   vl_api_control_ping_t *mp_ping;
14160   u32 sw_if_index = ~0;
14161   u8 sw_if_index_set = 0;
14162   u8 ipv4_set = 0;
14163   u8 ipv6_set = 0;
14164   int ret;
14165
14166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14167     {
14168       if (unformat (i, "sw_if_index %d", &sw_if_index))
14169         sw_if_index_set = 1;
14170       else
14171         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14172         sw_if_index_set = 1;
14173       else if (unformat (i, "ipv4"))
14174         ipv4_set = 1;
14175       else if (unformat (i, "ipv6"))
14176         ipv6_set = 1;
14177       else
14178         break;
14179     }
14180
14181   if (ipv4_set && ipv6_set)
14182     {
14183       errmsg ("ipv4 and ipv6 flags cannot be both set");
14184       return -99;
14185     }
14186
14187   if ((!ipv4_set) && (!ipv6_set))
14188     {
14189       errmsg ("no ipv4 nor ipv6 flag set");
14190       return -99;
14191     }
14192
14193   if (sw_if_index_set == 0)
14194     {
14195       errmsg ("missing interface name or sw_if_index");
14196       return -99;
14197     }
14198
14199   vam->current_sw_if_index = sw_if_index;
14200   vam->is_ipv6 = ipv6_set;
14201
14202   M (IP_ADDRESS_DUMP, mp);
14203   mp->sw_if_index = ntohl (sw_if_index);
14204   mp->is_ipv6 = ipv6_set;
14205   S (mp);
14206
14207   /* Use a control ping for synchronization */
14208   MPING (CONTROL_PING, mp_ping);
14209   S (mp_ping);
14210
14211   W (ret);
14212   return ret;
14213 }
14214
14215 static int
14216 api_ip_dump (vat_main_t * vam)
14217 {
14218   vl_api_ip_dump_t *mp;
14219   vl_api_control_ping_t *mp_ping;
14220   unformat_input_t *in = vam->input;
14221   int ipv4_set = 0;
14222   int ipv6_set = 0;
14223   int is_ipv6;
14224   int i;
14225   int ret;
14226
14227   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14228     {
14229       if (unformat (in, "ipv4"))
14230         ipv4_set = 1;
14231       else if (unformat (in, "ipv6"))
14232         ipv6_set = 1;
14233       else
14234         break;
14235     }
14236
14237   if (ipv4_set && ipv6_set)
14238     {
14239       errmsg ("ipv4 and ipv6 flags cannot be both set");
14240       return -99;
14241     }
14242
14243   if ((!ipv4_set) && (!ipv6_set))
14244     {
14245       errmsg ("no ipv4 nor ipv6 flag set");
14246       return -99;
14247     }
14248
14249   is_ipv6 = ipv6_set;
14250   vam->is_ipv6 = is_ipv6;
14251
14252   /* free old data */
14253   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14254     {
14255       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14256     }
14257   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14258
14259   M (IP_DUMP, mp);
14260   mp->is_ipv6 = ipv6_set;
14261   S (mp);
14262
14263   /* Use a control ping for synchronization */
14264   MPING (CONTROL_PING, mp_ping);
14265   S (mp_ping);
14266
14267   W (ret);
14268   return ret;
14269 }
14270
14271 static int
14272 api_ipsec_spd_add_del (vat_main_t * vam)
14273 {
14274   unformat_input_t *i = vam->input;
14275   vl_api_ipsec_spd_add_del_t *mp;
14276   u32 spd_id = ~0;
14277   u8 is_add = 1;
14278   int ret;
14279
14280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14281     {
14282       if (unformat (i, "spd_id %d", &spd_id))
14283         ;
14284       else if (unformat (i, "del"))
14285         is_add = 0;
14286       else
14287         {
14288           clib_warning ("parse error '%U'", format_unformat_error, i);
14289           return -99;
14290         }
14291     }
14292   if (spd_id == ~0)
14293     {
14294       errmsg ("spd_id must be set");
14295       return -99;
14296     }
14297
14298   M (IPSEC_SPD_ADD_DEL, mp);
14299
14300   mp->spd_id = ntohl (spd_id);
14301   mp->is_add = is_add;
14302
14303   S (mp);
14304   W (ret);
14305   return ret;
14306 }
14307
14308 static int
14309 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14310 {
14311   unformat_input_t *i = vam->input;
14312   vl_api_ipsec_interface_add_del_spd_t *mp;
14313   u32 sw_if_index;
14314   u8 sw_if_index_set = 0;
14315   u32 spd_id = (u32) ~ 0;
14316   u8 is_add = 1;
14317   int ret;
14318
14319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14320     {
14321       if (unformat (i, "del"))
14322         is_add = 0;
14323       else if (unformat (i, "spd_id %d", &spd_id))
14324         ;
14325       else
14326         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14327         sw_if_index_set = 1;
14328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14329         sw_if_index_set = 1;
14330       else
14331         {
14332           clib_warning ("parse error '%U'", format_unformat_error, i);
14333           return -99;
14334         }
14335
14336     }
14337
14338   if (spd_id == (u32) ~ 0)
14339     {
14340       errmsg ("spd_id must be set");
14341       return -99;
14342     }
14343
14344   if (sw_if_index_set == 0)
14345     {
14346       errmsg ("missing interface name or sw_if_index");
14347       return -99;
14348     }
14349
14350   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14351
14352   mp->spd_id = ntohl (spd_id);
14353   mp->sw_if_index = ntohl (sw_if_index);
14354   mp->is_add = is_add;
14355
14356   S (mp);
14357   W (ret);
14358   return ret;
14359 }
14360
14361 static int
14362 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14363 {
14364   unformat_input_t *i = vam->input;
14365   vl_api_ipsec_spd_add_del_entry_t *mp;
14366   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14367   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14368   i32 priority = 0;
14369   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14370   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14371   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14372   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14373   int ret;
14374
14375   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14376   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14377   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14378   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14379   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14380   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14381
14382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14383     {
14384       if (unformat (i, "del"))
14385         is_add = 0;
14386       if (unformat (i, "outbound"))
14387         is_outbound = 1;
14388       if (unformat (i, "inbound"))
14389         is_outbound = 0;
14390       else if (unformat (i, "spd_id %d", &spd_id))
14391         ;
14392       else if (unformat (i, "sa_id %d", &sa_id))
14393         ;
14394       else if (unformat (i, "priority %d", &priority))
14395         ;
14396       else if (unformat (i, "protocol %d", &protocol))
14397         ;
14398       else if (unformat (i, "lport_start %d", &lport_start))
14399         ;
14400       else if (unformat (i, "lport_stop %d", &lport_stop))
14401         ;
14402       else if (unformat (i, "rport_start %d", &rport_start))
14403         ;
14404       else if (unformat (i, "rport_stop %d", &rport_stop))
14405         ;
14406       else
14407         if (unformat
14408             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14409         {
14410           is_ipv6 = 0;
14411           is_ip_any = 0;
14412         }
14413       else
14414         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14415         {
14416           is_ipv6 = 0;
14417           is_ip_any = 0;
14418         }
14419       else
14420         if (unformat
14421             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14422         {
14423           is_ipv6 = 0;
14424           is_ip_any = 0;
14425         }
14426       else
14427         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14428         {
14429           is_ipv6 = 0;
14430           is_ip_any = 0;
14431         }
14432       else
14433         if (unformat
14434             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14435         {
14436           is_ipv6 = 1;
14437           is_ip_any = 0;
14438         }
14439       else
14440         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14441         {
14442           is_ipv6 = 1;
14443           is_ip_any = 0;
14444         }
14445       else
14446         if (unformat
14447             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14448         {
14449           is_ipv6 = 1;
14450           is_ip_any = 0;
14451         }
14452       else
14453         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14454         {
14455           is_ipv6 = 1;
14456           is_ip_any = 0;
14457         }
14458       else
14459         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14460         {
14461           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14462             {
14463               clib_warning ("unsupported action: 'resolve'");
14464               return -99;
14465             }
14466         }
14467       else
14468         {
14469           clib_warning ("parse error '%U'", format_unformat_error, i);
14470           return -99;
14471         }
14472
14473     }
14474
14475   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14476
14477   mp->spd_id = ntohl (spd_id);
14478   mp->priority = ntohl (priority);
14479   mp->is_outbound = is_outbound;
14480
14481   mp->is_ipv6 = is_ipv6;
14482   if (is_ipv6 || is_ip_any)
14483     {
14484       clib_memcpy (mp->remote_address_start, &raddr6_start,
14485                    sizeof (ip6_address_t));
14486       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14487                    sizeof (ip6_address_t));
14488       clib_memcpy (mp->local_address_start, &laddr6_start,
14489                    sizeof (ip6_address_t));
14490       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14491                    sizeof (ip6_address_t));
14492     }
14493   else
14494     {
14495       clib_memcpy (mp->remote_address_start, &raddr4_start,
14496                    sizeof (ip4_address_t));
14497       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14498                    sizeof (ip4_address_t));
14499       clib_memcpy (mp->local_address_start, &laddr4_start,
14500                    sizeof (ip4_address_t));
14501       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14502                    sizeof (ip4_address_t));
14503     }
14504   mp->protocol = (u8) protocol;
14505   mp->local_port_start = ntohs ((u16) lport_start);
14506   mp->local_port_stop = ntohs ((u16) lport_stop);
14507   mp->remote_port_start = ntohs ((u16) rport_start);
14508   mp->remote_port_stop = ntohs ((u16) rport_stop);
14509   mp->policy = (u8) policy;
14510   mp->sa_id = ntohl (sa_id);
14511   mp->is_add = is_add;
14512   mp->is_ip_any = is_ip_any;
14513   S (mp);
14514   W (ret);
14515   return ret;
14516 }
14517
14518 static int
14519 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14520 {
14521   unformat_input_t *i = vam->input;
14522   vl_api_ipsec_sad_add_del_entry_t *mp;
14523   u32 sad_id = 0, spi = 0;
14524   u8 *ck = 0, *ik = 0;
14525   u8 is_add = 1;
14526
14527   u8 protocol = IPSEC_PROTOCOL_AH;
14528   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14529   u32 crypto_alg = 0, integ_alg = 0;
14530   ip4_address_t tun_src4;
14531   ip4_address_t tun_dst4;
14532   ip6_address_t tun_src6;
14533   ip6_address_t tun_dst6;
14534   int ret;
14535
14536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14537     {
14538       if (unformat (i, "del"))
14539         is_add = 0;
14540       else if (unformat (i, "sad_id %d", &sad_id))
14541         ;
14542       else if (unformat (i, "spi %d", &spi))
14543         ;
14544       else if (unformat (i, "esp"))
14545         protocol = IPSEC_PROTOCOL_ESP;
14546       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14547         {
14548           is_tunnel = 1;
14549           is_tunnel_ipv6 = 0;
14550         }
14551       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14552         {
14553           is_tunnel = 1;
14554           is_tunnel_ipv6 = 0;
14555         }
14556       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14557         {
14558           is_tunnel = 1;
14559           is_tunnel_ipv6 = 1;
14560         }
14561       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14562         {
14563           is_tunnel = 1;
14564           is_tunnel_ipv6 = 1;
14565         }
14566       else
14567         if (unformat
14568             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14569         {
14570           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14571               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14572             {
14573               clib_warning ("unsupported crypto-alg: '%U'",
14574                             format_ipsec_crypto_alg, crypto_alg);
14575               return -99;
14576             }
14577         }
14578       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14579         ;
14580       else
14581         if (unformat
14582             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14583         {
14584           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14585               integ_alg >= IPSEC_INTEG_N_ALG)
14586             {
14587               clib_warning ("unsupported integ-alg: '%U'",
14588                             format_ipsec_integ_alg, integ_alg);
14589               return -99;
14590             }
14591         }
14592       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14593         ;
14594       else
14595         {
14596           clib_warning ("parse error '%U'", format_unformat_error, i);
14597           return -99;
14598         }
14599
14600     }
14601
14602   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14603
14604   mp->sad_id = ntohl (sad_id);
14605   mp->is_add = is_add;
14606   mp->protocol = protocol;
14607   mp->spi = ntohl (spi);
14608   mp->is_tunnel = is_tunnel;
14609   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14610   mp->crypto_algorithm = crypto_alg;
14611   mp->integrity_algorithm = integ_alg;
14612   mp->crypto_key_length = vec_len (ck);
14613   mp->integrity_key_length = vec_len (ik);
14614
14615   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14616     mp->crypto_key_length = sizeof (mp->crypto_key);
14617
14618   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14619     mp->integrity_key_length = sizeof (mp->integrity_key);
14620
14621   if (ck)
14622     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14623   if (ik)
14624     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14625
14626   if (is_tunnel)
14627     {
14628       if (is_tunnel_ipv6)
14629         {
14630           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14631                        sizeof (ip6_address_t));
14632           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14633                        sizeof (ip6_address_t));
14634         }
14635       else
14636         {
14637           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14638                        sizeof (ip4_address_t));
14639           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14640                        sizeof (ip4_address_t));
14641         }
14642     }
14643
14644   S (mp);
14645   W (ret);
14646   return ret;
14647 }
14648
14649 static int
14650 api_ipsec_sa_set_key (vat_main_t * vam)
14651 {
14652   unformat_input_t *i = vam->input;
14653   vl_api_ipsec_sa_set_key_t *mp;
14654   u32 sa_id;
14655   u8 *ck = 0, *ik = 0;
14656   int ret;
14657
14658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14659     {
14660       if (unformat (i, "sa_id %d", &sa_id))
14661         ;
14662       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14663         ;
14664       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14665         ;
14666       else
14667         {
14668           clib_warning ("parse error '%U'", format_unformat_error, i);
14669           return -99;
14670         }
14671     }
14672
14673   M (IPSEC_SA_SET_KEY, mp);
14674
14675   mp->sa_id = ntohl (sa_id);
14676   mp->crypto_key_length = vec_len (ck);
14677   mp->integrity_key_length = vec_len (ik);
14678
14679   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14680     mp->crypto_key_length = sizeof (mp->crypto_key);
14681
14682   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14683     mp->integrity_key_length = sizeof (mp->integrity_key);
14684
14685   if (ck)
14686     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14687   if (ik)
14688     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14689
14690   S (mp);
14691   W (ret);
14692   return ret;
14693 }
14694
14695 static int
14696 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14697 {
14698   unformat_input_t *i = vam->input;
14699   vl_api_ipsec_tunnel_if_add_del_t *mp;
14700   u32 local_spi = 0, remote_spi = 0;
14701   u32 crypto_alg = 0, integ_alg = 0;
14702   u8 *lck = NULL, *rck = NULL;
14703   u8 *lik = NULL, *rik = NULL;
14704   ip4_address_t local_ip = { {0} };
14705   ip4_address_t remote_ip = { {0} };
14706   u8 is_add = 1;
14707   u8 esn = 0;
14708   u8 anti_replay = 0;
14709   int ret;
14710
14711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14712     {
14713       if (unformat (i, "del"))
14714         is_add = 0;
14715       else if (unformat (i, "esn"))
14716         esn = 1;
14717       else if (unformat (i, "anti_replay"))
14718         anti_replay = 1;
14719       else if (unformat (i, "local_spi %d", &local_spi))
14720         ;
14721       else if (unformat (i, "remote_spi %d", &remote_spi))
14722         ;
14723       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14724         ;
14725       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14726         ;
14727       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14728         ;
14729       else
14730         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14731         ;
14732       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14733         ;
14734       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14735         ;
14736       else
14737         if (unformat
14738             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14739         {
14740           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14741               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14742             {
14743               errmsg ("unsupported crypto-alg: '%U'\n",
14744                       format_ipsec_crypto_alg, crypto_alg);
14745               return -99;
14746             }
14747         }
14748       else
14749         if (unformat
14750             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14751         {
14752           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14753               integ_alg >= IPSEC_INTEG_N_ALG)
14754             {
14755               errmsg ("unsupported integ-alg: '%U'\n",
14756                       format_ipsec_integ_alg, integ_alg);
14757               return -99;
14758             }
14759         }
14760       else
14761         {
14762           errmsg ("parse error '%U'\n", format_unformat_error, i);
14763           return -99;
14764         }
14765     }
14766
14767   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14768
14769   mp->is_add = is_add;
14770   mp->esn = esn;
14771   mp->anti_replay = anti_replay;
14772
14773   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14774   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14775
14776   mp->local_spi = htonl (local_spi);
14777   mp->remote_spi = htonl (remote_spi);
14778   mp->crypto_alg = (u8) crypto_alg;
14779
14780   mp->local_crypto_key_len = 0;
14781   if (lck)
14782     {
14783       mp->local_crypto_key_len = vec_len (lck);
14784       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14785         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14786       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14787     }
14788
14789   mp->remote_crypto_key_len = 0;
14790   if (rck)
14791     {
14792       mp->remote_crypto_key_len = vec_len (rck);
14793       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14794         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14795       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14796     }
14797
14798   mp->integ_alg = (u8) integ_alg;
14799
14800   mp->local_integ_key_len = 0;
14801   if (lik)
14802     {
14803       mp->local_integ_key_len = vec_len (lik);
14804       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14805         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14806       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14807     }
14808
14809   mp->remote_integ_key_len = 0;
14810   if (rik)
14811     {
14812       mp->remote_integ_key_len = vec_len (rik);
14813       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14814         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14815       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14816     }
14817
14818   S (mp);
14819   W (ret);
14820   return ret;
14821 }
14822
14823 static void
14824 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14825 {
14826   vat_main_t *vam = &vat_main;
14827
14828   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14829          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14830          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14831          "tunnel_src_addr %U tunnel_dst_addr %U "
14832          "salt %u seq_outbound %lu last_seq_inbound %lu "
14833          "replay_window %lu total_data_size %lu\n",
14834          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14835          mp->protocol,
14836          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14837          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14838          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14839          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14840          mp->tunnel_src_addr,
14841          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14842          mp->tunnel_dst_addr,
14843          ntohl (mp->salt),
14844          clib_net_to_host_u64 (mp->seq_outbound),
14845          clib_net_to_host_u64 (mp->last_seq_inbound),
14846          clib_net_to_host_u64 (mp->replay_window),
14847          clib_net_to_host_u64 (mp->total_data_size));
14848 }
14849
14850 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14851 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14852
14853 static void vl_api_ipsec_sa_details_t_handler_json
14854   (vl_api_ipsec_sa_details_t * mp)
14855 {
14856   vat_main_t *vam = &vat_main;
14857   vat_json_node_t *node = NULL;
14858   struct in_addr src_ip4, dst_ip4;
14859   struct in6_addr src_ip6, dst_ip6;
14860
14861   if (VAT_JSON_ARRAY != vam->json_tree.type)
14862     {
14863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14864       vat_json_init_array (&vam->json_tree);
14865     }
14866   node = vat_json_array_add (&vam->json_tree);
14867
14868   vat_json_init_object (node);
14869   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14870   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14871   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14872   vat_json_object_add_uint (node, "proto", mp->protocol);
14873   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14874   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14875   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14876   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14877   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14878   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14879   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14880                              mp->crypto_key_len);
14881   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14882                              mp->integ_key_len);
14883   if (mp->is_tunnel_ip6)
14884     {
14885       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14886       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14887       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14888       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14889     }
14890   else
14891     {
14892       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14893       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14894       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14895       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14896     }
14897   vat_json_object_add_uint (node, "replay_window",
14898                             clib_net_to_host_u64 (mp->replay_window));
14899   vat_json_object_add_uint (node, "total_data_size",
14900                             clib_net_to_host_u64 (mp->total_data_size));
14901
14902 }
14903
14904 static int
14905 api_ipsec_sa_dump (vat_main_t * vam)
14906 {
14907   unformat_input_t *i = vam->input;
14908   vl_api_ipsec_sa_dump_t *mp;
14909   vl_api_control_ping_t *mp_ping;
14910   u32 sa_id = ~0;
14911   int ret;
14912
14913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14914     {
14915       if (unformat (i, "sa_id %d", &sa_id))
14916         ;
14917       else
14918         {
14919           clib_warning ("parse error '%U'", format_unformat_error, i);
14920           return -99;
14921         }
14922     }
14923
14924   M (IPSEC_SA_DUMP, mp);
14925
14926   mp->sa_id = ntohl (sa_id);
14927
14928   S (mp);
14929
14930   /* Use a control ping for synchronization */
14931   M (CONTROL_PING, mp_ping);
14932   S (mp_ping);
14933
14934   W (ret);
14935   return ret;
14936 }
14937
14938 static int
14939 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14940 {
14941   unformat_input_t *i = vam->input;
14942   vl_api_ipsec_tunnel_if_set_key_t *mp;
14943   u32 sw_if_index = ~0;
14944   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14945   u8 *key = 0;
14946   u32 alg = ~0;
14947   int ret;
14948
14949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14950     {
14951       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14952         ;
14953       else
14954         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14955         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14956       else
14957         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14958         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14959       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14960         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14961       else
14962         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14963         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14964       else if (unformat (i, "%U", unformat_hex_string, &key))
14965         ;
14966       else
14967         {
14968           clib_warning ("parse error '%U'", format_unformat_error, i);
14969           return -99;
14970         }
14971     }
14972
14973   if (sw_if_index == ~0)
14974     {
14975       errmsg ("interface must be specified");
14976       return -99;
14977     }
14978
14979   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14980     {
14981       errmsg ("key type must be specified");
14982       return -99;
14983     }
14984
14985   if (alg == ~0)
14986     {
14987       errmsg ("algorithm must be specified");
14988       return -99;
14989     }
14990
14991   if (vec_len (key) == 0)
14992     {
14993       errmsg ("key must be specified");
14994       return -99;
14995     }
14996
14997   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14998
14999   mp->sw_if_index = htonl (sw_if_index);
15000   mp->alg = alg;
15001   mp->key_type = key_type;
15002   mp->key_len = vec_len (key);
15003   clib_memcpy (mp->key, key, vec_len (key));
15004
15005   S (mp);
15006   W (ret);
15007
15008   return ret;
15009 }
15010
15011 static int
15012 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15013 {
15014   unformat_input_t *i = vam->input;
15015   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15016   u32 sw_if_index = ~0;
15017   u32 sa_id = ~0;
15018   u8 is_outbound = (u8) ~ 0;
15019   int ret;
15020
15021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15024         ;
15025       else if (unformat (i, "sa_id %d", &sa_id))
15026         ;
15027       else if (unformat (i, "outbound"))
15028         is_outbound = 1;
15029       else if (unformat (i, "inbound"))
15030         is_outbound = 0;
15031       else
15032         {
15033           clib_warning ("parse error '%U'", format_unformat_error, i);
15034           return -99;
15035         }
15036     }
15037
15038   if (sw_if_index == ~0)
15039     {
15040       errmsg ("interface must be specified");
15041       return -99;
15042     }
15043
15044   if (sa_id == ~0)
15045     {
15046       errmsg ("SA ID must be specified");
15047       return -99;
15048     }
15049
15050   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15051
15052   mp->sw_if_index = htonl (sw_if_index);
15053   mp->sa_id = htonl (sa_id);
15054   mp->is_outbound = is_outbound;
15055
15056   S (mp);
15057   W (ret);
15058
15059   return ret;
15060 }
15061
15062 static int
15063 api_ikev2_profile_add_del (vat_main_t * vam)
15064 {
15065   unformat_input_t *i = vam->input;
15066   vl_api_ikev2_profile_add_del_t *mp;
15067   u8 is_add = 1;
15068   u8 *name = 0;
15069   int ret;
15070
15071   const char *valid_chars = "a-zA-Z0-9_";
15072
15073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15074     {
15075       if (unformat (i, "del"))
15076         is_add = 0;
15077       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15078         vec_add1 (name, 0);
15079       else
15080         {
15081           errmsg ("parse error '%U'", format_unformat_error, i);
15082           return -99;
15083         }
15084     }
15085
15086   if (!vec_len (name))
15087     {
15088       errmsg ("profile name must be specified");
15089       return -99;
15090     }
15091
15092   if (vec_len (name) > 64)
15093     {
15094       errmsg ("profile name too long");
15095       return -99;
15096     }
15097
15098   M (IKEV2_PROFILE_ADD_DEL, mp);
15099
15100   clib_memcpy (mp->name, name, vec_len (name));
15101   mp->is_add = is_add;
15102   vec_free (name);
15103
15104   S (mp);
15105   W (ret);
15106   return ret;
15107 }
15108
15109 static int
15110 api_ikev2_profile_set_auth (vat_main_t * vam)
15111 {
15112   unformat_input_t *i = vam->input;
15113   vl_api_ikev2_profile_set_auth_t *mp;
15114   u8 *name = 0;
15115   u8 *data = 0;
15116   u32 auth_method = 0;
15117   u8 is_hex = 0;
15118   int ret;
15119
15120   const char *valid_chars = "a-zA-Z0-9_";
15121
15122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15123     {
15124       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15125         vec_add1 (name, 0);
15126       else if (unformat (i, "auth_method %U",
15127                          unformat_ikev2_auth_method, &auth_method))
15128         ;
15129       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15130         is_hex = 1;
15131       else if (unformat (i, "auth_data %v", &data))
15132         ;
15133       else
15134         {
15135           errmsg ("parse error '%U'", format_unformat_error, i);
15136           return -99;
15137         }
15138     }
15139
15140   if (!vec_len (name))
15141     {
15142       errmsg ("profile name must be specified");
15143       return -99;
15144     }
15145
15146   if (vec_len (name) > 64)
15147     {
15148       errmsg ("profile name too long");
15149       return -99;
15150     }
15151
15152   if (!vec_len (data))
15153     {
15154       errmsg ("auth_data must be specified");
15155       return -99;
15156     }
15157
15158   if (!auth_method)
15159     {
15160       errmsg ("auth_method must be specified");
15161       return -99;
15162     }
15163
15164   M (IKEV2_PROFILE_SET_AUTH, mp);
15165
15166   mp->is_hex = is_hex;
15167   mp->auth_method = (u8) auth_method;
15168   mp->data_len = vec_len (data);
15169   clib_memcpy (mp->name, name, vec_len (name));
15170   clib_memcpy (mp->data, data, vec_len (data));
15171   vec_free (name);
15172   vec_free (data);
15173
15174   S (mp);
15175   W (ret);
15176   return ret;
15177 }
15178
15179 static int
15180 api_ikev2_profile_set_id (vat_main_t * vam)
15181 {
15182   unformat_input_t *i = vam->input;
15183   vl_api_ikev2_profile_set_id_t *mp;
15184   u8 *name = 0;
15185   u8 *data = 0;
15186   u8 is_local = 0;
15187   u32 id_type = 0;
15188   ip4_address_t ip4;
15189   int ret;
15190
15191   const char *valid_chars = "a-zA-Z0-9_";
15192
15193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15194     {
15195       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15196         vec_add1 (name, 0);
15197       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15198         ;
15199       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15200         {
15201           data = vec_new (u8, 4);
15202           clib_memcpy (data, ip4.as_u8, 4);
15203         }
15204       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15205         ;
15206       else if (unformat (i, "id_data %v", &data))
15207         ;
15208       else if (unformat (i, "local"))
15209         is_local = 1;
15210       else if (unformat (i, "remote"))
15211         is_local = 0;
15212       else
15213         {
15214           errmsg ("parse error '%U'", format_unformat_error, i);
15215           return -99;
15216         }
15217     }
15218
15219   if (!vec_len (name))
15220     {
15221       errmsg ("profile name must be specified");
15222       return -99;
15223     }
15224
15225   if (vec_len (name) > 64)
15226     {
15227       errmsg ("profile name too long");
15228       return -99;
15229     }
15230
15231   if (!vec_len (data))
15232     {
15233       errmsg ("id_data must be specified");
15234       return -99;
15235     }
15236
15237   if (!id_type)
15238     {
15239       errmsg ("id_type must be specified");
15240       return -99;
15241     }
15242
15243   M (IKEV2_PROFILE_SET_ID, mp);
15244
15245   mp->is_local = is_local;
15246   mp->id_type = (u8) id_type;
15247   mp->data_len = vec_len (data);
15248   clib_memcpy (mp->name, name, vec_len (name));
15249   clib_memcpy (mp->data, data, vec_len (data));
15250   vec_free (name);
15251   vec_free (data);
15252
15253   S (mp);
15254   W (ret);
15255   return ret;
15256 }
15257
15258 static int
15259 api_ikev2_profile_set_ts (vat_main_t * vam)
15260 {
15261   unformat_input_t *i = vam->input;
15262   vl_api_ikev2_profile_set_ts_t *mp;
15263   u8 *name = 0;
15264   u8 is_local = 0;
15265   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15266   ip4_address_t start_addr, end_addr;
15267
15268   const char *valid_chars = "a-zA-Z0-9_";
15269   int ret;
15270
15271   start_addr.as_u32 = 0;
15272   end_addr.as_u32 = (u32) ~ 0;
15273
15274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15275     {
15276       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15277         vec_add1 (name, 0);
15278       else if (unformat (i, "protocol %d", &proto))
15279         ;
15280       else if (unformat (i, "start_port %d", &start_port))
15281         ;
15282       else if (unformat (i, "end_port %d", &end_port))
15283         ;
15284       else
15285         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15286         ;
15287       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15288         ;
15289       else if (unformat (i, "local"))
15290         is_local = 1;
15291       else if (unformat (i, "remote"))
15292         is_local = 0;
15293       else
15294         {
15295           errmsg ("parse error '%U'", format_unformat_error, i);
15296           return -99;
15297         }
15298     }
15299
15300   if (!vec_len (name))
15301     {
15302       errmsg ("profile name must be specified");
15303       return -99;
15304     }
15305
15306   if (vec_len (name) > 64)
15307     {
15308       errmsg ("profile name too long");
15309       return -99;
15310     }
15311
15312   M (IKEV2_PROFILE_SET_TS, mp);
15313
15314   mp->is_local = is_local;
15315   mp->proto = (u8) proto;
15316   mp->start_port = (u16) start_port;
15317   mp->end_port = (u16) end_port;
15318   mp->start_addr = start_addr.as_u32;
15319   mp->end_addr = end_addr.as_u32;
15320   clib_memcpy (mp->name, name, vec_len (name));
15321   vec_free (name);
15322
15323   S (mp);
15324   W (ret);
15325   return ret;
15326 }
15327
15328 static int
15329 api_ikev2_set_local_key (vat_main_t * vam)
15330 {
15331   unformat_input_t *i = vam->input;
15332   vl_api_ikev2_set_local_key_t *mp;
15333   u8 *file = 0;
15334   int ret;
15335
15336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15337     {
15338       if (unformat (i, "file %v", &file))
15339         vec_add1 (file, 0);
15340       else
15341         {
15342           errmsg ("parse error '%U'", format_unformat_error, i);
15343           return -99;
15344         }
15345     }
15346
15347   if (!vec_len (file))
15348     {
15349       errmsg ("RSA key file must be specified");
15350       return -99;
15351     }
15352
15353   if (vec_len (file) > 256)
15354     {
15355       errmsg ("file name too long");
15356       return -99;
15357     }
15358
15359   M (IKEV2_SET_LOCAL_KEY, mp);
15360
15361   clib_memcpy (mp->key_file, file, vec_len (file));
15362   vec_free (file);
15363
15364   S (mp);
15365   W (ret);
15366   return ret;
15367 }
15368
15369 static int
15370 api_ikev2_set_responder (vat_main_t * vam)
15371 {
15372   unformat_input_t *i = vam->input;
15373   vl_api_ikev2_set_responder_t *mp;
15374   int ret;
15375   u8 *name = 0;
15376   u32 sw_if_index = ~0;
15377   ip4_address_t address;
15378
15379   const char *valid_chars = "a-zA-Z0-9_";
15380
15381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15382     {
15383       if (unformat
15384           (i, "%U interface %d address %U", unformat_token, valid_chars,
15385            &name, &sw_if_index, unformat_ip4_address, &address))
15386         vec_add1 (name, 0);
15387       else
15388         {
15389           errmsg ("parse error '%U'", format_unformat_error, i);
15390           return -99;
15391         }
15392     }
15393
15394   if (!vec_len (name))
15395     {
15396       errmsg ("profile name must be specified");
15397       return -99;
15398     }
15399
15400   if (vec_len (name) > 64)
15401     {
15402       errmsg ("profile name too long");
15403       return -99;
15404     }
15405
15406   M (IKEV2_SET_RESPONDER, mp);
15407
15408   clib_memcpy (mp->name, name, vec_len (name));
15409   vec_free (name);
15410
15411   mp->sw_if_index = sw_if_index;
15412   clib_memcpy (mp->address, &address, sizeof (address));
15413
15414   S (mp);
15415   W (ret);
15416   return ret;
15417 }
15418
15419 static int
15420 api_ikev2_set_ike_transforms (vat_main_t * vam)
15421 {
15422   unformat_input_t *i = vam->input;
15423   vl_api_ikev2_set_ike_transforms_t *mp;
15424   int ret;
15425   u8 *name = 0;
15426   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15427
15428   const char *valid_chars = "a-zA-Z0-9_";
15429
15430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15431     {
15432       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15433                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15434         vec_add1 (name, 0);
15435       else
15436         {
15437           errmsg ("parse error '%U'", format_unformat_error, i);
15438           return -99;
15439         }
15440     }
15441
15442   if (!vec_len (name))
15443     {
15444       errmsg ("profile name must be specified");
15445       return -99;
15446     }
15447
15448   if (vec_len (name) > 64)
15449     {
15450       errmsg ("profile name too long");
15451       return -99;
15452     }
15453
15454   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15455
15456   clib_memcpy (mp->name, name, vec_len (name));
15457   vec_free (name);
15458   mp->crypto_alg = crypto_alg;
15459   mp->crypto_key_size = crypto_key_size;
15460   mp->integ_alg = integ_alg;
15461   mp->dh_group = dh_group;
15462
15463   S (mp);
15464   W (ret);
15465   return ret;
15466 }
15467
15468
15469 static int
15470 api_ikev2_set_esp_transforms (vat_main_t * vam)
15471 {
15472   unformat_input_t *i = vam->input;
15473   vl_api_ikev2_set_esp_transforms_t *mp;
15474   int ret;
15475   u8 *name = 0;
15476   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15477
15478   const char *valid_chars = "a-zA-Z0-9_";
15479
15480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15481     {
15482       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15483                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15484         vec_add1 (name, 0);
15485       else
15486         {
15487           errmsg ("parse error '%U'", format_unformat_error, i);
15488           return -99;
15489         }
15490     }
15491
15492   if (!vec_len (name))
15493     {
15494       errmsg ("profile name must be specified");
15495       return -99;
15496     }
15497
15498   if (vec_len (name) > 64)
15499     {
15500       errmsg ("profile name too long");
15501       return -99;
15502     }
15503
15504   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15505
15506   clib_memcpy (mp->name, name, vec_len (name));
15507   vec_free (name);
15508   mp->crypto_alg = crypto_alg;
15509   mp->crypto_key_size = crypto_key_size;
15510   mp->integ_alg = integ_alg;
15511   mp->dh_group = dh_group;
15512
15513   S (mp);
15514   W (ret);
15515   return ret;
15516 }
15517
15518 static int
15519 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15520 {
15521   unformat_input_t *i = vam->input;
15522   vl_api_ikev2_set_sa_lifetime_t *mp;
15523   int ret;
15524   u8 *name = 0;
15525   u64 lifetime, lifetime_maxdata;
15526   u32 lifetime_jitter, handover;
15527
15528   const char *valid_chars = "a-zA-Z0-9_";
15529
15530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15531     {
15532       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15533                     &lifetime, &lifetime_jitter, &handover,
15534                     &lifetime_maxdata))
15535         vec_add1 (name, 0);
15536       else
15537         {
15538           errmsg ("parse error '%U'", format_unformat_error, i);
15539           return -99;
15540         }
15541     }
15542
15543   if (!vec_len (name))
15544     {
15545       errmsg ("profile name must be specified");
15546       return -99;
15547     }
15548
15549   if (vec_len (name) > 64)
15550     {
15551       errmsg ("profile name too long");
15552       return -99;
15553     }
15554
15555   M (IKEV2_SET_SA_LIFETIME, mp);
15556
15557   clib_memcpy (mp->name, name, vec_len (name));
15558   vec_free (name);
15559   mp->lifetime = lifetime;
15560   mp->lifetime_jitter = lifetime_jitter;
15561   mp->handover = handover;
15562   mp->lifetime_maxdata = lifetime_maxdata;
15563
15564   S (mp);
15565   W (ret);
15566   return ret;
15567 }
15568
15569 static int
15570 api_ikev2_initiate_sa_init (vat_main_t * vam)
15571 {
15572   unformat_input_t *i = vam->input;
15573   vl_api_ikev2_initiate_sa_init_t *mp;
15574   int ret;
15575   u8 *name = 0;
15576
15577   const char *valid_chars = "a-zA-Z0-9_";
15578
15579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15580     {
15581       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15582         vec_add1 (name, 0);
15583       else
15584         {
15585           errmsg ("parse error '%U'", format_unformat_error, i);
15586           return -99;
15587         }
15588     }
15589
15590   if (!vec_len (name))
15591     {
15592       errmsg ("profile name must be specified");
15593       return -99;
15594     }
15595
15596   if (vec_len (name) > 64)
15597     {
15598       errmsg ("profile name too long");
15599       return -99;
15600     }
15601
15602   M (IKEV2_INITIATE_SA_INIT, mp);
15603
15604   clib_memcpy (mp->name, name, vec_len (name));
15605   vec_free (name);
15606
15607   S (mp);
15608   W (ret);
15609   return ret;
15610 }
15611
15612 static int
15613 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15614 {
15615   unformat_input_t *i = vam->input;
15616   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15617   int ret;
15618   u64 ispi;
15619
15620
15621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15622     {
15623       if (unformat (i, "%lx", &ispi))
15624         ;
15625       else
15626         {
15627           errmsg ("parse error '%U'", format_unformat_error, i);
15628           return -99;
15629         }
15630     }
15631
15632   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15633
15634   mp->ispi = ispi;
15635
15636   S (mp);
15637   W (ret);
15638   return ret;
15639 }
15640
15641 static int
15642 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15643 {
15644   unformat_input_t *i = vam->input;
15645   vl_api_ikev2_initiate_del_child_sa_t *mp;
15646   int ret;
15647   u32 ispi;
15648
15649
15650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15651     {
15652       if (unformat (i, "%x", &ispi))
15653         ;
15654       else
15655         {
15656           errmsg ("parse error '%U'", format_unformat_error, i);
15657           return -99;
15658         }
15659     }
15660
15661   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15662
15663   mp->ispi = ispi;
15664
15665   S (mp);
15666   W (ret);
15667   return ret;
15668 }
15669
15670 static int
15671 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15672 {
15673   unformat_input_t *i = vam->input;
15674   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15675   int ret;
15676   u32 ispi;
15677
15678
15679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15680     {
15681       if (unformat (i, "%x", &ispi))
15682         ;
15683       else
15684         {
15685           errmsg ("parse error '%U'", format_unformat_error, i);
15686           return -99;
15687         }
15688     }
15689
15690   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15691
15692   mp->ispi = ispi;
15693
15694   S (mp);
15695   W (ret);
15696   return ret;
15697 }
15698
15699 /*
15700  * MAP
15701  */
15702 static int
15703 api_map_add_domain (vat_main_t * vam)
15704 {
15705   unformat_input_t *i = vam->input;
15706   vl_api_map_add_domain_t *mp;
15707
15708   ip4_address_t ip4_prefix;
15709   ip6_address_t ip6_prefix;
15710   ip6_address_t ip6_src;
15711   u32 num_m_args = 0;
15712   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15713     0, psid_length = 0;
15714   u8 is_translation = 0;
15715   u32 mtu = 0;
15716   u32 ip6_src_len = 128;
15717   int ret;
15718
15719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15720     {
15721       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15722                     &ip4_prefix, &ip4_prefix_len))
15723         num_m_args++;
15724       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15725                          &ip6_prefix, &ip6_prefix_len))
15726         num_m_args++;
15727       else
15728         if (unformat
15729             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15730              &ip6_src_len))
15731         num_m_args++;
15732       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15733         num_m_args++;
15734       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15735         num_m_args++;
15736       else if (unformat (i, "psid-offset %d", &psid_offset))
15737         num_m_args++;
15738       else if (unformat (i, "psid-len %d", &psid_length))
15739         num_m_args++;
15740       else if (unformat (i, "mtu %d", &mtu))
15741         num_m_args++;
15742       else if (unformat (i, "map-t"))
15743         is_translation = 1;
15744       else
15745         {
15746           clib_warning ("parse error '%U'", format_unformat_error, i);
15747           return -99;
15748         }
15749     }
15750
15751   if (num_m_args < 3)
15752     {
15753       errmsg ("mandatory argument(s) missing");
15754       return -99;
15755     }
15756
15757   /* Construct the API message */
15758   M (MAP_ADD_DOMAIN, mp);
15759
15760   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15761   mp->ip4_prefix_len = ip4_prefix_len;
15762
15763   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15764   mp->ip6_prefix_len = ip6_prefix_len;
15765
15766   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15767   mp->ip6_src_prefix_len = ip6_src_len;
15768
15769   mp->ea_bits_len = ea_bits_len;
15770   mp->psid_offset = psid_offset;
15771   mp->psid_length = psid_length;
15772   mp->is_translation = is_translation;
15773   mp->mtu = htons (mtu);
15774
15775   /* send it... */
15776   S (mp);
15777
15778   /* Wait for a reply, return good/bad news  */
15779   W (ret);
15780   return ret;
15781 }
15782
15783 static int
15784 api_map_del_domain (vat_main_t * vam)
15785 {
15786   unformat_input_t *i = vam->input;
15787   vl_api_map_del_domain_t *mp;
15788
15789   u32 num_m_args = 0;
15790   u32 index;
15791   int ret;
15792
15793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15794     {
15795       if (unformat (i, "index %d", &index))
15796         num_m_args++;
15797       else
15798         {
15799           clib_warning ("parse error '%U'", format_unformat_error, i);
15800           return -99;
15801         }
15802     }
15803
15804   if (num_m_args != 1)
15805     {
15806       errmsg ("mandatory argument(s) missing");
15807       return -99;
15808     }
15809
15810   /* Construct the API message */
15811   M (MAP_DEL_DOMAIN, mp);
15812
15813   mp->index = ntohl (index);
15814
15815   /* send it... */
15816   S (mp);
15817
15818   /* Wait for a reply, return good/bad news  */
15819   W (ret);
15820   return ret;
15821 }
15822
15823 static int
15824 api_map_add_del_rule (vat_main_t * vam)
15825 {
15826   unformat_input_t *i = vam->input;
15827   vl_api_map_add_del_rule_t *mp;
15828   u8 is_add = 1;
15829   ip6_address_t ip6_dst;
15830   u32 num_m_args = 0, index, psid = 0;
15831   int ret;
15832
15833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15834     {
15835       if (unformat (i, "index %d", &index))
15836         num_m_args++;
15837       else if (unformat (i, "psid %d", &psid))
15838         num_m_args++;
15839       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15840         num_m_args++;
15841       else if (unformat (i, "del"))
15842         {
15843           is_add = 0;
15844         }
15845       else
15846         {
15847           clib_warning ("parse error '%U'", format_unformat_error, i);
15848           return -99;
15849         }
15850     }
15851
15852   /* Construct the API message */
15853   M (MAP_ADD_DEL_RULE, mp);
15854
15855   mp->index = ntohl (index);
15856   mp->is_add = is_add;
15857   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15858   mp->psid = ntohs (psid);
15859
15860   /* send it... */
15861   S (mp);
15862
15863   /* Wait for a reply, return good/bad news  */
15864   W (ret);
15865   return ret;
15866 }
15867
15868 static int
15869 api_map_domain_dump (vat_main_t * vam)
15870 {
15871   vl_api_map_domain_dump_t *mp;
15872   vl_api_control_ping_t *mp_ping;
15873   int ret;
15874
15875   /* Construct the API message */
15876   M (MAP_DOMAIN_DUMP, mp);
15877
15878   /* send it... */
15879   S (mp);
15880
15881   /* Use a control ping for synchronization */
15882   MPING (CONTROL_PING, mp_ping);
15883   S (mp_ping);
15884
15885   W (ret);
15886   return ret;
15887 }
15888
15889 static int
15890 api_map_rule_dump (vat_main_t * vam)
15891 {
15892   unformat_input_t *i = vam->input;
15893   vl_api_map_rule_dump_t *mp;
15894   vl_api_control_ping_t *mp_ping;
15895   u32 domain_index = ~0;
15896   int ret;
15897
15898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15899     {
15900       if (unformat (i, "index %u", &domain_index))
15901         ;
15902       else
15903         break;
15904     }
15905
15906   if (domain_index == ~0)
15907     {
15908       clib_warning ("parse error: domain index expected");
15909       return -99;
15910     }
15911
15912   /* Construct the API message */
15913   M (MAP_RULE_DUMP, mp);
15914
15915   mp->domain_index = htonl (domain_index);
15916
15917   /* send it... */
15918   S (mp);
15919
15920   /* Use a control ping for synchronization */
15921   MPING (CONTROL_PING, mp_ping);
15922   S (mp_ping);
15923
15924   W (ret);
15925   return ret;
15926 }
15927
15928 static void vl_api_map_add_domain_reply_t_handler
15929   (vl_api_map_add_domain_reply_t * mp)
15930 {
15931   vat_main_t *vam = &vat_main;
15932   i32 retval = ntohl (mp->retval);
15933
15934   if (vam->async_mode)
15935     {
15936       vam->async_errors += (retval < 0);
15937     }
15938   else
15939     {
15940       vam->retval = retval;
15941       vam->result_ready = 1;
15942     }
15943 }
15944
15945 static void vl_api_map_add_domain_reply_t_handler_json
15946   (vl_api_map_add_domain_reply_t * mp)
15947 {
15948   vat_main_t *vam = &vat_main;
15949   vat_json_node_t node;
15950
15951   vat_json_init_object (&node);
15952   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15953   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15954
15955   vat_json_print (vam->ofp, &node);
15956   vat_json_free (&node);
15957
15958   vam->retval = ntohl (mp->retval);
15959   vam->result_ready = 1;
15960 }
15961
15962 static int
15963 api_get_first_msg_id (vat_main_t * vam)
15964 {
15965   vl_api_get_first_msg_id_t *mp;
15966   unformat_input_t *i = vam->input;
15967   u8 *name;
15968   u8 name_set = 0;
15969   int ret;
15970
15971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15972     {
15973       if (unformat (i, "client %s", &name))
15974         name_set = 1;
15975       else
15976         break;
15977     }
15978
15979   if (name_set == 0)
15980     {
15981       errmsg ("missing client name");
15982       return -99;
15983     }
15984   vec_add1 (name, 0);
15985
15986   if (vec_len (name) > 63)
15987     {
15988       errmsg ("client name too long");
15989       return -99;
15990     }
15991
15992   M (GET_FIRST_MSG_ID, mp);
15993   clib_memcpy (mp->name, name, vec_len (name));
15994   S (mp);
15995   W (ret);
15996   return ret;
15997 }
15998
15999 static int
16000 api_cop_interface_enable_disable (vat_main_t * vam)
16001 {
16002   unformat_input_t *line_input = vam->input;
16003   vl_api_cop_interface_enable_disable_t *mp;
16004   u32 sw_if_index = ~0;
16005   u8 enable_disable = 1;
16006   int ret;
16007
16008   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16009     {
16010       if (unformat (line_input, "disable"))
16011         enable_disable = 0;
16012       if (unformat (line_input, "enable"))
16013         enable_disable = 1;
16014       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16015                          vam, &sw_if_index))
16016         ;
16017       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16018         ;
16019       else
16020         break;
16021     }
16022
16023   if (sw_if_index == ~0)
16024     {
16025       errmsg ("missing interface name or sw_if_index");
16026       return -99;
16027     }
16028
16029   /* Construct the API message */
16030   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16031   mp->sw_if_index = ntohl (sw_if_index);
16032   mp->enable_disable = enable_disable;
16033
16034   /* send it... */
16035   S (mp);
16036   /* Wait for the reply */
16037   W (ret);
16038   return ret;
16039 }
16040
16041 static int
16042 api_cop_whitelist_enable_disable (vat_main_t * vam)
16043 {
16044   unformat_input_t *line_input = vam->input;
16045   vl_api_cop_whitelist_enable_disable_t *mp;
16046   u32 sw_if_index = ~0;
16047   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16048   u32 fib_id = 0;
16049   int ret;
16050
16051   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16052     {
16053       if (unformat (line_input, "ip4"))
16054         ip4 = 1;
16055       else if (unformat (line_input, "ip6"))
16056         ip6 = 1;
16057       else if (unformat (line_input, "default"))
16058         default_cop = 1;
16059       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16060                          vam, &sw_if_index))
16061         ;
16062       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16063         ;
16064       else if (unformat (line_input, "fib-id %d", &fib_id))
16065         ;
16066       else
16067         break;
16068     }
16069
16070   if (sw_if_index == ~0)
16071     {
16072       errmsg ("missing interface name or sw_if_index");
16073       return -99;
16074     }
16075
16076   /* Construct the API message */
16077   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16078   mp->sw_if_index = ntohl (sw_if_index);
16079   mp->fib_id = ntohl (fib_id);
16080   mp->ip4 = ip4;
16081   mp->ip6 = ip6;
16082   mp->default_cop = default_cop;
16083
16084   /* send it... */
16085   S (mp);
16086   /* Wait for the reply */
16087   W (ret);
16088   return ret;
16089 }
16090
16091 static int
16092 api_get_node_graph (vat_main_t * vam)
16093 {
16094   vl_api_get_node_graph_t *mp;
16095   int ret;
16096
16097   M (GET_NODE_GRAPH, mp);
16098
16099   /* send it... */
16100   S (mp);
16101   /* Wait for the reply */
16102   W (ret);
16103   return ret;
16104 }
16105
16106 /* *INDENT-OFF* */
16107 /** Used for parsing LISP eids */
16108 typedef CLIB_PACKED(struct{
16109   u8 addr[16];   /**< eid address */
16110   u32 len;       /**< prefix length if IP */
16111   u8 type;      /**< type of eid */
16112 }) lisp_eid_vat_t;
16113 /* *INDENT-ON* */
16114
16115 static uword
16116 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16117 {
16118   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16119
16120   memset (a, 0, sizeof (a[0]));
16121
16122   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16123     {
16124       a->type = 0;              /* ipv4 type */
16125     }
16126   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16127     {
16128       a->type = 1;              /* ipv6 type */
16129     }
16130   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16131     {
16132       a->type = 2;              /* mac type */
16133     }
16134   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16135     {
16136       a->type = 3;              /* NSH type */
16137       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16138       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16139     }
16140   else
16141     {
16142       return 0;
16143     }
16144
16145   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16146     {
16147       return 0;
16148     }
16149
16150   return 1;
16151 }
16152
16153 static int
16154 lisp_eid_size_vat (u8 type)
16155 {
16156   switch (type)
16157     {
16158     case 0:
16159       return 4;
16160     case 1:
16161       return 16;
16162     case 2:
16163       return 6;
16164     case 3:
16165       return 5;
16166     }
16167   return 0;
16168 }
16169
16170 static void
16171 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16172 {
16173   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16174 }
16175
16176 static int
16177 api_one_add_del_locator_set (vat_main_t * vam)
16178 {
16179   unformat_input_t *input = vam->input;
16180   vl_api_one_add_del_locator_set_t *mp;
16181   u8 is_add = 1;
16182   u8 *locator_set_name = NULL;
16183   u8 locator_set_name_set = 0;
16184   vl_api_local_locator_t locator, *locators = 0;
16185   u32 sw_if_index, priority, weight;
16186   u32 data_len = 0;
16187
16188   int ret;
16189   /* Parse args required to build the message */
16190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16191     {
16192       if (unformat (input, "del"))
16193         {
16194           is_add = 0;
16195         }
16196       else if (unformat (input, "locator-set %s", &locator_set_name))
16197         {
16198           locator_set_name_set = 1;
16199         }
16200       else if (unformat (input, "sw_if_index %u p %u w %u",
16201                          &sw_if_index, &priority, &weight))
16202         {
16203           locator.sw_if_index = htonl (sw_if_index);
16204           locator.priority = priority;
16205           locator.weight = weight;
16206           vec_add1 (locators, locator);
16207         }
16208       else
16209         if (unformat
16210             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16211              &sw_if_index, &priority, &weight))
16212         {
16213           locator.sw_if_index = htonl (sw_if_index);
16214           locator.priority = priority;
16215           locator.weight = weight;
16216           vec_add1 (locators, locator);
16217         }
16218       else
16219         break;
16220     }
16221
16222   if (locator_set_name_set == 0)
16223     {
16224       errmsg ("missing locator-set name");
16225       vec_free (locators);
16226       return -99;
16227     }
16228
16229   if (vec_len (locator_set_name) > 64)
16230     {
16231       errmsg ("locator-set name too long");
16232       vec_free (locator_set_name);
16233       vec_free (locators);
16234       return -99;
16235     }
16236   vec_add1 (locator_set_name, 0);
16237
16238   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16239
16240   /* Construct the API message */
16241   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16242
16243   mp->is_add = is_add;
16244   clib_memcpy (mp->locator_set_name, locator_set_name,
16245                vec_len (locator_set_name));
16246   vec_free (locator_set_name);
16247
16248   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16249   if (locators)
16250     clib_memcpy (mp->locators, locators, data_len);
16251   vec_free (locators);
16252
16253   /* send it... */
16254   S (mp);
16255
16256   /* Wait for a reply... */
16257   W (ret);
16258   return ret;
16259 }
16260
16261 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16262
16263 static int
16264 api_one_add_del_locator (vat_main_t * vam)
16265 {
16266   unformat_input_t *input = vam->input;
16267   vl_api_one_add_del_locator_t *mp;
16268   u32 tmp_if_index = ~0;
16269   u32 sw_if_index = ~0;
16270   u8 sw_if_index_set = 0;
16271   u8 sw_if_index_if_name_set = 0;
16272   u32 priority = ~0;
16273   u8 priority_set = 0;
16274   u32 weight = ~0;
16275   u8 weight_set = 0;
16276   u8 is_add = 1;
16277   u8 *locator_set_name = NULL;
16278   u8 locator_set_name_set = 0;
16279   int ret;
16280
16281   /* Parse args required to build the message */
16282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16283     {
16284       if (unformat (input, "del"))
16285         {
16286           is_add = 0;
16287         }
16288       else if (unformat (input, "locator-set %s", &locator_set_name))
16289         {
16290           locator_set_name_set = 1;
16291         }
16292       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16293                          &tmp_if_index))
16294         {
16295           sw_if_index_if_name_set = 1;
16296           sw_if_index = tmp_if_index;
16297         }
16298       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16299         {
16300           sw_if_index_set = 1;
16301           sw_if_index = tmp_if_index;
16302         }
16303       else if (unformat (input, "p %d", &priority))
16304         {
16305           priority_set = 1;
16306         }
16307       else if (unformat (input, "w %d", &weight))
16308         {
16309           weight_set = 1;
16310         }
16311       else
16312         break;
16313     }
16314
16315   if (locator_set_name_set == 0)
16316     {
16317       errmsg ("missing locator-set name");
16318       return -99;
16319     }
16320
16321   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16322     {
16323       errmsg ("missing sw_if_index");
16324       vec_free (locator_set_name);
16325       return -99;
16326     }
16327
16328   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16329     {
16330       errmsg ("cannot use both params interface name and sw_if_index");
16331       vec_free (locator_set_name);
16332       return -99;
16333     }
16334
16335   if (priority_set == 0)
16336     {
16337       errmsg ("missing locator-set priority");
16338       vec_free (locator_set_name);
16339       return -99;
16340     }
16341
16342   if (weight_set == 0)
16343     {
16344       errmsg ("missing locator-set weight");
16345       vec_free (locator_set_name);
16346       return -99;
16347     }
16348
16349   if (vec_len (locator_set_name) > 64)
16350     {
16351       errmsg ("locator-set name too long");
16352       vec_free (locator_set_name);
16353       return -99;
16354     }
16355   vec_add1 (locator_set_name, 0);
16356
16357   /* Construct the API message */
16358   M (ONE_ADD_DEL_LOCATOR, mp);
16359
16360   mp->is_add = is_add;
16361   mp->sw_if_index = ntohl (sw_if_index);
16362   mp->priority = priority;
16363   mp->weight = weight;
16364   clib_memcpy (mp->locator_set_name, locator_set_name,
16365                vec_len (locator_set_name));
16366   vec_free (locator_set_name);
16367
16368   /* send it... */
16369   S (mp);
16370
16371   /* Wait for a reply... */
16372   W (ret);
16373   return ret;
16374 }
16375
16376 #define api_lisp_add_del_locator api_one_add_del_locator
16377
16378 uword
16379 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16380 {
16381   u32 *key_id = va_arg (*args, u32 *);
16382   u8 *s = 0;
16383
16384   if (unformat (input, "%s", &s))
16385     {
16386       if (!strcmp ((char *) s, "sha1"))
16387         key_id[0] = HMAC_SHA_1_96;
16388       else if (!strcmp ((char *) s, "sha256"))
16389         key_id[0] = HMAC_SHA_256_128;
16390       else
16391         {
16392           clib_warning ("invalid key_id: '%s'", s);
16393           key_id[0] = HMAC_NO_KEY;
16394         }
16395     }
16396   else
16397     return 0;
16398
16399   vec_free (s);
16400   return 1;
16401 }
16402
16403 static int
16404 api_one_add_del_local_eid (vat_main_t * vam)
16405 {
16406   unformat_input_t *input = vam->input;
16407   vl_api_one_add_del_local_eid_t *mp;
16408   u8 is_add = 1;
16409   u8 eid_set = 0;
16410   lisp_eid_vat_t _eid, *eid = &_eid;
16411   u8 *locator_set_name = 0;
16412   u8 locator_set_name_set = 0;
16413   u32 vni = 0;
16414   u16 key_id = 0;
16415   u8 *key = 0;
16416   int ret;
16417
16418   /* Parse args required to build the message */
16419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16420     {
16421       if (unformat (input, "del"))
16422         {
16423           is_add = 0;
16424         }
16425       else if (unformat (input, "vni %d", &vni))
16426         {
16427           ;
16428         }
16429       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16430         {
16431           eid_set = 1;
16432         }
16433       else if (unformat (input, "locator-set %s", &locator_set_name))
16434         {
16435           locator_set_name_set = 1;
16436         }
16437       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16438         ;
16439       else if (unformat (input, "secret-key %_%v%_", &key))
16440         ;
16441       else
16442         break;
16443     }
16444
16445   if (locator_set_name_set == 0)
16446     {
16447       errmsg ("missing locator-set name");
16448       return -99;
16449     }
16450
16451   if (0 == eid_set)
16452     {
16453       errmsg ("EID address not set!");
16454       vec_free (locator_set_name);
16455       return -99;
16456     }
16457
16458   if (key && (0 == key_id))
16459     {
16460       errmsg ("invalid key_id!");
16461       return -99;
16462     }
16463
16464   if (vec_len (key) > 64)
16465     {
16466       errmsg ("key too long");
16467       vec_free (key);
16468       return -99;
16469     }
16470
16471   if (vec_len (locator_set_name) > 64)
16472     {
16473       errmsg ("locator-set name too long");
16474       vec_free (locator_set_name);
16475       return -99;
16476     }
16477   vec_add1 (locator_set_name, 0);
16478
16479   /* Construct the API message */
16480   M (ONE_ADD_DEL_LOCAL_EID, mp);
16481
16482   mp->is_add = is_add;
16483   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16484   mp->eid_type = eid->type;
16485   mp->prefix_len = eid->len;
16486   mp->vni = clib_host_to_net_u32 (vni);
16487   mp->key_id = clib_host_to_net_u16 (key_id);
16488   clib_memcpy (mp->locator_set_name, locator_set_name,
16489                vec_len (locator_set_name));
16490   clib_memcpy (mp->key, key, vec_len (key));
16491
16492   vec_free (locator_set_name);
16493   vec_free (key);
16494
16495   /* send it... */
16496   S (mp);
16497
16498   /* Wait for a reply... */
16499   W (ret);
16500   return ret;
16501 }
16502
16503 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16504
16505 static int
16506 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16507 {
16508   u32 dp_table = 0, vni = 0;;
16509   unformat_input_t *input = vam->input;
16510   vl_api_gpe_add_del_fwd_entry_t *mp;
16511   u8 is_add = 1;
16512   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16513   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16514   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16515   u32 action = ~0, w;
16516   ip4_address_t rmt_rloc4, lcl_rloc4;
16517   ip6_address_t rmt_rloc6, lcl_rloc6;
16518   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16519   int ret;
16520
16521   memset (&rloc, 0, sizeof (rloc));
16522
16523   /* Parse args required to build the message */
16524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16525     {
16526       if (unformat (input, "del"))
16527         is_add = 0;
16528       else if (unformat (input, "add"))
16529         is_add = 1;
16530       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16531         {
16532           rmt_eid_set = 1;
16533         }
16534       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16535         {
16536           lcl_eid_set = 1;
16537         }
16538       else if (unformat (input, "vrf %d", &dp_table))
16539         ;
16540       else if (unformat (input, "bd %d", &dp_table))
16541         ;
16542       else if (unformat (input, "vni %d", &vni))
16543         ;
16544       else if (unformat (input, "w %d", &w))
16545         {
16546           if (!curr_rloc)
16547             {
16548               errmsg ("No RLOC configured for setting priority/weight!");
16549               return -99;
16550             }
16551           curr_rloc->weight = w;
16552         }
16553       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16554                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16555         {
16556           rloc.is_ip4 = 1;
16557
16558           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16559           rloc.weight = 0;
16560           vec_add1 (lcl_locs, rloc);
16561
16562           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16563           vec_add1 (rmt_locs, rloc);
16564           /* weight saved in rmt loc */
16565           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16566         }
16567       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16568                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16569         {
16570           rloc.is_ip4 = 0;
16571           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16572           rloc.weight = 0;
16573           vec_add1 (lcl_locs, rloc);
16574
16575           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16576           vec_add1 (rmt_locs, rloc);
16577           /* weight saved in rmt loc */
16578           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16579         }
16580       else if (unformat (input, "action %d", &action))
16581         {
16582           ;
16583         }
16584       else
16585         {
16586           clib_warning ("parse error '%U'", format_unformat_error, input);
16587           return -99;
16588         }
16589     }
16590
16591   if (!rmt_eid_set)
16592     {
16593       errmsg ("remote eid addresses not set");
16594       return -99;
16595     }
16596
16597   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16598     {
16599       errmsg ("eid types don't match");
16600       return -99;
16601     }
16602
16603   if (0 == rmt_locs && (u32) ~ 0 == action)
16604     {
16605       errmsg ("action not set for negative mapping");
16606       return -99;
16607     }
16608
16609   /* Construct the API message */
16610   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16611       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16612
16613   mp->is_add = is_add;
16614   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16615   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16616   mp->eid_type = rmt_eid->type;
16617   mp->dp_table = clib_host_to_net_u32 (dp_table);
16618   mp->vni = clib_host_to_net_u32 (vni);
16619   mp->rmt_len = rmt_eid->len;
16620   mp->lcl_len = lcl_eid->len;
16621   mp->action = action;
16622
16623   if (0 != rmt_locs && 0 != lcl_locs)
16624     {
16625       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16626       clib_memcpy (mp->locs, lcl_locs,
16627                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16628
16629       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16630       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16631                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16632     }
16633   vec_free (lcl_locs);
16634   vec_free (rmt_locs);
16635
16636   /* send it... */
16637   S (mp);
16638
16639   /* Wait for a reply... */
16640   W (ret);
16641   return ret;
16642 }
16643
16644 static int
16645 api_one_add_del_map_server (vat_main_t * vam)
16646 {
16647   unformat_input_t *input = vam->input;
16648   vl_api_one_add_del_map_server_t *mp;
16649   u8 is_add = 1;
16650   u8 ipv4_set = 0;
16651   u8 ipv6_set = 0;
16652   ip4_address_t ipv4;
16653   ip6_address_t ipv6;
16654   int ret;
16655
16656   /* Parse args required to build the message */
16657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16658     {
16659       if (unformat (input, "del"))
16660         {
16661           is_add = 0;
16662         }
16663       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16664         {
16665           ipv4_set = 1;
16666         }
16667       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16668         {
16669           ipv6_set = 1;
16670         }
16671       else
16672         break;
16673     }
16674
16675   if (ipv4_set && ipv6_set)
16676     {
16677       errmsg ("both eid v4 and v6 addresses set");
16678       return -99;
16679     }
16680
16681   if (!ipv4_set && !ipv6_set)
16682     {
16683       errmsg ("eid addresses not set");
16684       return -99;
16685     }
16686
16687   /* Construct the API message */
16688   M (ONE_ADD_DEL_MAP_SERVER, mp);
16689
16690   mp->is_add = is_add;
16691   if (ipv6_set)
16692     {
16693       mp->is_ipv6 = 1;
16694       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16695     }
16696   else
16697     {
16698       mp->is_ipv6 = 0;
16699       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16700     }
16701
16702   /* send it... */
16703   S (mp);
16704
16705   /* Wait for a reply... */
16706   W (ret);
16707   return ret;
16708 }
16709
16710 #define api_lisp_add_del_map_server api_one_add_del_map_server
16711
16712 static int
16713 api_one_add_del_map_resolver (vat_main_t * vam)
16714 {
16715   unformat_input_t *input = vam->input;
16716   vl_api_one_add_del_map_resolver_t *mp;
16717   u8 is_add = 1;
16718   u8 ipv4_set = 0;
16719   u8 ipv6_set = 0;
16720   ip4_address_t ipv4;
16721   ip6_address_t ipv6;
16722   int ret;
16723
16724   /* Parse args required to build the message */
16725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16726     {
16727       if (unformat (input, "del"))
16728         {
16729           is_add = 0;
16730         }
16731       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16732         {
16733           ipv4_set = 1;
16734         }
16735       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16736         {
16737           ipv6_set = 1;
16738         }
16739       else
16740         break;
16741     }
16742
16743   if (ipv4_set && ipv6_set)
16744     {
16745       errmsg ("both eid v4 and v6 addresses set");
16746       return -99;
16747     }
16748
16749   if (!ipv4_set && !ipv6_set)
16750     {
16751       errmsg ("eid addresses not set");
16752       return -99;
16753     }
16754
16755   /* Construct the API message */
16756   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16757
16758   mp->is_add = is_add;
16759   if (ipv6_set)
16760     {
16761       mp->is_ipv6 = 1;
16762       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16763     }
16764   else
16765     {
16766       mp->is_ipv6 = 0;
16767       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16768     }
16769
16770   /* send it... */
16771   S (mp);
16772
16773   /* Wait for a reply... */
16774   W (ret);
16775   return ret;
16776 }
16777
16778 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16779
16780 static int
16781 api_lisp_gpe_enable_disable (vat_main_t * vam)
16782 {
16783   unformat_input_t *input = vam->input;
16784   vl_api_gpe_enable_disable_t *mp;
16785   u8 is_set = 0;
16786   u8 is_en = 1;
16787   int ret;
16788
16789   /* Parse args required to build the message */
16790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16791     {
16792       if (unformat (input, "enable"))
16793         {
16794           is_set = 1;
16795           is_en = 1;
16796         }
16797       else if (unformat (input, "disable"))
16798         {
16799           is_set = 1;
16800           is_en = 0;
16801         }
16802       else
16803         break;
16804     }
16805
16806   if (is_set == 0)
16807     {
16808       errmsg ("Value not set");
16809       return -99;
16810     }
16811
16812   /* Construct the API message */
16813   M (GPE_ENABLE_DISABLE, mp);
16814
16815   mp->is_en = is_en;
16816
16817   /* send it... */
16818   S (mp);
16819
16820   /* Wait for a reply... */
16821   W (ret);
16822   return ret;
16823 }
16824
16825 static int
16826 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16827 {
16828   unformat_input_t *input = vam->input;
16829   vl_api_one_rloc_probe_enable_disable_t *mp;
16830   u8 is_set = 0;
16831   u8 is_en = 0;
16832   int ret;
16833
16834   /* Parse args required to build the message */
16835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16836     {
16837       if (unformat (input, "enable"))
16838         {
16839           is_set = 1;
16840           is_en = 1;
16841         }
16842       else if (unformat (input, "disable"))
16843         is_set = 1;
16844       else
16845         break;
16846     }
16847
16848   if (!is_set)
16849     {
16850       errmsg ("Value not set");
16851       return -99;
16852     }
16853
16854   /* Construct the API message */
16855   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16856
16857   mp->is_enabled = is_en;
16858
16859   /* send it... */
16860   S (mp);
16861
16862   /* Wait for a reply... */
16863   W (ret);
16864   return ret;
16865 }
16866
16867 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16868
16869 static int
16870 api_one_map_register_enable_disable (vat_main_t * vam)
16871 {
16872   unformat_input_t *input = vam->input;
16873   vl_api_one_map_register_enable_disable_t *mp;
16874   u8 is_set = 0;
16875   u8 is_en = 0;
16876   int ret;
16877
16878   /* Parse args required to build the message */
16879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16880     {
16881       if (unformat (input, "enable"))
16882         {
16883           is_set = 1;
16884           is_en = 1;
16885         }
16886       else if (unformat (input, "disable"))
16887         is_set = 1;
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_MAP_REGISTER_ENABLE_DISABLE, mp);
16900
16901   mp->is_enabled = 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_map_register_enable_disable api_one_map_register_enable_disable
16912
16913 static int
16914 api_one_enable_disable (vat_main_t * vam)
16915 {
16916   unformat_input_t *input = vam->input;
16917   vl_api_one_enable_disable_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, 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 #define api_lisp_enable_disable api_one_enable_disable
16958
16959 static int
16960 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16961 {
16962   unformat_input_t *input = vam->input;
16963   vl_api_one_enable_disable_xtr_mode_t *mp;
16964   u8 is_set = 0;
16965   u8 is_en = 0;
16966   int ret;
16967
16968   /* Parse args required to build the message */
16969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16970     {
16971       if (unformat (input, "enable"))
16972         {
16973           is_set = 1;
16974           is_en = 1;
16975         }
16976       else if (unformat (input, "disable"))
16977         {
16978           is_set = 1;
16979         }
16980       else
16981         break;
16982     }
16983
16984   if (!is_set)
16985     {
16986       errmsg ("Value not set");
16987       return -99;
16988     }
16989
16990   /* Construct the API message */
16991   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16992
16993   mp->is_en = is_en;
16994
16995   /* send it... */
16996   S (mp);
16997
16998   /* Wait for a reply... */
16999   W (ret);
17000   return ret;
17001 }
17002
17003 static int
17004 api_one_show_xtr_mode (vat_main_t * vam)
17005 {
17006   vl_api_one_show_xtr_mode_t *mp;
17007   int ret;
17008
17009   /* Construct the API message */
17010   M (ONE_SHOW_XTR_MODE, mp);
17011
17012   /* send it... */
17013   S (mp);
17014
17015   /* Wait for a reply... */
17016   W (ret);
17017   return ret;
17018 }
17019
17020 static int
17021 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17022 {
17023   unformat_input_t *input = vam->input;
17024   vl_api_one_enable_disable_pitr_mode_t *mp;
17025   u8 is_set = 0;
17026   u8 is_en = 0;
17027   int ret;
17028
17029   /* Parse args required to build the message */
17030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17031     {
17032       if (unformat (input, "enable"))
17033         {
17034           is_set = 1;
17035           is_en = 1;
17036         }
17037       else if (unformat (input, "disable"))
17038         {
17039           is_set = 1;
17040         }
17041       else
17042         break;
17043     }
17044
17045   if (!is_set)
17046     {
17047       errmsg ("Value not set");
17048       return -99;
17049     }
17050
17051   /* Construct the API message */
17052   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17053
17054   mp->is_en = is_en;
17055
17056   /* send it... */
17057   S (mp);
17058
17059   /* Wait for a reply... */
17060   W (ret);
17061   return ret;
17062 }
17063
17064 static int
17065 api_one_show_pitr_mode (vat_main_t * vam)
17066 {
17067   vl_api_one_show_pitr_mode_t *mp;
17068   int ret;
17069
17070   /* Construct the API message */
17071   M (ONE_SHOW_PITR_MODE, mp);
17072
17073   /* send it... */
17074   S (mp);
17075
17076   /* Wait for a reply... */
17077   W (ret);
17078   return ret;
17079 }
17080
17081 static int
17082 api_one_enable_disable_petr_mode (vat_main_t * vam)
17083 {
17084   unformat_input_t *input = vam->input;
17085   vl_api_one_enable_disable_petr_mode_t *mp;
17086   u8 is_set = 0;
17087   u8 is_en = 0;
17088   int ret;
17089
17090   /* Parse args required to build the message */
17091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17092     {
17093       if (unformat (input, "enable"))
17094         {
17095           is_set = 1;
17096           is_en = 1;
17097         }
17098       else if (unformat (input, "disable"))
17099         {
17100           is_set = 1;
17101         }
17102       else
17103         break;
17104     }
17105
17106   if (!is_set)
17107     {
17108       errmsg ("Value not set");
17109       return -99;
17110     }
17111
17112   /* Construct the API message */
17113   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17114
17115   mp->is_en = is_en;
17116
17117   /* send it... */
17118   S (mp);
17119
17120   /* Wait for a reply... */
17121   W (ret);
17122   return ret;
17123 }
17124
17125 static int
17126 api_one_show_petr_mode (vat_main_t * vam)
17127 {
17128   vl_api_one_show_petr_mode_t *mp;
17129   int ret;
17130
17131   /* Construct the API message */
17132   M (ONE_SHOW_PETR_MODE, mp);
17133
17134   /* send it... */
17135   S (mp);
17136
17137   /* Wait for a reply... */
17138   W (ret);
17139   return ret;
17140 }
17141
17142 static int
17143 api_show_one_map_register_state (vat_main_t * vam)
17144 {
17145   vl_api_show_one_map_register_state_t *mp;
17146   int ret;
17147
17148   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17149
17150   /* send */
17151   S (mp);
17152
17153   /* wait for reply */
17154   W (ret);
17155   return ret;
17156 }
17157
17158 #define api_show_lisp_map_register_state api_show_one_map_register_state
17159
17160 static int
17161 api_show_one_rloc_probe_state (vat_main_t * vam)
17162 {
17163   vl_api_show_one_rloc_probe_state_t *mp;
17164   int ret;
17165
17166   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17167
17168   /* send */
17169   S (mp);
17170
17171   /* wait for reply */
17172   W (ret);
17173   return ret;
17174 }
17175
17176 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17177
17178 static int
17179 api_one_add_del_ndp_entry (vat_main_t * vam)
17180 {
17181   vl_api_one_add_del_ndp_entry_t *mp;
17182   unformat_input_t *input = vam->input;
17183   u8 is_add = 1;
17184   u8 mac_set = 0;
17185   u8 bd_set = 0;
17186   u8 ip_set = 0;
17187   u8 mac[6] = { 0, };
17188   u8 ip6[16] = { 0, };
17189   u32 bd = ~0;
17190   int ret;
17191
17192   /* Parse args required to build the message */
17193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17194     {
17195       if (unformat (input, "del"))
17196         is_add = 0;
17197       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17198         mac_set = 1;
17199       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17200         ip_set = 1;
17201       else if (unformat (input, "bd %d", &bd))
17202         bd_set = 1;
17203       else
17204         {
17205           errmsg ("parse error '%U'", format_unformat_error, input);
17206           return -99;
17207         }
17208     }
17209
17210   if (!bd_set || !ip_set || (!mac_set && is_add))
17211     {
17212       errmsg ("Missing BD, IP or MAC!");
17213       return -99;
17214     }
17215
17216   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17217   mp->is_add = is_add;
17218   clib_memcpy (mp->mac, mac, 6);
17219   mp->bd = clib_host_to_net_u32 (bd);
17220   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17221
17222   /* send */
17223   S (mp);
17224
17225   /* wait for reply */
17226   W (ret);
17227   return ret;
17228 }
17229
17230 static int
17231 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17232 {
17233   vl_api_one_add_del_l2_arp_entry_t *mp;
17234   unformat_input_t *input = vam->input;
17235   u8 is_add = 1;
17236   u8 mac_set = 0;
17237   u8 bd_set = 0;
17238   u8 ip_set = 0;
17239   u8 mac[6] = { 0, };
17240   u32 ip4 = 0, bd = ~0;
17241   int ret;
17242
17243   /* Parse args required to build the message */
17244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17245     {
17246       if (unformat (input, "del"))
17247         is_add = 0;
17248       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17249         mac_set = 1;
17250       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17251         ip_set = 1;
17252       else if (unformat (input, "bd %d", &bd))
17253         bd_set = 1;
17254       else
17255         {
17256           errmsg ("parse error '%U'", format_unformat_error, input);
17257           return -99;
17258         }
17259     }
17260
17261   if (!bd_set || !ip_set || (!mac_set && is_add))
17262     {
17263       errmsg ("Missing BD, IP or MAC!");
17264       return -99;
17265     }
17266
17267   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17268   mp->is_add = is_add;
17269   clib_memcpy (mp->mac, mac, 6);
17270   mp->bd = clib_host_to_net_u32 (bd);
17271   mp->ip4 = ip4;
17272
17273   /* send */
17274   S (mp);
17275
17276   /* wait for reply */
17277   W (ret);
17278   return ret;
17279 }
17280
17281 static int
17282 api_one_ndp_bd_get (vat_main_t * vam)
17283 {
17284   vl_api_one_ndp_bd_get_t *mp;
17285   int ret;
17286
17287   M (ONE_NDP_BD_GET, mp);
17288
17289   /* send */
17290   S (mp);
17291
17292   /* wait for reply */
17293   W (ret);
17294   return ret;
17295 }
17296
17297 static int
17298 api_one_ndp_entries_get (vat_main_t * vam)
17299 {
17300   vl_api_one_ndp_entries_get_t *mp;
17301   unformat_input_t *input = vam->input;
17302   u8 bd_set = 0;
17303   u32 bd = ~0;
17304   int ret;
17305
17306   /* Parse args required to build the message */
17307   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17308     {
17309       if (unformat (input, "bd %d", &bd))
17310         bd_set = 1;
17311       else
17312         {
17313           errmsg ("parse error '%U'", format_unformat_error, input);
17314           return -99;
17315         }
17316     }
17317
17318   if (!bd_set)
17319     {
17320       errmsg ("Expected bridge domain!");
17321       return -99;
17322     }
17323
17324   M (ONE_NDP_ENTRIES_GET, mp);
17325   mp->bd = clib_host_to_net_u32 (bd);
17326
17327   /* send */
17328   S (mp);
17329
17330   /* wait for reply */
17331   W (ret);
17332   return ret;
17333 }
17334
17335 static int
17336 api_one_l2_arp_bd_get (vat_main_t * vam)
17337 {
17338   vl_api_one_l2_arp_bd_get_t *mp;
17339   int ret;
17340
17341   M (ONE_L2_ARP_BD_GET, mp);
17342
17343   /* send */
17344   S (mp);
17345
17346   /* wait for reply */
17347   W (ret);
17348   return ret;
17349 }
17350
17351 static int
17352 api_one_l2_arp_entries_get (vat_main_t * vam)
17353 {
17354   vl_api_one_l2_arp_entries_get_t *mp;
17355   unformat_input_t *input = vam->input;
17356   u8 bd_set = 0;
17357   u32 bd = ~0;
17358   int ret;
17359
17360   /* Parse args required to build the message */
17361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17362     {
17363       if (unformat (input, "bd %d", &bd))
17364         bd_set = 1;
17365       else
17366         {
17367           errmsg ("parse error '%U'", format_unformat_error, input);
17368           return -99;
17369         }
17370     }
17371
17372   if (!bd_set)
17373     {
17374       errmsg ("Expected bridge domain!");
17375       return -99;
17376     }
17377
17378   M (ONE_L2_ARP_ENTRIES_GET, mp);
17379   mp->bd = clib_host_to_net_u32 (bd);
17380
17381   /* send */
17382   S (mp);
17383
17384   /* wait for reply */
17385   W (ret);
17386   return ret;
17387 }
17388
17389 static int
17390 api_one_stats_enable_disable (vat_main_t * vam)
17391 {
17392   vl_api_one_stats_enable_disable_t *mp;
17393   unformat_input_t *input = vam->input;
17394   u8 is_set = 0;
17395   u8 is_en = 0;
17396   int ret;
17397
17398   /* Parse args required to build the message */
17399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17400     {
17401       if (unformat (input, "enable"))
17402         {
17403           is_set = 1;
17404           is_en = 1;
17405         }
17406       else if (unformat (input, "disable"))
17407         {
17408           is_set = 1;
17409         }
17410       else
17411         break;
17412     }
17413
17414   if (!is_set)
17415     {
17416       errmsg ("Value not set");
17417       return -99;
17418     }
17419
17420   M (ONE_STATS_ENABLE_DISABLE, mp);
17421   mp->is_en = is_en;
17422
17423   /* send */
17424   S (mp);
17425
17426   /* wait for reply */
17427   W (ret);
17428   return ret;
17429 }
17430
17431 static int
17432 api_show_one_stats_enable_disable (vat_main_t * vam)
17433 {
17434   vl_api_show_one_stats_enable_disable_t *mp;
17435   int ret;
17436
17437   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17438
17439   /* send */
17440   S (mp);
17441
17442   /* wait for reply */
17443   W (ret);
17444   return ret;
17445 }
17446
17447 static int
17448 api_show_one_map_request_mode (vat_main_t * vam)
17449 {
17450   vl_api_show_one_map_request_mode_t *mp;
17451   int ret;
17452
17453   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17454
17455   /* send */
17456   S (mp);
17457
17458   /* wait for reply */
17459   W (ret);
17460   return ret;
17461 }
17462
17463 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17464
17465 static int
17466 api_one_map_request_mode (vat_main_t * vam)
17467 {
17468   unformat_input_t *input = vam->input;
17469   vl_api_one_map_request_mode_t *mp;
17470   u8 mode = 0;
17471   int ret;
17472
17473   /* Parse args required to build the message */
17474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17475     {
17476       if (unformat (input, "dst-only"))
17477         mode = 0;
17478       else if (unformat (input, "src-dst"))
17479         mode = 1;
17480       else
17481         {
17482           errmsg ("parse error '%U'", format_unformat_error, input);
17483           return -99;
17484         }
17485     }
17486
17487   M (ONE_MAP_REQUEST_MODE, mp);
17488
17489   mp->mode = mode;
17490
17491   /* send */
17492   S (mp);
17493
17494   /* wait for reply */
17495   W (ret);
17496   return ret;
17497 }
17498
17499 #define api_lisp_map_request_mode api_one_map_request_mode
17500
17501 /**
17502  * Enable/disable ONE proxy ITR.
17503  *
17504  * @param vam vpp API test context
17505  * @return return code
17506  */
17507 static int
17508 api_one_pitr_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_pitr_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, "locator-set %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)
17532     {
17533       errmsg ("locator-set name not set!");
17534       return -99;
17535     }
17536
17537   M (ONE_PITR_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 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17552
17553 static int
17554 api_one_nsh_set_locator_set (vat_main_t * vam)
17555 {
17556   u8 ls_name_set = 0;
17557   unformat_input_t *input = vam->input;
17558   vl_api_one_nsh_set_locator_set_t *mp;
17559   u8 is_add = 1;
17560   u8 *ls_name = 0;
17561   int ret;
17562
17563   /* Parse args required to build the message */
17564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17565     {
17566       if (unformat (input, "del"))
17567         is_add = 0;
17568       else if (unformat (input, "ls %s", &ls_name))
17569         ls_name_set = 1;
17570       else
17571         {
17572           errmsg ("parse error '%U'", format_unformat_error, input);
17573           return -99;
17574         }
17575     }
17576
17577   if (!ls_name_set && is_add)
17578     {
17579       errmsg ("locator-set name not set!");
17580       return -99;
17581     }
17582
17583   M (ONE_NSH_SET_LOCATOR_SET, mp);
17584
17585   mp->is_add = is_add;
17586   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17587   vec_free (ls_name);
17588
17589   /* send */
17590   S (mp);
17591
17592   /* wait for reply */
17593   W (ret);
17594   return ret;
17595 }
17596
17597 static int
17598 api_show_one_pitr (vat_main_t * vam)
17599 {
17600   vl_api_show_one_pitr_t *mp;
17601   int ret;
17602
17603   if (!vam->json_output)
17604     {
17605       print (vam->ofp, "%=20s", "lisp status:");
17606     }
17607
17608   M (SHOW_ONE_PITR, mp);
17609   /* send it... */
17610   S (mp);
17611
17612   /* Wait for a reply... */
17613   W (ret);
17614   return ret;
17615 }
17616
17617 #define api_show_lisp_pitr api_show_one_pitr
17618
17619 static int
17620 api_one_use_petr (vat_main_t * vam)
17621 {
17622   unformat_input_t *input = vam->input;
17623   vl_api_one_use_petr_t *mp;
17624   u8 is_add = 0;
17625   ip_address_t ip;
17626   int ret;
17627
17628   memset (&ip, 0, sizeof (ip));
17629
17630   /* Parse args required to build the message */
17631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17632     {
17633       if (unformat (input, "disable"))
17634         is_add = 0;
17635       else
17636         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17637         {
17638           is_add = 1;
17639           ip_addr_version (&ip) = IP4;
17640         }
17641       else
17642         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17643         {
17644           is_add = 1;
17645           ip_addr_version (&ip) = IP6;
17646         }
17647       else
17648         {
17649           errmsg ("parse error '%U'", format_unformat_error, input);
17650           return -99;
17651         }
17652     }
17653
17654   M (ONE_USE_PETR, mp);
17655
17656   mp->is_add = is_add;
17657   if (is_add)
17658     {
17659       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17660       if (mp->is_ip4)
17661         clib_memcpy (mp->address, &ip, 4);
17662       else
17663         clib_memcpy (mp->address, &ip, 16);
17664     }
17665
17666   /* send */
17667   S (mp);
17668
17669   /* wait for reply */
17670   W (ret);
17671   return ret;
17672 }
17673
17674 #define api_lisp_use_petr api_one_use_petr
17675
17676 static int
17677 api_show_one_nsh_mapping (vat_main_t * vam)
17678 {
17679   vl_api_show_one_use_petr_t *mp;
17680   int ret;
17681
17682   if (!vam->json_output)
17683     {
17684       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17685     }
17686
17687   M (SHOW_ONE_NSH_MAPPING, mp);
17688   /* send it... */
17689   S (mp);
17690
17691   /* Wait for a reply... */
17692   W (ret);
17693   return ret;
17694 }
17695
17696 static int
17697 api_show_one_use_petr (vat_main_t * vam)
17698 {
17699   vl_api_show_one_use_petr_t *mp;
17700   int ret;
17701
17702   if (!vam->json_output)
17703     {
17704       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17705     }
17706
17707   M (SHOW_ONE_USE_PETR, mp);
17708   /* send it... */
17709   S (mp);
17710
17711   /* Wait for a reply... */
17712   W (ret);
17713   return ret;
17714 }
17715
17716 #define api_show_lisp_use_petr api_show_one_use_petr
17717
17718 /**
17719  * Add/delete mapping between vni and vrf
17720  */
17721 static int
17722 api_one_eid_table_add_del_map (vat_main_t * vam)
17723 {
17724   unformat_input_t *input = vam->input;
17725   vl_api_one_eid_table_add_del_map_t *mp;
17726   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17727   u32 vni, vrf, bd_index;
17728   int ret;
17729
17730   /* Parse args required to build the message */
17731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17732     {
17733       if (unformat (input, "del"))
17734         is_add = 0;
17735       else if (unformat (input, "vrf %d", &vrf))
17736         vrf_set = 1;
17737       else if (unformat (input, "bd_index %d", &bd_index))
17738         bd_index_set = 1;
17739       else if (unformat (input, "vni %d", &vni))
17740         vni_set = 1;
17741       else
17742         break;
17743     }
17744
17745   if (!vni_set || (!vrf_set && !bd_index_set))
17746     {
17747       errmsg ("missing arguments!");
17748       return -99;
17749     }
17750
17751   if (vrf_set && bd_index_set)
17752     {
17753       errmsg ("error: both vrf and bd entered!");
17754       return -99;
17755     }
17756
17757   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17758
17759   mp->is_add = is_add;
17760   mp->vni = htonl (vni);
17761   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17762   mp->is_l2 = bd_index_set;
17763
17764   /* send */
17765   S (mp);
17766
17767   /* wait for reply */
17768   W (ret);
17769   return ret;
17770 }
17771
17772 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17773
17774 uword
17775 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17776 {
17777   u32 *action = va_arg (*args, u32 *);
17778   u8 *s = 0;
17779
17780   if (unformat (input, "%s", &s))
17781     {
17782       if (!strcmp ((char *) s, "no-action"))
17783         action[0] = 0;
17784       else if (!strcmp ((char *) s, "natively-forward"))
17785         action[0] = 1;
17786       else if (!strcmp ((char *) s, "send-map-request"))
17787         action[0] = 2;
17788       else if (!strcmp ((char *) s, "drop"))
17789         action[0] = 3;
17790       else
17791         {
17792           clib_warning ("invalid action: '%s'", s);
17793           action[0] = 3;
17794         }
17795     }
17796   else
17797     return 0;
17798
17799   vec_free (s);
17800   return 1;
17801 }
17802
17803 /**
17804  * Add/del remote mapping to/from ONE control plane
17805  *
17806  * @param vam vpp API test context
17807  * @return return code
17808  */
17809 static int
17810 api_one_add_del_remote_mapping (vat_main_t * vam)
17811 {
17812   unformat_input_t *input = vam->input;
17813   vl_api_one_add_del_remote_mapping_t *mp;
17814   u32 vni = 0;
17815   lisp_eid_vat_t _eid, *eid = &_eid;
17816   lisp_eid_vat_t _seid, *seid = &_seid;
17817   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17818   u32 action = ~0, p, w, data_len;
17819   ip4_address_t rloc4;
17820   ip6_address_t rloc6;
17821   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17822   int ret;
17823
17824   memset (&rloc, 0, sizeof (rloc));
17825
17826   /* Parse args required to build the message */
17827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17828     {
17829       if (unformat (input, "del-all"))
17830         {
17831           del_all = 1;
17832         }
17833       else if (unformat (input, "del"))
17834         {
17835           is_add = 0;
17836         }
17837       else if (unformat (input, "add"))
17838         {
17839           is_add = 1;
17840         }
17841       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17842         {
17843           eid_set = 1;
17844         }
17845       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17846         {
17847           seid_set = 1;
17848         }
17849       else if (unformat (input, "vni %d", &vni))
17850         {
17851           ;
17852         }
17853       else if (unformat (input, "p %d w %d", &p, &w))
17854         {
17855           if (!curr_rloc)
17856             {
17857               errmsg ("No RLOC configured for setting priority/weight!");
17858               return -99;
17859             }
17860           curr_rloc->priority = p;
17861           curr_rloc->weight = w;
17862         }
17863       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17864         {
17865           rloc.is_ip4 = 1;
17866           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17867           vec_add1 (rlocs, rloc);
17868           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17869         }
17870       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17871         {
17872           rloc.is_ip4 = 0;
17873           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17874           vec_add1 (rlocs, rloc);
17875           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17876         }
17877       else if (unformat (input, "action %U",
17878                          unformat_negative_mapping_action, &action))
17879         {
17880           ;
17881         }
17882       else
17883         {
17884           clib_warning ("parse error '%U'", format_unformat_error, input);
17885           return -99;
17886         }
17887     }
17888
17889   if (0 == eid_set)
17890     {
17891       errmsg ("missing params!");
17892       return -99;
17893     }
17894
17895   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17896     {
17897       errmsg ("no action set for negative map-reply!");
17898       return -99;
17899     }
17900
17901   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17902
17903   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17904   mp->is_add = is_add;
17905   mp->vni = htonl (vni);
17906   mp->action = (u8) action;
17907   mp->is_src_dst = seid_set;
17908   mp->eid_len = eid->len;
17909   mp->seid_len = seid->len;
17910   mp->del_all = del_all;
17911   mp->eid_type = eid->type;
17912   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17913   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17914
17915   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17916   clib_memcpy (mp->rlocs, rlocs, data_len);
17917   vec_free (rlocs);
17918
17919   /* send it... */
17920   S (mp);
17921
17922   /* Wait for a reply... */
17923   W (ret);
17924   return ret;
17925 }
17926
17927 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17928
17929 /**
17930  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17931  * forwarding entries in data-plane accordingly.
17932  *
17933  * @param vam vpp API test context
17934  * @return return code
17935  */
17936 static int
17937 api_one_add_del_adjacency (vat_main_t * vam)
17938 {
17939   unformat_input_t *input = vam->input;
17940   vl_api_one_add_del_adjacency_t *mp;
17941   u32 vni = 0;
17942   ip4_address_t leid4, reid4;
17943   ip6_address_t leid6, reid6;
17944   u8 reid_mac[6] = { 0 };
17945   u8 leid_mac[6] = { 0 };
17946   u8 reid_type, leid_type;
17947   u32 leid_len = 0, reid_len = 0, len;
17948   u8 is_add = 1;
17949   int ret;
17950
17951   leid_type = reid_type = (u8) ~ 0;
17952
17953   /* Parse args required to build the message */
17954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17955     {
17956       if (unformat (input, "del"))
17957         {
17958           is_add = 0;
17959         }
17960       else if (unformat (input, "add"))
17961         {
17962           is_add = 1;
17963         }
17964       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17965                          &reid4, &len))
17966         {
17967           reid_type = 0;        /* ipv4 */
17968           reid_len = len;
17969         }
17970       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17971                          &reid6, &len))
17972         {
17973           reid_type = 1;        /* ipv6 */
17974           reid_len = len;
17975         }
17976       else if (unformat (input, "reid %U", unformat_ethernet_address,
17977                          reid_mac))
17978         {
17979           reid_type = 2;        /* mac */
17980         }
17981       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17982                          &leid4, &len))
17983         {
17984           leid_type = 0;        /* ipv4 */
17985           leid_len = len;
17986         }
17987       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17988                          &leid6, &len))
17989         {
17990           leid_type = 1;        /* ipv6 */
17991           leid_len = len;
17992         }
17993       else if (unformat (input, "leid %U", unformat_ethernet_address,
17994                          leid_mac))
17995         {
17996           leid_type = 2;        /* mac */
17997         }
17998       else if (unformat (input, "vni %d", &vni))
17999         {
18000           ;
18001         }
18002       else
18003         {
18004           errmsg ("parse error '%U'", format_unformat_error, input);
18005           return -99;
18006         }
18007     }
18008
18009   if ((u8) ~ 0 == reid_type)
18010     {
18011       errmsg ("missing params!");
18012       return -99;
18013     }
18014
18015   if (leid_type != reid_type)
18016     {
18017       errmsg ("remote and local EIDs are of different types!");
18018       return -99;
18019     }
18020
18021   M (ONE_ADD_DEL_ADJACENCY, mp);
18022   mp->is_add = is_add;
18023   mp->vni = htonl (vni);
18024   mp->leid_len = leid_len;
18025   mp->reid_len = reid_len;
18026   mp->eid_type = reid_type;
18027
18028   switch (mp->eid_type)
18029     {
18030     case 0:
18031       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18032       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18033       break;
18034     case 1:
18035       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18036       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18037       break;
18038     case 2:
18039       clib_memcpy (mp->leid, leid_mac, 6);
18040       clib_memcpy (mp->reid, reid_mac, 6);
18041       break;
18042     default:
18043       errmsg ("unknown EID type %d!", mp->eid_type);
18044       return 0;
18045     }
18046
18047   /* send it... */
18048   S (mp);
18049
18050   /* Wait for a reply... */
18051   W (ret);
18052   return ret;
18053 }
18054
18055 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18056
18057 uword
18058 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18059 {
18060   u32 *mode = va_arg (*args, u32 *);
18061
18062   if (unformat (input, "lisp"))
18063     *mode = 0;
18064   else if (unformat (input, "vxlan"))
18065     *mode = 1;
18066   else
18067     return 0;
18068
18069   return 1;
18070 }
18071
18072 static int
18073 api_gpe_get_encap_mode (vat_main_t * vam)
18074 {
18075   vl_api_gpe_get_encap_mode_t *mp;
18076   int ret;
18077
18078   /* Construct the API message */
18079   M (GPE_GET_ENCAP_MODE, mp);
18080
18081   /* send it... */
18082   S (mp);
18083
18084   /* Wait for a reply... */
18085   W (ret);
18086   return ret;
18087 }
18088
18089 static int
18090 api_gpe_set_encap_mode (vat_main_t * vam)
18091 {
18092   unformat_input_t *input = vam->input;
18093   vl_api_gpe_set_encap_mode_t *mp;
18094   int ret;
18095   u32 mode = 0;
18096
18097   /* Parse args required to build the message */
18098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18099     {
18100       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18101         ;
18102       else
18103         break;
18104     }
18105
18106   /* Construct the API message */
18107   M (GPE_SET_ENCAP_MODE, mp);
18108
18109   mp->mode = mode;
18110
18111   /* send it... */
18112   S (mp);
18113
18114   /* Wait for a reply... */
18115   W (ret);
18116   return ret;
18117 }
18118
18119 static int
18120 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18121 {
18122   unformat_input_t *input = vam->input;
18123   vl_api_gpe_add_del_iface_t *mp;
18124   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18125   u32 dp_table = 0, vni = 0;
18126   int ret;
18127
18128   /* Parse args required to build the message */
18129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18130     {
18131       if (unformat (input, "up"))
18132         {
18133           action_set = 1;
18134           is_add = 1;
18135         }
18136       else if (unformat (input, "down"))
18137         {
18138           action_set = 1;
18139           is_add = 0;
18140         }
18141       else if (unformat (input, "table_id %d", &dp_table))
18142         {
18143           dp_table_set = 1;
18144         }
18145       else if (unformat (input, "bd_id %d", &dp_table))
18146         {
18147           dp_table_set = 1;
18148           is_l2 = 1;
18149         }
18150       else if (unformat (input, "vni %d", &vni))
18151         {
18152           vni_set = 1;
18153         }
18154       else
18155         break;
18156     }
18157
18158   if (action_set == 0)
18159     {
18160       errmsg ("Action not set");
18161       return -99;
18162     }
18163   if (dp_table_set == 0 || vni_set == 0)
18164     {
18165       errmsg ("vni and dp_table must be set");
18166       return -99;
18167     }
18168
18169   /* Construct the API message */
18170   M (GPE_ADD_DEL_IFACE, mp);
18171
18172   mp->is_add = is_add;
18173   mp->dp_table = clib_host_to_net_u32 (dp_table);
18174   mp->is_l2 = is_l2;
18175   mp->vni = clib_host_to_net_u32 (vni);
18176
18177   /* send it... */
18178   S (mp);
18179
18180   /* Wait for a reply... */
18181   W (ret);
18182   return ret;
18183 }
18184
18185 static int
18186 api_one_map_register_fallback_threshold (vat_main_t * vam)
18187 {
18188   unformat_input_t *input = vam->input;
18189   vl_api_one_map_register_fallback_threshold_t *mp;
18190   u32 value = 0;
18191   u8 is_set = 0;
18192   int ret;
18193
18194   /* Parse args required to build the message */
18195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18196     {
18197       if (unformat (input, "%u", &value))
18198         is_set = 1;
18199       else
18200         {
18201           clib_warning ("parse error '%U'", format_unformat_error, input);
18202           return -99;
18203         }
18204     }
18205
18206   if (!is_set)
18207     {
18208       errmsg ("fallback threshold value is missing!");
18209       return -99;
18210     }
18211
18212   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18213   mp->value = clib_host_to_net_u32 (value);
18214
18215   /* send it... */
18216   S (mp);
18217
18218   /* Wait for a reply... */
18219   W (ret);
18220   return ret;
18221 }
18222
18223 static int
18224 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18225 {
18226   vl_api_show_one_map_register_fallback_threshold_t *mp;
18227   int ret;
18228
18229   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18230
18231   /* send it... */
18232   S (mp);
18233
18234   /* Wait for a reply... */
18235   W (ret);
18236   return ret;
18237 }
18238
18239 uword
18240 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18241 {
18242   u32 *proto = va_arg (*args, u32 *);
18243
18244   if (unformat (input, "udp"))
18245     *proto = 1;
18246   else if (unformat (input, "api"))
18247     *proto = 2;
18248   else
18249     return 0;
18250
18251   return 1;
18252 }
18253
18254 static int
18255 api_one_set_transport_protocol (vat_main_t * vam)
18256 {
18257   unformat_input_t *input = vam->input;
18258   vl_api_one_set_transport_protocol_t *mp;
18259   u8 is_set = 0;
18260   u32 protocol = 0;
18261   int ret;
18262
18263   /* Parse args required to build the message */
18264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18265     {
18266       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18267         is_set = 1;
18268       else
18269         {
18270           clib_warning ("parse error '%U'", format_unformat_error, input);
18271           return -99;
18272         }
18273     }
18274
18275   if (!is_set)
18276     {
18277       errmsg ("Transport protocol missing!");
18278       return -99;
18279     }
18280
18281   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18282   mp->protocol = (u8) protocol;
18283
18284   /* send it... */
18285   S (mp);
18286
18287   /* Wait for a reply... */
18288   W (ret);
18289   return ret;
18290 }
18291
18292 static int
18293 api_one_get_transport_protocol (vat_main_t * vam)
18294 {
18295   vl_api_one_get_transport_protocol_t *mp;
18296   int ret;
18297
18298   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18299
18300   /* send it... */
18301   S (mp);
18302
18303   /* Wait for a reply... */
18304   W (ret);
18305   return ret;
18306 }
18307
18308 static int
18309 api_one_map_register_set_ttl (vat_main_t * vam)
18310 {
18311   unformat_input_t *input = vam->input;
18312   vl_api_one_map_register_set_ttl_t *mp;
18313   u32 ttl = 0;
18314   u8 is_set = 0;
18315   int ret;
18316
18317   /* Parse args required to build the message */
18318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18319     {
18320       if (unformat (input, "%u", &ttl))
18321         is_set = 1;
18322       else
18323         {
18324           clib_warning ("parse error '%U'", format_unformat_error, input);
18325           return -99;
18326         }
18327     }
18328
18329   if (!is_set)
18330     {
18331       errmsg ("TTL value missing!");
18332       return -99;
18333     }
18334
18335   M (ONE_MAP_REGISTER_SET_TTL, mp);
18336   mp->ttl = clib_host_to_net_u32 (ttl);
18337
18338   /* send it... */
18339   S (mp);
18340
18341   /* Wait for a reply... */
18342   W (ret);
18343   return ret;
18344 }
18345
18346 static int
18347 api_show_one_map_register_ttl (vat_main_t * vam)
18348 {
18349   vl_api_show_one_map_register_ttl_t *mp;
18350   int ret;
18351
18352   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18353
18354   /* send it... */
18355   S (mp);
18356
18357   /* Wait for a reply... */
18358   W (ret);
18359   return ret;
18360 }
18361
18362 /**
18363  * Add/del map request itr rlocs from ONE control plane and updates
18364  *
18365  * @param vam vpp API test context
18366  * @return return code
18367  */
18368 static int
18369 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18370 {
18371   unformat_input_t *input = vam->input;
18372   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18373   u8 *locator_set_name = 0;
18374   u8 locator_set_name_set = 0;
18375   u8 is_add = 1;
18376   int ret;
18377
18378   /* Parse args required to build the message */
18379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18380     {
18381       if (unformat (input, "del"))
18382         {
18383           is_add = 0;
18384         }
18385       else if (unformat (input, "%_%v%_", &locator_set_name))
18386         {
18387           locator_set_name_set = 1;
18388         }
18389       else
18390         {
18391           clib_warning ("parse error '%U'", format_unformat_error, input);
18392           return -99;
18393         }
18394     }
18395
18396   if (is_add && !locator_set_name_set)
18397     {
18398       errmsg ("itr-rloc is not set!");
18399       return -99;
18400     }
18401
18402   if (is_add && vec_len (locator_set_name) > 64)
18403     {
18404       errmsg ("itr-rloc locator-set name too long");
18405       vec_free (locator_set_name);
18406       return -99;
18407     }
18408
18409   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18410   mp->is_add = is_add;
18411   if (is_add)
18412     {
18413       clib_memcpy (mp->locator_set_name, locator_set_name,
18414                    vec_len (locator_set_name));
18415     }
18416   else
18417     {
18418       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18419     }
18420   vec_free (locator_set_name);
18421
18422   /* send it... */
18423   S (mp);
18424
18425   /* Wait for a reply... */
18426   W (ret);
18427   return ret;
18428 }
18429
18430 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18431
18432 static int
18433 api_one_locator_dump (vat_main_t * vam)
18434 {
18435   unformat_input_t *input = vam->input;
18436   vl_api_one_locator_dump_t *mp;
18437   vl_api_control_ping_t *mp_ping;
18438   u8 is_index_set = 0, is_name_set = 0;
18439   u8 *ls_name = 0;
18440   u32 ls_index = ~0;
18441   int ret;
18442
18443   /* Parse args required to build the message */
18444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18445     {
18446       if (unformat (input, "ls_name %_%v%_", &ls_name))
18447         {
18448           is_name_set = 1;
18449         }
18450       else if (unformat (input, "ls_index %d", &ls_index))
18451         {
18452           is_index_set = 1;
18453         }
18454       else
18455         {
18456           errmsg ("parse error '%U'", format_unformat_error, input);
18457           return -99;
18458         }
18459     }
18460
18461   if (!is_index_set && !is_name_set)
18462     {
18463       errmsg ("error: expected one of index or name!");
18464       return -99;
18465     }
18466
18467   if (is_index_set && is_name_set)
18468     {
18469       errmsg ("error: only one param expected!");
18470       return -99;
18471     }
18472
18473   if (vec_len (ls_name) > 62)
18474     {
18475       errmsg ("error: locator set name too long!");
18476       return -99;
18477     }
18478
18479   if (!vam->json_output)
18480     {
18481       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18482     }
18483
18484   M (ONE_LOCATOR_DUMP, mp);
18485   mp->is_index_set = is_index_set;
18486
18487   if (is_index_set)
18488     mp->ls_index = clib_host_to_net_u32 (ls_index);
18489   else
18490     {
18491       vec_add1 (ls_name, 0);
18492       strncpy ((char *) mp->ls_name, (char *) ls_name,
18493                sizeof (mp->ls_name) - 1);
18494     }
18495
18496   /* send it... */
18497   S (mp);
18498
18499   /* Use a control ping for synchronization */
18500   MPING (CONTROL_PING, mp_ping);
18501   S (mp_ping);
18502
18503   /* Wait for a reply... */
18504   W (ret);
18505   return ret;
18506 }
18507
18508 #define api_lisp_locator_dump api_one_locator_dump
18509
18510 static int
18511 api_one_locator_set_dump (vat_main_t * vam)
18512 {
18513   vl_api_one_locator_set_dump_t *mp;
18514   vl_api_control_ping_t *mp_ping;
18515   unformat_input_t *input = vam->input;
18516   u8 filter = 0;
18517   int ret;
18518
18519   /* Parse args required to build the message */
18520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18521     {
18522       if (unformat (input, "local"))
18523         {
18524           filter = 1;
18525         }
18526       else if (unformat (input, "remote"))
18527         {
18528           filter = 2;
18529         }
18530       else
18531         {
18532           errmsg ("parse error '%U'", format_unformat_error, input);
18533           return -99;
18534         }
18535     }
18536
18537   if (!vam->json_output)
18538     {
18539       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18540     }
18541
18542   M (ONE_LOCATOR_SET_DUMP, mp);
18543
18544   mp->filter = filter;
18545
18546   /* send it... */
18547   S (mp);
18548
18549   /* Use a control ping for synchronization */
18550   MPING (CONTROL_PING, mp_ping);
18551   S (mp_ping);
18552
18553   /* Wait for a reply... */
18554   W (ret);
18555   return ret;
18556 }
18557
18558 #define api_lisp_locator_set_dump api_one_locator_set_dump
18559
18560 static int
18561 api_one_eid_table_map_dump (vat_main_t * vam)
18562 {
18563   u8 is_l2 = 0;
18564   u8 mode_set = 0;
18565   unformat_input_t *input = vam->input;
18566   vl_api_one_eid_table_map_dump_t *mp;
18567   vl_api_control_ping_t *mp_ping;
18568   int ret;
18569
18570   /* Parse args required to build the message */
18571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18572     {
18573       if (unformat (input, "l2"))
18574         {
18575           is_l2 = 1;
18576           mode_set = 1;
18577         }
18578       else if (unformat (input, "l3"))
18579         {
18580           is_l2 = 0;
18581           mode_set = 1;
18582         }
18583       else
18584         {
18585           errmsg ("parse error '%U'", format_unformat_error, input);
18586           return -99;
18587         }
18588     }
18589
18590   if (!mode_set)
18591     {
18592       errmsg ("expected one of 'l2' or 'l3' parameter!");
18593       return -99;
18594     }
18595
18596   if (!vam->json_output)
18597     {
18598       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18599     }
18600
18601   M (ONE_EID_TABLE_MAP_DUMP, mp);
18602   mp->is_l2 = is_l2;
18603
18604   /* send it... */
18605   S (mp);
18606
18607   /* Use a control ping for synchronization */
18608   MPING (CONTROL_PING, mp_ping);
18609   S (mp_ping);
18610
18611   /* Wait for a reply... */
18612   W (ret);
18613   return ret;
18614 }
18615
18616 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18617
18618 static int
18619 api_one_eid_table_vni_dump (vat_main_t * vam)
18620 {
18621   vl_api_one_eid_table_vni_dump_t *mp;
18622   vl_api_control_ping_t *mp_ping;
18623   int ret;
18624
18625   if (!vam->json_output)
18626     {
18627       print (vam->ofp, "VNI");
18628     }
18629
18630   M (ONE_EID_TABLE_VNI_DUMP, mp);
18631
18632   /* send it... */
18633   S (mp);
18634
18635   /* Use a control ping for synchronization */
18636   MPING (CONTROL_PING, mp_ping);
18637   S (mp_ping);
18638
18639   /* Wait for a reply... */
18640   W (ret);
18641   return ret;
18642 }
18643
18644 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18645
18646 static int
18647 api_one_eid_table_dump (vat_main_t * vam)
18648 {
18649   unformat_input_t *i = vam->input;
18650   vl_api_one_eid_table_dump_t *mp;
18651   vl_api_control_ping_t *mp_ping;
18652   struct in_addr ip4;
18653   struct in6_addr ip6;
18654   u8 mac[6];
18655   u8 eid_type = ~0, eid_set = 0;
18656   u32 prefix_length = ~0, t, vni = 0;
18657   u8 filter = 0;
18658   int ret;
18659   lisp_nsh_api_t nsh;
18660
18661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18662     {
18663       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18664         {
18665           eid_set = 1;
18666           eid_type = 0;
18667           prefix_length = t;
18668         }
18669       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18670         {
18671           eid_set = 1;
18672           eid_type = 1;
18673           prefix_length = t;
18674         }
18675       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18676         {
18677           eid_set = 1;
18678           eid_type = 2;
18679         }
18680       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18681         {
18682           eid_set = 1;
18683           eid_type = 3;
18684         }
18685       else if (unformat (i, "vni %d", &t))
18686         {
18687           vni = t;
18688         }
18689       else if (unformat (i, "local"))
18690         {
18691           filter = 1;
18692         }
18693       else if (unformat (i, "remote"))
18694         {
18695           filter = 2;
18696         }
18697       else
18698         {
18699           errmsg ("parse error '%U'", format_unformat_error, i);
18700           return -99;
18701         }
18702     }
18703
18704   if (!vam->json_output)
18705     {
18706       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18707              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18708     }
18709
18710   M (ONE_EID_TABLE_DUMP, mp);
18711
18712   mp->filter = filter;
18713   if (eid_set)
18714     {
18715       mp->eid_set = 1;
18716       mp->vni = htonl (vni);
18717       mp->eid_type = eid_type;
18718       switch (eid_type)
18719         {
18720         case 0:
18721           mp->prefix_length = prefix_length;
18722           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18723           break;
18724         case 1:
18725           mp->prefix_length = prefix_length;
18726           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18727           break;
18728         case 2:
18729           clib_memcpy (mp->eid, mac, sizeof (mac));
18730           break;
18731         case 3:
18732           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18733           break;
18734         default:
18735           errmsg ("unknown EID type %d!", eid_type);
18736           return -99;
18737         }
18738     }
18739
18740   /* send it... */
18741   S (mp);
18742
18743   /* Use a control ping for synchronization */
18744   MPING (CONTROL_PING, mp_ping);
18745   S (mp_ping);
18746
18747   /* Wait for a reply... */
18748   W (ret);
18749   return ret;
18750 }
18751
18752 #define api_lisp_eid_table_dump api_one_eid_table_dump
18753
18754 static int
18755 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18756 {
18757   unformat_input_t *i = vam->input;
18758   vl_api_gpe_fwd_entries_get_t *mp;
18759   u8 vni_set = 0;
18760   u32 vni = ~0;
18761   int ret;
18762
18763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18764     {
18765       if (unformat (i, "vni %d", &vni))
18766         {
18767           vni_set = 1;
18768         }
18769       else
18770         {
18771           errmsg ("parse error '%U'", format_unformat_error, i);
18772           return -99;
18773         }
18774     }
18775
18776   if (!vni_set)
18777     {
18778       errmsg ("vni not set!");
18779       return -99;
18780     }
18781
18782   if (!vam->json_output)
18783     {
18784       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18785              "leid", "reid");
18786     }
18787
18788   M (GPE_FWD_ENTRIES_GET, mp);
18789   mp->vni = clib_host_to_net_u32 (vni);
18790
18791   /* send it... */
18792   S (mp);
18793
18794   /* Wait for a reply... */
18795   W (ret);
18796   return ret;
18797 }
18798
18799 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18800 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18801 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18802 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18803 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18804 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18805 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18806 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18807
18808 static int
18809 api_one_adjacencies_get (vat_main_t * vam)
18810 {
18811   unformat_input_t *i = vam->input;
18812   vl_api_one_adjacencies_get_t *mp;
18813   u8 vni_set = 0;
18814   u32 vni = ~0;
18815   int ret;
18816
18817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18818     {
18819       if (unformat (i, "vni %d", &vni))
18820         {
18821           vni_set = 1;
18822         }
18823       else
18824         {
18825           errmsg ("parse error '%U'", format_unformat_error, i);
18826           return -99;
18827         }
18828     }
18829
18830   if (!vni_set)
18831     {
18832       errmsg ("vni not set!");
18833       return -99;
18834     }
18835
18836   if (!vam->json_output)
18837     {
18838       print (vam->ofp, "%s %40s", "leid", "reid");
18839     }
18840
18841   M (ONE_ADJACENCIES_GET, mp);
18842   mp->vni = clib_host_to_net_u32 (vni);
18843
18844   /* send it... */
18845   S (mp);
18846
18847   /* Wait for a reply... */
18848   W (ret);
18849   return ret;
18850 }
18851
18852 #define api_lisp_adjacencies_get api_one_adjacencies_get
18853
18854 static int
18855 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18856 {
18857   unformat_input_t *i = vam->input;
18858   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18859   int ret;
18860   u8 ip_family_set = 0, is_ip4 = 1;
18861
18862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18863     {
18864       if (unformat (i, "ip4"))
18865         {
18866           ip_family_set = 1;
18867           is_ip4 = 1;
18868         }
18869       else if (unformat (i, "ip6"))
18870         {
18871           ip_family_set = 1;
18872           is_ip4 = 0;
18873         }
18874       else
18875         {
18876           errmsg ("parse error '%U'", format_unformat_error, i);
18877           return -99;
18878         }
18879     }
18880
18881   if (!ip_family_set)
18882     {
18883       errmsg ("ip family not set!");
18884       return -99;
18885     }
18886
18887   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18888   mp->is_ip4 = is_ip4;
18889
18890   /* send it... */
18891   S (mp);
18892
18893   /* Wait for a reply... */
18894   W (ret);
18895   return ret;
18896 }
18897
18898 static int
18899 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18900 {
18901   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18902   int ret;
18903
18904   if (!vam->json_output)
18905     {
18906       print (vam->ofp, "VNIs");
18907     }
18908
18909   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18910
18911   /* send it... */
18912   S (mp);
18913
18914   /* Wait for a reply... */
18915   W (ret);
18916   return ret;
18917 }
18918
18919 static int
18920 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18921 {
18922   unformat_input_t *i = vam->input;
18923   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18924   int ret = 0;
18925   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18926   struct in_addr ip4;
18927   struct in6_addr ip6;
18928   u32 table_id = 0, nh_sw_if_index = ~0;
18929
18930   memset (&ip4, 0, sizeof (ip4));
18931   memset (&ip6, 0, sizeof (ip6));
18932
18933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18934     {
18935       if (unformat (i, "del"))
18936         is_add = 0;
18937       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18938                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18939         {
18940           ip_set = 1;
18941           is_ip4 = 1;
18942         }
18943       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18944                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18945         {
18946           ip_set = 1;
18947           is_ip4 = 0;
18948         }
18949       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18950         {
18951           ip_set = 1;
18952           is_ip4 = 1;
18953           nh_sw_if_index = ~0;
18954         }
18955       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18956         {
18957           ip_set = 1;
18958           is_ip4 = 0;
18959           nh_sw_if_index = ~0;
18960         }
18961       else if (unformat (i, "table %d", &table_id))
18962         ;
18963       else
18964         {
18965           errmsg ("parse error '%U'", format_unformat_error, i);
18966           return -99;
18967         }
18968     }
18969
18970   if (!ip_set)
18971     {
18972       errmsg ("nh addr not set!");
18973       return -99;
18974     }
18975
18976   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18977   mp->is_add = is_add;
18978   mp->table_id = clib_host_to_net_u32 (table_id);
18979   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18980   mp->is_ip4 = is_ip4;
18981   if (is_ip4)
18982     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18983   else
18984     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18985
18986   /* send it... */
18987   S (mp);
18988
18989   /* Wait for a reply... */
18990   W (ret);
18991   return ret;
18992 }
18993
18994 static int
18995 api_one_map_server_dump (vat_main_t * vam)
18996 {
18997   vl_api_one_map_server_dump_t *mp;
18998   vl_api_control_ping_t *mp_ping;
18999   int ret;
19000
19001   if (!vam->json_output)
19002     {
19003       print (vam->ofp, "%=20s", "Map server");
19004     }
19005
19006   M (ONE_MAP_SERVER_DUMP, mp);
19007   /* send it... */
19008   S (mp);
19009
19010   /* Use a control ping for synchronization */
19011   MPING (CONTROL_PING, mp_ping);
19012   S (mp_ping);
19013
19014   /* Wait for a reply... */
19015   W (ret);
19016   return ret;
19017 }
19018
19019 #define api_lisp_map_server_dump api_one_map_server_dump
19020
19021 static int
19022 api_one_map_resolver_dump (vat_main_t * vam)
19023 {
19024   vl_api_one_map_resolver_dump_t *mp;
19025   vl_api_control_ping_t *mp_ping;
19026   int ret;
19027
19028   if (!vam->json_output)
19029     {
19030       print (vam->ofp, "%=20s", "Map resolver");
19031     }
19032
19033   M (ONE_MAP_RESOLVER_DUMP, mp);
19034   /* send it... */
19035   S (mp);
19036
19037   /* Use a control ping for synchronization */
19038   MPING (CONTROL_PING, mp_ping);
19039   S (mp_ping);
19040
19041   /* Wait for a reply... */
19042   W (ret);
19043   return ret;
19044 }
19045
19046 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19047
19048 static int
19049 api_one_stats_flush (vat_main_t * vam)
19050 {
19051   vl_api_one_stats_flush_t *mp;
19052   int ret = 0;
19053
19054   M (ONE_STATS_FLUSH, mp);
19055   S (mp);
19056   W (ret);
19057   return ret;
19058 }
19059
19060 static int
19061 api_one_stats_dump (vat_main_t * vam)
19062 {
19063   vl_api_one_stats_dump_t *mp;
19064   vl_api_control_ping_t *mp_ping;
19065   int ret;
19066
19067   M (ONE_STATS_DUMP, mp);
19068   /* send it... */
19069   S (mp);
19070
19071   /* Use a control ping for synchronization */
19072   MPING (CONTROL_PING, mp_ping);
19073   S (mp_ping);
19074
19075   /* Wait for a reply... */
19076   W (ret);
19077   return ret;
19078 }
19079
19080 static int
19081 api_show_one_status (vat_main_t * vam)
19082 {
19083   vl_api_show_one_status_t *mp;
19084   int ret;
19085
19086   if (!vam->json_output)
19087     {
19088       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19089     }
19090
19091   M (SHOW_ONE_STATUS, mp);
19092   /* send it... */
19093   S (mp);
19094   /* Wait for a reply... */
19095   W (ret);
19096   return ret;
19097 }
19098
19099 #define api_show_lisp_status api_show_one_status
19100
19101 static int
19102 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19103 {
19104   vl_api_gpe_fwd_entry_path_dump_t *mp;
19105   vl_api_control_ping_t *mp_ping;
19106   unformat_input_t *i = vam->input;
19107   u32 fwd_entry_index = ~0;
19108   int ret;
19109
19110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19111     {
19112       if (unformat (i, "index %d", &fwd_entry_index))
19113         ;
19114       else
19115         break;
19116     }
19117
19118   if (~0 == fwd_entry_index)
19119     {
19120       errmsg ("no index specified!");
19121       return -99;
19122     }
19123
19124   if (!vam->json_output)
19125     {
19126       print (vam->ofp, "first line");
19127     }
19128
19129   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19130
19131   /* send it... */
19132   S (mp);
19133   /* Use a control ping for synchronization */
19134   MPING (CONTROL_PING, mp_ping);
19135   S (mp_ping);
19136
19137   /* Wait for a reply... */
19138   W (ret);
19139   return ret;
19140 }
19141
19142 static int
19143 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19144 {
19145   vl_api_one_get_map_request_itr_rlocs_t *mp;
19146   int ret;
19147
19148   if (!vam->json_output)
19149     {
19150       print (vam->ofp, "%=20s", "itr-rlocs:");
19151     }
19152
19153   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19154   /* send it... */
19155   S (mp);
19156   /* Wait for a reply... */
19157   W (ret);
19158   return ret;
19159 }
19160
19161 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19162
19163 static int
19164 api_af_packet_create (vat_main_t * vam)
19165 {
19166   unformat_input_t *i = vam->input;
19167   vl_api_af_packet_create_t *mp;
19168   u8 *host_if_name = 0;
19169   u8 hw_addr[6];
19170   u8 random_hw_addr = 1;
19171   int ret;
19172
19173   memset (hw_addr, 0, sizeof (hw_addr));
19174
19175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19176     {
19177       if (unformat (i, "name %s", &host_if_name))
19178         vec_add1 (host_if_name, 0);
19179       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19180         random_hw_addr = 0;
19181       else
19182         break;
19183     }
19184
19185   if (!vec_len (host_if_name))
19186     {
19187       errmsg ("host-interface name must be specified");
19188       return -99;
19189     }
19190
19191   if (vec_len (host_if_name) > 64)
19192     {
19193       errmsg ("host-interface name too long");
19194       return -99;
19195     }
19196
19197   M (AF_PACKET_CREATE, mp);
19198
19199   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19200   clib_memcpy (mp->hw_addr, hw_addr, 6);
19201   mp->use_random_hw_addr = random_hw_addr;
19202   vec_free (host_if_name);
19203
19204   S (mp);
19205
19206   /* *INDENT-OFF* */
19207   W2 (ret,
19208       ({
19209         if (ret == 0)
19210           fprintf (vam->ofp ? vam->ofp : stderr,
19211                    " new sw_if_index = %d\n", vam->sw_if_index);
19212       }));
19213   /* *INDENT-ON* */
19214   return ret;
19215 }
19216
19217 static int
19218 api_af_packet_delete (vat_main_t * vam)
19219 {
19220   unformat_input_t *i = vam->input;
19221   vl_api_af_packet_delete_t *mp;
19222   u8 *host_if_name = 0;
19223   int ret;
19224
19225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19226     {
19227       if (unformat (i, "name %s", &host_if_name))
19228         vec_add1 (host_if_name, 0);
19229       else
19230         break;
19231     }
19232
19233   if (!vec_len (host_if_name))
19234     {
19235       errmsg ("host-interface name must be specified");
19236       return -99;
19237     }
19238
19239   if (vec_len (host_if_name) > 64)
19240     {
19241       errmsg ("host-interface name too long");
19242       return -99;
19243     }
19244
19245   M (AF_PACKET_DELETE, mp);
19246
19247   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19248   vec_free (host_if_name);
19249
19250   S (mp);
19251   W (ret);
19252   return ret;
19253 }
19254
19255 static int
19256 api_policer_add_del (vat_main_t * vam)
19257 {
19258   unformat_input_t *i = vam->input;
19259   vl_api_policer_add_del_t *mp;
19260   u8 is_add = 1;
19261   u8 *name = 0;
19262   u32 cir = 0;
19263   u32 eir = 0;
19264   u64 cb = 0;
19265   u64 eb = 0;
19266   u8 rate_type = 0;
19267   u8 round_type = 0;
19268   u8 type = 0;
19269   u8 color_aware = 0;
19270   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19271   int ret;
19272
19273   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19274   conform_action.dscp = 0;
19275   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19276   exceed_action.dscp = 0;
19277   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19278   violate_action.dscp = 0;
19279
19280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19281     {
19282       if (unformat (i, "del"))
19283         is_add = 0;
19284       else if (unformat (i, "name %s", &name))
19285         vec_add1 (name, 0);
19286       else if (unformat (i, "cir %u", &cir))
19287         ;
19288       else if (unformat (i, "eir %u", &eir))
19289         ;
19290       else if (unformat (i, "cb %u", &cb))
19291         ;
19292       else if (unformat (i, "eb %u", &eb))
19293         ;
19294       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19295                          &rate_type))
19296         ;
19297       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19298                          &round_type))
19299         ;
19300       else if (unformat (i, "type %U", unformat_policer_type, &type))
19301         ;
19302       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19303                          &conform_action))
19304         ;
19305       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19306                          &exceed_action))
19307         ;
19308       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19309                          &violate_action))
19310         ;
19311       else if (unformat (i, "color-aware"))
19312         color_aware = 1;
19313       else
19314         break;
19315     }
19316
19317   if (!vec_len (name))
19318     {
19319       errmsg ("policer name must be specified");
19320       return -99;
19321     }
19322
19323   if (vec_len (name) > 64)
19324     {
19325       errmsg ("policer name too long");
19326       return -99;
19327     }
19328
19329   M (POLICER_ADD_DEL, mp);
19330
19331   clib_memcpy (mp->name, name, vec_len (name));
19332   vec_free (name);
19333   mp->is_add = is_add;
19334   mp->cir = ntohl (cir);
19335   mp->eir = ntohl (eir);
19336   mp->cb = clib_net_to_host_u64 (cb);
19337   mp->eb = clib_net_to_host_u64 (eb);
19338   mp->rate_type = rate_type;
19339   mp->round_type = round_type;
19340   mp->type = type;
19341   mp->conform_action_type = conform_action.action_type;
19342   mp->conform_dscp = conform_action.dscp;
19343   mp->exceed_action_type = exceed_action.action_type;
19344   mp->exceed_dscp = exceed_action.dscp;
19345   mp->violate_action_type = violate_action.action_type;
19346   mp->violate_dscp = violate_action.dscp;
19347   mp->color_aware = color_aware;
19348
19349   S (mp);
19350   W (ret);
19351   return ret;
19352 }
19353
19354 static int
19355 api_policer_dump (vat_main_t * vam)
19356 {
19357   unformat_input_t *i = vam->input;
19358   vl_api_policer_dump_t *mp;
19359   vl_api_control_ping_t *mp_ping;
19360   u8 *match_name = 0;
19361   u8 match_name_valid = 0;
19362   int ret;
19363
19364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19365     {
19366       if (unformat (i, "name %s", &match_name))
19367         {
19368           vec_add1 (match_name, 0);
19369           match_name_valid = 1;
19370         }
19371       else
19372         break;
19373     }
19374
19375   M (POLICER_DUMP, mp);
19376   mp->match_name_valid = match_name_valid;
19377   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19378   vec_free (match_name);
19379   /* send it... */
19380   S (mp);
19381
19382   /* Use a control ping for synchronization */
19383   MPING (CONTROL_PING, mp_ping);
19384   S (mp_ping);
19385
19386   /* Wait for a reply... */
19387   W (ret);
19388   return ret;
19389 }
19390
19391 static int
19392 api_policer_classify_set_interface (vat_main_t * vam)
19393 {
19394   unformat_input_t *i = vam->input;
19395   vl_api_policer_classify_set_interface_t *mp;
19396   u32 sw_if_index;
19397   int sw_if_index_set;
19398   u32 ip4_table_index = ~0;
19399   u32 ip6_table_index = ~0;
19400   u32 l2_table_index = ~0;
19401   u8 is_add = 1;
19402   int ret;
19403
19404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19405     {
19406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19407         sw_if_index_set = 1;
19408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19409         sw_if_index_set = 1;
19410       else if (unformat (i, "del"))
19411         is_add = 0;
19412       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19413         ;
19414       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19415         ;
19416       else if (unformat (i, "l2-table %d", &l2_table_index))
19417         ;
19418       else
19419         {
19420           clib_warning ("parse error '%U'", format_unformat_error, i);
19421           return -99;
19422         }
19423     }
19424
19425   if (sw_if_index_set == 0)
19426     {
19427       errmsg ("missing interface name or sw_if_index");
19428       return -99;
19429     }
19430
19431   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19432
19433   mp->sw_if_index = ntohl (sw_if_index);
19434   mp->ip4_table_index = ntohl (ip4_table_index);
19435   mp->ip6_table_index = ntohl (ip6_table_index);
19436   mp->l2_table_index = ntohl (l2_table_index);
19437   mp->is_add = is_add;
19438
19439   S (mp);
19440   W (ret);
19441   return ret;
19442 }
19443
19444 static int
19445 api_policer_classify_dump (vat_main_t * vam)
19446 {
19447   unformat_input_t *i = vam->input;
19448   vl_api_policer_classify_dump_t *mp;
19449   vl_api_control_ping_t *mp_ping;
19450   u8 type = POLICER_CLASSIFY_N_TABLES;
19451   int ret;
19452
19453   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19454     ;
19455   else
19456     {
19457       errmsg ("classify table type must be specified");
19458       return -99;
19459     }
19460
19461   if (!vam->json_output)
19462     {
19463       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19464     }
19465
19466   M (POLICER_CLASSIFY_DUMP, mp);
19467   mp->type = type;
19468   /* send it... */
19469   S (mp);
19470
19471   /* Use a control ping for synchronization */
19472   MPING (CONTROL_PING, mp_ping);
19473   S (mp_ping);
19474
19475   /* Wait for a reply... */
19476   W (ret);
19477   return ret;
19478 }
19479
19480 static int
19481 api_netmap_create (vat_main_t * vam)
19482 {
19483   unformat_input_t *i = vam->input;
19484   vl_api_netmap_create_t *mp;
19485   u8 *if_name = 0;
19486   u8 hw_addr[6];
19487   u8 random_hw_addr = 1;
19488   u8 is_pipe = 0;
19489   u8 is_master = 0;
19490   int ret;
19491
19492   memset (hw_addr, 0, sizeof (hw_addr));
19493
19494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19495     {
19496       if (unformat (i, "name %s", &if_name))
19497         vec_add1 (if_name, 0);
19498       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19499         random_hw_addr = 0;
19500       else if (unformat (i, "pipe"))
19501         is_pipe = 1;
19502       else if (unformat (i, "master"))
19503         is_master = 1;
19504       else if (unformat (i, "slave"))
19505         is_master = 0;
19506       else
19507         break;
19508     }
19509
19510   if (!vec_len (if_name))
19511     {
19512       errmsg ("interface name must be specified");
19513       return -99;
19514     }
19515
19516   if (vec_len (if_name) > 64)
19517     {
19518       errmsg ("interface name too long");
19519       return -99;
19520     }
19521
19522   M (NETMAP_CREATE, mp);
19523
19524   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19525   clib_memcpy (mp->hw_addr, hw_addr, 6);
19526   mp->use_random_hw_addr = random_hw_addr;
19527   mp->is_pipe = is_pipe;
19528   mp->is_master = is_master;
19529   vec_free (if_name);
19530
19531   S (mp);
19532   W (ret);
19533   return ret;
19534 }
19535
19536 static int
19537 api_netmap_delete (vat_main_t * vam)
19538 {
19539   unformat_input_t *i = vam->input;
19540   vl_api_netmap_delete_t *mp;
19541   u8 *if_name = 0;
19542   int ret;
19543
19544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19545     {
19546       if (unformat (i, "name %s", &if_name))
19547         vec_add1 (if_name, 0);
19548       else
19549         break;
19550     }
19551
19552   if (!vec_len (if_name))
19553     {
19554       errmsg ("interface name must be specified");
19555       return -99;
19556     }
19557
19558   if (vec_len (if_name) > 64)
19559     {
19560       errmsg ("interface name too long");
19561       return -99;
19562     }
19563
19564   M (NETMAP_DELETE, mp);
19565
19566   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19567   vec_free (if_name);
19568
19569   S (mp);
19570   W (ret);
19571   return ret;
19572 }
19573
19574 static void
19575 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19576 {
19577   if (fp->afi == IP46_TYPE_IP6)
19578     print (vam->ofp,
19579            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19580            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19581            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19582            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19583            format_ip6_address, fp->next_hop);
19584   else if (fp->afi == IP46_TYPE_IP4)
19585     print (vam->ofp,
19586            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19587            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19588            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19589            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19590            format_ip4_address, fp->next_hop);
19591 }
19592
19593 static void
19594 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19595                                  vl_api_fib_path2_t * fp)
19596 {
19597   struct in_addr ip4;
19598   struct in6_addr ip6;
19599
19600   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19601   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19602   vat_json_object_add_uint (node, "is_local", fp->is_local);
19603   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19604   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19605   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19606   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19607   if (fp->afi == IP46_TYPE_IP4)
19608     {
19609       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19610       vat_json_object_add_ip4 (node, "next_hop", ip4);
19611     }
19612   else if (fp->afi == IP46_TYPE_IP6)
19613     {
19614       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19615       vat_json_object_add_ip6 (node, "next_hop", ip6);
19616     }
19617 }
19618
19619 static void
19620 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19621 {
19622   vat_main_t *vam = &vat_main;
19623   int count = ntohl (mp->mt_count);
19624   vl_api_fib_path2_t *fp;
19625   i32 i;
19626
19627   print (vam->ofp, "[%d]: sw_if_index %d via:",
19628          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19629   fp = mp->mt_paths;
19630   for (i = 0; i < count; i++)
19631     {
19632       vl_api_mpls_fib_path_print (vam, fp);
19633       fp++;
19634     }
19635
19636   print (vam->ofp, "");
19637 }
19638
19639 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19640 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19641
19642 static void
19643 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19644 {
19645   vat_main_t *vam = &vat_main;
19646   vat_json_node_t *node = NULL;
19647   int count = ntohl (mp->mt_count);
19648   vl_api_fib_path2_t *fp;
19649   i32 i;
19650
19651   if (VAT_JSON_ARRAY != vam->json_tree.type)
19652     {
19653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19654       vat_json_init_array (&vam->json_tree);
19655     }
19656   node = vat_json_array_add (&vam->json_tree);
19657
19658   vat_json_init_object (node);
19659   vat_json_object_add_uint (node, "tunnel_index",
19660                             ntohl (mp->mt_tunnel_index));
19661   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19662
19663   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19664
19665   fp = mp->mt_paths;
19666   for (i = 0; i < count; i++)
19667     {
19668       vl_api_mpls_fib_path_json_print (node, fp);
19669       fp++;
19670     }
19671 }
19672
19673 static int
19674 api_mpls_tunnel_dump (vat_main_t * vam)
19675 {
19676   vl_api_mpls_tunnel_dump_t *mp;
19677   vl_api_control_ping_t *mp_ping;
19678   i32 index = -1;
19679   int ret;
19680
19681   /* Parse args required to build the message */
19682   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19683     {
19684       if (!unformat (vam->input, "tunnel_index %d", &index))
19685         {
19686           index = -1;
19687           break;
19688         }
19689     }
19690
19691   print (vam->ofp, "  tunnel_index %d", index);
19692
19693   M (MPLS_TUNNEL_DUMP, mp);
19694   mp->tunnel_index = htonl (index);
19695   S (mp);
19696
19697   /* Use a control ping for synchronization */
19698   MPING (CONTROL_PING, mp_ping);
19699   S (mp_ping);
19700
19701   W (ret);
19702   return ret;
19703 }
19704
19705 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19706 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19707
19708
19709 static void
19710 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19711 {
19712   vat_main_t *vam = &vat_main;
19713   int count = ntohl (mp->count);
19714   vl_api_fib_path2_t *fp;
19715   int i;
19716
19717   print (vam->ofp,
19718          "table-id %d, label %u, ess_bit %u",
19719          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19720   fp = mp->path;
19721   for (i = 0; i < count; i++)
19722     {
19723       vl_api_mpls_fib_path_print (vam, fp);
19724       fp++;
19725     }
19726 }
19727
19728 static void vl_api_mpls_fib_details_t_handler_json
19729   (vl_api_mpls_fib_details_t * mp)
19730 {
19731   vat_main_t *vam = &vat_main;
19732   int count = ntohl (mp->count);
19733   vat_json_node_t *node = NULL;
19734   vl_api_fib_path2_t *fp;
19735   int i;
19736
19737   if (VAT_JSON_ARRAY != vam->json_tree.type)
19738     {
19739       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19740       vat_json_init_array (&vam->json_tree);
19741     }
19742   node = vat_json_array_add (&vam->json_tree);
19743
19744   vat_json_init_object (node);
19745   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19746   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19747   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19748   vat_json_object_add_uint (node, "path_count", count);
19749   fp = mp->path;
19750   for (i = 0; i < count; i++)
19751     {
19752       vl_api_mpls_fib_path_json_print (node, fp);
19753       fp++;
19754     }
19755 }
19756
19757 static int
19758 api_mpls_fib_dump (vat_main_t * vam)
19759 {
19760   vl_api_mpls_fib_dump_t *mp;
19761   vl_api_control_ping_t *mp_ping;
19762   int ret;
19763
19764   M (MPLS_FIB_DUMP, mp);
19765   S (mp);
19766
19767   /* Use a control ping for synchronization */
19768   MPING (CONTROL_PING, mp_ping);
19769   S (mp_ping);
19770
19771   W (ret);
19772   return ret;
19773 }
19774
19775 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19776 #define vl_api_ip_fib_details_t_print vl_noop_handler
19777
19778 static void
19779 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19780 {
19781   vat_main_t *vam = &vat_main;
19782   int count = ntohl (mp->count);
19783   vl_api_fib_path_t *fp;
19784   int i;
19785
19786   print (vam->ofp,
19787          "table-id %d, prefix %U/%d",
19788          ntohl (mp->table_id), format_ip4_address, mp->address,
19789          mp->address_length);
19790   fp = mp->path;
19791   for (i = 0; i < count; i++)
19792     {
19793       if (fp->afi == IP46_TYPE_IP6)
19794         print (vam->ofp,
19795                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19796                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19797                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19798                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19799                format_ip6_address, fp->next_hop);
19800       else if (fp->afi == IP46_TYPE_IP4)
19801         print (vam->ofp,
19802                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19803                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19804                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19805                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19806                format_ip4_address, fp->next_hop);
19807       fp++;
19808     }
19809 }
19810
19811 static void vl_api_ip_fib_details_t_handler_json
19812   (vl_api_ip_fib_details_t * mp)
19813 {
19814   vat_main_t *vam = &vat_main;
19815   int count = ntohl (mp->count);
19816   vat_json_node_t *node = NULL;
19817   struct in_addr ip4;
19818   struct in6_addr ip6;
19819   vl_api_fib_path_t *fp;
19820   int i;
19821
19822   if (VAT_JSON_ARRAY != vam->json_tree.type)
19823     {
19824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19825       vat_json_init_array (&vam->json_tree);
19826     }
19827   node = vat_json_array_add (&vam->json_tree);
19828
19829   vat_json_init_object (node);
19830   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19831   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19832   vat_json_object_add_ip4 (node, "prefix", ip4);
19833   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19834   vat_json_object_add_uint (node, "path_count", count);
19835   fp = mp->path;
19836   for (i = 0; i < count; i++)
19837     {
19838       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19839       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19840       vat_json_object_add_uint (node, "is_local", fp->is_local);
19841       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19842       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19843       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19844       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19845       if (fp->afi == IP46_TYPE_IP4)
19846         {
19847           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19848           vat_json_object_add_ip4 (node, "next_hop", ip4);
19849         }
19850       else if (fp->afi == IP46_TYPE_IP6)
19851         {
19852           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19853           vat_json_object_add_ip6 (node, "next_hop", ip6);
19854         }
19855     }
19856 }
19857
19858 static int
19859 api_ip_fib_dump (vat_main_t * vam)
19860 {
19861   vl_api_ip_fib_dump_t *mp;
19862   vl_api_control_ping_t *mp_ping;
19863   int ret;
19864
19865   M (IP_FIB_DUMP, mp);
19866   S (mp);
19867
19868   /* Use a control ping for synchronization */
19869   MPING (CONTROL_PING, mp_ping);
19870   S (mp_ping);
19871
19872   W (ret);
19873   return ret;
19874 }
19875
19876 static int
19877 api_ip_mfib_dump (vat_main_t * vam)
19878 {
19879   vl_api_ip_mfib_dump_t *mp;
19880   vl_api_control_ping_t *mp_ping;
19881   int ret;
19882
19883   M (IP_MFIB_DUMP, mp);
19884   S (mp);
19885
19886   /* Use a control ping for synchronization */
19887   MPING (CONTROL_PING, mp_ping);
19888   S (mp_ping);
19889
19890   W (ret);
19891   return ret;
19892 }
19893
19894 static void vl_api_ip_neighbor_details_t_handler
19895   (vl_api_ip_neighbor_details_t * mp)
19896 {
19897   vat_main_t *vam = &vat_main;
19898
19899   print (vam->ofp, "%c %U %U",
19900          (mp->is_static) ? 'S' : 'D',
19901          format_ethernet_address, &mp->mac_address,
19902          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19903          &mp->ip_address);
19904 }
19905
19906 static void vl_api_ip_neighbor_details_t_handler_json
19907   (vl_api_ip_neighbor_details_t * mp)
19908 {
19909
19910   vat_main_t *vam = &vat_main;
19911   vat_json_node_t *node;
19912   struct in_addr ip4;
19913   struct in6_addr ip6;
19914
19915   if (VAT_JSON_ARRAY != vam->json_tree.type)
19916     {
19917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19918       vat_json_init_array (&vam->json_tree);
19919     }
19920   node = vat_json_array_add (&vam->json_tree);
19921
19922   vat_json_init_object (node);
19923   vat_json_object_add_string_copy (node, "flag",
19924                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19925                                    "dynamic");
19926
19927   vat_json_object_add_string_copy (node, "link_layer",
19928                                    format (0, "%U", format_ethernet_address,
19929                                            &mp->mac_address));
19930
19931   if (mp->is_ipv6)
19932     {
19933       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19934       vat_json_object_add_ip6 (node, "ip_address", ip6);
19935     }
19936   else
19937     {
19938       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19939       vat_json_object_add_ip4 (node, "ip_address", ip4);
19940     }
19941 }
19942
19943 static int
19944 api_ip_neighbor_dump (vat_main_t * vam)
19945 {
19946   unformat_input_t *i = vam->input;
19947   vl_api_ip_neighbor_dump_t *mp;
19948   vl_api_control_ping_t *mp_ping;
19949   u8 is_ipv6 = 0;
19950   u32 sw_if_index = ~0;
19951   int ret;
19952
19953   /* Parse args required to build the message */
19954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19955     {
19956       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19957         ;
19958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19959         ;
19960       else if (unformat (i, "ip6"))
19961         is_ipv6 = 1;
19962       else
19963         break;
19964     }
19965
19966   if (sw_if_index == ~0)
19967     {
19968       errmsg ("missing interface name or sw_if_index");
19969       return -99;
19970     }
19971
19972   M (IP_NEIGHBOR_DUMP, mp);
19973   mp->is_ipv6 = (u8) is_ipv6;
19974   mp->sw_if_index = ntohl (sw_if_index);
19975   S (mp);
19976
19977   /* Use a control ping for synchronization */
19978   MPING (CONTROL_PING, mp_ping);
19979   S (mp_ping);
19980
19981   W (ret);
19982   return ret;
19983 }
19984
19985 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19986 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19987
19988 static void
19989 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19990 {
19991   vat_main_t *vam = &vat_main;
19992   int count = ntohl (mp->count);
19993   vl_api_fib_path_t *fp;
19994   int i;
19995
19996   print (vam->ofp,
19997          "table-id %d, prefix %U/%d",
19998          ntohl (mp->table_id), format_ip6_address, mp->address,
19999          mp->address_length);
20000   fp = mp->path;
20001   for (i = 0; i < count; i++)
20002     {
20003       if (fp->afi == IP46_TYPE_IP6)
20004         print (vam->ofp,
20005                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20006                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20007                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20008                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20009                format_ip6_address, fp->next_hop);
20010       else if (fp->afi == IP46_TYPE_IP4)
20011         print (vam->ofp,
20012                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20013                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20014                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20015                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20016                format_ip4_address, fp->next_hop);
20017       fp++;
20018     }
20019 }
20020
20021 static void vl_api_ip6_fib_details_t_handler_json
20022   (vl_api_ip6_fib_details_t * mp)
20023 {
20024   vat_main_t *vam = &vat_main;
20025   int count = ntohl (mp->count);
20026   vat_json_node_t *node = NULL;
20027   struct in_addr ip4;
20028   struct in6_addr ip6;
20029   vl_api_fib_path_t *fp;
20030   int i;
20031
20032   if (VAT_JSON_ARRAY != vam->json_tree.type)
20033     {
20034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20035       vat_json_init_array (&vam->json_tree);
20036     }
20037   node = vat_json_array_add (&vam->json_tree);
20038
20039   vat_json_init_object (node);
20040   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20041   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20042   vat_json_object_add_ip6 (node, "prefix", ip6);
20043   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20044   vat_json_object_add_uint (node, "path_count", count);
20045   fp = mp->path;
20046   for (i = 0; i < count; i++)
20047     {
20048       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20049       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20050       vat_json_object_add_uint (node, "is_local", fp->is_local);
20051       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20052       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20053       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20054       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20055       if (fp->afi == IP46_TYPE_IP4)
20056         {
20057           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20058           vat_json_object_add_ip4 (node, "next_hop", ip4);
20059         }
20060       else if (fp->afi == IP46_TYPE_IP6)
20061         {
20062           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20063           vat_json_object_add_ip6 (node, "next_hop", ip6);
20064         }
20065     }
20066 }
20067
20068 static int
20069 api_ip6_fib_dump (vat_main_t * vam)
20070 {
20071   vl_api_ip6_fib_dump_t *mp;
20072   vl_api_control_ping_t *mp_ping;
20073   int ret;
20074
20075   M (IP6_FIB_DUMP, mp);
20076   S (mp);
20077
20078   /* Use a control ping for synchronization */
20079   MPING (CONTROL_PING, mp_ping);
20080   S (mp_ping);
20081
20082   W (ret);
20083   return ret;
20084 }
20085
20086 static int
20087 api_ip6_mfib_dump (vat_main_t * vam)
20088 {
20089   vl_api_ip6_mfib_dump_t *mp;
20090   vl_api_control_ping_t *mp_ping;
20091   int ret;
20092
20093   M (IP6_MFIB_DUMP, mp);
20094   S (mp);
20095
20096   /* Use a control ping for synchronization */
20097   MPING (CONTROL_PING, mp_ping);
20098   S (mp_ping);
20099
20100   W (ret);
20101   return ret;
20102 }
20103
20104 int
20105 api_classify_table_ids (vat_main_t * vam)
20106 {
20107   vl_api_classify_table_ids_t *mp;
20108   int ret;
20109
20110   /* Construct the API message */
20111   M (CLASSIFY_TABLE_IDS, mp);
20112   mp->context = 0;
20113
20114   S (mp);
20115   W (ret);
20116   return ret;
20117 }
20118
20119 int
20120 api_classify_table_by_interface (vat_main_t * vam)
20121 {
20122   unformat_input_t *input = vam->input;
20123   vl_api_classify_table_by_interface_t *mp;
20124
20125   u32 sw_if_index = ~0;
20126   int ret;
20127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20128     {
20129       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20130         ;
20131       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20132         ;
20133       else
20134         break;
20135     }
20136   if (sw_if_index == ~0)
20137     {
20138       errmsg ("missing interface name or sw_if_index");
20139       return -99;
20140     }
20141
20142   /* Construct the API message */
20143   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20144   mp->context = 0;
20145   mp->sw_if_index = ntohl (sw_if_index);
20146
20147   S (mp);
20148   W (ret);
20149   return ret;
20150 }
20151
20152 int
20153 api_classify_table_info (vat_main_t * vam)
20154 {
20155   unformat_input_t *input = vam->input;
20156   vl_api_classify_table_info_t *mp;
20157
20158   u32 table_id = ~0;
20159   int ret;
20160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20161     {
20162       if (unformat (input, "table_id %d", &table_id))
20163         ;
20164       else
20165         break;
20166     }
20167   if (table_id == ~0)
20168     {
20169       errmsg ("missing table id");
20170       return -99;
20171     }
20172
20173   /* Construct the API message */
20174   M (CLASSIFY_TABLE_INFO, mp);
20175   mp->context = 0;
20176   mp->table_id = ntohl (table_id);
20177
20178   S (mp);
20179   W (ret);
20180   return ret;
20181 }
20182
20183 int
20184 api_classify_session_dump (vat_main_t * vam)
20185 {
20186   unformat_input_t *input = vam->input;
20187   vl_api_classify_session_dump_t *mp;
20188   vl_api_control_ping_t *mp_ping;
20189
20190   u32 table_id = ~0;
20191   int ret;
20192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20193     {
20194       if (unformat (input, "table_id %d", &table_id))
20195         ;
20196       else
20197         break;
20198     }
20199   if (table_id == ~0)
20200     {
20201       errmsg ("missing table id");
20202       return -99;
20203     }
20204
20205   /* Construct the API message */
20206   M (CLASSIFY_SESSION_DUMP, mp);
20207   mp->context = 0;
20208   mp->table_id = ntohl (table_id);
20209   S (mp);
20210
20211   /* Use a control ping for synchronization */
20212   MPING (CONTROL_PING, mp_ping);
20213   S (mp_ping);
20214
20215   W (ret);
20216   return ret;
20217 }
20218
20219 static void
20220 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20221 {
20222   vat_main_t *vam = &vat_main;
20223
20224   print (vam->ofp, "collector_address %U, collector_port %d, "
20225          "src_address %U, vrf_id %d, path_mtu %u, "
20226          "template_interval %u, udp_checksum %d",
20227          format_ip4_address, mp->collector_address,
20228          ntohs (mp->collector_port),
20229          format_ip4_address, mp->src_address,
20230          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20231          ntohl (mp->template_interval), mp->udp_checksum);
20232
20233   vam->retval = 0;
20234   vam->result_ready = 1;
20235 }
20236
20237 static void
20238   vl_api_ipfix_exporter_details_t_handler_json
20239   (vl_api_ipfix_exporter_details_t * mp)
20240 {
20241   vat_main_t *vam = &vat_main;
20242   vat_json_node_t node;
20243   struct in_addr collector_address;
20244   struct in_addr src_address;
20245
20246   vat_json_init_object (&node);
20247   clib_memcpy (&collector_address, &mp->collector_address,
20248                sizeof (collector_address));
20249   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20250   vat_json_object_add_uint (&node, "collector_port",
20251                             ntohs (mp->collector_port));
20252   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20253   vat_json_object_add_ip4 (&node, "src_address", src_address);
20254   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20255   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20256   vat_json_object_add_uint (&node, "template_interval",
20257                             ntohl (mp->template_interval));
20258   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20259
20260   vat_json_print (vam->ofp, &node);
20261   vat_json_free (&node);
20262   vam->retval = 0;
20263   vam->result_ready = 1;
20264 }
20265
20266 int
20267 api_ipfix_exporter_dump (vat_main_t * vam)
20268 {
20269   vl_api_ipfix_exporter_dump_t *mp;
20270   int ret;
20271
20272   /* Construct the API message */
20273   M (IPFIX_EXPORTER_DUMP, mp);
20274   mp->context = 0;
20275
20276   S (mp);
20277   W (ret);
20278   return ret;
20279 }
20280
20281 static int
20282 api_ipfix_classify_stream_dump (vat_main_t * vam)
20283 {
20284   vl_api_ipfix_classify_stream_dump_t *mp;
20285   int ret;
20286
20287   /* Construct the API message */
20288   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20289   mp->context = 0;
20290
20291   S (mp);
20292   W (ret);
20293   return ret;
20294   /* NOTREACHED */
20295   return 0;
20296 }
20297
20298 static void
20299   vl_api_ipfix_classify_stream_details_t_handler
20300   (vl_api_ipfix_classify_stream_details_t * mp)
20301 {
20302   vat_main_t *vam = &vat_main;
20303   print (vam->ofp, "domain_id %d, src_port %d",
20304          ntohl (mp->domain_id), ntohs (mp->src_port));
20305   vam->retval = 0;
20306   vam->result_ready = 1;
20307 }
20308
20309 static void
20310   vl_api_ipfix_classify_stream_details_t_handler_json
20311   (vl_api_ipfix_classify_stream_details_t * mp)
20312 {
20313   vat_main_t *vam = &vat_main;
20314   vat_json_node_t node;
20315
20316   vat_json_init_object (&node);
20317   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20318   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20319
20320   vat_json_print (vam->ofp, &node);
20321   vat_json_free (&node);
20322   vam->retval = 0;
20323   vam->result_ready = 1;
20324 }
20325
20326 static int
20327 api_ipfix_classify_table_dump (vat_main_t * vam)
20328 {
20329   vl_api_ipfix_classify_table_dump_t *mp;
20330   vl_api_control_ping_t *mp_ping;
20331   int ret;
20332
20333   if (!vam->json_output)
20334     {
20335       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20336              "transport_protocol");
20337     }
20338
20339   /* Construct the API message */
20340   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20341
20342   /* send it... */
20343   S (mp);
20344
20345   /* Use a control ping for synchronization */
20346   MPING (CONTROL_PING, mp_ping);
20347   S (mp_ping);
20348
20349   W (ret);
20350   return ret;
20351 }
20352
20353 static void
20354   vl_api_ipfix_classify_table_details_t_handler
20355   (vl_api_ipfix_classify_table_details_t * mp)
20356 {
20357   vat_main_t *vam = &vat_main;
20358   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20359          mp->transport_protocol);
20360 }
20361
20362 static void
20363   vl_api_ipfix_classify_table_details_t_handler_json
20364   (vl_api_ipfix_classify_table_details_t * mp)
20365 {
20366   vat_json_node_t *node = NULL;
20367   vat_main_t *vam = &vat_main;
20368
20369   if (VAT_JSON_ARRAY != vam->json_tree.type)
20370     {
20371       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20372       vat_json_init_array (&vam->json_tree);
20373     }
20374
20375   node = vat_json_array_add (&vam->json_tree);
20376   vat_json_init_object (node);
20377
20378   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20379   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20380   vat_json_object_add_uint (node, "transport_protocol",
20381                             mp->transport_protocol);
20382 }
20383
20384 static int
20385 api_sw_interface_span_enable_disable (vat_main_t * vam)
20386 {
20387   unformat_input_t *i = vam->input;
20388   vl_api_sw_interface_span_enable_disable_t *mp;
20389   u32 src_sw_if_index = ~0;
20390   u32 dst_sw_if_index = ~0;
20391   u8 state = 3;
20392   int ret;
20393   u8 is_l2 = 0;
20394
20395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20396     {
20397       if (unformat
20398           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20399         ;
20400       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20401         ;
20402       else
20403         if (unformat
20404             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20405         ;
20406       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20407         ;
20408       else if (unformat (i, "disable"))
20409         state = 0;
20410       else if (unformat (i, "rx"))
20411         state = 1;
20412       else if (unformat (i, "tx"))
20413         state = 2;
20414       else if (unformat (i, "both"))
20415         state = 3;
20416       else if (unformat (i, "l2"))
20417         is_l2 = 1;
20418       else
20419         break;
20420     }
20421
20422   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20423
20424   mp->sw_if_index_from = htonl (src_sw_if_index);
20425   mp->sw_if_index_to = htonl (dst_sw_if_index);
20426   mp->state = state;
20427   mp->is_l2 = is_l2;
20428
20429   S (mp);
20430   W (ret);
20431   return ret;
20432 }
20433
20434 static void
20435 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20436                                             * mp)
20437 {
20438   vat_main_t *vam = &vat_main;
20439   u8 *sw_if_from_name = 0;
20440   u8 *sw_if_to_name = 0;
20441   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20442   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20443   char *states[] = { "none", "rx", "tx", "both" };
20444   hash_pair_t *p;
20445
20446   /* *INDENT-OFF* */
20447   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20448   ({
20449     if ((u32) p->value[0] == sw_if_index_from)
20450       {
20451         sw_if_from_name = (u8 *)(p->key);
20452         if (sw_if_to_name)
20453           break;
20454       }
20455     if ((u32) p->value[0] == sw_if_index_to)
20456       {
20457         sw_if_to_name = (u8 *)(p->key);
20458         if (sw_if_from_name)
20459           break;
20460       }
20461   }));
20462   /* *INDENT-ON* */
20463   print (vam->ofp, "%20s => %20s (%s)",
20464          sw_if_from_name, sw_if_to_name, states[mp->state]);
20465 }
20466
20467 static void
20468   vl_api_sw_interface_span_details_t_handler_json
20469   (vl_api_sw_interface_span_details_t * mp)
20470 {
20471   vat_main_t *vam = &vat_main;
20472   vat_json_node_t *node = NULL;
20473   u8 *sw_if_from_name = 0;
20474   u8 *sw_if_to_name = 0;
20475   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20476   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20477   hash_pair_t *p;
20478
20479   /* *INDENT-OFF* */
20480   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20481   ({
20482     if ((u32) p->value[0] == sw_if_index_from)
20483       {
20484         sw_if_from_name = (u8 *)(p->key);
20485         if (sw_if_to_name)
20486           break;
20487       }
20488     if ((u32) p->value[0] == sw_if_index_to)
20489       {
20490         sw_if_to_name = (u8 *)(p->key);
20491         if (sw_if_from_name)
20492           break;
20493       }
20494   }));
20495   /* *INDENT-ON* */
20496
20497   if (VAT_JSON_ARRAY != vam->json_tree.type)
20498     {
20499       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20500       vat_json_init_array (&vam->json_tree);
20501     }
20502   node = vat_json_array_add (&vam->json_tree);
20503
20504   vat_json_init_object (node);
20505   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20506   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20507   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20508   if (0 != sw_if_to_name)
20509     {
20510       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20511     }
20512   vat_json_object_add_uint (node, "state", mp->state);
20513 }
20514
20515 static int
20516 api_sw_interface_span_dump (vat_main_t * vam)
20517 {
20518   unformat_input_t *input = vam->input;
20519   vl_api_sw_interface_span_dump_t *mp;
20520   vl_api_control_ping_t *mp_ping;
20521   u8 is_l2 = 0;
20522   int ret;
20523
20524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20525     {
20526       if (unformat (input, "l2"))
20527         is_l2 = 1;
20528       else
20529         break;
20530     }
20531
20532   M (SW_INTERFACE_SPAN_DUMP, mp);
20533   mp->is_l2 = is_l2;
20534   S (mp);
20535
20536   /* Use a control ping for synchronization */
20537   MPING (CONTROL_PING, mp_ping);
20538   S (mp_ping);
20539
20540   W (ret);
20541   return ret;
20542 }
20543
20544 int
20545 api_pg_create_interface (vat_main_t * vam)
20546 {
20547   unformat_input_t *input = vam->input;
20548   vl_api_pg_create_interface_t *mp;
20549
20550   u32 if_id = ~0;
20551   int ret;
20552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20553     {
20554       if (unformat (input, "if_id %d", &if_id))
20555         ;
20556       else
20557         break;
20558     }
20559   if (if_id == ~0)
20560     {
20561       errmsg ("missing pg interface index");
20562       return -99;
20563     }
20564
20565   /* Construct the API message */
20566   M (PG_CREATE_INTERFACE, mp);
20567   mp->context = 0;
20568   mp->interface_id = ntohl (if_id);
20569
20570   S (mp);
20571   W (ret);
20572   return ret;
20573 }
20574
20575 int
20576 api_pg_capture (vat_main_t * vam)
20577 {
20578   unformat_input_t *input = vam->input;
20579   vl_api_pg_capture_t *mp;
20580
20581   u32 if_id = ~0;
20582   u8 enable = 1;
20583   u32 count = 1;
20584   u8 pcap_file_set = 0;
20585   u8 *pcap_file = 0;
20586   int ret;
20587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20588     {
20589       if (unformat (input, "if_id %d", &if_id))
20590         ;
20591       else if (unformat (input, "pcap %s", &pcap_file))
20592         pcap_file_set = 1;
20593       else if (unformat (input, "count %d", &count))
20594         ;
20595       else if (unformat (input, "disable"))
20596         enable = 0;
20597       else
20598         break;
20599     }
20600   if (if_id == ~0)
20601     {
20602       errmsg ("missing pg interface index");
20603       return -99;
20604     }
20605   if (pcap_file_set > 0)
20606     {
20607       if (vec_len (pcap_file) > 255)
20608         {
20609           errmsg ("pcap file name is too long");
20610           return -99;
20611         }
20612     }
20613
20614   u32 name_len = vec_len (pcap_file);
20615   /* Construct the API message */
20616   M (PG_CAPTURE, mp);
20617   mp->context = 0;
20618   mp->interface_id = ntohl (if_id);
20619   mp->is_enabled = enable;
20620   mp->count = ntohl (count);
20621   mp->pcap_name_length = ntohl (name_len);
20622   if (pcap_file_set != 0)
20623     {
20624       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20625     }
20626   vec_free (pcap_file);
20627
20628   S (mp);
20629   W (ret);
20630   return ret;
20631 }
20632
20633 int
20634 api_pg_enable_disable (vat_main_t * vam)
20635 {
20636   unformat_input_t *input = vam->input;
20637   vl_api_pg_enable_disable_t *mp;
20638
20639   u8 enable = 1;
20640   u8 stream_name_set = 0;
20641   u8 *stream_name = 0;
20642   int ret;
20643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20644     {
20645       if (unformat (input, "stream %s", &stream_name))
20646         stream_name_set = 1;
20647       else if (unformat (input, "disable"))
20648         enable = 0;
20649       else
20650         break;
20651     }
20652
20653   if (stream_name_set > 0)
20654     {
20655       if (vec_len (stream_name) > 255)
20656         {
20657           errmsg ("stream name too long");
20658           return -99;
20659         }
20660     }
20661
20662   u32 name_len = vec_len (stream_name);
20663   /* Construct the API message */
20664   M (PG_ENABLE_DISABLE, mp);
20665   mp->context = 0;
20666   mp->is_enabled = enable;
20667   if (stream_name_set != 0)
20668     {
20669       mp->stream_name_length = ntohl (name_len);
20670       clib_memcpy (mp->stream_name, stream_name, name_len);
20671     }
20672   vec_free (stream_name);
20673
20674   S (mp);
20675   W (ret);
20676   return ret;
20677 }
20678
20679 int
20680 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20681 {
20682   unformat_input_t *input = vam->input;
20683   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20684
20685   u16 *low_ports = 0;
20686   u16 *high_ports = 0;
20687   u16 this_low;
20688   u16 this_hi;
20689   ip4_address_t ip4_addr;
20690   ip6_address_t ip6_addr;
20691   u32 length;
20692   u32 tmp, tmp2;
20693   u8 prefix_set = 0;
20694   u32 vrf_id = ~0;
20695   u8 is_add = 1;
20696   u8 is_ipv6 = 0;
20697   int ret;
20698
20699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20700     {
20701       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20702         {
20703           prefix_set = 1;
20704         }
20705       else
20706         if (unformat
20707             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20708         {
20709           prefix_set = 1;
20710           is_ipv6 = 1;
20711         }
20712       else if (unformat (input, "vrf %d", &vrf_id))
20713         ;
20714       else if (unformat (input, "del"))
20715         is_add = 0;
20716       else if (unformat (input, "port %d", &tmp))
20717         {
20718           if (tmp == 0 || tmp > 65535)
20719             {
20720               errmsg ("port %d out of range", tmp);
20721               return -99;
20722             }
20723           this_low = tmp;
20724           this_hi = this_low + 1;
20725           vec_add1 (low_ports, this_low);
20726           vec_add1 (high_ports, this_hi);
20727         }
20728       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20729         {
20730           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20731             {
20732               errmsg ("incorrect range parameters");
20733               return -99;
20734             }
20735           this_low = tmp;
20736           /* Note: in debug CLI +1 is added to high before
20737              passing to real fn that does "the work"
20738              (ip_source_and_port_range_check_add_del).
20739              This fn is a wrapper around the binary API fn a
20740              control plane will call, which expects this increment
20741              to have occurred. Hence letting the binary API control
20742              plane fn do the increment for consistency between VAT
20743              and other control planes.
20744            */
20745           this_hi = tmp2;
20746           vec_add1 (low_ports, this_low);
20747           vec_add1 (high_ports, this_hi);
20748         }
20749       else
20750         break;
20751     }
20752
20753   if (prefix_set == 0)
20754     {
20755       errmsg ("<address>/<mask> not specified");
20756       return -99;
20757     }
20758
20759   if (vrf_id == ~0)
20760     {
20761       errmsg ("VRF ID required, not specified");
20762       return -99;
20763     }
20764
20765   if (vrf_id == 0)
20766     {
20767       errmsg
20768         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20769       return -99;
20770     }
20771
20772   if (vec_len (low_ports) == 0)
20773     {
20774       errmsg ("At least one port or port range required");
20775       return -99;
20776     }
20777
20778   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20779
20780   mp->is_add = is_add;
20781
20782   if (is_ipv6)
20783     {
20784       mp->is_ipv6 = 1;
20785       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20786     }
20787   else
20788     {
20789       mp->is_ipv6 = 0;
20790       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20791     }
20792
20793   mp->mask_length = length;
20794   mp->number_of_ranges = vec_len (low_ports);
20795
20796   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20797   vec_free (low_ports);
20798
20799   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20800   vec_free (high_ports);
20801
20802   mp->vrf_id = ntohl (vrf_id);
20803
20804   S (mp);
20805   W (ret);
20806   return ret;
20807 }
20808
20809 int
20810 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20811 {
20812   unformat_input_t *input = vam->input;
20813   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20814   u32 sw_if_index = ~0;
20815   int vrf_set = 0;
20816   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20817   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20818   u8 is_add = 1;
20819   int ret;
20820
20821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20822     {
20823       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20824         ;
20825       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20826         ;
20827       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20828         vrf_set = 1;
20829       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20830         vrf_set = 1;
20831       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20832         vrf_set = 1;
20833       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20834         vrf_set = 1;
20835       else if (unformat (input, "del"))
20836         is_add = 0;
20837       else
20838         break;
20839     }
20840
20841   if (sw_if_index == ~0)
20842     {
20843       errmsg ("Interface required but not specified");
20844       return -99;
20845     }
20846
20847   if (vrf_set == 0)
20848     {
20849       errmsg ("VRF ID required but not specified");
20850       return -99;
20851     }
20852
20853   if (tcp_out_vrf_id == 0
20854       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20855     {
20856       errmsg
20857         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20858       return -99;
20859     }
20860
20861   /* Construct the API message */
20862   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20863
20864   mp->sw_if_index = ntohl (sw_if_index);
20865   mp->is_add = is_add;
20866   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20867   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20868   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20869   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20870
20871   /* send it... */
20872   S (mp);
20873
20874   /* Wait for a reply... */
20875   W (ret);
20876   return ret;
20877 }
20878
20879 static int
20880 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20881 {
20882   unformat_input_t *i = vam->input;
20883   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20884   u32 local_sa_id = 0;
20885   u32 remote_sa_id = 0;
20886   ip4_address_t src_address;
20887   ip4_address_t dst_address;
20888   u8 is_add = 1;
20889   int ret;
20890
20891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20892     {
20893       if (unformat (i, "local_sa %d", &local_sa_id))
20894         ;
20895       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20896         ;
20897       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20898         ;
20899       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20900         ;
20901       else if (unformat (i, "del"))
20902         is_add = 0;
20903       else
20904         {
20905           clib_warning ("parse error '%U'", format_unformat_error, i);
20906           return -99;
20907         }
20908     }
20909
20910   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20911
20912   mp->local_sa_id = ntohl (local_sa_id);
20913   mp->remote_sa_id = ntohl (remote_sa_id);
20914   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20915   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20916   mp->is_add = is_add;
20917
20918   S (mp);
20919   W (ret);
20920   return ret;
20921 }
20922
20923 static int
20924 api_punt (vat_main_t * vam)
20925 {
20926   unformat_input_t *i = vam->input;
20927   vl_api_punt_t *mp;
20928   u32 ipv = ~0;
20929   u32 protocol = ~0;
20930   u32 port = ~0;
20931   int is_add = 1;
20932   int ret;
20933
20934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20935     {
20936       if (unformat (i, "ip %d", &ipv))
20937         ;
20938       else if (unformat (i, "protocol %d", &protocol))
20939         ;
20940       else if (unformat (i, "port %d", &port))
20941         ;
20942       else if (unformat (i, "del"))
20943         is_add = 0;
20944       else
20945         {
20946           clib_warning ("parse error '%U'", format_unformat_error, i);
20947           return -99;
20948         }
20949     }
20950
20951   M (PUNT, mp);
20952
20953   mp->is_add = (u8) is_add;
20954   mp->ipv = (u8) ipv;
20955   mp->l4_protocol = (u8) protocol;
20956   mp->l4_port = htons ((u16) port);
20957
20958   S (mp);
20959   W (ret);
20960   return ret;
20961 }
20962
20963 static void vl_api_ipsec_gre_tunnel_details_t_handler
20964   (vl_api_ipsec_gre_tunnel_details_t * mp)
20965 {
20966   vat_main_t *vam = &vat_main;
20967
20968   print (vam->ofp, "%11d%15U%15U%14d%14d",
20969          ntohl (mp->sw_if_index),
20970          format_ip4_address, &mp->src_address,
20971          format_ip4_address, &mp->dst_address,
20972          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20973 }
20974
20975 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20976   (vl_api_ipsec_gre_tunnel_details_t * mp)
20977 {
20978   vat_main_t *vam = &vat_main;
20979   vat_json_node_t *node = NULL;
20980   struct in_addr ip4;
20981
20982   if (VAT_JSON_ARRAY != vam->json_tree.type)
20983     {
20984       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20985       vat_json_init_array (&vam->json_tree);
20986     }
20987   node = vat_json_array_add (&vam->json_tree);
20988
20989   vat_json_init_object (node);
20990   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20991   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20992   vat_json_object_add_ip4 (node, "src_address", ip4);
20993   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20994   vat_json_object_add_ip4 (node, "dst_address", ip4);
20995   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20996   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20997 }
20998
20999 static int
21000 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21001 {
21002   unformat_input_t *i = vam->input;
21003   vl_api_ipsec_gre_tunnel_dump_t *mp;
21004   vl_api_control_ping_t *mp_ping;
21005   u32 sw_if_index;
21006   u8 sw_if_index_set = 0;
21007   int ret;
21008
21009   /* Parse args required to build the message */
21010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21011     {
21012       if (unformat (i, "sw_if_index %d", &sw_if_index))
21013         sw_if_index_set = 1;
21014       else
21015         break;
21016     }
21017
21018   if (sw_if_index_set == 0)
21019     {
21020       sw_if_index = ~0;
21021     }
21022
21023   if (!vam->json_output)
21024     {
21025       print (vam->ofp, "%11s%15s%15s%14s%14s",
21026              "sw_if_index", "src_address", "dst_address",
21027              "local_sa_id", "remote_sa_id");
21028     }
21029
21030   /* Get list of gre-tunnel interfaces */
21031   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21032
21033   mp->sw_if_index = htonl (sw_if_index);
21034
21035   S (mp);
21036
21037   /* Use a control ping for synchronization */
21038   MPING (CONTROL_PING, mp_ping);
21039   S (mp_ping);
21040
21041   W (ret);
21042   return ret;
21043 }
21044
21045 static int
21046 api_delete_subif (vat_main_t * vam)
21047 {
21048   unformat_input_t *i = vam->input;
21049   vl_api_delete_subif_t *mp;
21050   u32 sw_if_index = ~0;
21051   int ret;
21052
21053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21054     {
21055       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21056         ;
21057       if (unformat (i, "sw_if_index %d", &sw_if_index))
21058         ;
21059       else
21060         break;
21061     }
21062
21063   if (sw_if_index == ~0)
21064     {
21065       errmsg ("missing sw_if_index");
21066       return -99;
21067     }
21068
21069   /* Construct the API message */
21070   M (DELETE_SUBIF, mp);
21071   mp->sw_if_index = ntohl (sw_if_index);
21072
21073   S (mp);
21074   W (ret);
21075   return ret;
21076 }
21077
21078 #define foreach_pbb_vtr_op      \
21079 _("disable",  L2_VTR_DISABLED)  \
21080 _("pop",  L2_VTR_POP_2)         \
21081 _("push",  L2_VTR_PUSH_2)
21082
21083 static int
21084 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21085 {
21086   unformat_input_t *i = vam->input;
21087   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21088   u32 sw_if_index = ~0, vtr_op = ~0;
21089   u16 outer_tag = ~0;
21090   u8 dmac[6], smac[6];
21091   u8 dmac_set = 0, smac_set = 0;
21092   u16 vlanid = 0;
21093   u32 sid = ~0;
21094   u32 tmp;
21095   int ret;
21096
21097   /* Shut up coverity */
21098   memset (dmac, 0, sizeof (dmac));
21099   memset (smac, 0, sizeof (smac));
21100
21101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21102     {
21103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21104         ;
21105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21106         ;
21107       else if (unformat (i, "vtr_op %d", &vtr_op))
21108         ;
21109 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21110       foreach_pbb_vtr_op
21111 #undef _
21112         else if (unformat (i, "translate_pbb_stag"))
21113         {
21114           if (unformat (i, "%d", &tmp))
21115             {
21116               vtr_op = L2_VTR_TRANSLATE_2_1;
21117               outer_tag = tmp;
21118             }
21119           else
21120             {
21121               errmsg
21122                 ("translate_pbb_stag operation requires outer tag definition");
21123               return -99;
21124             }
21125         }
21126       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21127         dmac_set++;
21128       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21129         smac_set++;
21130       else if (unformat (i, "sid %d", &sid))
21131         ;
21132       else if (unformat (i, "vlanid %d", &tmp))
21133         vlanid = tmp;
21134       else
21135         {
21136           clib_warning ("parse error '%U'", format_unformat_error, i);
21137           return -99;
21138         }
21139     }
21140
21141   if ((sw_if_index == ~0) || (vtr_op == ~0))
21142     {
21143       errmsg ("missing sw_if_index or vtr operation");
21144       return -99;
21145     }
21146   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21147       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21148     {
21149       errmsg
21150         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21151       return -99;
21152     }
21153
21154   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21155   mp->sw_if_index = ntohl (sw_if_index);
21156   mp->vtr_op = ntohl (vtr_op);
21157   mp->outer_tag = ntohs (outer_tag);
21158   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21159   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21160   mp->b_vlanid = ntohs (vlanid);
21161   mp->i_sid = ntohl (sid);
21162
21163   S (mp);
21164   W (ret);
21165   return ret;
21166 }
21167
21168 static int
21169 api_flow_classify_set_interface (vat_main_t * vam)
21170 {
21171   unformat_input_t *i = vam->input;
21172   vl_api_flow_classify_set_interface_t *mp;
21173   u32 sw_if_index;
21174   int sw_if_index_set;
21175   u32 ip4_table_index = ~0;
21176   u32 ip6_table_index = ~0;
21177   u8 is_add = 1;
21178   int ret;
21179
21180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21181     {
21182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21183         sw_if_index_set = 1;
21184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21185         sw_if_index_set = 1;
21186       else if (unformat (i, "del"))
21187         is_add = 0;
21188       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21189         ;
21190       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21191         ;
21192       else
21193         {
21194           clib_warning ("parse error '%U'", format_unformat_error, i);
21195           return -99;
21196         }
21197     }
21198
21199   if (sw_if_index_set == 0)
21200     {
21201       errmsg ("missing interface name or sw_if_index");
21202       return -99;
21203     }
21204
21205   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21206
21207   mp->sw_if_index = ntohl (sw_if_index);
21208   mp->ip4_table_index = ntohl (ip4_table_index);
21209   mp->ip6_table_index = ntohl (ip6_table_index);
21210   mp->is_add = is_add;
21211
21212   S (mp);
21213   W (ret);
21214   return ret;
21215 }
21216
21217 static int
21218 api_flow_classify_dump (vat_main_t * vam)
21219 {
21220   unformat_input_t *i = vam->input;
21221   vl_api_flow_classify_dump_t *mp;
21222   vl_api_control_ping_t *mp_ping;
21223   u8 type = FLOW_CLASSIFY_N_TABLES;
21224   int ret;
21225
21226   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21227     ;
21228   else
21229     {
21230       errmsg ("classify table type must be specified");
21231       return -99;
21232     }
21233
21234   if (!vam->json_output)
21235     {
21236       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21237     }
21238
21239   M (FLOW_CLASSIFY_DUMP, mp);
21240   mp->type = type;
21241   /* send it... */
21242   S (mp);
21243
21244   /* Use a control ping for synchronization */
21245   MPING (CONTROL_PING, mp_ping);
21246   S (mp_ping);
21247
21248   /* Wait for a reply... */
21249   W (ret);
21250   return ret;
21251 }
21252
21253 static int
21254 api_feature_enable_disable (vat_main_t * vam)
21255 {
21256   unformat_input_t *i = vam->input;
21257   vl_api_feature_enable_disable_t *mp;
21258   u8 *arc_name = 0;
21259   u8 *feature_name = 0;
21260   u32 sw_if_index = ~0;
21261   u8 enable = 1;
21262   int ret;
21263
21264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21265     {
21266       if (unformat (i, "arc_name %s", &arc_name))
21267         ;
21268       else if (unformat (i, "feature_name %s", &feature_name))
21269         ;
21270       else
21271         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21272         ;
21273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21274         ;
21275       else if (unformat (i, "disable"))
21276         enable = 0;
21277       else
21278         break;
21279     }
21280
21281   if (arc_name == 0)
21282     {
21283       errmsg ("missing arc name");
21284       return -99;
21285     }
21286   if (vec_len (arc_name) > 63)
21287     {
21288       errmsg ("arc name too long");
21289     }
21290
21291   if (feature_name == 0)
21292     {
21293       errmsg ("missing feature name");
21294       return -99;
21295     }
21296   if (vec_len (feature_name) > 63)
21297     {
21298       errmsg ("feature name too long");
21299     }
21300
21301   if (sw_if_index == ~0)
21302     {
21303       errmsg ("missing interface name or sw_if_index");
21304       return -99;
21305     }
21306
21307   /* Construct the API message */
21308   M (FEATURE_ENABLE_DISABLE, mp);
21309   mp->sw_if_index = ntohl (sw_if_index);
21310   mp->enable = enable;
21311   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21312   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21313   vec_free (arc_name);
21314   vec_free (feature_name);
21315
21316   S (mp);
21317   W (ret);
21318   return ret;
21319 }
21320
21321 static int
21322 api_sw_interface_tag_add_del (vat_main_t * vam)
21323 {
21324   unformat_input_t *i = vam->input;
21325   vl_api_sw_interface_tag_add_del_t *mp;
21326   u32 sw_if_index = ~0;
21327   u8 *tag = 0;
21328   u8 enable = 1;
21329   int ret;
21330
21331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21332     {
21333       if (unformat (i, "tag %s", &tag))
21334         ;
21335       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21336         ;
21337       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21338         ;
21339       else if (unformat (i, "del"))
21340         enable = 0;
21341       else
21342         break;
21343     }
21344
21345   if (sw_if_index == ~0)
21346     {
21347       errmsg ("missing interface name or sw_if_index");
21348       return -99;
21349     }
21350
21351   if (enable && (tag == 0))
21352     {
21353       errmsg ("no tag specified");
21354       return -99;
21355     }
21356
21357   /* Construct the API message */
21358   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21359   mp->sw_if_index = ntohl (sw_if_index);
21360   mp->is_add = enable;
21361   if (enable)
21362     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21363   vec_free (tag);
21364
21365   S (mp);
21366   W (ret);
21367   return ret;
21368 }
21369
21370 static void vl_api_l2_xconnect_details_t_handler
21371   (vl_api_l2_xconnect_details_t * mp)
21372 {
21373   vat_main_t *vam = &vat_main;
21374
21375   print (vam->ofp, "%15d%15d",
21376          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21377 }
21378
21379 static void vl_api_l2_xconnect_details_t_handler_json
21380   (vl_api_l2_xconnect_details_t * mp)
21381 {
21382   vat_main_t *vam = &vat_main;
21383   vat_json_node_t *node = NULL;
21384
21385   if (VAT_JSON_ARRAY != vam->json_tree.type)
21386     {
21387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21388       vat_json_init_array (&vam->json_tree);
21389     }
21390   node = vat_json_array_add (&vam->json_tree);
21391
21392   vat_json_init_object (node);
21393   vat_json_object_add_uint (node, "rx_sw_if_index",
21394                             ntohl (mp->rx_sw_if_index));
21395   vat_json_object_add_uint (node, "tx_sw_if_index",
21396                             ntohl (mp->tx_sw_if_index));
21397 }
21398
21399 static int
21400 api_l2_xconnect_dump (vat_main_t * vam)
21401 {
21402   vl_api_l2_xconnect_dump_t *mp;
21403   vl_api_control_ping_t *mp_ping;
21404   int ret;
21405
21406   if (!vam->json_output)
21407     {
21408       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21409     }
21410
21411   M (L2_XCONNECT_DUMP, mp);
21412
21413   S (mp);
21414
21415   /* Use a control ping for synchronization */
21416   MPING (CONTROL_PING, mp_ping);
21417   S (mp_ping);
21418
21419   W (ret);
21420   return ret;
21421 }
21422
21423 static int
21424 api_sw_interface_set_mtu (vat_main_t * vam)
21425 {
21426   unformat_input_t *i = vam->input;
21427   vl_api_sw_interface_set_mtu_t *mp;
21428   u32 sw_if_index = ~0;
21429   u32 mtu = 0;
21430   int ret;
21431
21432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21433     {
21434       if (unformat (i, "mtu %d", &mtu))
21435         ;
21436       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21437         ;
21438       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21439         ;
21440       else
21441         break;
21442     }
21443
21444   if (sw_if_index == ~0)
21445     {
21446       errmsg ("missing interface name or sw_if_index");
21447       return -99;
21448     }
21449
21450   if (mtu == 0)
21451     {
21452       errmsg ("no mtu specified");
21453       return -99;
21454     }
21455
21456   /* Construct the API message */
21457   M (SW_INTERFACE_SET_MTU, mp);
21458   mp->sw_if_index = ntohl (sw_if_index);
21459   mp->mtu = ntohs ((u16) mtu);
21460
21461   S (mp);
21462   W (ret);
21463   return ret;
21464 }
21465
21466 static int
21467 api_p2p_ethernet_add (vat_main_t * vam)
21468 {
21469   unformat_input_t *i = vam->input;
21470   vl_api_p2p_ethernet_add_t *mp;
21471   u32 parent_if_index = ~0;
21472   u32 sub_id = ~0;
21473   u8 remote_mac[6];
21474   u8 mac_set = 0;
21475   int ret;
21476
21477   memset (remote_mac, 0, sizeof (remote_mac));
21478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21479     {
21480       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21481         ;
21482       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21483         ;
21484       else
21485         if (unformat
21486             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21487         mac_set++;
21488       else if (unformat (i, "sub_id %d", &sub_id))
21489         ;
21490       else
21491         {
21492           clib_warning ("parse error '%U'", format_unformat_error, i);
21493           return -99;
21494         }
21495     }
21496
21497   if (parent_if_index == ~0)
21498     {
21499       errmsg ("missing interface name or sw_if_index");
21500       return -99;
21501     }
21502   if (mac_set == 0)
21503     {
21504       errmsg ("missing remote mac address");
21505       return -99;
21506     }
21507   if (sub_id == ~0)
21508     {
21509       errmsg ("missing sub-interface id");
21510       return -99;
21511     }
21512
21513   M (P2P_ETHERNET_ADD, mp);
21514   mp->parent_if_index = ntohl (parent_if_index);
21515   mp->subif_id = ntohl (sub_id);
21516   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21517
21518   S (mp);
21519   W (ret);
21520   return ret;
21521 }
21522
21523 static int
21524 api_p2p_ethernet_del (vat_main_t * vam)
21525 {
21526   unformat_input_t *i = vam->input;
21527   vl_api_p2p_ethernet_del_t *mp;
21528   u32 parent_if_index = ~0;
21529   u8 remote_mac[6];
21530   u8 mac_set = 0;
21531   int ret;
21532
21533   memset (remote_mac, 0, sizeof (remote_mac));
21534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21535     {
21536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21537         ;
21538       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21539         ;
21540       else
21541         if (unformat
21542             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21543         mac_set++;
21544       else
21545         {
21546           clib_warning ("parse error '%U'", format_unformat_error, i);
21547           return -99;
21548         }
21549     }
21550
21551   if (parent_if_index == ~0)
21552     {
21553       errmsg ("missing interface name or sw_if_index");
21554       return -99;
21555     }
21556   if (mac_set == 0)
21557     {
21558       errmsg ("missing remote mac address");
21559       return -99;
21560     }
21561
21562   M (P2P_ETHERNET_DEL, mp);
21563   mp->parent_if_index = ntohl (parent_if_index);
21564   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21565
21566   S (mp);
21567   W (ret);
21568   return ret;
21569 }
21570
21571 static int
21572 api_lldp_config (vat_main_t * vam)
21573 {
21574   unformat_input_t *i = vam->input;
21575   vl_api_lldp_config_t *mp;
21576   int tx_hold = 0;
21577   int tx_interval = 0;
21578   u8 *sys_name = NULL;
21579   int ret;
21580
21581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21582     {
21583       if (unformat (i, "system-name %s", &sys_name))
21584         ;
21585       else if (unformat (i, "tx-hold %d", &tx_hold))
21586         ;
21587       else if (unformat (i, "tx-interval %d", &tx_interval))
21588         ;
21589       else
21590         {
21591           clib_warning ("parse error '%U'", format_unformat_error, i);
21592           return -99;
21593         }
21594     }
21595
21596   vec_add1 (sys_name, 0);
21597
21598   M (LLDP_CONFIG, mp);
21599   mp->tx_hold = htonl (tx_hold);
21600   mp->tx_interval = htonl (tx_interval);
21601   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21602   vec_free (sys_name);
21603
21604   S (mp);
21605   W (ret);
21606   return ret;
21607 }
21608
21609 static int
21610 api_sw_interface_set_lldp (vat_main_t * vam)
21611 {
21612   unformat_input_t *i = vam->input;
21613   vl_api_sw_interface_set_lldp_t *mp;
21614   u32 sw_if_index = ~0;
21615   u32 enable = 1;
21616   u8 *port_desc = NULL, *mgmt_oid = NULL;
21617   ip4_address_t ip4_addr;
21618   ip6_address_t ip6_addr;
21619   int ret;
21620
21621   memset (&ip4_addr, 0, sizeof (ip4_addr));
21622   memset (&ip6_addr, 0, sizeof (ip6_addr));
21623
21624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21625     {
21626       if (unformat (i, "disable"))
21627         enable = 0;
21628       else
21629         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21630         ;
21631       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21632         ;
21633       else if (unformat (i, "port-desc %s", &port_desc))
21634         ;
21635       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21636         ;
21637       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21638         ;
21639       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21640         ;
21641       else
21642         break;
21643     }
21644
21645   if (sw_if_index == ~0)
21646     {
21647       errmsg ("missing interface name or sw_if_index");
21648       return -99;
21649     }
21650
21651   /* Construct the API message */
21652   vec_add1 (port_desc, 0);
21653   vec_add1 (mgmt_oid, 0);
21654   M (SW_INTERFACE_SET_LLDP, mp);
21655   mp->sw_if_index = ntohl (sw_if_index);
21656   mp->enable = enable;
21657   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21658   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21659   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21660   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21661   vec_free (port_desc);
21662   vec_free (mgmt_oid);
21663
21664   S (mp);
21665   W (ret);
21666   return ret;
21667 }
21668
21669 static int
21670 api_tcp_configure_src_addresses (vat_main_t * vam)
21671 {
21672   vl_api_tcp_configure_src_addresses_t *mp;
21673   unformat_input_t *i = vam->input;
21674   ip4_address_t v4first, v4last;
21675   ip6_address_t v6first, v6last;
21676   u8 range_set = 0;
21677   u32 vrf_id = 0;
21678   int ret;
21679
21680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21681     {
21682       if (unformat (i, "%U - %U",
21683                     unformat_ip4_address, &v4first,
21684                     unformat_ip4_address, &v4last))
21685         {
21686           if (range_set)
21687             {
21688               errmsg ("one range per message (range already set)");
21689               return -99;
21690             }
21691           range_set = 1;
21692         }
21693       else if (unformat (i, "%U - %U",
21694                          unformat_ip6_address, &v6first,
21695                          unformat_ip6_address, &v6last))
21696         {
21697           if (range_set)
21698             {
21699               errmsg ("one range per message (range already set)");
21700               return -99;
21701             }
21702           range_set = 2;
21703         }
21704       else if (unformat (i, "vrf %d", &vrf_id))
21705         ;
21706       else
21707         break;
21708     }
21709
21710   if (range_set == 0)
21711     {
21712       errmsg ("address range not set");
21713       return -99;
21714     }
21715
21716   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21717   mp->vrf_id = ntohl (vrf_id);
21718   /* ipv6? */
21719   if (range_set == 2)
21720     {
21721       mp->is_ipv6 = 1;
21722       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21723       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21724     }
21725   else
21726     {
21727       mp->is_ipv6 = 0;
21728       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21729       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21730     }
21731   S (mp);
21732   W (ret);
21733   return ret;
21734 }
21735
21736 static void vl_api_app_namespace_add_del_reply_t_handler
21737   (vl_api_app_namespace_add_del_reply_t * mp)
21738 {
21739   vat_main_t *vam = &vat_main;
21740   i32 retval = ntohl (mp->retval);
21741   if (vam->async_mode)
21742     {
21743       vam->async_errors += (retval < 0);
21744     }
21745   else
21746     {
21747       vam->retval = retval;
21748       if (retval == 0)
21749         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21750       vam->result_ready = 1;
21751     }
21752 }
21753
21754 static void vl_api_app_namespace_add_del_reply_t_handler_json
21755   (vl_api_app_namespace_add_del_reply_t * mp)
21756 {
21757   vat_main_t *vam = &vat_main;
21758   vat_json_node_t node;
21759
21760   vat_json_init_object (&node);
21761   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21762   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21763
21764   vat_json_print (vam->ofp, &node);
21765   vat_json_free (&node);
21766
21767   vam->retval = ntohl (mp->retval);
21768   vam->result_ready = 1;
21769 }
21770
21771 static int
21772 api_app_namespace_add_del (vat_main_t * vam)
21773 {
21774   vl_api_app_namespace_add_del_t *mp;
21775   unformat_input_t *i = vam->input;
21776   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21777   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21778   u64 secret;
21779   int ret;
21780
21781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21782     {
21783       if (unformat (i, "id %_%v%_", &ns_id))
21784         ;
21785       else if (unformat (i, "secret %lu", &secret))
21786         secret_set = 1;
21787       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21788         sw_if_index_set = 1;
21789       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21790         ;
21791       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21792         ;
21793       else
21794         break;
21795     }
21796   if (!ns_id || !secret_set || !sw_if_index_set)
21797     {
21798       errmsg ("namespace id, secret and sw_if_index must be set");
21799       return -99;
21800     }
21801   if (vec_len (ns_id) > 64)
21802     {
21803       errmsg ("namespace id too long");
21804       return -99;
21805     }
21806   M (APP_NAMESPACE_ADD_DEL, mp);
21807
21808   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21809   mp->namespace_id_len = vec_len (ns_id);
21810   mp->secret = clib_host_to_net_u64 (secret);
21811   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21812   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21813   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21814   vec_free (ns_id);
21815   S (mp);
21816   W (ret);
21817   return ret;
21818 }
21819
21820 static int
21821 api_memfd_segment_create (vat_main_t * vam)
21822 {
21823 #if VPP_API_TEST_BUILTIN == 0
21824   unformat_input_t *i = vam->input;
21825   vl_api_memfd_segment_create_t *mp;
21826   u64 size = 64 << 20;
21827   int ret;
21828
21829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21830     {
21831       if (unformat (i, "size %U", unformat_memory_size, &size))
21832         ;
21833       else
21834         break;
21835     }
21836
21837   M (MEMFD_SEGMENT_CREATE, mp);
21838   mp->requested_size = size;
21839   S (mp);
21840   W (ret);
21841   return ret;
21842
21843 #else
21844   errmsg ("memfd_segment_create (builtin) not supported");
21845   return -99;
21846 #endif
21847 }
21848
21849 static int
21850 api_dns_enable_disable (vat_main_t * vam)
21851 {
21852   unformat_input_t *line_input = vam->input;
21853   vl_api_dns_enable_disable_t *mp;
21854   u8 enable_disable = 1;
21855   int ret;
21856
21857   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21858     {
21859       if (unformat (line_input, "disable"))
21860         enable_disable = 0;
21861       if (unformat (line_input, "enable"))
21862         enable_disable = 1;
21863       else
21864         break;
21865     }
21866
21867   /* Construct the API message */
21868   M (DNS_ENABLE_DISABLE, mp);
21869   mp->enable = enable_disable;
21870
21871   /* send it... */
21872   S (mp);
21873   /* Wait for the reply */
21874   W (ret);
21875   return ret;
21876 }
21877
21878 static int
21879 api_dns_resolve_name (vat_main_t * vam)
21880 {
21881   unformat_input_t *line_input = vam->input;
21882   vl_api_dns_resolve_name_t *mp;
21883   u8 *name = 0;
21884   int ret;
21885
21886   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21887     {
21888       if (unformat (line_input, "%s", &name))
21889         ;
21890       else
21891         break;
21892     }
21893
21894   if (vec_len (name) > 127)
21895     {
21896       errmsg ("name too long");
21897       return -99;
21898     }
21899
21900   /* Construct the API message */
21901   M (DNS_RESOLVE_NAME, mp);
21902   memcpy (mp->name, name, vec_len (name));
21903   vec_free (name);
21904
21905   /* send it... */
21906   S (mp);
21907   /* Wait for the reply */
21908   W (ret);
21909   return ret;
21910 }
21911
21912 static int
21913 api_dns_resolve_ip (vat_main_t * vam)
21914 {
21915   unformat_input_t *line_input = vam->input;
21916   vl_api_dns_resolve_ip_t *mp;
21917   int is_ip6 = -1;
21918   ip4_address_t addr4;
21919   ip6_address_t addr6;
21920   int ret;
21921
21922   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21923     {
21924       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21925         is_ip6 = 1;
21926       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21927         is_ip6 = 0;
21928       else
21929         break;
21930     }
21931
21932   if (is_ip6 == -1)
21933     {
21934       errmsg ("missing address");
21935       return -99;
21936     }
21937
21938   /* Construct the API message */
21939   M (DNS_RESOLVE_IP, mp);
21940   mp->is_ip6 = is_ip6;
21941   if (is_ip6)
21942     memcpy (mp->address, &addr6, sizeof (addr6));
21943   else
21944     memcpy (mp->address, &addr4, sizeof (addr4));
21945
21946   /* send it... */
21947   S (mp);
21948   /* Wait for the reply */
21949   W (ret);
21950   return ret;
21951 }
21952
21953 static int
21954 api_dns_name_server_add_del (vat_main_t * vam)
21955 {
21956   unformat_input_t *i = vam->input;
21957   vl_api_dns_name_server_add_del_t *mp;
21958   u8 is_add = 1;
21959   ip6_address_t ip6_server;
21960   ip4_address_t ip4_server;
21961   int ip6_set = 0;
21962   int ip4_set = 0;
21963   int ret = 0;
21964
21965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21966     {
21967       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21968         ip6_set = 1;
21969       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21970         ip4_set = 1;
21971       else if (unformat (i, "del"))
21972         is_add = 0;
21973       else
21974         {
21975           clib_warning ("parse error '%U'", format_unformat_error, i);
21976           return -99;
21977         }
21978     }
21979
21980   if (ip4_set && ip6_set)
21981     {
21982       errmsg ("Only one server address allowed per message");
21983       return -99;
21984     }
21985   if ((ip4_set + ip6_set) == 0)
21986     {
21987       errmsg ("Server address required");
21988       return -99;
21989     }
21990
21991   /* Construct the API message */
21992   M (DNS_NAME_SERVER_ADD_DEL, mp);
21993
21994   if (ip6_set)
21995     {
21996       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21997       mp->is_ip6 = 1;
21998     }
21999   else
22000     {
22001       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22002       mp->is_ip6 = 0;
22003     }
22004
22005   mp->is_add = is_add;
22006
22007   /* send it... */
22008   S (mp);
22009
22010   /* Wait for a reply, return good/bad news  */
22011   W (ret);
22012   return ret;
22013 }
22014
22015 static void
22016 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22017 {
22018   vat_main_t *vam = &vat_main;
22019
22020   if (mp->is_ip4)
22021     {
22022       print (vam->ofp,
22023              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22024              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22025              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22026              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22027              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22028              clib_net_to_host_u32 (mp->action_index), mp->tag);
22029     }
22030   else
22031     {
22032       print (vam->ofp,
22033              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22034              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22035              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22036              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22037              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22038              clib_net_to_host_u32 (mp->action_index), mp->tag);
22039     }
22040 }
22041
22042 static void
22043 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22044                                              mp)
22045 {
22046   vat_main_t *vam = &vat_main;
22047   vat_json_node_t *node = NULL;
22048   struct in6_addr ip6;
22049   struct in_addr ip4;
22050
22051   if (VAT_JSON_ARRAY != vam->json_tree.type)
22052     {
22053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22054       vat_json_init_array (&vam->json_tree);
22055     }
22056   node = vat_json_array_add (&vam->json_tree);
22057   vat_json_init_object (node);
22058
22059   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22060   vat_json_object_add_uint (node, "appns_index",
22061                             clib_net_to_host_u32 (mp->appns_index));
22062   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22063   vat_json_object_add_uint (node, "scope", mp->scope);
22064   vat_json_object_add_uint (node, "action_index",
22065                             clib_net_to_host_u32 (mp->action_index));
22066   vat_json_object_add_uint (node, "lcl_port",
22067                             clib_net_to_host_u16 (mp->lcl_port));
22068   vat_json_object_add_uint (node, "rmt_port",
22069                             clib_net_to_host_u16 (mp->rmt_port));
22070   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22071   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22072   vat_json_object_add_string_copy (node, "tag", mp->tag);
22073   if (mp->is_ip4)
22074     {
22075       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22076       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22077       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22078       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22079     }
22080   else
22081     {
22082       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22083       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22084       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22085       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22086     }
22087 }
22088
22089 static int
22090 api_session_rule_add_del (vat_main_t * vam)
22091 {
22092   vl_api_session_rule_add_del_t *mp;
22093   unformat_input_t *i = vam->input;
22094   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22095   u32 appns_index = 0, scope = 0;
22096   ip4_address_t lcl_ip4, rmt_ip4;
22097   ip6_address_t lcl_ip6, rmt_ip6;
22098   u8 is_ip4 = 1, conn_set = 0;
22099   u8 is_add = 1, *tag = 0;
22100   int ret;
22101
22102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22103     {
22104       if (unformat (i, "del"))
22105         is_add = 0;
22106       else if (unformat (i, "add"))
22107         ;
22108       else if (unformat (i, "proto tcp"))
22109         proto = 0;
22110       else if (unformat (i, "proto udp"))
22111         proto = 1;
22112       else if (unformat (i, "appns %d", &appns_index))
22113         ;
22114       else if (unformat (i, "scope %d", &scope))
22115         ;
22116       else if (unformat (i, "tag %_%v%_", &tag))
22117         ;
22118       else
22119         if (unformat
22120             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22121              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22122              &rmt_port))
22123         {
22124           is_ip4 = 1;
22125           conn_set = 1;
22126         }
22127       else
22128         if (unformat
22129             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22130              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22131              &rmt_port))
22132         {
22133           is_ip4 = 0;
22134           conn_set = 1;
22135         }
22136       else if (unformat (i, "action %d", &action))
22137         ;
22138       else
22139         break;
22140     }
22141   if (proto == ~0 || !conn_set || action == ~0)
22142     {
22143       errmsg ("transport proto, connection and action must be set");
22144       return -99;
22145     }
22146
22147   if (scope > 3)
22148     {
22149       errmsg ("scope should be 0-3");
22150       return -99;
22151     }
22152
22153   M (SESSION_RULE_ADD_DEL, mp);
22154
22155   mp->is_ip4 = is_ip4;
22156   mp->transport_proto = proto;
22157   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22158   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22159   mp->lcl_plen = lcl_plen;
22160   mp->rmt_plen = rmt_plen;
22161   mp->action_index = clib_host_to_net_u32 (action);
22162   mp->appns_index = clib_host_to_net_u32 (appns_index);
22163   mp->scope = scope;
22164   mp->is_add = is_add;
22165   if (is_ip4)
22166     {
22167       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22168       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22169     }
22170   else
22171     {
22172       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22173       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22174     }
22175   if (tag)
22176     {
22177       clib_memcpy (mp->tag, tag, vec_len (tag));
22178       vec_free (tag);
22179     }
22180
22181   S (mp);
22182   W (ret);
22183   return ret;
22184 }
22185
22186 static int
22187 api_session_rules_dump (vat_main_t * vam)
22188 {
22189   vl_api_session_rules_dump_t *mp;
22190   vl_api_control_ping_t *mp_ping;
22191   int ret;
22192
22193   if (!vam->json_output)
22194     {
22195       print (vam->ofp, "%=20s", "Session Rules");
22196     }
22197
22198   M (SESSION_RULES_DUMP, mp);
22199   /* send it... */
22200   S (mp);
22201
22202   /* Use a control ping for synchronization */
22203   MPING (CONTROL_PING, mp_ping);
22204   S (mp_ping);
22205
22206   /* Wait for a reply... */
22207   W (ret);
22208   return ret;
22209 }
22210
22211 static int
22212 api_ip_container_proxy_add_del (vat_main_t * vam)
22213 {
22214   vl_api_ip_container_proxy_add_del_t *mp;
22215   unformat_input_t *i = vam->input;
22216   u32 plen = ~0, sw_if_index = ~0;
22217   ip4_address_t ip4;
22218   ip6_address_t ip6;
22219   u8 is_ip4 = 1;
22220   u8 is_add = 1;
22221   int ret;
22222
22223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22224     {
22225       if (unformat (i, "del"))
22226         is_add = 0;
22227       else if (unformat (i, "add"))
22228         ;
22229       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22230         {
22231           is_ip4 = 1;
22232           plen = 32;
22233         }
22234       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22235         {
22236           is_ip4 = 0;
22237           plen = 128;
22238         }
22239       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22240         ;
22241       else
22242         break;
22243     }
22244   if (sw_if_index == ~0 || plen == ~0)
22245     {
22246       errmsg ("address and sw_if_index must be set");
22247       return -99;
22248     }
22249
22250   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22251
22252   mp->is_ip4 = is_ip4;
22253   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22254   mp->plen = plen;
22255   mp->is_add = is_add;
22256   if (is_ip4)
22257     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22258   else
22259     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22260
22261   S (mp);
22262   W (ret);
22263   return ret;
22264 }
22265
22266 static int
22267 q_or_quit (vat_main_t * vam)
22268 {
22269 #if VPP_API_TEST_BUILTIN == 0
22270   longjmp (vam->jump_buf, 1);
22271 #endif
22272   return 0;                     /* not so much */
22273 }
22274
22275 static int
22276 q (vat_main_t * vam)
22277 {
22278   return q_or_quit (vam);
22279 }
22280
22281 static int
22282 quit (vat_main_t * vam)
22283 {
22284   return q_or_quit (vam);
22285 }
22286
22287 static int
22288 comment (vat_main_t * vam)
22289 {
22290   return 0;
22291 }
22292
22293 static int
22294 cmd_cmp (void *a1, void *a2)
22295 {
22296   u8 **c1 = a1;
22297   u8 **c2 = a2;
22298
22299   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22300 }
22301
22302 static int
22303 help (vat_main_t * vam)
22304 {
22305   u8 **cmds = 0;
22306   u8 *name = 0;
22307   hash_pair_t *p;
22308   unformat_input_t *i = vam->input;
22309   int j;
22310
22311   if (unformat (i, "%s", &name))
22312     {
22313       uword *hs;
22314
22315       vec_add1 (name, 0);
22316
22317       hs = hash_get_mem (vam->help_by_name, name);
22318       if (hs)
22319         print (vam->ofp, "usage: %s %s", name, hs[0]);
22320       else
22321         print (vam->ofp, "No such msg / command '%s'", name);
22322       vec_free (name);
22323       return 0;
22324     }
22325
22326   print (vam->ofp, "Help is available for the following:");
22327
22328     /* *INDENT-OFF* */
22329     hash_foreach_pair (p, vam->function_by_name,
22330     ({
22331       vec_add1 (cmds, (u8 *)(p->key));
22332     }));
22333     /* *INDENT-ON* */
22334
22335   vec_sort_with_function (cmds, cmd_cmp);
22336
22337   for (j = 0; j < vec_len (cmds); j++)
22338     print (vam->ofp, "%s", cmds[j]);
22339
22340   vec_free (cmds);
22341   return 0;
22342 }
22343
22344 static int
22345 set (vat_main_t * vam)
22346 {
22347   u8 *name = 0, *value = 0;
22348   unformat_input_t *i = vam->input;
22349
22350   if (unformat (i, "%s", &name))
22351     {
22352       /* The input buffer is a vector, not a string. */
22353       value = vec_dup (i->buffer);
22354       vec_delete (value, i->index, 0);
22355       /* Almost certainly has a trailing newline */
22356       if (value[vec_len (value) - 1] == '\n')
22357         value[vec_len (value) - 1] = 0;
22358       /* Make sure it's a proper string, one way or the other */
22359       vec_add1 (value, 0);
22360       (void) clib_macro_set_value (&vam->macro_main,
22361                                    (char *) name, (char *) value);
22362     }
22363   else
22364     errmsg ("usage: set <name> <value>");
22365
22366   vec_free (name);
22367   vec_free (value);
22368   return 0;
22369 }
22370
22371 static int
22372 unset (vat_main_t * vam)
22373 {
22374   u8 *name = 0;
22375
22376   if (unformat (vam->input, "%s", &name))
22377     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22378       errmsg ("unset: %s wasn't set", name);
22379   vec_free (name);
22380   return 0;
22381 }
22382
22383 typedef struct
22384 {
22385   u8 *name;
22386   u8 *value;
22387 } macro_sort_t;
22388
22389
22390 static int
22391 macro_sort_cmp (void *a1, void *a2)
22392 {
22393   macro_sort_t *s1 = a1;
22394   macro_sort_t *s2 = a2;
22395
22396   return strcmp ((char *) (s1->name), (char *) (s2->name));
22397 }
22398
22399 static int
22400 dump_macro_table (vat_main_t * vam)
22401 {
22402   macro_sort_t *sort_me = 0, *sm;
22403   int i;
22404   hash_pair_t *p;
22405
22406     /* *INDENT-OFF* */
22407     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22408     ({
22409       vec_add2 (sort_me, sm, 1);
22410       sm->name = (u8 *)(p->key);
22411       sm->value = (u8 *) (p->value[0]);
22412     }));
22413     /* *INDENT-ON* */
22414
22415   vec_sort_with_function (sort_me, macro_sort_cmp);
22416
22417   if (vec_len (sort_me))
22418     print (vam->ofp, "%-15s%s", "Name", "Value");
22419   else
22420     print (vam->ofp, "The macro table is empty...");
22421
22422   for (i = 0; i < vec_len (sort_me); i++)
22423     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22424   return 0;
22425 }
22426
22427 static int
22428 dump_node_table (vat_main_t * vam)
22429 {
22430   int i, j;
22431   vlib_node_t *node, *next_node;
22432
22433   if (vec_len (vam->graph_nodes) == 0)
22434     {
22435       print (vam->ofp, "Node table empty, issue get_node_graph...");
22436       return 0;
22437     }
22438
22439   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22440     {
22441       node = vam->graph_nodes[i];
22442       print (vam->ofp, "[%d] %s", i, node->name);
22443       for (j = 0; j < vec_len (node->next_nodes); j++)
22444         {
22445           if (node->next_nodes[j] != ~0)
22446             {
22447               next_node = vam->graph_nodes[node->next_nodes[j]];
22448               print (vam->ofp, "  [%d] %s", j, next_node->name);
22449             }
22450         }
22451     }
22452   return 0;
22453 }
22454
22455 static int
22456 value_sort_cmp (void *a1, void *a2)
22457 {
22458   name_sort_t *n1 = a1;
22459   name_sort_t *n2 = a2;
22460
22461   if (n1->value < n2->value)
22462     return -1;
22463   if (n1->value > n2->value)
22464     return 1;
22465   return 0;
22466 }
22467
22468
22469 static int
22470 dump_msg_api_table (vat_main_t * vam)
22471 {
22472   api_main_t *am = &api_main;
22473   name_sort_t *nses = 0, *ns;
22474   hash_pair_t *hp;
22475   int i;
22476
22477   /* *INDENT-OFF* */
22478   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22479   ({
22480     vec_add2 (nses, ns, 1);
22481     ns->name = (u8 *)(hp->key);
22482     ns->value = (u32) hp->value[0];
22483   }));
22484   /* *INDENT-ON* */
22485
22486   vec_sort_with_function (nses, value_sort_cmp);
22487
22488   for (i = 0; i < vec_len (nses); i++)
22489     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22490   vec_free (nses);
22491   return 0;
22492 }
22493
22494 static int
22495 get_msg_id (vat_main_t * vam)
22496 {
22497   u8 *name_and_crc;
22498   u32 message_index;
22499
22500   if (unformat (vam->input, "%s", &name_and_crc))
22501     {
22502       message_index = vl_api_get_msg_index (name_and_crc);
22503       if (message_index == ~0)
22504         {
22505           print (vam->ofp, " '%s' not found", name_and_crc);
22506           return 0;
22507         }
22508       print (vam->ofp, " '%s' has message index %d",
22509              name_and_crc, message_index);
22510       return 0;
22511     }
22512   errmsg ("name_and_crc required...");
22513   return 0;
22514 }
22515
22516 static int
22517 search_node_table (vat_main_t * vam)
22518 {
22519   unformat_input_t *line_input = vam->input;
22520   u8 *node_to_find;
22521   int j;
22522   vlib_node_t *node, *next_node;
22523   uword *p;
22524
22525   if (vam->graph_node_index_by_name == 0)
22526     {
22527       print (vam->ofp, "Node table empty, issue get_node_graph...");
22528       return 0;
22529     }
22530
22531   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22532     {
22533       if (unformat (line_input, "%s", &node_to_find))
22534         {
22535           vec_add1 (node_to_find, 0);
22536           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22537           if (p == 0)
22538             {
22539               print (vam->ofp, "%s not found...", node_to_find);
22540               goto out;
22541             }
22542           node = vam->graph_nodes[p[0]];
22543           print (vam->ofp, "[%d] %s", p[0], node->name);
22544           for (j = 0; j < vec_len (node->next_nodes); j++)
22545             {
22546               if (node->next_nodes[j] != ~0)
22547                 {
22548                   next_node = vam->graph_nodes[node->next_nodes[j]];
22549                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22550                 }
22551             }
22552         }
22553
22554       else
22555         {
22556           clib_warning ("parse error '%U'", format_unformat_error,
22557                         line_input);
22558           return -99;
22559         }
22560
22561     out:
22562       vec_free (node_to_find);
22563
22564     }
22565
22566   return 0;
22567 }
22568
22569
22570 static int
22571 script (vat_main_t * vam)
22572 {
22573 #if (VPP_API_TEST_BUILTIN==0)
22574   u8 *s = 0;
22575   char *save_current_file;
22576   unformat_input_t save_input;
22577   jmp_buf save_jump_buf;
22578   u32 save_line_number;
22579
22580   FILE *new_fp, *save_ifp;
22581
22582   if (unformat (vam->input, "%s", &s))
22583     {
22584       new_fp = fopen ((char *) s, "r");
22585       if (new_fp == 0)
22586         {
22587           errmsg ("Couldn't open script file %s", s);
22588           vec_free (s);
22589           return -99;
22590         }
22591     }
22592   else
22593     {
22594       errmsg ("Missing script name");
22595       return -99;
22596     }
22597
22598   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22599   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22600   save_ifp = vam->ifp;
22601   save_line_number = vam->input_line_number;
22602   save_current_file = (char *) vam->current_file;
22603
22604   vam->input_line_number = 0;
22605   vam->ifp = new_fp;
22606   vam->current_file = s;
22607   do_one_file (vam);
22608
22609   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22610   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22611   vam->ifp = save_ifp;
22612   vam->input_line_number = save_line_number;
22613   vam->current_file = (u8 *) save_current_file;
22614   vec_free (s);
22615
22616   return 0;
22617 #else
22618   clib_warning ("use the exec command...");
22619   return -99;
22620 #endif
22621 }
22622
22623 static int
22624 echo (vat_main_t * vam)
22625 {
22626   print (vam->ofp, "%v", vam->input->buffer);
22627   return 0;
22628 }
22629
22630 /* List of API message constructors, CLI names map to api_xxx */
22631 #define foreach_vpe_api_msg                                             \
22632 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22633 _(sw_interface_dump,"")                                                 \
22634 _(sw_interface_set_flags,                                               \
22635   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22636 _(sw_interface_add_del_address,                                         \
22637   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22638 _(sw_interface_set_rx_mode,                                             \
22639   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22640 _(sw_interface_set_table,                                               \
22641   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22642 _(sw_interface_set_mpls_enable,                                         \
22643   "<intfc> | sw_if_index [disable | dis]")                              \
22644 _(sw_interface_set_vpath,                                               \
22645   "<intfc> | sw_if_index <id> enable | disable")                        \
22646 _(sw_interface_set_vxlan_bypass,                                        \
22647   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22648 _(sw_interface_set_geneve_bypass,                                       \
22649   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22650 _(sw_interface_set_l2_xconnect,                                         \
22651   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22652   "enable | disable")                                                   \
22653 _(sw_interface_set_l2_bridge,                                           \
22654   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22655   "[shg <split-horizon-group>] [bvi]\n"                                 \
22656   "enable | disable")                                                   \
22657 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22658 _(bridge_domain_add_del,                                                \
22659   "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") \
22660 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22661 _(l2fib_add_del,                                                        \
22662   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22663 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22664 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22665 _(l2_flags,                                                             \
22666   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22667 _(bridge_flags,                                                         \
22668   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22669 _(tap_connect,                                                          \
22670   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22671 _(tap_modify,                                                           \
22672   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22673 _(tap_delete,                                                           \
22674   "<vpp-if-name> | sw_if_index <id>")                                   \
22675 _(sw_interface_tap_dump, "")                                            \
22676 _(tap_create_v2,                                                        \
22677   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22678 _(tap_delete_v2,                                                        \
22679   "<vpp-if-name> | sw_if_index <id>")                                   \
22680 _(sw_interface_tap_v2_dump, "")                                         \
22681 _(ip_table_add_del,                                                     \
22682   "table-id <n> [ipv6]\n")                                              \
22683 _(ip_add_del_route,                                                     \
22684   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22685   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22686   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22687   "[multipath] [count <n>]")                                            \
22688 _(ip_mroute_add_del,                                                    \
22689   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22690   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22691 _(mpls_table_add_del,                                                   \
22692   "table-id <n>\n")                                                     \
22693 _(mpls_route_add_del,                                                   \
22694   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22695   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22696   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22697   "[multipath] [count <n>]")                                            \
22698 _(mpls_ip_bind_unbind,                                                  \
22699   "<label> <addr/len>")                                                 \
22700 _(mpls_tunnel_add_del,                                                  \
22701   " via <addr> [table-id <n>]\n"                                        \
22702   "sw_if_index <id>] [l2]  [del]")                                      \
22703 _(bier_table_add_del,                                                   \
22704   "<label> <sub-domain> <set> <bsl> [del]")                             \
22705 _(bier_route_add_del,                                                   \
22706   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22707   "[<intfc> | sw_if_index <id>]"                                        \
22708   "[weight <n>] [del] [multipath]")                                     \
22709 _(proxy_arp_add_del,                                                    \
22710   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22711 _(proxy_arp_intfc_enable_disable,                                       \
22712   "<intfc> | sw_if_index <id> enable | disable")                        \
22713 _(sw_interface_set_unnumbered,                                          \
22714   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22715 _(ip_neighbor_add_del,                                                  \
22716   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22717   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22718 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22719 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22720   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22721   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22722   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22723 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22724 _(reset_fib, "vrf <n> [ipv6]")                                          \
22725 _(dhcp_proxy_config,                                                    \
22726   "svr <v46-address> src <v46-address>\n"                               \
22727    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22728 _(dhcp_proxy_set_vss,                                                   \
22729   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22730 _(dhcp_proxy_dump, "ip6")                                               \
22731 _(dhcp_client_config,                                                   \
22732   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22733 _(set_ip_flow_hash,                                                     \
22734   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22735 _(sw_interface_ip6_enable_disable,                                      \
22736   "<intfc> | sw_if_index <id> enable | disable")                        \
22737 _(sw_interface_ip6_set_link_local_address,                              \
22738   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22739 _(ip6nd_proxy_add_del,                                                  \
22740   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22741 _(ip6nd_proxy_dump, "")                                                 \
22742 _(sw_interface_ip6nd_ra_prefix,                                         \
22743   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22744   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22745   "[nolink] [isno]")                                                    \
22746 _(sw_interface_ip6nd_ra_config,                                         \
22747   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22748   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22749   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22750 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22751 _(l2_patch_add_del,                                                     \
22752   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22753   "enable | disable")                                                   \
22754 _(sr_localsid_add_del,                                                  \
22755   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22756   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22757 _(classify_add_del_table,                                               \
22758   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22759   " [del] [del-chain] mask <mask-value>\n"                              \
22760   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22761   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22762 _(classify_add_del_session,                                             \
22763   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22764   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22765   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22766   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22767 _(classify_set_interface_ip_table,                                      \
22768   "<intfc> | sw_if_index <nn> table <nn>")                              \
22769 _(classify_set_interface_l2_tables,                                     \
22770   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22771   "  [other-table <nn>]")                                               \
22772 _(get_node_index, "node <node-name")                                    \
22773 _(add_node_next, "node <node-name> next <next-node-name>")              \
22774 _(l2tpv3_create_tunnel,                                                 \
22775   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22776   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22777   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22778 _(l2tpv3_set_tunnel_cookies,                                            \
22779   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22780   "[new_remote_cookie <nn>]\n")                                         \
22781 _(l2tpv3_interface_enable_disable,                                      \
22782   "<intfc> | sw_if_index <nn> enable | disable")                        \
22783 _(l2tpv3_set_lookup_key,                                                \
22784   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22785 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22786 _(vxlan_add_del_tunnel,                                                 \
22787   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22788   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22789   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22790 _(geneve_add_del_tunnel,                                                \
22791   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22792   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22793   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22794 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22795 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22796 _(gre_add_del_tunnel,                                                   \
22797   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22798 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22799 _(l2_fib_clear_table, "")                                               \
22800 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22801 _(l2_interface_vlan_tag_rewrite,                                        \
22802   "<intfc> | sw_if_index <nn> \n"                                       \
22803   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22804   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22805 _(create_vhost_user_if,                                                 \
22806         "socket <filename> [server] [renumber <dev_instance>] "         \
22807         "[mac <mac_address>]")                                          \
22808 _(modify_vhost_user_if,                                                 \
22809         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22810         "[server] [renumber <dev_instance>]")                           \
22811 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22812 _(sw_interface_vhost_user_dump, "")                                     \
22813 _(show_version, "")                                                     \
22814 _(vxlan_gpe_add_del_tunnel,                                             \
22815   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22816   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22817   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22818   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22819 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22820 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22821 _(interface_name_renumber,                                              \
22822   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22823 _(input_acl_set_interface,                                              \
22824   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22825   "  [l2-table <nn>] [del]")                                            \
22826 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22827 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22828 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22829 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22830 _(ip_dump, "ipv4 | ipv6")                                               \
22831 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22832 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22833   "  spid_id <n> ")                                                     \
22834 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22835   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22836   "  integ_alg <alg> integ_key <hex>")                                  \
22837 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22838   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22839   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22840   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22841 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22842 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22843   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22844   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22845   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22846 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22847 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22848   "  <alg> <hex>\n")                                                    \
22849 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22850 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22851 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22852   "(auth_data 0x<data> | auth_data <data>)")                            \
22853 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22854   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22855 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22856   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22857   "(local|remote)")                                                     \
22858 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22859 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22860 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22861 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22862 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22863 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22864 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22865 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22866 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22867 _(delete_loopback,"sw_if_index <nn>")                                   \
22868 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22869 _(map_add_domain,                                                       \
22870   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22871   "ip6-src <ip6addr> "                                                  \
22872   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22873 _(map_del_domain, "index <n>")                                          \
22874 _(map_add_del_rule,                                                     \
22875   "index <n> psid <n> dst <ip6addr> [del]")                             \
22876 _(map_domain_dump, "")                                                  \
22877 _(map_rule_dump, "index <map-domain>")                                  \
22878 _(want_interface_events,  "enable|disable")                             \
22879 _(want_stats,"enable|disable")                                          \
22880 _(get_first_msg_id, "client <name>")                                    \
22881 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22882 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22883   "fib-id <nn> [ip4][ip6][default]")                                    \
22884 _(get_node_graph, " ")                                                  \
22885 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22886 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22887 _(ioam_disable, "")                                                     \
22888 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22889                             " sw_if_index <sw_if_index> p <priority> "  \
22890                             "w <weight>] [del]")                        \
22891 _(one_add_del_locator, "locator-set <locator_name> "                    \
22892                         "iface <intf> | sw_if_index <sw_if_index> "     \
22893                         "p <priority> w <weight> [del]")                \
22894 _(one_add_del_local_eid,"vni <vni> eid "                                \
22895                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22896                          "locator-set <locator_name> [del]"             \
22897                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22898 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22899 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22900 _(one_enable_disable, "enable|disable")                                 \
22901 _(one_map_register_enable_disable, "enable|disable")                    \
22902 _(one_map_register_fallback_threshold, "<value>")                       \
22903 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22904 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22905                                "[seid <seid>] "                         \
22906                                "rloc <locator> p <prio> "               \
22907                                "w <weight> [rloc <loc> ... ] "          \
22908                                "action <action> [del-all]")             \
22909 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22910                           "<local-eid>")                                \
22911 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22912 _(one_use_petr, "ip-address> | disable")                                \
22913 _(one_map_request_mode, "src-dst|dst-only")                             \
22914 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22915 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22916 _(one_locator_set_dump, "[local | remote]")                             \
22917 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22918 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22919                        "[local] | [remote]")                            \
22920 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22921 _(one_ndp_bd_get, "")                                                   \
22922 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22923 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22924 _(one_l2_arp_bd_get, "")                                                \
22925 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22926 _(one_stats_enable_disable, "enable|disalbe")                           \
22927 _(show_one_stats_enable_disable, "")                                    \
22928 _(one_eid_table_vni_dump, "")                                           \
22929 _(one_eid_table_map_dump, "l2|l3")                                      \
22930 _(one_map_resolver_dump, "")                                            \
22931 _(one_map_server_dump, "")                                              \
22932 _(one_adjacencies_get, "vni <vni>")                                     \
22933 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22934 _(show_one_rloc_probe_state, "")                                        \
22935 _(show_one_map_register_state, "")                                      \
22936 _(show_one_status, "")                                                  \
22937 _(one_stats_dump, "")                                                   \
22938 _(one_stats_flush, "")                                                  \
22939 _(one_get_map_request_itr_rlocs, "")                                    \
22940 _(one_map_register_set_ttl, "<ttl>")                                    \
22941 _(one_set_transport_protocol, "udp|api")                                \
22942 _(one_get_transport_protocol, "")                                       \
22943 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22944 _(one_show_xtr_mode, "")                                                \
22945 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22946 _(one_show_pitr_mode, "")                                               \
22947 _(one_enable_disable_petr_mode, "enable|disable")                       \
22948 _(one_show_petr_mode, "")                                               \
22949 _(show_one_nsh_mapping, "")                                             \
22950 _(show_one_pitr, "")                                                    \
22951 _(show_one_use_petr, "")                                                \
22952 _(show_one_map_request_mode, "")                                        \
22953 _(show_one_map_register_ttl, "")                                        \
22954 _(show_one_map_register_fallback_threshold, "")                         \
22955 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22956                             " sw_if_index <sw_if_index> p <priority> "  \
22957                             "w <weight>] [del]")                        \
22958 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22959                         "iface <intf> | sw_if_index <sw_if_index> "     \
22960                         "p <priority> w <weight> [del]")                \
22961 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22962                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22963                          "locator-set <locator_name> [del]"             \
22964                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22965 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22966 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22967 _(lisp_enable_disable, "enable|disable")                                \
22968 _(lisp_map_register_enable_disable, "enable|disable")                   \
22969 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22970 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22971                                "[seid <seid>] "                         \
22972                                "rloc <locator> p <prio> "               \
22973                                "w <weight> [rloc <loc> ... ] "          \
22974                                "action <action> [del-all]")             \
22975 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22976                           "<local-eid>")                                \
22977 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22978 _(lisp_use_petr, "<ip-address> | disable")                              \
22979 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22980 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22981 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22982 _(lisp_locator_set_dump, "[local | remote]")                            \
22983 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22984 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22985                        "[local] | [remote]")                            \
22986 _(lisp_eid_table_vni_dump, "")                                          \
22987 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22988 _(lisp_map_resolver_dump, "")                                           \
22989 _(lisp_map_server_dump, "")                                             \
22990 _(lisp_adjacencies_get, "vni <vni>")                                    \
22991 _(gpe_fwd_entry_vnis_get, "")                                           \
22992 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22993 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22994                                 "[table <table-id>]")                   \
22995 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22996 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22997 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22998 _(gpe_get_encap_mode, "")                                               \
22999 _(lisp_gpe_add_del_iface, "up|down")                                    \
23000 _(lisp_gpe_enable_disable, "enable|disable")                            \
23001 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23002   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23003 _(show_lisp_rloc_probe_state, "")                                       \
23004 _(show_lisp_map_register_state, "")                                     \
23005 _(show_lisp_status, "")                                                 \
23006 _(lisp_get_map_request_itr_rlocs, "")                                   \
23007 _(show_lisp_pitr, "")                                                   \
23008 _(show_lisp_use_petr, "")                                               \
23009 _(show_lisp_map_request_mode, "")                                       \
23010 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23011 _(af_packet_delete, "name <host interface name>")                       \
23012 _(policer_add_del, "name <policer name> <params> [del]")                \
23013 _(policer_dump, "[name <policer name>]")                                \
23014 _(policer_classify_set_interface,                                       \
23015   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23016   "  [l2-table <nn>] [del]")                                            \
23017 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23018 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23019     "[master|slave]")                                                   \
23020 _(netmap_delete, "name <interface name>")                               \
23021 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23022 _(mpls_fib_dump, "")                                                    \
23023 _(classify_table_ids, "")                                               \
23024 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23025 _(classify_table_info, "table_id <nn>")                                 \
23026 _(classify_session_dump, "table_id <nn>")                               \
23027 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23028     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23029     "[template_interval <nn>] [udp_checksum]")                          \
23030 _(ipfix_exporter_dump, "")                                              \
23031 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23032 _(ipfix_classify_stream_dump, "")                                       \
23033 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23034 _(ipfix_classify_table_dump, "")                                        \
23035 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23036 _(sw_interface_span_dump, "[l2]")                                           \
23037 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23038 _(pg_create_interface, "if_id <nn>")                                    \
23039 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23040 _(pg_enable_disable, "[stream <id>] disable")                           \
23041 _(ip_source_and_port_range_check_add_del,                               \
23042   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23043 _(ip_source_and_port_range_check_interface_add_del,                     \
23044   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23045   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23046 _(ipsec_gre_add_del_tunnel,                                             \
23047   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23048 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23049 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23050 _(l2_interface_pbb_tag_rewrite,                                         \
23051   "<intfc> | sw_if_index <nn> \n"                                       \
23052   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23053   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23054 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23055 _(flow_classify_set_interface,                                          \
23056   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23057 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23058 _(ip_fib_dump, "")                                                      \
23059 _(ip_mfib_dump, "")                                                     \
23060 _(ip6_fib_dump, "")                                                     \
23061 _(ip6_mfib_dump, "")                                                    \
23062 _(feature_enable_disable, "arc_name <arc_name> "                        \
23063   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23064 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23065 "[disable]")                                                            \
23066 _(l2_xconnect_dump, "")                                                 \
23067 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23068 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23069 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23070 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23071 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23072 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23073 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23074   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23075 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23076 _(memfd_segment_create,"size <nnn>")                                    \
23077 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23078 _(dns_enable_disable, "[enable][disable]")                              \
23079 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23080 _(dns_resolve_name, "<hostname>")                                       \
23081 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23082 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23083 _(dns_resolve_name, "<hostname>")                                       \
23084 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23085   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23086 _(session_rules_dump, "")                                               \
23087 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23088
23089 /* List of command functions, CLI names map directly to functions */
23090 #define foreach_cli_function                                    \
23091 _(comment, "usage: comment <ignore-rest-of-line>")              \
23092 _(dump_interface_table, "usage: dump_interface_table")          \
23093 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23094 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23095 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23096 _(dump_stats_table, "usage: dump_stats_table")                  \
23097 _(dump_macro_table, "usage: dump_macro_table ")                 \
23098 _(dump_node_table, "usage: dump_node_table")                    \
23099 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23100 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23101 _(echo, "usage: echo <message>")                                \
23102 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23103 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23104 _(help, "usage: help")                                          \
23105 _(q, "usage: quit")                                             \
23106 _(quit, "usage: quit")                                          \
23107 _(search_node_table, "usage: search_node_table <name>...")      \
23108 _(set, "usage: set <variable-name> <value>")                    \
23109 _(script, "usage: script <file-name>")                          \
23110 _(unset, "usage: unset <variable-name>")
23111 #define _(N,n)                                  \
23112     static void vl_api_##n##_t_handler_uni      \
23113     (vl_api_##n##_t * mp)                       \
23114     {                                           \
23115         vat_main_t * vam = &vat_main;           \
23116         if (vam->json_output) {                 \
23117             vl_api_##n##_t_handler_json(mp);    \
23118         } else {                                \
23119             vl_api_##n##_t_handler(mp);         \
23120         }                                       \
23121     }
23122 foreach_vpe_api_reply_msg;
23123 #if VPP_API_TEST_BUILTIN == 0
23124 foreach_standalone_reply_msg;
23125 #endif
23126 #undef _
23127
23128 void
23129 vat_api_hookup (vat_main_t * vam)
23130 {
23131 #define _(N,n)                                                  \
23132     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23133                            vl_api_##n##_t_handler_uni,          \
23134                            vl_noop_handler,                     \
23135                            vl_api_##n##_t_endian,               \
23136                            vl_api_##n##_t_print,                \
23137                            sizeof(vl_api_##n##_t), 1);
23138   foreach_vpe_api_reply_msg;
23139 #if VPP_API_TEST_BUILTIN == 0
23140   foreach_standalone_reply_msg;
23141 #endif
23142 #undef _
23143
23144 #if (VPP_API_TEST_BUILTIN==0)
23145   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23146
23147   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23148
23149   vam->function_by_name = hash_create_string (0, sizeof (uword));
23150
23151   vam->help_by_name = hash_create_string (0, sizeof (uword));
23152 #endif
23153
23154   /* API messages we can send */
23155 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23156   foreach_vpe_api_msg;
23157 #undef _
23158
23159   /* Help strings */
23160 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23161   foreach_vpe_api_msg;
23162 #undef _
23163
23164   /* CLI functions */
23165 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23166   foreach_cli_function;
23167 #undef _
23168
23169   /* Help strings */
23170 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23171   foreach_cli_function;
23172 #undef _
23173 }
23174
23175 #if VPP_API_TEST_BUILTIN
23176 static clib_error_t *
23177 vat_api_hookup_shim (vlib_main_t * vm)
23178 {
23179   vat_api_hookup (&vat_main);
23180   return 0;
23181 }
23182
23183 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23184 #endif
23185
23186 /*
23187  * fd.io coding-style-patch-verification: ON
23188  *
23189  * Local Variables:
23190  * eval: (c-set-style "gnu")
23191  * End:
23192  */