Add Support of DHCP VSS Type 0 where VPN-ID is ASCII
[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 vl_api_mpls_tunnel_add_del_reply_t_handler
1698   (vl_api_mpls_tunnel_add_del_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->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1714   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1722                             ntohl (mp->sw_if_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1732   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->sw_if_index = ntohl (mp->sw_if_index);
1744       vam->result_ready = 1;
1745     }
1746 }
1747
1748 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1749   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1750 {
1751   vat_main_t *vam = &vat_main;
1752   vat_json_node_t node;
1753
1754   vat_json_init_object (&node);
1755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1756   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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_gpe_add_del_fwd_entry_reply_t_handler
1766   (vl_api_gpe_add_del_fwd_entry_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_gpe_add_del_fwd_entry_reply_t_handler_json
1782   (vl_api_gpe_add_del_fwd_entry_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, "fwd_entry_index",
1790                             clib_net_to_host_u32 (mp->fwd_entry_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 u8 *
1800 format_lisp_transport_protocol (u8 * s, va_list * args)
1801 {
1802   u32 proto = va_arg (*args, u32);
1803
1804   switch (proto)
1805     {
1806     case 1:
1807       return format (s, "udp");
1808     case 2:
1809       return format (s, "api");
1810     default:
1811       return 0;
1812     }
1813   return 0;
1814 }
1815
1816 static void vl_api_one_get_transport_protocol_reply_t_handler
1817   (vl_api_one_get_transport_protocol_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   i32 retval = ntohl (mp->retval);
1821   if (vam->async_mode)
1822     {
1823       vam->async_errors += (retval < 0);
1824     }
1825   else
1826     {
1827       u32 proto = mp->protocol;
1828       print (vam->ofp, "Transport protocol: %U",
1829              format_lisp_transport_protocol, proto);
1830       vam->retval = retval;
1831       vam->result_ready = 1;
1832     }
1833 }
1834
1835 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1836   (vl_api_one_get_transport_protocol_reply_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   vat_json_node_t node;
1840   u8 *s;
1841
1842   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1843   vec_add1 (s, 0);
1844
1845   vat_json_init_object (&node);
1846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1847   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1848
1849   vec_free (s);
1850   vat_json_print (vam->ofp, &node);
1851   vat_json_free (&node);
1852
1853   vam->retval = ntohl (mp->retval);
1854   vam->result_ready = 1;
1855 }
1856
1857 static void vl_api_one_add_del_locator_set_reply_t_handler
1858   (vl_api_one_add_del_locator_set_reply_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   i32 retval = ntohl (mp->retval);
1862   if (vam->async_mode)
1863     {
1864       vam->async_errors += (retval < 0);
1865     }
1866   else
1867     {
1868       vam->retval = retval;
1869       vam->result_ready = 1;
1870     }
1871 }
1872
1873 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1874   (vl_api_one_add_del_locator_set_reply_t * mp)
1875 {
1876   vat_main_t *vam = &vat_main;
1877   vat_json_node_t node;
1878
1879   vat_json_init_object (&node);
1880   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1881   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1882
1883   vat_json_print (vam->ofp, &node);
1884   vat_json_free (&node);
1885
1886   vam->retval = ntohl (mp->retval);
1887   vam->result_ready = 1;
1888 }
1889
1890 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1891   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   i32 retval = ntohl (mp->retval);
1895   if (vam->async_mode)
1896     {
1897       vam->async_errors += (retval < 0);
1898     }
1899   else
1900     {
1901       vam->retval = retval;
1902       vam->sw_if_index = ntohl (mp->sw_if_index);
1903       vam->result_ready = 1;
1904     }
1905 }
1906
1907 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1908   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1909 {
1910   vat_main_t *vam = &vat_main;
1911   vat_json_node_t node;
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1916
1917   vat_json_print (vam->ofp, &node);
1918   vat_json_free (&node);
1919
1920   vam->retval = ntohl (mp->retval);
1921   vam->result_ready = 1;
1922 }
1923
1924 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1925   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1926 {
1927   vat_main_t *vam = &vat_main;
1928   i32 retval = ntohl (mp->retval);
1929   if (vam->async_mode)
1930     {
1931       vam->async_errors += (retval < 0);
1932     }
1933   else
1934     {
1935       vam->retval = retval;
1936       vam->sw_if_index = ntohl (mp->sw_if_index);
1937       vam->result_ready = 1;
1938     }
1939 }
1940
1941 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
1942   (vl_api_geneve_add_del_tunnel_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, "sw_if_index", ntohl (mp->sw_if_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_gpe_add_del_tunnel_reply_t_handler
1959   (vl_api_vxlan_gpe_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_gpe_add_del_tunnel_reply_t_handler_json
1976   (vl_api_vxlan_gpe_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_gre_add_del_tunnel_reply_t_handler
1993   (vl_api_gre_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_gre_add_del_tunnel_reply_t_handler_json
2010   (vl_api_gre_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_create_vhost_user_if_reply_t_handler
2027   (vl_api_create_vhost_user_if_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_create_vhost_user_if_reply_t_handler_json
2044   (vl_api_create_vhost_user_if_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 clib_error_t *
2061 receive_fd_msg (int socket_fd, int *my_fd)
2062 {
2063   char msgbuf[16];
2064   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2065   struct msghdr mh = { 0 };
2066   struct iovec iov[1];
2067   ssize_t size;
2068   struct ucred *cr = 0;
2069   struct cmsghdr *cmsg;
2070   pid_t pid __attribute__ ((unused));
2071   uid_t uid __attribute__ ((unused));
2072   gid_t gid __attribute__ ((unused));
2073
2074   iov[0].iov_base = msgbuf;
2075   iov[0].iov_len = 5;
2076   mh.msg_iov = iov;
2077   mh.msg_iovlen = 1;
2078   mh.msg_control = ctl;
2079   mh.msg_controllen = sizeof (ctl);
2080
2081   memset (ctl, 0, sizeof (ctl));
2082
2083   /* receive the incoming message */
2084   size = recvmsg (socket_fd, &mh, 0);
2085   if (size != 5)
2086     {
2087       return (size == 0) ? clib_error_return (0, "disconnected") :
2088         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2089                                 socket_fd);
2090     }
2091
2092   cmsg = CMSG_FIRSTHDR (&mh);
2093   while (cmsg)
2094     {
2095       if (cmsg->cmsg_level == SOL_SOCKET)
2096         {
2097           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2098             {
2099               cr = (struct ucred *) CMSG_DATA (cmsg);
2100               uid = cr->uid;
2101               gid = cr->gid;
2102               pid = cr->pid;
2103             }
2104           else if (cmsg->cmsg_type == SCM_RIGHTS)
2105             {
2106               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2107             }
2108         }
2109       cmsg = CMSG_NXTHDR (&mh, cmsg);
2110     }
2111   return 0;
2112 }
2113
2114 static void vl_api_memfd_segment_create_reply_t_handler
2115   (vl_api_memfd_segment_create_reply_t * mp)
2116 {
2117   /* Dont bother in the builtin version */
2118 #if VPP_API_TEST_BUILTIN == 0
2119   vat_main_t *vam = &vat_main;
2120   api_main_t *am = &api_main;
2121   socket_client_main_t *scm = &vam->socket_client_main;
2122   int my_fd = -1;
2123   clib_error_t *error;
2124   memfd_private_t memfd;
2125   i32 retval = ntohl (mp->retval);
2126
2127   if (retval == 0)
2128     {
2129       error = receive_fd_msg (scm->socket_fd, &my_fd);
2130       if (error)
2131         {
2132           retval = -99;
2133           goto out;
2134         }
2135
2136       memset (&memfd, 0, sizeof (memfd));
2137       memfd.fd = my_fd;
2138
2139       vam->client_index_invalid = 1;
2140
2141       /* Note: this closes memfd.fd */
2142       retval = memfd_slave_init (&memfd);
2143       if (retval)
2144         clib_warning ("WARNING: segment map returned %d", retval);
2145
2146       /* Pivot to the memory client segment that vpp just created */
2147
2148       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2149
2150       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2151
2152       vl_client_install_client_message_handlers ();
2153
2154       vl_client_connect_to_vlib_no_map ("pvt",
2155                                         "vpp_api_test(p)",
2156                                         32 /* input_queue_length */ );
2157       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2158
2159       vl_socket_client_enable_disable (&vam->socket_client_main,
2160                                        0 /* disable socket */ );
2161     }
2162
2163 out:
2164   if (vam->async_mode)
2165     {
2166       vam->async_errors += (retval < 0);
2167     }
2168   else
2169     {
2170       vam->retval = retval;
2171       vam->result_ready = 1;
2172     }
2173 #endif
2174 }
2175
2176 static void vl_api_memfd_segment_create_reply_t_handler_json
2177   (vl_api_memfd_segment_create_reply_t * mp)
2178 {
2179   clib_warning ("no");
2180 }
2181
2182 static void vl_api_dns_resolve_name_reply_t_handler
2183   (vl_api_dns_resolve_name_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   i32 retval = ntohl (mp->retval);
2187   if (vam->async_mode)
2188     {
2189       vam->async_errors += (retval < 0);
2190     }
2191   else
2192     {
2193       vam->retval = retval;
2194       vam->result_ready = 1;
2195
2196       if (retval == 0)
2197         {
2198           if (mp->ip4_set)
2199             clib_warning ("ip4 address %U", format_ip4_address,
2200                           (ip4_address_t *) mp->ip4_address);
2201           if (mp->ip6_set)
2202             clib_warning ("ip6 address %U", format_ip6_address,
2203                           (ip6_address_t *) mp->ip6_address);
2204         }
2205       else
2206         clib_warning ("retval %d", retval);
2207     }
2208 }
2209
2210 static void vl_api_dns_resolve_name_reply_t_handler_json
2211   (vl_api_dns_resolve_name_reply_t * mp)
2212 {
2213   clib_warning ("not implemented");
2214 }
2215
2216 static void vl_api_dns_resolve_ip_reply_t_handler
2217   (vl_api_dns_resolve_ip_reply_t * mp)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   i32 retval = ntohl (mp->retval);
2221   if (vam->async_mode)
2222     {
2223       vam->async_errors += (retval < 0);
2224     }
2225   else
2226     {
2227       vam->retval = retval;
2228       vam->result_ready = 1;
2229
2230       if (retval == 0)
2231         {
2232           clib_warning ("canonical name %s", mp->name);
2233         }
2234       else
2235         clib_warning ("retval %d", retval);
2236     }
2237 }
2238
2239 static void vl_api_dns_resolve_ip_reply_t_handler_json
2240   (vl_api_dns_resolve_ip_reply_t * mp)
2241 {
2242   clib_warning ("not implemented");
2243 }
2244
2245
2246 static void vl_api_ip_address_details_t_handler
2247   (vl_api_ip_address_details_t * mp)
2248 {
2249   vat_main_t *vam = &vat_main;
2250   static ip_address_details_t empty_ip_address_details = { {0} };
2251   ip_address_details_t *address = NULL;
2252   ip_details_t *current_ip_details = NULL;
2253   ip_details_t *details = NULL;
2254
2255   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2256
2257   if (!details || vam->current_sw_if_index >= vec_len (details)
2258       || !details[vam->current_sw_if_index].present)
2259     {
2260       errmsg ("ip address details arrived but not stored");
2261       errmsg ("ip_dump should be called first");
2262       return;
2263     }
2264
2265   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2266
2267 #define addresses (current_ip_details->addr)
2268
2269   vec_validate_init_empty (addresses, vec_len (addresses),
2270                            empty_ip_address_details);
2271
2272   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2273
2274   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2275   address->prefix_length = mp->prefix_length;
2276 #undef addresses
2277 }
2278
2279 static void vl_api_ip_address_details_t_handler_json
2280   (vl_api_ip_address_details_t * mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   vat_json_node_t *node = NULL;
2284   struct in6_addr ip6;
2285   struct in_addr ip4;
2286
2287   if (VAT_JSON_ARRAY != vam->json_tree.type)
2288     {
2289       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2290       vat_json_init_array (&vam->json_tree);
2291     }
2292   node = vat_json_array_add (&vam->json_tree);
2293
2294   vat_json_init_object (node);
2295   if (vam->is_ipv6)
2296     {
2297       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2298       vat_json_object_add_ip6 (node, "ip", ip6);
2299     }
2300   else
2301     {
2302       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2303       vat_json_object_add_ip4 (node, "ip", ip4);
2304     }
2305   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2306 }
2307
2308 static void
2309 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2310 {
2311   vat_main_t *vam = &vat_main;
2312   static ip_details_t empty_ip_details = { 0 };
2313   ip_details_t *ip = NULL;
2314   u32 sw_if_index = ~0;
2315
2316   sw_if_index = ntohl (mp->sw_if_index);
2317
2318   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2319                            sw_if_index, empty_ip_details);
2320
2321   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2322                          sw_if_index);
2323
2324   ip->present = 1;
2325 }
2326
2327 static void
2328 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2329 {
2330   vat_main_t *vam = &vat_main;
2331
2332   if (VAT_JSON_ARRAY != vam->json_tree.type)
2333     {
2334       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2335       vat_json_init_array (&vam->json_tree);
2336     }
2337   vat_json_array_add_uint (&vam->json_tree,
2338                            clib_net_to_host_u32 (mp->sw_if_index));
2339 }
2340
2341 static void vl_api_map_domain_details_t_handler_json
2342   (vl_api_map_domain_details_t * mp)
2343 {
2344   vat_json_node_t *node = NULL;
2345   vat_main_t *vam = &vat_main;
2346   struct in6_addr ip6;
2347   struct in_addr ip4;
2348
2349   if (VAT_JSON_ARRAY != vam->json_tree.type)
2350     {
2351       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2352       vat_json_init_array (&vam->json_tree);
2353     }
2354
2355   node = vat_json_array_add (&vam->json_tree);
2356   vat_json_init_object (node);
2357
2358   vat_json_object_add_uint (node, "domain_index",
2359                             clib_net_to_host_u32 (mp->domain_index));
2360   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2361   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2362   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2363   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2364   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2365   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2366   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2367   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2368   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2369   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2370   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2371   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2372   vat_json_object_add_uint (node, "flags", mp->flags);
2373   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2374   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2375 }
2376
2377 static void vl_api_map_domain_details_t_handler
2378   (vl_api_map_domain_details_t * mp)
2379 {
2380   vat_main_t *vam = &vat_main;
2381
2382   if (mp->is_translation)
2383     {
2384       print (vam->ofp,
2385              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2386              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2387              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2388              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2389              clib_net_to_host_u32 (mp->domain_index));
2390     }
2391   else
2392     {
2393       print (vam->ofp,
2394              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2395              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2396              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2397              format_ip6_address, mp->ip6_src,
2398              clib_net_to_host_u32 (mp->domain_index));
2399     }
2400   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2401          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2402          mp->is_translation ? "map-t" : "");
2403 }
2404
2405 static void vl_api_map_rule_details_t_handler_json
2406   (vl_api_map_rule_details_t * mp)
2407 {
2408   struct in6_addr ip6;
2409   vat_json_node_t *node = NULL;
2410   vat_main_t *vam = &vat_main;
2411
2412   if (VAT_JSON_ARRAY != vam->json_tree.type)
2413     {
2414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2415       vat_json_init_array (&vam->json_tree);
2416     }
2417
2418   node = vat_json_array_add (&vam->json_tree);
2419   vat_json_init_object (node);
2420
2421   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2422   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2423   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2424 }
2425
2426 static void
2427 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2431          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2432 }
2433
2434 static void
2435 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2436 {
2437   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2438           "router_addr %U host_mac %U",
2439           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2440           format_ip4_address, &mp->host_address,
2441           format_ip4_address, &mp->router_address,
2442           format_ethernet_address, mp->host_mac);
2443 }
2444
2445 static void vl_api_dhcp_compl_event_t_handler_json
2446   (vl_api_dhcp_compl_event_t * mp)
2447 {
2448   /* JSON output not supported */
2449 }
2450
2451 static void
2452 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2453                               u32 counter)
2454 {
2455   vat_main_t *vam = &vat_main;
2456   static u64 default_counter = 0;
2457
2458   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2459                            NULL);
2460   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2461                            sw_if_index, default_counter);
2462   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2463 }
2464
2465 static void
2466 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2467                                 interface_counter_t counter)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   static interface_counter_t default_counter = { 0, };
2471
2472   vec_validate_init_empty (vam->combined_interface_counters,
2473                            vnet_counter_type, NULL);
2474   vec_validate_init_empty (vam->combined_interface_counters
2475                            [vnet_counter_type], sw_if_index, default_counter);
2476   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2477 }
2478
2479 static void vl_api_vnet_interface_simple_counters_t_handler
2480   (vl_api_vnet_interface_simple_counters_t * mp)
2481 {
2482   /* not supported */
2483 }
2484
2485 static void vl_api_vnet_interface_combined_counters_t_handler
2486   (vl_api_vnet_interface_combined_counters_t * mp)
2487 {
2488   /* not supported */
2489 }
2490
2491 static void vl_api_vnet_interface_simple_counters_t_handler_json
2492   (vl_api_vnet_interface_simple_counters_t * mp)
2493 {
2494   u64 *v_packets;
2495   u64 packets;
2496   u32 count;
2497   u32 first_sw_if_index;
2498   int i;
2499
2500   count = ntohl (mp->count);
2501   first_sw_if_index = ntohl (mp->first_sw_if_index);
2502
2503   v_packets = (u64 *) & mp->data;
2504   for (i = 0; i < count; i++)
2505     {
2506       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2507       set_simple_interface_counter (mp->vnet_counter_type,
2508                                     first_sw_if_index + i, packets);
2509       v_packets++;
2510     }
2511 }
2512
2513 static void vl_api_vnet_interface_combined_counters_t_handler_json
2514   (vl_api_vnet_interface_combined_counters_t * mp)
2515 {
2516   interface_counter_t counter;
2517   vlib_counter_t *v;
2518   u32 first_sw_if_index;
2519   int i;
2520   u32 count;
2521
2522   count = ntohl (mp->count);
2523   first_sw_if_index = ntohl (mp->first_sw_if_index);
2524
2525   v = (vlib_counter_t *) & mp->data;
2526   for (i = 0; i < count; i++)
2527     {
2528       counter.packets =
2529         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2530       counter.bytes =
2531         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2532       set_combined_interface_counter (mp->vnet_counter_type,
2533                                       first_sw_if_index + i, counter);
2534       v++;
2535     }
2536 }
2537
2538 static u32
2539 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2540 {
2541   vat_main_t *vam = &vat_main;
2542   u32 i;
2543
2544   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2545     {
2546       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2547         {
2548           return i;
2549         }
2550     }
2551   return ~0;
2552 }
2553
2554 static u32
2555 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2556 {
2557   vat_main_t *vam = &vat_main;
2558   u32 i;
2559
2560   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2561     {
2562       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2563         {
2564           return i;
2565         }
2566     }
2567   return ~0;
2568 }
2569
2570 static void vl_api_vnet_ip4_fib_counters_t_handler
2571   (vl_api_vnet_ip4_fib_counters_t * mp)
2572 {
2573   /* not supported */
2574 }
2575
2576 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2577   (vl_api_vnet_ip4_fib_counters_t * mp)
2578 {
2579   vat_main_t *vam = &vat_main;
2580   vl_api_ip4_fib_counter_t *v;
2581   ip4_fib_counter_t *counter;
2582   struct in_addr ip4;
2583   u32 vrf_id;
2584   u32 vrf_index;
2585   u32 count;
2586   int i;
2587
2588   vrf_id = ntohl (mp->vrf_id);
2589   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2590   if (~0 == vrf_index)
2591     {
2592       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2593       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2594       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2595       vec_validate (vam->ip4_fib_counters, vrf_index);
2596       vam->ip4_fib_counters[vrf_index] = NULL;
2597     }
2598
2599   vec_free (vam->ip4_fib_counters[vrf_index]);
2600   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2601   count = ntohl (mp->count);
2602   for (i = 0; i < count; i++)
2603     {
2604       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2605       counter = &vam->ip4_fib_counters[vrf_index][i];
2606       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2607       counter->address = ip4;
2608       counter->address_length = v->address_length;
2609       counter->packets = clib_net_to_host_u64 (v->packets);
2610       counter->bytes = clib_net_to_host_u64 (v->bytes);
2611       v++;
2612     }
2613 }
2614
2615 static void vl_api_vnet_ip4_nbr_counters_t_handler
2616   (vl_api_vnet_ip4_nbr_counters_t * mp)
2617 {
2618   /* not supported */
2619 }
2620
2621 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2622   (vl_api_vnet_ip4_nbr_counters_t * mp)
2623 {
2624   vat_main_t *vam = &vat_main;
2625   vl_api_ip4_nbr_counter_t *v;
2626   ip4_nbr_counter_t *counter;
2627   u32 sw_if_index;
2628   u32 count;
2629   int i;
2630
2631   sw_if_index = ntohl (mp->sw_if_index);
2632   count = ntohl (mp->count);
2633   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2634
2635   if (mp->begin)
2636     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2637
2638   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2639   for (i = 0; i < count; i++)
2640     {
2641       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2642       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2643       counter->address.s_addr = v->address;
2644       counter->packets = clib_net_to_host_u64 (v->packets);
2645       counter->bytes = clib_net_to_host_u64 (v->bytes);
2646       counter->linkt = v->link_type;
2647       v++;
2648     }
2649 }
2650
2651 static void vl_api_vnet_ip6_fib_counters_t_handler
2652   (vl_api_vnet_ip6_fib_counters_t * mp)
2653 {
2654   /* not supported */
2655 }
2656
2657 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2658   (vl_api_vnet_ip6_fib_counters_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   vl_api_ip6_fib_counter_t *v;
2662   ip6_fib_counter_t *counter;
2663   struct in6_addr ip6;
2664   u32 vrf_id;
2665   u32 vrf_index;
2666   u32 count;
2667   int i;
2668
2669   vrf_id = ntohl (mp->vrf_id);
2670   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2671   if (~0 == vrf_index)
2672     {
2673       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2674       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2675       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2676       vec_validate (vam->ip6_fib_counters, vrf_index);
2677       vam->ip6_fib_counters[vrf_index] = NULL;
2678     }
2679
2680   vec_free (vam->ip6_fib_counters[vrf_index]);
2681   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2682   count = ntohl (mp->count);
2683   for (i = 0; i < count; i++)
2684     {
2685       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2686       counter = &vam->ip6_fib_counters[vrf_index][i];
2687       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2688       counter->address = ip6;
2689       counter->address_length = v->address_length;
2690       counter->packets = clib_net_to_host_u64 (v->packets);
2691       counter->bytes = clib_net_to_host_u64 (v->bytes);
2692       v++;
2693     }
2694 }
2695
2696 static void vl_api_vnet_ip6_nbr_counters_t_handler
2697   (vl_api_vnet_ip6_nbr_counters_t * mp)
2698 {
2699   /* not supported */
2700 }
2701
2702 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2703   (vl_api_vnet_ip6_nbr_counters_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   vl_api_ip6_nbr_counter_t *v;
2707   ip6_nbr_counter_t *counter;
2708   struct in6_addr ip6;
2709   u32 sw_if_index;
2710   u32 count;
2711   int i;
2712
2713   sw_if_index = ntohl (mp->sw_if_index);
2714   count = ntohl (mp->count);
2715   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2716
2717   if (mp->begin)
2718     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2719
2720   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2721   for (i = 0; i < count; i++)
2722     {
2723       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2724       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2725       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2726       counter->address = ip6;
2727       counter->packets = clib_net_to_host_u64 (v->packets);
2728       counter->bytes = clib_net_to_host_u64 (v->bytes);
2729       v++;
2730     }
2731 }
2732
2733 static void vl_api_get_first_msg_id_reply_t_handler
2734   (vl_api_get_first_msg_id_reply_t * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   i32 retval = ntohl (mp->retval);
2738
2739   if (vam->async_mode)
2740     {
2741       vam->async_errors += (retval < 0);
2742     }
2743   else
2744     {
2745       vam->retval = retval;
2746       vam->result_ready = 1;
2747     }
2748   if (retval >= 0)
2749     {
2750       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2751     }
2752 }
2753
2754 static void vl_api_get_first_msg_id_reply_t_handler_json
2755   (vl_api_get_first_msg_id_reply_t * mp)
2756 {
2757   vat_main_t *vam = &vat_main;
2758   vat_json_node_t node;
2759
2760   vat_json_init_object (&node);
2761   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2762   vat_json_object_add_uint (&node, "first_msg_id",
2763                             (uint) ntohs (mp->first_msg_id));
2764
2765   vat_json_print (vam->ofp, &node);
2766   vat_json_free (&node);
2767
2768   vam->retval = ntohl (mp->retval);
2769   vam->result_ready = 1;
2770 }
2771
2772 static void vl_api_get_node_graph_reply_t_handler
2773   (vl_api_get_node_graph_reply_t * mp)
2774 {
2775   vat_main_t *vam = &vat_main;
2776   api_main_t *am = &api_main;
2777   i32 retval = ntohl (mp->retval);
2778   u8 *pvt_copy, *reply;
2779   void *oldheap;
2780   vlib_node_t *node;
2781   int i;
2782
2783   if (vam->async_mode)
2784     {
2785       vam->async_errors += (retval < 0);
2786     }
2787   else
2788     {
2789       vam->retval = retval;
2790       vam->result_ready = 1;
2791     }
2792
2793   /* "Should never happen..." */
2794   if (retval != 0)
2795     return;
2796
2797   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2798   pvt_copy = vec_dup (reply);
2799
2800   /* Toss the shared-memory original... */
2801   pthread_mutex_lock (&am->vlib_rp->mutex);
2802   oldheap = svm_push_data_heap (am->vlib_rp);
2803
2804   vec_free (reply);
2805
2806   svm_pop_heap (oldheap);
2807   pthread_mutex_unlock (&am->vlib_rp->mutex);
2808
2809   if (vam->graph_nodes)
2810     {
2811       hash_free (vam->graph_node_index_by_name);
2812
2813       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2814         {
2815           node = vam->graph_nodes[i];
2816           vec_free (node->name);
2817           vec_free (node->next_nodes);
2818           vec_free (node);
2819         }
2820       vec_free (vam->graph_nodes);
2821     }
2822
2823   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2824   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2825   vec_free (pvt_copy);
2826
2827   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2828     {
2829       node = vam->graph_nodes[i];
2830       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2831     }
2832 }
2833
2834 static void vl_api_get_node_graph_reply_t_handler_json
2835   (vl_api_get_node_graph_reply_t * mp)
2836 {
2837   vat_main_t *vam = &vat_main;
2838   api_main_t *am = &api_main;
2839   void *oldheap;
2840   vat_json_node_t node;
2841   u8 *reply;
2842
2843   /* $$$$ make this real? */
2844   vat_json_init_object (&node);
2845   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2846   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2847
2848   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2849
2850   /* Toss the shared-memory original... */
2851   pthread_mutex_lock (&am->vlib_rp->mutex);
2852   oldheap = svm_push_data_heap (am->vlib_rp);
2853
2854   vec_free (reply);
2855
2856   svm_pop_heap (oldheap);
2857   pthread_mutex_unlock (&am->vlib_rp->mutex);
2858
2859   vat_json_print (vam->ofp, &node);
2860   vat_json_free (&node);
2861
2862   vam->retval = ntohl (mp->retval);
2863   vam->result_ready = 1;
2864 }
2865
2866 static void
2867 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   u8 *s = 0;
2871
2872   if (mp->local)
2873     {
2874       s = format (s, "%=16d%=16d%=16d",
2875                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2876     }
2877   else
2878     {
2879       s = format (s, "%=16U%=16d%=16d",
2880                   mp->is_ipv6 ? format_ip6_address :
2881                   format_ip4_address,
2882                   mp->ip_address, mp->priority, mp->weight);
2883     }
2884
2885   print (vam->ofp, "%v", s);
2886   vec_free (s);
2887 }
2888
2889 static void
2890 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2891 {
2892   vat_main_t *vam = &vat_main;
2893   vat_json_node_t *node = NULL;
2894   struct in6_addr ip6;
2895   struct in_addr ip4;
2896
2897   if (VAT_JSON_ARRAY != vam->json_tree.type)
2898     {
2899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2900       vat_json_init_array (&vam->json_tree);
2901     }
2902   node = vat_json_array_add (&vam->json_tree);
2903   vat_json_init_object (node);
2904
2905   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2906   vat_json_object_add_uint (node, "priority", mp->priority);
2907   vat_json_object_add_uint (node, "weight", mp->weight);
2908
2909   if (mp->local)
2910     vat_json_object_add_uint (node, "sw_if_index",
2911                               clib_net_to_host_u32 (mp->sw_if_index));
2912   else
2913     {
2914       if (mp->is_ipv6)
2915         {
2916           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2917           vat_json_object_add_ip6 (node, "address", ip6);
2918         }
2919       else
2920         {
2921           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2922           vat_json_object_add_ip4 (node, "address", ip4);
2923         }
2924     }
2925 }
2926
2927 static void
2928 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2929                                           mp)
2930 {
2931   vat_main_t *vam = &vat_main;
2932   u8 *ls_name = 0;
2933
2934   ls_name = format (0, "%s", mp->ls_name);
2935
2936   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2937          ls_name);
2938   vec_free (ls_name);
2939 }
2940
2941 static void
2942   vl_api_one_locator_set_details_t_handler_json
2943   (vl_api_one_locator_set_details_t * mp)
2944 {
2945   vat_main_t *vam = &vat_main;
2946   vat_json_node_t *node = 0;
2947   u8 *ls_name = 0;
2948
2949   ls_name = format (0, "%s", mp->ls_name);
2950   vec_add1 (ls_name, 0);
2951
2952   if (VAT_JSON_ARRAY != vam->json_tree.type)
2953     {
2954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2955       vat_json_init_array (&vam->json_tree);
2956     }
2957   node = vat_json_array_add (&vam->json_tree);
2958
2959   vat_json_init_object (node);
2960   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2961   vat_json_object_add_uint (node, "ls_index",
2962                             clib_net_to_host_u32 (mp->ls_index));
2963   vec_free (ls_name);
2964 }
2965
2966 typedef struct
2967 {
2968   u32 spi;
2969   u8 si;
2970 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2971
2972 uword
2973 unformat_nsh_address (unformat_input_t * input, va_list * args)
2974 {
2975   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2976   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2977 }
2978
2979 u8 *
2980 format_nsh_address_vat (u8 * s, va_list * args)
2981 {
2982   nsh_t *a = va_arg (*args, nsh_t *);
2983   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2984 }
2985
2986 static u8 *
2987 format_lisp_flat_eid (u8 * s, va_list * args)
2988 {
2989   u32 type = va_arg (*args, u32);
2990   u8 *eid = va_arg (*args, u8 *);
2991   u32 eid_len = va_arg (*args, u32);
2992
2993   switch (type)
2994     {
2995     case 0:
2996       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2997     case 1:
2998       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2999     case 2:
3000       return format (s, "%U", format_ethernet_address, eid);
3001     case 3:
3002       return format (s, "%U", format_nsh_address_vat, eid);
3003     }
3004   return 0;
3005 }
3006
3007 static u8 *
3008 format_lisp_eid_vat (u8 * s, va_list * args)
3009 {
3010   u32 type = va_arg (*args, u32);
3011   u8 *eid = va_arg (*args, u8 *);
3012   u32 eid_len = va_arg (*args, u32);
3013   u8 *seid = va_arg (*args, u8 *);
3014   u32 seid_len = va_arg (*args, u32);
3015   u32 is_src_dst = va_arg (*args, u32);
3016
3017   if (is_src_dst)
3018     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3019
3020   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3021
3022   return s;
3023 }
3024
3025 static void
3026 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029   u8 *s = 0, *eid = 0;
3030
3031   if (~0 == mp->locator_set_index)
3032     s = format (0, "action: %d", mp->action);
3033   else
3034     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3035
3036   eid = format (0, "%U", format_lisp_eid_vat,
3037                 mp->eid_type,
3038                 mp->eid,
3039                 mp->eid_prefix_len,
3040                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3041   vec_add1 (eid, 0);
3042
3043   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3044          clib_net_to_host_u32 (mp->vni),
3045          eid,
3046          mp->is_local ? "local" : "remote",
3047          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3048          clib_net_to_host_u16 (mp->key_id), mp->key);
3049
3050   vec_free (s);
3051   vec_free (eid);
3052 }
3053
3054 static void
3055 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3056                                              * mp)
3057 {
3058   vat_main_t *vam = &vat_main;
3059   vat_json_node_t *node = 0;
3060   u8 *eid = 0;
3061
3062   if (VAT_JSON_ARRAY != vam->json_tree.type)
3063     {
3064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3065       vat_json_init_array (&vam->json_tree);
3066     }
3067   node = vat_json_array_add (&vam->json_tree);
3068
3069   vat_json_init_object (node);
3070   if (~0 == mp->locator_set_index)
3071     vat_json_object_add_uint (node, "action", mp->action);
3072   else
3073     vat_json_object_add_uint (node, "locator_set_index",
3074                               clib_net_to_host_u32 (mp->locator_set_index));
3075
3076   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3077   if (mp->eid_type == 3)
3078     {
3079       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3080       vat_json_init_object (nsh_json);
3081       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3082       vat_json_object_add_uint (nsh_json, "spi",
3083                                 clib_net_to_host_u32 (nsh->spi));
3084       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3085     }
3086   else
3087     {
3088       eid = format (0, "%U", format_lisp_eid_vat,
3089                     mp->eid_type,
3090                     mp->eid,
3091                     mp->eid_prefix_len,
3092                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3093       vec_add1 (eid, 0);
3094       vat_json_object_add_string_copy (node, "eid", eid);
3095       vec_free (eid);
3096     }
3097   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3098   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3099   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3100
3101   if (mp->key_id)
3102     {
3103       vat_json_object_add_uint (node, "key_id",
3104                                 clib_net_to_host_u16 (mp->key_id));
3105       vat_json_object_add_string_copy (node, "key", mp->key);
3106     }
3107 }
3108
3109 static void
3110 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3111 {
3112   vat_main_t *vam = &vat_main;
3113   u8 *seid = 0, *deid = 0;
3114   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3115
3116   deid = format (0, "%U", format_lisp_eid_vat,
3117                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3118
3119   seid = format (0, "%U", format_lisp_eid_vat,
3120                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3121
3122   vec_add1 (deid, 0);
3123   vec_add1 (seid, 0);
3124
3125   if (mp->is_ip4)
3126     format_ip_address_fcn = format_ip4_address;
3127   else
3128     format_ip_address_fcn = format_ip6_address;
3129
3130
3131   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3132          clib_net_to_host_u32 (mp->vni),
3133          seid, deid,
3134          format_ip_address_fcn, mp->lloc,
3135          format_ip_address_fcn, mp->rloc,
3136          clib_net_to_host_u32 (mp->pkt_count),
3137          clib_net_to_host_u32 (mp->bytes));
3138
3139   vec_free (deid);
3140   vec_free (seid);
3141 }
3142
3143 static void
3144 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3145 {
3146   struct in6_addr ip6;
3147   struct in_addr ip4;
3148   vat_main_t *vam = &vat_main;
3149   vat_json_node_t *node = 0;
3150   u8 *deid = 0, *seid = 0;
3151
3152   if (VAT_JSON_ARRAY != vam->json_tree.type)
3153     {
3154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3155       vat_json_init_array (&vam->json_tree);
3156     }
3157   node = vat_json_array_add (&vam->json_tree);
3158
3159   vat_json_init_object (node);
3160   deid = format (0, "%U", format_lisp_eid_vat,
3161                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3162
3163   seid = format (0, "%U", format_lisp_eid_vat,
3164                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3165
3166   vec_add1 (deid, 0);
3167   vec_add1 (seid, 0);
3168
3169   vat_json_object_add_string_copy (node, "seid", seid);
3170   vat_json_object_add_string_copy (node, "deid", deid);
3171   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3172
3173   if (mp->is_ip4)
3174     {
3175       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3176       vat_json_object_add_ip4 (node, "lloc", ip4);
3177       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3178       vat_json_object_add_ip4 (node, "rloc", ip4);
3179     }
3180   else
3181     {
3182       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3183       vat_json_object_add_ip6 (node, "lloc", ip6);
3184       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3185       vat_json_object_add_ip6 (node, "rloc", ip6);
3186     }
3187   vat_json_object_add_uint (node, "pkt_count",
3188                             clib_net_to_host_u32 (mp->pkt_count));
3189   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3190
3191   vec_free (deid);
3192   vec_free (seid);
3193 }
3194
3195 static void
3196   vl_api_one_eid_table_map_details_t_handler
3197   (vl_api_one_eid_table_map_details_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200
3201   u8 *line = format (0, "%=10d%=10d",
3202                      clib_net_to_host_u32 (mp->vni),
3203                      clib_net_to_host_u32 (mp->dp_table));
3204   print (vam->ofp, "%v", line);
3205   vec_free (line);
3206 }
3207
3208 static void
3209   vl_api_one_eid_table_map_details_t_handler_json
3210   (vl_api_one_eid_table_map_details_t * mp)
3211 {
3212   vat_main_t *vam = &vat_main;
3213   vat_json_node_t *node = NULL;
3214
3215   if (VAT_JSON_ARRAY != vam->json_tree.type)
3216     {
3217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3218       vat_json_init_array (&vam->json_tree);
3219     }
3220   node = vat_json_array_add (&vam->json_tree);
3221   vat_json_init_object (node);
3222   vat_json_object_add_uint (node, "dp_table",
3223                             clib_net_to_host_u32 (mp->dp_table));
3224   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3225 }
3226
3227 static void
3228   vl_api_one_eid_table_vni_details_t_handler
3229   (vl_api_one_eid_table_vni_details_t * mp)
3230 {
3231   vat_main_t *vam = &vat_main;
3232
3233   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3234   print (vam->ofp, "%v", line);
3235   vec_free (line);
3236 }
3237
3238 static void
3239   vl_api_one_eid_table_vni_details_t_handler_json
3240   (vl_api_one_eid_table_vni_details_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243   vat_json_node_t *node = NULL;
3244
3245   if (VAT_JSON_ARRAY != vam->json_tree.type)
3246     {
3247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3248       vat_json_init_array (&vam->json_tree);
3249     }
3250   node = vat_json_array_add (&vam->json_tree);
3251   vat_json_init_object (node);
3252   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3253 }
3254
3255 static void
3256   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3257   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260   int retval = clib_net_to_host_u32 (mp->retval);
3261
3262   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3263   print (vam->ofp, "fallback threshold value: %d", mp->value);
3264
3265   vam->retval = retval;
3266   vam->result_ready = 1;
3267 }
3268
3269 static void
3270   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3271   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3272 {
3273   vat_main_t *vam = &vat_main;
3274   vat_json_node_t _node, *node = &_node;
3275   int retval = clib_net_to_host_u32 (mp->retval);
3276
3277   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3278   vat_json_init_object (node);
3279   vat_json_object_add_uint (node, "value", mp->value);
3280
3281   vat_json_print (vam->ofp, node);
3282   vat_json_free (node);
3283
3284   vam->retval = retval;
3285   vam->result_ready = 1;
3286 }
3287
3288 static void
3289   vl_api_show_one_map_register_state_reply_t_handler
3290   (vl_api_show_one_map_register_state_reply_t * mp)
3291 {
3292   vat_main_t *vam = &vat_main;
3293   int retval = clib_net_to_host_u32 (mp->retval);
3294
3295   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3296
3297   vam->retval = retval;
3298   vam->result_ready = 1;
3299 }
3300
3301 static void
3302   vl_api_show_one_map_register_state_reply_t_handler_json
3303   (vl_api_show_one_map_register_state_reply_t * mp)
3304 {
3305   vat_main_t *vam = &vat_main;
3306   vat_json_node_t _node, *node = &_node;
3307   int retval = clib_net_to_host_u32 (mp->retval);
3308
3309   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3310
3311   vat_json_init_object (node);
3312   vat_json_object_add_string_copy (node, "state", s);
3313
3314   vat_json_print (vam->ofp, node);
3315   vat_json_free (node);
3316
3317   vam->retval = retval;
3318   vam->result_ready = 1;
3319   vec_free (s);
3320 }
3321
3322 static void
3323   vl_api_show_one_rloc_probe_state_reply_t_handler
3324   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3325 {
3326   vat_main_t *vam = &vat_main;
3327   int retval = clib_net_to_host_u32 (mp->retval);
3328
3329   if (retval)
3330     goto end;
3331
3332   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3333 end:
3334   vam->retval = retval;
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3340   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t _node, *node = &_node;
3344   int retval = clib_net_to_host_u32 (mp->retval);
3345
3346   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3347   vat_json_init_object (node);
3348   vat_json_object_add_string_copy (node, "state", s);
3349
3350   vat_json_print (vam->ofp, node);
3351   vat_json_free (node);
3352
3353   vam->retval = retval;
3354   vam->result_ready = 1;
3355   vec_free (s);
3356 }
3357
3358 static void
3359   vl_api_show_one_stats_enable_disable_reply_t_handler
3360   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3361 {
3362   vat_main_t *vam = &vat_main;
3363   int retval = clib_net_to_host_u32 (mp->retval);
3364
3365   if (retval)
3366     goto end;
3367
3368   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3369 end:
3370   vam->retval = retval;
3371   vam->result_ready = 1;
3372 }
3373
3374 static void
3375   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3376   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3377 {
3378   vat_main_t *vam = &vat_main;
3379   vat_json_node_t _node, *node = &_node;
3380   int retval = clib_net_to_host_u32 (mp->retval);
3381
3382   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3383   vat_json_init_object (node);
3384   vat_json_object_add_string_copy (node, "state", s);
3385
3386   vat_json_print (vam->ofp, node);
3387   vat_json_free (node);
3388
3389   vam->retval = retval;
3390   vam->result_ready = 1;
3391   vec_free (s);
3392 }
3393
3394 static void
3395 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3396 {
3397   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3398   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3399   e->vni = clib_net_to_host_u32 (e->vni);
3400 }
3401
3402 static void
3403   gpe_fwd_entries_get_reply_t_net_to_host
3404   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3405 {
3406   u32 i;
3407
3408   mp->count = clib_net_to_host_u32 (mp->count);
3409   for (i = 0; i < mp->count; i++)
3410     {
3411       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3412     }
3413 }
3414
3415 static u8 *
3416 format_gpe_encap_mode (u8 * s, va_list * args)
3417 {
3418   u32 mode = va_arg (*args, u32);
3419
3420   switch (mode)
3421     {
3422     case 0:
3423       return format (s, "lisp");
3424     case 1:
3425       return format (s, "vxlan");
3426     }
3427   return 0;
3428 }
3429
3430 static void
3431   vl_api_gpe_get_encap_mode_reply_t_handler
3432   (vl_api_gpe_get_encap_mode_reply_t * mp)
3433 {
3434   vat_main_t *vam = &vat_main;
3435
3436   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3437   vam->retval = ntohl (mp->retval);
3438   vam->result_ready = 1;
3439 }
3440
3441 static void
3442   vl_api_gpe_get_encap_mode_reply_t_handler_json
3443   (vl_api_gpe_get_encap_mode_reply_t * mp)
3444 {
3445   vat_main_t *vam = &vat_main;
3446   vat_json_node_t node;
3447
3448   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3449   vec_add1 (encap_mode, 0);
3450
3451   vat_json_init_object (&node);
3452   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3453
3454   vec_free (encap_mode);
3455   vat_json_print (vam->ofp, &node);
3456   vat_json_free (&node);
3457
3458   vam->retval = ntohl (mp->retval);
3459   vam->result_ready = 1;
3460 }
3461
3462 static void
3463   vl_api_gpe_fwd_entry_path_details_t_handler
3464   (vl_api_gpe_fwd_entry_path_details_t * mp)
3465 {
3466   vat_main_t *vam = &vat_main;
3467   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3468
3469   if (mp->lcl_loc.is_ip4)
3470     format_ip_address_fcn = format_ip4_address;
3471   else
3472     format_ip_address_fcn = format_ip6_address;
3473
3474   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3475          format_ip_address_fcn, &mp->lcl_loc,
3476          format_ip_address_fcn, &mp->rmt_loc);
3477 }
3478
3479 static void
3480 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3481 {
3482   struct in6_addr ip6;
3483   struct in_addr ip4;
3484
3485   if (loc->is_ip4)
3486     {
3487       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3488       vat_json_object_add_ip4 (n, "address", ip4);
3489     }
3490   else
3491     {
3492       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3493       vat_json_object_add_ip6 (n, "address", ip6);
3494     }
3495   vat_json_object_add_uint (n, "weight", loc->weight);
3496 }
3497
3498 static void
3499   vl_api_gpe_fwd_entry_path_details_t_handler_json
3500   (vl_api_gpe_fwd_entry_path_details_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503   vat_json_node_t *node = NULL;
3504   vat_json_node_t *loc_node;
3505
3506   if (VAT_JSON_ARRAY != vam->json_tree.type)
3507     {
3508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3509       vat_json_init_array (&vam->json_tree);
3510     }
3511   node = vat_json_array_add (&vam->json_tree);
3512   vat_json_init_object (node);
3513
3514   loc_node = vat_json_object_add (node, "local_locator");
3515   vat_json_init_object (loc_node);
3516   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3517
3518   loc_node = vat_json_object_add (node, "remote_locator");
3519   vat_json_init_object (loc_node);
3520   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3521 }
3522
3523 static void
3524   vl_api_gpe_fwd_entries_get_reply_t_handler
3525   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3526 {
3527   vat_main_t *vam = &vat_main;
3528   u32 i;
3529   int retval = clib_net_to_host_u32 (mp->retval);
3530   vl_api_gpe_fwd_entry_t *e;
3531
3532   if (retval)
3533     goto end;
3534
3535   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3536
3537   for (i = 0; i < mp->count; i++)
3538     {
3539       e = &mp->entries[i];
3540       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3541              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3542              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3543     }
3544
3545 end:
3546   vam->retval = retval;
3547   vam->result_ready = 1;
3548 }
3549
3550 static void
3551   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3552   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3553 {
3554   u8 *s = 0;
3555   vat_main_t *vam = &vat_main;
3556   vat_json_node_t *e = 0, root;
3557   u32 i;
3558   int retval = clib_net_to_host_u32 (mp->retval);
3559   vl_api_gpe_fwd_entry_t *fwd;
3560
3561   if (retval)
3562     goto end;
3563
3564   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3565   vat_json_init_array (&root);
3566
3567   for (i = 0; i < mp->count; i++)
3568     {
3569       e = vat_json_array_add (&root);
3570       fwd = &mp->entries[i];
3571
3572       vat_json_init_object (e);
3573       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3574       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3575       vat_json_object_add_int (e, "vni", fwd->vni);
3576       vat_json_object_add_int (e, "action", fwd->action);
3577
3578       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3579                   fwd->leid_prefix_len);
3580       vec_add1 (s, 0);
3581       vat_json_object_add_string_copy (e, "leid", s);
3582       vec_free (s);
3583
3584       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3585                   fwd->reid_prefix_len);
3586       vec_add1 (s, 0);
3587       vat_json_object_add_string_copy (e, "reid", s);
3588       vec_free (s);
3589     }
3590
3591   vat_json_print (vam->ofp, &root);
3592   vat_json_free (&root);
3593
3594 end:
3595   vam->retval = retval;
3596   vam->result_ready = 1;
3597 }
3598
3599 static void
3600   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3601   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3602 {
3603   vat_main_t *vam = &vat_main;
3604   u32 i, n;
3605   int retval = clib_net_to_host_u32 (mp->retval);
3606   vl_api_gpe_native_fwd_rpath_t *r;
3607
3608   if (retval)
3609     goto end;
3610
3611   n = clib_net_to_host_u32 (mp->count);
3612
3613   for (i = 0; i < n; i++)
3614     {
3615       r = &mp->entries[i];
3616       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3617              clib_net_to_host_u32 (r->fib_index),
3618              clib_net_to_host_u32 (r->nh_sw_if_index),
3619              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3620     }
3621
3622 end:
3623   vam->retval = retval;
3624   vam->result_ready = 1;
3625 }
3626
3627 static void
3628   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3629   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3630 {
3631   vat_main_t *vam = &vat_main;
3632   vat_json_node_t root, *e;
3633   u32 i, n;
3634   int retval = clib_net_to_host_u32 (mp->retval);
3635   vl_api_gpe_native_fwd_rpath_t *r;
3636   u8 *s;
3637
3638   if (retval)
3639     goto end;
3640
3641   n = clib_net_to_host_u32 (mp->count);
3642   vat_json_init_array (&root);
3643
3644   for (i = 0; i < n; i++)
3645     {
3646       e = vat_json_array_add (&root);
3647       vat_json_init_object (e);
3648       r = &mp->entries[i];
3649       s =
3650         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3651                 r->nh_addr);
3652       vec_add1 (s, 0);
3653       vat_json_object_add_string_copy (e, "ip4", s);
3654       vec_free (s);
3655
3656       vat_json_object_add_uint (e, "fib_index",
3657                                 clib_net_to_host_u32 (r->fib_index));
3658       vat_json_object_add_uint (e, "nh_sw_if_index",
3659                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3660     }
3661
3662   vat_json_print (vam->ofp, &root);
3663   vat_json_free (&root);
3664
3665 end:
3666   vam->retval = retval;
3667   vam->result_ready = 1;
3668 }
3669
3670 static void
3671   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3672   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3673 {
3674   vat_main_t *vam = &vat_main;
3675   u32 i, n;
3676   int retval = clib_net_to_host_u32 (mp->retval);
3677
3678   if (retval)
3679     goto end;
3680
3681   n = clib_net_to_host_u32 (mp->count);
3682
3683   for (i = 0; i < n; i++)
3684     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3685
3686 end:
3687   vam->retval = retval;
3688   vam->result_ready = 1;
3689 }
3690
3691 static void
3692   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3693   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3694 {
3695   vat_main_t *vam = &vat_main;
3696   vat_json_node_t root;
3697   u32 i, n;
3698   int retval = clib_net_to_host_u32 (mp->retval);
3699
3700   if (retval)
3701     goto end;
3702
3703   n = clib_net_to_host_u32 (mp->count);
3704   vat_json_init_array (&root);
3705
3706   for (i = 0; i < n; i++)
3707     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3708
3709   vat_json_print (vam->ofp, &root);
3710   vat_json_free (&root);
3711
3712 end:
3713   vam->retval = retval;
3714   vam->result_ready = 1;
3715 }
3716
3717 static void
3718   vl_api_one_ndp_entries_get_reply_t_handler
3719   (vl_api_one_ndp_entries_get_reply_t * mp)
3720 {
3721   vat_main_t *vam = &vat_main;
3722   u32 i, n;
3723   int retval = clib_net_to_host_u32 (mp->retval);
3724
3725   if (retval)
3726     goto end;
3727
3728   n = clib_net_to_host_u32 (mp->count);
3729
3730   for (i = 0; i < n; i++)
3731     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3732            format_ethernet_address, mp->entries[i].mac);
3733
3734 end:
3735   vam->retval = retval;
3736   vam->result_ready = 1;
3737 }
3738
3739 static void
3740   vl_api_one_ndp_entries_get_reply_t_handler_json
3741   (vl_api_one_ndp_entries_get_reply_t * mp)
3742 {
3743   u8 *s = 0;
3744   vat_main_t *vam = &vat_main;
3745   vat_json_node_t *e = 0, root;
3746   u32 i, n;
3747   int retval = clib_net_to_host_u32 (mp->retval);
3748   vl_api_one_ndp_entry_t *arp_entry;
3749
3750   if (retval)
3751     goto end;
3752
3753   n = clib_net_to_host_u32 (mp->count);
3754   vat_json_init_array (&root);
3755
3756   for (i = 0; i < n; i++)
3757     {
3758       e = vat_json_array_add (&root);
3759       arp_entry = &mp->entries[i];
3760
3761       vat_json_init_object (e);
3762       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3763       vec_add1 (s, 0);
3764
3765       vat_json_object_add_string_copy (e, "mac", s);
3766       vec_free (s);
3767
3768       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3769       vec_add1 (s, 0);
3770       vat_json_object_add_string_copy (e, "ip6", s);
3771       vec_free (s);
3772     }
3773
3774   vat_json_print (vam->ofp, &root);
3775   vat_json_free (&root);
3776
3777 end:
3778   vam->retval = retval;
3779   vam->result_ready = 1;
3780 }
3781
3782 static void
3783   vl_api_one_l2_arp_entries_get_reply_t_handler
3784   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3785 {
3786   vat_main_t *vam = &vat_main;
3787   u32 i, n;
3788   int retval = clib_net_to_host_u32 (mp->retval);
3789
3790   if (retval)
3791     goto end;
3792
3793   n = clib_net_to_host_u32 (mp->count);
3794
3795   for (i = 0; i < n; i++)
3796     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3797            format_ethernet_address, mp->entries[i].mac);
3798
3799 end:
3800   vam->retval = retval;
3801   vam->result_ready = 1;
3802 }
3803
3804 static void
3805   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3806   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3807 {
3808   u8 *s = 0;
3809   vat_main_t *vam = &vat_main;
3810   vat_json_node_t *e = 0, root;
3811   u32 i, n;
3812   int retval = clib_net_to_host_u32 (mp->retval);
3813   vl_api_one_l2_arp_entry_t *arp_entry;
3814
3815   if (retval)
3816     goto end;
3817
3818   n = clib_net_to_host_u32 (mp->count);
3819   vat_json_init_array (&root);
3820
3821   for (i = 0; i < n; i++)
3822     {
3823       e = vat_json_array_add (&root);
3824       arp_entry = &mp->entries[i];
3825
3826       vat_json_init_object (e);
3827       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3828       vec_add1 (s, 0);
3829
3830       vat_json_object_add_string_copy (e, "mac", s);
3831       vec_free (s);
3832
3833       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3834       vec_add1 (s, 0);
3835       vat_json_object_add_string_copy (e, "ip4", s);
3836       vec_free (s);
3837     }
3838
3839   vat_json_print (vam->ofp, &root);
3840   vat_json_free (&root);
3841
3842 end:
3843   vam->retval = retval;
3844   vam->result_ready = 1;
3845 }
3846
3847 static void
3848 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3849 {
3850   vat_main_t *vam = &vat_main;
3851   u32 i, n;
3852   int retval = clib_net_to_host_u32 (mp->retval);
3853
3854   if (retval)
3855     goto end;
3856
3857   n = clib_net_to_host_u32 (mp->count);
3858
3859   for (i = 0; i < n; i++)
3860     {
3861       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3862     }
3863
3864 end:
3865   vam->retval = retval;
3866   vam->result_ready = 1;
3867 }
3868
3869 static void
3870   vl_api_one_ndp_bd_get_reply_t_handler_json
3871   (vl_api_one_ndp_bd_get_reply_t * mp)
3872 {
3873   vat_main_t *vam = &vat_main;
3874   vat_json_node_t root;
3875   u32 i, n;
3876   int retval = clib_net_to_host_u32 (mp->retval);
3877
3878   if (retval)
3879     goto end;
3880
3881   n = clib_net_to_host_u32 (mp->count);
3882   vat_json_init_array (&root);
3883
3884   for (i = 0; i < n; i++)
3885     {
3886       vat_json_array_add_uint (&root,
3887                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3888     }
3889
3890   vat_json_print (vam->ofp, &root);
3891   vat_json_free (&root);
3892
3893 end:
3894   vam->retval = retval;
3895   vam->result_ready = 1;
3896 }
3897
3898 static void
3899   vl_api_one_l2_arp_bd_get_reply_t_handler
3900   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3901 {
3902   vat_main_t *vam = &vat_main;
3903   u32 i, n;
3904   int retval = clib_net_to_host_u32 (mp->retval);
3905
3906   if (retval)
3907     goto end;
3908
3909   n = clib_net_to_host_u32 (mp->count);
3910
3911   for (i = 0; i < n; i++)
3912     {
3913       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3914     }
3915
3916 end:
3917   vam->retval = retval;
3918   vam->result_ready = 1;
3919 }
3920
3921 static void
3922   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3923   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3924 {
3925   vat_main_t *vam = &vat_main;
3926   vat_json_node_t root;
3927   u32 i, n;
3928   int retval = clib_net_to_host_u32 (mp->retval);
3929
3930   if (retval)
3931     goto end;
3932
3933   n = clib_net_to_host_u32 (mp->count);
3934   vat_json_init_array (&root);
3935
3936   for (i = 0; i < n; i++)
3937     {
3938       vat_json_array_add_uint (&root,
3939                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3940     }
3941
3942   vat_json_print (vam->ofp, &root);
3943   vat_json_free (&root);
3944
3945 end:
3946   vam->retval = retval;
3947   vam->result_ready = 1;
3948 }
3949
3950 static void
3951   vl_api_one_adjacencies_get_reply_t_handler
3952   (vl_api_one_adjacencies_get_reply_t * mp)
3953 {
3954   vat_main_t *vam = &vat_main;
3955   u32 i, n;
3956   int retval = clib_net_to_host_u32 (mp->retval);
3957   vl_api_one_adjacency_t *a;
3958
3959   if (retval)
3960     goto end;
3961
3962   n = clib_net_to_host_u32 (mp->count);
3963
3964   for (i = 0; i < n; i++)
3965     {
3966       a = &mp->adjacencies[i];
3967       print (vam->ofp, "%U %40U",
3968              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3969              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3970     }
3971
3972 end:
3973   vam->retval = retval;
3974   vam->result_ready = 1;
3975 }
3976
3977 static void
3978   vl_api_one_adjacencies_get_reply_t_handler_json
3979   (vl_api_one_adjacencies_get_reply_t * mp)
3980 {
3981   u8 *s = 0;
3982   vat_main_t *vam = &vat_main;
3983   vat_json_node_t *e = 0, root;
3984   u32 i, n;
3985   int retval = clib_net_to_host_u32 (mp->retval);
3986   vl_api_one_adjacency_t *a;
3987
3988   if (retval)
3989     goto end;
3990
3991   n = clib_net_to_host_u32 (mp->count);
3992   vat_json_init_array (&root);
3993
3994   for (i = 0; i < n; i++)
3995     {
3996       e = vat_json_array_add (&root);
3997       a = &mp->adjacencies[i];
3998
3999       vat_json_init_object (e);
4000       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4001                   a->leid_prefix_len);
4002       vec_add1 (s, 0);
4003       vat_json_object_add_string_copy (e, "leid", s);
4004       vec_free (s);
4005
4006       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4007                   a->reid_prefix_len);
4008       vec_add1 (s, 0);
4009       vat_json_object_add_string_copy (e, "reid", s);
4010       vec_free (s);
4011     }
4012
4013   vat_json_print (vam->ofp, &root);
4014   vat_json_free (&root);
4015
4016 end:
4017   vam->retval = retval;
4018   vam->result_ready = 1;
4019 }
4020
4021 static void
4022 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4023 {
4024   vat_main_t *vam = &vat_main;
4025
4026   print (vam->ofp, "%=20U",
4027          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4028          mp->ip_address);
4029 }
4030
4031 static void
4032   vl_api_one_map_server_details_t_handler_json
4033   (vl_api_one_map_server_details_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   vat_json_node_t *node = NULL;
4037   struct in6_addr ip6;
4038   struct in_addr ip4;
4039
4040   if (VAT_JSON_ARRAY != vam->json_tree.type)
4041     {
4042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4043       vat_json_init_array (&vam->json_tree);
4044     }
4045   node = vat_json_array_add (&vam->json_tree);
4046
4047   vat_json_init_object (node);
4048   if (mp->is_ipv6)
4049     {
4050       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4051       vat_json_object_add_ip6 (node, "map-server", ip6);
4052     }
4053   else
4054     {
4055       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4056       vat_json_object_add_ip4 (node, "map-server", ip4);
4057     }
4058 }
4059
4060 static void
4061 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4062                                            * mp)
4063 {
4064   vat_main_t *vam = &vat_main;
4065
4066   print (vam->ofp, "%=20U",
4067          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4068          mp->ip_address);
4069 }
4070
4071 static void
4072   vl_api_one_map_resolver_details_t_handler_json
4073   (vl_api_one_map_resolver_details_t * mp)
4074 {
4075   vat_main_t *vam = &vat_main;
4076   vat_json_node_t *node = NULL;
4077   struct in6_addr ip6;
4078   struct in_addr ip4;
4079
4080   if (VAT_JSON_ARRAY != vam->json_tree.type)
4081     {
4082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4083       vat_json_init_array (&vam->json_tree);
4084     }
4085   node = vat_json_array_add (&vam->json_tree);
4086
4087   vat_json_init_object (node);
4088   if (mp->is_ipv6)
4089     {
4090       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4091       vat_json_object_add_ip6 (node, "map resolver", ip6);
4092     }
4093   else
4094     {
4095       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4096       vat_json_object_add_ip4 (node, "map resolver", ip4);
4097     }
4098 }
4099
4100 static void
4101 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4102 {
4103   vat_main_t *vam = &vat_main;
4104   i32 retval = ntohl (mp->retval);
4105
4106   if (0 <= retval)
4107     {
4108       print (vam->ofp, "feature: %s\ngpe: %s",
4109              mp->feature_status ? "enabled" : "disabled",
4110              mp->gpe_status ? "enabled" : "disabled");
4111     }
4112
4113   vam->retval = retval;
4114   vam->result_ready = 1;
4115 }
4116
4117 static void
4118   vl_api_show_one_status_reply_t_handler_json
4119   (vl_api_show_one_status_reply_t * mp)
4120 {
4121   vat_main_t *vam = &vat_main;
4122   vat_json_node_t node;
4123   u8 *gpe_status = NULL;
4124   u8 *feature_status = NULL;
4125
4126   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4127   feature_status = format (0, "%s",
4128                            mp->feature_status ? "enabled" : "disabled");
4129   vec_add1 (gpe_status, 0);
4130   vec_add1 (feature_status, 0);
4131
4132   vat_json_init_object (&node);
4133   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4134   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4135
4136   vec_free (gpe_status);
4137   vec_free (feature_status);
4138
4139   vat_json_print (vam->ofp, &node);
4140   vat_json_free (&node);
4141
4142   vam->retval = ntohl (mp->retval);
4143   vam->result_ready = 1;
4144 }
4145
4146 static void
4147   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4148   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4149 {
4150   vat_main_t *vam = &vat_main;
4151   i32 retval = ntohl (mp->retval);
4152
4153   if (retval >= 0)
4154     {
4155       print (vam->ofp, "%=20s", mp->locator_set_name);
4156     }
4157
4158   vam->retval = retval;
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4164   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4165 {
4166   vat_main_t *vam = &vat_main;
4167   vat_json_node_t *node = NULL;
4168
4169   if (VAT_JSON_ARRAY != vam->json_tree.type)
4170     {
4171       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4172       vat_json_init_array (&vam->json_tree);
4173     }
4174   node = vat_json_array_add (&vam->json_tree);
4175
4176   vat_json_init_object (node);
4177   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4178
4179   vat_json_print (vam->ofp, node);
4180   vat_json_free (node);
4181
4182   vam->retval = ntohl (mp->retval);
4183   vam->result_ready = 1;
4184 }
4185
4186 static u8 *
4187 format_lisp_map_request_mode (u8 * s, va_list * args)
4188 {
4189   u32 mode = va_arg (*args, u32);
4190
4191   switch (mode)
4192     {
4193     case 0:
4194       return format (0, "dst-only");
4195     case 1:
4196       return format (0, "src-dst");
4197     }
4198   return 0;
4199 }
4200
4201 static void
4202   vl_api_show_one_map_request_mode_reply_t_handler
4203   (vl_api_show_one_map_request_mode_reply_t * mp)
4204 {
4205   vat_main_t *vam = &vat_main;
4206   i32 retval = ntohl (mp->retval);
4207
4208   if (0 <= retval)
4209     {
4210       u32 mode = mp->mode;
4211       print (vam->ofp, "map_request_mode: %U",
4212              format_lisp_map_request_mode, mode);
4213     }
4214
4215   vam->retval = retval;
4216   vam->result_ready = 1;
4217 }
4218
4219 static void
4220   vl_api_show_one_map_request_mode_reply_t_handler_json
4221   (vl_api_show_one_map_request_mode_reply_t * mp)
4222 {
4223   vat_main_t *vam = &vat_main;
4224   vat_json_node_t node;
4225   u8 *s = 0;
4226   u32 mode;
4227
4228   mode = mp->mode;
4229   s = format (0, "%U", format_lisp_map_request_mode, mode);
4230   vec_add1 (s, 0);
4231
4232   vat_json_init_object (&node);
4233   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4234   vat_json_print (vam->ofp, &node);
4235   vat_json_free (&node);
4236
4237   vec_free (s);
4238   vam->retval = ntohl (mp->retval);
4239   vam->result_ready = 1;
4240 }
4241
4242 static void
4243   vl_api_one_show_xtr_mode_reply_t_handler
4244   (vl_api_one_show_xtr_mode_reply_t * mp)
4245 {
4246   vat_main_t *vam = &vat_main;
4247   i32 retval = ntohl (mp->retval);
4248
4249   if (0 <= retval)
4250     {
4251       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4252     }
4253
4254   vam->retval = retval;
4255   vam->result_ready = 1;
4256 }
4257
4258 static void
4259   vl_api_one_show_xtr_mode_reply_t_handler_json
4260   (vl_api_one_show_xtr_mode_reply_t * mp)
4261 {
4262   vat_main_t *vam = &vat_main;
4263   vat_json_node_t node;
4264   u8 *status = 0;
4265
4266   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4267   vec_add1 (status, 0);
4268
4269   vat_json_init_object (&node);
4270   vat_json_object_add_string_copy (&node, "status", status);
4271
4272   vec_free (status);
4273
4274   vat_json_print (vam->ofp, &node);
4275   vat_json_free (&node);
4276
4277   vam->retval = ntohl (mp->retval);
4278   vam->result_ready = 1;
4279 }
4280
4281 static void
4282   vl_api_one_show_pitr_mode_reply_t_handler
4283   (vl_api_one_show_pitr_mode_reply_t * mp)
4284 {
4285   vat_main_t *vam = &vat_main;
4286   i32 retval = ntohl (mp->retval);
4287
4288   if (0 <= retval)
4289     {
4290       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4291     }
4292
4293   vam->retval = retval;
4294   vam->result_ready = 1;
4295 }
4296
4297 static void
4298   vl_api_one_show_pitr_mode_reply_t_handler_json
4299   (vl_api_one_show_pitr_mode_reply_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   vat_json_node_t node;
4303   u8 *status = 0;
4304
4305   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4306   vec_add1 (status, 0);
4307
4308   vat_json_init_object (&node);
4309   vat_json_object_add_string_copy (&node, "status", status);
4310
4311   vec_free (status);
4312
4313   vat_json_print (vam->ofp, &node);
4314   vat_json_free (&node);
4315
4316   vam->retval = ntohl (mp->retval);
4317   vam->result_ready = 1;
4318 }
4319
4320 static void
4321   vl_api_one_show_petr_mode_reply_t_handler
4322   (vl_api_one_show_petr_mode_reply_t * mp)
4323 {
4324   vat_main_t *vam = &vat_main;
4325   i32 retval = ntohl (mp->retval);
4326
4327   if (0 <= retval)
4328     {
4329       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4330     }
4331
4332   vam->retval = retval;
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_one_show_petr_mode_reply_t_handler_json
4338   (vl_api_one_show_petr_mode_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   vat_json_node_t node;
4342   u8 *status = 0;
4343
4344   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4345   vec_add1 (status, 0);
4346
4347   vat_json_init_object (&node);
4348   vat_json_object_add_string_copy (&node, "status", status);
4349
4350   vec_free (status);
4351
4352   vat_json_print (vam->ofp, &node);
4353   vat_json_free (&node);
4354
4355   vam->retval = ntohl (mp->retval);
4356   vam->result_ready = 1;
4357 }
4358
4359 static void
4360   vl_api_show_one_use_petr_reply_t_handler
4361   (vl_api_show_one_use_petr_reply_t * mp)
4362 {
4363   vat_main_t *vam = &vat_main;
4364   i32 retval = ntohl (mp->retval);
4365
4366   if (0 <= retval)
4367     {
4368       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4369       if (mp->status)
4370         {
4371           print (vam->ofp, "Proxy-ETR address; %U",
4372                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4373                  mp->address);
4374         }
4375     }
4376
4377   vam->retval = retval;
4378   vam->result_ready = 1;
4379 }
4380
4381 static void
4382   vl_api_show_one_use_petr_reply_t_handler_json
4383   (vl_api_show_one_use_petr_reply_t * mp)
4384 {
4385   vat_main_t *vam = &vat_main;
4386   vat_json_node_t node;
4387   u8 *status = 0;
4388   struct in_addr ip4;
4389   struct in6_addr ip6;
4390
4391   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4392   vec_add1 (status, 0);
4393
4394   vat_json_init_object (&node);
4395   vat_json_object_add_string_copy (&node, "status", status);
4396   if (mp->status)
4397     {
4398       if (mp->is_ip4)
4399         {
4400           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4401           vat_json_object_add_ip6 (&node, "address", ip6);
4402         }
4403       else
4404         {
4405           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4406           vat_json_object_add_ip4 (&node, "address", ip4);
4407         }
4408     }
4409
4410   vec_free (status);
4411
4412   vat_json_print (vam->ofp, &node);
4413   vat_json_free (&node);
4414
4415   vam->retval = ntohl (mp->retval);
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_show_one_nsh_mapping_reply_t_handler
4421   (vl_api_show_one_nsh_mapping_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   i32 retval = ntohl (mp->retval);
4425
4426   if (0 <= retval)
4427     {
4428       print (vam->ofp, "%-20s%-16s",
4429              mp->is_set ? "set" : "not-set",
4430              mp->is_set ? (char *) mp->locator_set_name : "");
4431     }
4432
4433   vam->retval = retval;
4434   vam->result_ready = 1;
4435 }
4436
4437 static void
4438   vl_api_show_one_nsh_mapping_reply_t_handler_json
4439   (vl_api_show_one_nsh_mapping_reply_t * mp)
4440 {
4441   vat_main_t *vam = &vat_main;
4442   vat_json_node_t node;
4443   u8 *status = 0;
4444
4445   status = format (0, "%s", mp->is_set ? "yes" : "no");
4446   vec_add1 (status, 0);
4447
4448   vat_json_init_object (&node);
4449   vat_json_object_add_string_copy (&node, "is_set", status);
4450   if (mp->is_set)
4451     {
4452       vat_json_object_add_string_copy (&node, "locator_set",
4453                                        mp->locator_set_name);
4454     }
4455
4456   vec_free (status);
4457
4458   vat_json_print (vam->ofp, &node);
4459   vat_json_free (&node);
4460
4461   vam->retval = ntohl (mp->retval);
4462   vam->result_ready = 1;
4463 }
4464
4465 static void
4466   vl_api_show_one_map_register_ttl_reply_t_handler
4467   (vl_api_show_one_map_register_ttl_reply_t * mp)
4468 {
4469   vat_main_t *vam = &vat_main;
4470   i32 retval = ntohl (mp->retval);
4471
4472   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4473
4474   if (0 <= retval)
4475     {
4476       print (vam->ofp, "ttl: %u", mp->ttl);
4477     }
4478
4479   vam->retval = retval;
4480   vam->result_ready = 1;
4481 }
4482
4483 static void
4484   vl_api_show_one_map_register_ttl_reply_t_handler_json
4485   (vl_api_show_one_map_register_ttl_reply_t * mp)
4486 {
4487   vat_main_t *vam = &vat_main;
4488   vat_json_node_t node;
4489
4490   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4491   vat_json_init_object (&node);
4492   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4493
4494   vat_json_print (vam->ofp, &node);
4495   vat_json_free (&node);
4496
4497   vam->retval = ntohl (mp->retval);
4498   vam->result_ready = 1;
4499 }
4500
4501 static void
4502 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4503 {
4504   vat_main_t *vam = &vat_main;
4505   i32 retval = ntohl (mp->retval);
4506
4507   if (0 <= retval)
4508     {
4509       print (vam->ofp, "%-20s%-16s",
4510              mp->status ? "enabled" : "disabled",
4511              mp->status ? (char *) mp->locator_set_name : "");
4512     }
4513
4514   vam->retval = retval;
4515   vam->result_ready = 1;
4516 }
4517
4518 static void
4519 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4520 {
4521   vat_main_t *vam = &vat_main;
4522   vat_json_node_t node;
4523   u8 *status = 0;
4524
4525   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4526   vec_add1 (status, 0);
4527
4528   vat_json_init_object (&node);
4529   vat_json_object_add_string_copy (&node, "status", status);
4530   if (mp->status)
4531     {
4532       vat_json_object_add_string_copy (&node, "locator_set",
4533                                        mp->locator_set_name);
4534     }
4535
4536   vec_free (status);
4537
4538   vat_json_print (vam->ofp, &node);
4539   vat_json_free (&node);
4540
4541   vam->retval = ntohl (mp->retval);
4542   vam->result_ready = 1;
4543 }
4544
4545 static u8 *
4546 format_policer_type (u8 * s, va_list * va)
4547 {
4548   u32 i = va_arg (*va, u32);
4549
4550   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4551     s = format (s, "1r2c");
4552   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4553     s = format (s, "1r3c");
4554   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4555     s = format (s, "2r3c-2698");
4556   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4557     s = format (s, "2r3c-4115");
4558   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4559     s = format (s, "2r3c-mef5cf1");
4560   else
4561     s = format (s, "ILLEGAL");
4562   return s;
4563 }
4564
4565 static u8 *
4566 format_policer_rate_type (u8 * s, va_list * va)
4567 {
4568   u32 i = va_arg (*va, u32);
4569
4570   if (i == SSE2_QOS_RATE_KBPS)
4571     s = format (s, "kbps");
4572   else if (i == SSE2_QOS_RATE_PPS)
4573     s = format (s, "pps");
4574   else
4575     s = format (s, "ILLEGAL");
4576   return s;
4577 }
4578
4579 static u8 *
4580 format_policer_round_type (u8 * s, va_list * va)
4581 {
4582   u32 i = va_arg (*va, u32);
4583
4584   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4585     s = format (s, "closest");
4586   else if (i == SSE2_QOS_ROUND_TO_UP)
4587     s = format (s, "up");
4588   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4589     s = format (s, "down");
4590   else
4591     s = format (s, "ILLEGAL");
4592   return s;
4593 }
4594
4595 static u8 *
4596 format_policer_action_type (u8 * s, va_list * va)
4597 {
4598   u32 i = va_arg (*va, u32);
4599
4600   if (i == SSE2_QOS_ACTION_DROP)
4601     s = format (s, "drop");
4602   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4603     s = format (s, "transmit");
4604   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4605     s = format (s, "mark-and-transmit");
4606   else
4607     s = format (s, "ILLEGAL");
4608   return s;
4609 }
4610
4611 static u8 *
4612 format_dscp (u8 * s, va_list * va)
4613 {
4614   u32 i = va_arg (*va, u32);
4615   char *t = 0;
4616
4617   switch (i)
4618     {
4619 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4620       foreach_vnet_dscp
4621 #undef _
4622     default:
4623       return format (s, "ILLEGAL");
4624     }
4625   s = format (s, "%s", t);
4626   return s;
4627 }
4628
4629 static void
4630 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4631 {
4632   vat_main_t *vam = &vat_main;
4633   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4634
4635   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4636     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4637   else
4638     conform_dscp_str = format (0, "");
4639
4640   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4641     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4642   else
4643     exceed_dscp_str = format (0, "");
4644
4645   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4646     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4647   else
4648     violate_dscp_str = format (0, "");
4649
4650   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4651          "rate type %U, round type %U, %s rate, %s color-aware, "
4652          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4653          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4654          "conform action %U%s, exceed action %U%s, violate action %U%s",
4655          mp->name,
4656          format_policer_type, mp->type,
4657          ntohl (mp->cir),
4658          ntohl (mp->eir),
4659          clib_net_to_host_u64 (mp->cb),
4660          clib_net_to_host_u64 (mp->eb),
4661          format_policer_rate_type, mp->rate_type,
4662          format_policer_round_type, mp->round_type,
4663          mp->single_rate ? "single" : "dual",
4664          mp->color_aware ? "is" : "not",
4665          ntohl (mp->cir_tokens_per_period),
4666          ntohl (mp->pir_tokens_per_period),
4667          ntohl (mp->scale),
4668          ntohl (mp->current_limit),
4669          ntohl (mp->current_bucket),
4670          ntohl (mp->extended_limit),
4671          ntohl (mp->extended_bucket),
4672          clib_net_to_host_u64 (mp->last_update_time),
4673          format_policer_action_type, mp->conform_action_type,
4674          conform_dscp_str,
4675          format_policer_action_type, mp->exceed_action_type,
4676          exceed_dscp_str,
4677          format_policer_action_type, mp->violate_action_type,
4678          violate_dscp_str);
4679
4680   vec_free (conform_dscp_str);
4681   vec_free (exceed_dscp_str);
4682   vec_free (violate_dscp_str);
4683 }
4684
4685 static void vl_api_policer_details_t_handler_json
4686   (vl_api_policer_details_t * mp)
4687 {
4688   vat_main_t *vam = &vat_main;
4689   vat_json_node_t *node;
4690   u8 *rate_type_str, *round_type_str, *type_str;
4691   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4692
4693   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4694   round_type_str =
4695     format (0, "%U", format_policer_round_type, mp->round_type);
4696   type_str = format (0, "%U", format_policer_type, mp->type);
4697   conform_action_str = format (0, "%U", format_policer_action_type,
4698                                mp->conform_action_type);
4699   exceed_action_str = format (0, "%U", format_policer_action_type,
4700                               mp->exceed_action_type);
4701   violate_action_str = format (0, "%U", format_policer_action_type,
4702                                mp->violate_action_type);
4703
4704   if (VAT_JSON_ARRAY != vam->json_tree.type)
4705     {
4706       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4707       vat_json_init_array (&vam->json_tree);
4708     }
4709   node = vat_json_array_add (&vam->json_tree);
4710
4711   vat_json_init_object (node);
4712   vat_json_object_add_string_copy (node, "name", mp->name);
4713   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4714   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4715   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4716   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4717   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4718   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4719   vat_json_object_add_string_copy (node, "type", type_str);
4720   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4721   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4722   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4723   vat_json_object_add_uint (node, "cir_tokens_per_period",
4724                             ntohl (mp->cir_tokens_per_period));
4725   vat_json_object_add_uint (node, "eir_tokens_per_period",
4726                             ntohl (mp->pir_tokens_per_period));
4727   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4728   vat_json_object_add_uint (node, "current_bucket",
4729                             ntohl (mp->current_bucket));
4730   vat_json_object_add_uint (node, "extended_limit",
4731                             ntohl (mp->extended_limit));
4732   vat_json_object_add_uint (node, "extended_bucket",
4733                             ntohl (mp->extended_bucket));
4734   vat_json_object_add_uint (node, "last_update_time",
4735                             ntohl (mp->last_update_time));
4736   vat_json_object_add_string_copy (node, "conform_action",
4737                                    conform_action_str);
4738   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4739     {
4740       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4741       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4742       vec_free (dscp_str);
4743     }
4744   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4745   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4746     {
4747       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4748       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4749       vec_free (dscp_str);
4750     }
4751   vat_json_object_add_string_copy (node, "violate_action",
4752                                    violate_action_str);
4753   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4754     {
4755       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4756       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4757       vec_free (dscp_str);
4758     }
4759
4760   vec_free (rate_type_str);
4761   vec_free (round_type_str);
4762   vec_free (type_str);
4763   vec_free (conform_action_str);
4764   vec_free (exceed_action_str);
4765   vec_free (violate_action_str);
4766 }
4767
4768 static void
4769 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4770                                            mp)
4771 {
4772   vat_main_t *vam = &vat_main;
4773   int i, count = ntohl (mp->count);
4774
4775   if (count > 0)
4776     print (vam->ofp, "classify table ids (%d) : ", count);
4777   for (i = 0; i < count; i++)
4778     {
4779       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4780       print (vam->ofp, (i < count - 1) ? "," : "");
4781     }
4782   vam->retval = ntohl (mp->retval);
4783   vam->result_ready = 1;
4784 }
4785
4786 static void
4787   vl_api_classify_table_ids_reply_t_handler_json
4788   (vl_api_classify_table_ids_reply_t * mp)
4789 {
4790   vat_main_t *vam = &vat_main;
4791   int i, count = ntohl (mp->count);
4792
4793   if (count > 0)
4794     {
4795       vat_json_node_t node;
4796
4797       vat_json_init_object (&node);
4798       for (i = 0; i < count; i++)
4799         {
4800           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4801         }
4802       vat_json_print (vam->ofp, &node);
4803       vat_json_free (&node);
4804     }
4805   vam->retval = ntohl (mp->retval);
4806   vam->result_ready = 1;
4807 }
4808
4809 static void
4810   vl_api_classify_table_by_interface_reply_t_handler
4811   (vl_api_classify_table_by_interface_reply_t * mp)
4812 {
4813   vat_main_t *vam = &vat_main;
4814   u32 table_id;
4815
4816   table_id = ntohl (mp->l2_table_id);
4817   if (table_id != ~0)
4818     print (vam->ofp, "l2 table id : %d", table_id);
4819   else
4820     print (vam->ofp, "l2 table id : No input ACL tables configured");
4821   table_id = ntohl (mp->ip4_table_id);
4822   if (table_id != ~0)
4823     print (vam->ofp, "ip4 table id : %d", table_id);
4824   else
4825     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4826   table_id = ntohl (mp->ip6_table_id);
4827   if (table_id != ~0)
4828     print (vam->ofp, "ip6 table id : %d", table_id);
4829   else
4830     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4831   vam->retval = ntohl (mp->retval);
4832   vam->result_ready = 1;
4833 }
4834
4835 static void
4836   vl_api_classify_table_by_interface_reply_t_handler_json
4837   (vl_api_classify_table_by_interface_reply_t * mp)
4838 {
4839   vat_main_t *vam = &vat_main;
4840   vat_json_node_t node;
4841
4842   vat_json_init_object (&node);
4843
4844   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4845   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4846   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4847
4848   vat_json_print (vam->ofp, &node);
4849   vat_json_free (&node);
4850
4851   vam->retval = ntohl (mp->retval);
4852   vam->result_ready = 1;
4853 }
4854
4855 static void vl_api_policer_add_del_reply_t_handler
4856   (vl_api_policer_add_del_reply_t * mp)
4857 {
4858   vat_main_t *vam = &vat_main;
4859   i32 retval = ntohl (mp->retval);
4860   if (vam->async_mode)
4861     {
4862       vam->async_errors += (retval < 0);
4863     }
4864   else
4865     {
4866       vam->retval = retval;
4867       vam->result_ready = 1;
4868       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4869         /*
4870          * Note: this is just barely thread-safe, depends on
4871          * the main thread spinning waiting for an answer...
4872          */
4873         errmsg ("policer index %d", ntohl (mp->policer_index));
4874     }
4875 }
4876
4877 static void vl_api_policer_add_del_reply_t_handler_json
4878   (vl_api_policer_add_del_reply_t * mp)
4879 {
4880   vat_main_t *vam = &vat_main;
4881   vat_json_node_t node;
4882
4883   vat_json_init_object (&node);
4884   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4885   vat_json_object_add_uint (&node, "policer_index",
4886                             ntohl (mp->policer_index));
4887
4888   vat_json_print (vam->ofp, &node);
4889   vat_json_free (&node);
4890
4891   vam->retval = ntohl (mp->retval);
4892   vam->result_ready = 1;
4893 }
4894
4895 /* Format hex dump. */
4896 u8 *
4897 format_hex_bytes (u8 * s, va_list * va)
4898 {
4899   u8 *bytes = va_arg (*va, u8 *);
4900   int n_bytes = va_arg (*va, int);
4901   uword i;
4902
4903   /* Print short or long form depending on byte count. */
4904   uword short_form = n_bytes <= 32;
4905   u32 indent = format_get_indent (s);
4906
4907   if (n_bytes == 0)
4908     return s;
4909
4910   for (i = 0; i < n_bytes; i++)
4911     {
4912       if (!short_form && (i % 32) == 0)
4913         s = format (s, "%08x: ", i);
4914       s = format (s, "%02x", bytes[i]);
4915       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4916         s = format (s, "\n%U", format_white_space, indent);
4917     }
4918
4919   return s;
4920 }
4921
4922 static void
4923 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4924                                             * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927   i32 retval = ntohl (mp->retval);
4928   if (retval == 0)
4929     {
4930       print (vam->ofp, "classify table info :");
4931       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4932              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4933              ntohl (mp->miss_next_index));
4934       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4935              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4936              ntohl (mp->match_n_vectors));
4937       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4938              ntohl (mp->mask_length));
4939     }
4940   vam->retval = retval;
4941   vam->result_ready = 1;
4942 }
4943
4944 static void
4945   vl_api_classify_table_info_reply_t_handler_json
4946   (vl_api_classify_table_info_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   i32 retval = ntohl (mp->retval);
4952   if (retval == 0)
4953     {
4954       vat_json_init_object (&node);
4955
4956       vat_json_object_add_int (&node, "sessions",
4957                                ntohl (mp->active_sessions));
4958       vat_json_object_add_int (&node, "nexttbl",
4959                                ntohl (mp->next_table_index));
4960       vat_json_object_add_int (&node, "nextnode",
4961                                ntohl (mp->miss_next_index));
4962       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4963       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4964       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4965       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4966                       ntohl (mp->mask_length), 0);
4967       vat_json_object_add_string_copy (&node, "mask", s);
4968
4969       vat_json_print (vam->ofp, &node);
4970       vat_json_free (&node);
4971     }
4972   vam->retval = ntohl (mp->retval);
4973   vam->result_ready = 1;
4974 }
4975
4976 static void
4977 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4978                                            mp)
4979 {
4980   vat_main_t *vam = &vat_main;
4981
4982   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4983          ntohl (mp->hit_next_index), ntohl (mp->advance),
4984          ntohl (mp->opaque_index));
4985   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4986          ntohl (mp->match_length));
4987 }
4988
4989 static void
4990   vl_api_classify_session_details_t_handler_json
4991   (vl_api_classify_session_details_t * mp)
4992 {
4993   vat_main_t *vam = &vat_main;
4994   vat_json_node_t *node = NULL;
4995
4996   if (VAT_JSON_ARRAY != vam->json_tree.type)
4997     {
4998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4999       vat_json_init_array (&vam->json_tree);
5000     }
5001   node = vat_json_array_add (&vam->json_tree);
5002
5003   vat_json_init_object (node);
5004   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5005   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5006   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5007   u8 *s =
5008     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5009             0);
5010   vat_json_object_add_string_copy (node, "match", s);
5011 }
5012
5013 static void vl_api_pg_create_interface_reply_t_handler
5014   (vl_api_pg_create_interface_reply_t * mp)
5015 {
5016   vat_main_t *vam = &vat_main;
5017
5018   vam->retval = ntohl (mp->retval);
5019   vam->result_ready = 1;
5020 }
5021
5022 static void vl_api_pg_create_interface_reply_t_handler_json
5023   (vl_api_pg_create_interface_reply_t * mp)
5024 {
5025   vat_main_t *vam = &vat_main;
5026   vat_json_node_t node;
5027
5028   i32 retval = ntohl (mp->retval);
5029   if (retval == 0)
5030     {
5031       vat_json_init_object (&node);
5032
5033       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5034
5035       vat_json_print (vam->ofp, &node);
5036       vat_json_free (&node);
5037     }
5038   vam->retval = ntohl (mp->retval);
5039   vam->result_ready = 1;
5040 }
5041
5042 static void vl_api_policer_classify_details_t_handler
5043   (vl_api_policer_classify_details_t * mp)
5044 {
5045   vat_main_t *vam = &vat_main;
5046
5047   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5048          ntohl (mp->table_index));
5049 }
5050
5051 static void vl_api_policer_classify_details_t_handler_json
5052   (vl_api_policer_classify_details_t * mp)
5053 {
5054   vat_main_t *vam = &vat_main;
5055   vat_json_node_t *node;
5056
5057   if (VAT_JSON_ARRAY != vam->json_tree.type)
5058     {
5059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5060       vat_json_init_array (&vam->json_tree);
5061     }
5062   node = vat_json_array_add (&vam->json_tree);
5063
5064   vat_json_init_object (node);
5065   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5066   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5067 }
5068
5069 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5070   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5071 {
5072   vat_main_t *vam = &vat_main;
5073   i32 retval = ntohl (mp->retval);
5074   if (vam->async_mode)
5075     {
5076       vam->async_errors += (retval < 0);
5077     }
5078   else
5079     {
5080       vam->retval = retval;
5081       vam->sw_if_index = ntohl (mp->sw_if_index);
5082       vam->result_ready = 1;
5083     }
5084 }
5085
5086 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5087   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5088 {
5089   vat_main_t *vam = &vat_main;
5090   vat_json_node_t node;
5091
5092   vat_json_init_object (&node);
5093   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5094   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5095
5096   vat_json_print (vam->ofp, &node);
5097   vat_json_free (&node);
5098
5099   vam->retval = ntohl (mp->retval);
5100   vam->result_ready = 1;
5101 }
5102
5103 static void vl_api_flow_classify_details_t_handler
5104   (vl_api_flow_classify_details_t * mp)
5105 {
5106   vat_main_t *vam = &vat_main;
5107
5108   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5109          ntohl (mp->table_index));
5110 }
5111
5112 static void vl_api_flow_classify_details_t_handler_json
5113   (vl_api_flow_classify_details_t * mp)
5114 {
5115   vat_main_t *vam = &vat_main;
5116   vat_json_node_t *node;
5117
5118   if (VAT_JSON_ARRAY != vam->json_tree.type)
5119     {
5120       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5121       vat_json_init_array (&vam->json_tree);
5122     }
5123   node = vat_json_array_add (&vam->json_tree);
5124
5125   vat_json_init_object (node);
5126   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5127   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5128 }
5129
5130 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5131 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5132 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5133 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5134 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5135 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5136 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5137 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5138 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5139 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5140 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5141 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5142 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5143 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5144 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5145 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5146 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5147 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5148 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5149 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5150 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5151 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5152
5153 /*
5154  * Generate boilerplate reply handlers, which
5155  * dig the return value out of the xxx_reply_t API message,
5156  * stick it into vam->retval, and set vam->result_ready
5157  *
5158  * Could also do this by pointing N message decode slots at
5159  * a single function, but that could break in subtle ways.
5160  */
5161
5162 #define foreach_standard_reply_retval_handler           \
5163 _(sw_interface_set_flags_reply)                         \
5164 _(sw_interface_add_del_address_reply)                   \
5165 _(sw_interface_set_rx_mode_reply)                       \
5166 _(sw_interface_set_table_reply)                         \
5167 _(sw_interface_set_mpls_enable_reply)                   \
5168 _(sw_interface_set_vpath_reply)                         \
5169 _(sw_interface_set_vxlan_bypass_reply)                  \
5170 _(sw_interface_set_geneve_bypass_reply)                 \
5171 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5172 _(sw_interface_set_l2_bridge_reply)                     \
5173 _(bridge_domain_add_del_reply)                          \
5174 _(sw_interface_set_l2_xconnect_reply)                   \
5175 _(l2fib_add_del_reply)                                  \
5176 _(l2fib_flush_int_reply)                                \
5177 _(l2fib_flush_bd_reply)                                 \
5178 _(ip_add_del_route_reply)                               \
5179 _(ip_table_add_del_reply)                               \
5180 _(ip_mroute_add_del_reply)                              \
5181 _(mpls_route_add_del_reply)                             \
5182 _(mpls_table_add_del_reply)                             \
5183 _(mpls_ip_bind_unbind_reply)                            \
5184 _(bier_route_add_del_reply)                             \
5185 _(bier_table_add_del_reply)                             \
5186 _(proxy_arp_add_del_reply)                              \
5187 _(proxy_arp_intfc_enable_disable_reply)                 \
5188 _(sw_interface_set_unnumbered_reply)                    \
5189 _(ip_neighbor_add_del_reply)                            \
5190 _(oam_add_del_reply)                                    \
5191 _(reset_fib_reply)                                      \
5192 _(dhcp_proxy_config_reply)                              \
5193 _(dhcp_proxy_set_vss_reply)                             \
5194 _(dhcp_client_config_reply)                             \
5195 _(set_ip_flow_hash_reply)                               \
5196 _(sw_interface_ip6_enable_disable_reply)                \
5197 _(sw_interface_ip6_set_link_local_address_reply)        \
5198 _(ip6nd_proxy_add_del_reply)                            \
5199 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5200 _(sw_interface_ip6nd_ra_config_reply)                   \
5201 _(set_arp_neighbor_limit_reply)                         \
5202 _(l2_patch_add_del_reply)                               \
5203 _(sr_policy_add_reply)                                  \
5204 _(sr_policy_mod_reply)                                  \
5205 _(sr_policy_del_reply)                                  \
5206 _(sr_localsid_add_del_reply)                            \
5207 _(sr_steering_add_del_reply)                            \
5208 _(classify_add_del_session_reply)                       \
5209 _(classify_set_interface_ip_table_reply)                \
5210 _(classify_set_interface_l2_tables_reply)               \
5211 _(l2tpv3_set_tunnel_cookies_reply)                      \
5212 _(l2tpv3_interface_enable_disable_reply)                \
5213 _(l2tpv3_set_lookup_key_reply)                          \
5214 _(l2_fib_clear_table_reply)                             \
5215 _(l2_interface_efp_filter_reply)                        \
5216 _(l2_interface_vlan_tag_rewrite_reply)                  \
5217 _(modify_vhost_user_if_reply)                           \
5218 _(delete_vhost_user_if_reply)                           \
5219 _(want_ip4_arp_events_reply)                            \
5220 _(want_ip6_nd_events_reply)                             \
5221 _(want_l2_macs_events_reply)                            \
5222 _(input_acl_set_interface_reply)                        \
5223 _(ipsec_spd_add_del_reply)                              \
5224 _(ipsec_interface_add_del_spd_reply)                    \
5225 _(ipsec_spd_add_del_entry_reply)                        \
5226 _(ipsec_sad_add_del_entry_reply)                        \
5227 _(ipsec_sa_set_key_reply)                               \
5228 _(ipsec_tunnel_if_add_del_reply)                        \
5229 _(ipsec_tunnel_if_set_key_reply)                        \
5230 _(ipsec_tunnel_if_set_sa_reply)                         \
5231 _(ikev2_profile_add_del_reply)                          \
5232 _(ikev2_profile_set_auth_reply)                         \
5233 _(ikev2_profile_set_id_reply)                           \
5234 _(ikev2_profile_set_ts_reply)                           \
5235 _(ikev2_set_local_key_reply)                            \
5236 _(ikev2_set_responder_reply)                            \
5237 _(ikev2_set_ike_transforms_reply)                       \
5238 _(ikev2_set_esp_transforms_reply)                       \
5239 _(ikev2_set_sa_lifetime_reply)                          \
5240 _(ikev2_initiate_sa_init_reply)                         \
5241 _(ikev2_initiate_del_ike_sa_reply)                      \
5242 _(ikev2_initiate_del_child_sa_reply)                    \
5243 _(ikev2_initiate_rekey_child_sa_reply)                  \
5244 _(delete_loopback_reply)                                \
5245 _(bd_ip_mac_add_del_reply)                              \
5246 _(map_del_domain_reply)                                 \
5247 _(map_add_del_rule_reply)                               \
5248 _(want_interface_events_reply)                          \
5249 _(want_stats_reply)                                     \
5250 _(cop_interface_enable_disable_reply)                   \
5251 _(cop_whitelist_enable_disable_reply)                   \
5252 _(sw_interface_clear_stats_reply)                       \
5253 _(ioam_enable_reply)                                    \
5254 _(ioam_disable_reply)                                   \
5255 _(one_add_del_locator_reply)                            \
5256 _(one_add_del_local_eid_reply)                          \
5257 _(one_add_del_remote_mapping_reply)                     \
5258 _(one_add_del_adjacency_reply)                          \
5259 _(one_add_del_map_resolver_reply)                       \
5260 _(one_add_del_map_server_reply)                         \
5261 _(one_enable_disable_reply)                             \
5262 _(one_rloc_probe_enable_disable_reply)                  \
5263 _(one_map_register_enable_disable_reply)                \
5264 _(one_map_register_set_ttl_reply)                       \
5265 _(one_set_transport_protocol_reply)                     \
5266 _(one_map_register_fallback_threshold_reply)            \
5267 _(one_pitr_set_locator_set_reply)                       \
5268 _(one_map_request_mode_reply)                           \
5269 _(one_add_del_map_request_itr_rlocs_reply)              \
5270 _(one_eid_table_add_del_map_reply)                      \
5271 _(one_use_petr_reply)                                   \
5272 _(one_stats_enable_disable_reply)                       \
5273 _(one_add_del_l2_arp_entry_reply)                       \
5274 _(one_add_del_ndp_entry_reply)                          \
5275 _(one_stats_flush_reply)                                \
5276 _(one_enable_disable_xtr_mode_reply)                    \
5277 _(one_enable_disable_pitr_mode_reply)                   \
5278 _(one_enable_disable_petr_mode_reply)                   \
5279 _(gpe_enable_disable_reply)                             \
5280 _(gpe_set_encap_mode_reply)                             \
5281 _(gpe_add_del_iface_reply)                              \
5282 _(gpe_add_del_native_fwd_rpath_reply)                   \
5283 _(af_packet_delete_reply)                               \
5284 _(policer_classify_set_interface_reply)                 \
5285 _(netmap_create_reply)                                  \
5286 _(netmap_delete_reply)                                  \
5287 _(set_ipfix_exporter_reply)                             \
5288 _(set_ipfix_classify_stream_reply)                      \
5289 _(ipfix_classify_table_add_del_reply)                   \
5290 _(flow_classify_set_interface_reply)                    \
5291 _(sw_interface_span_enable_disable_reply)               \
5292 _(pg_capture_reply)                                     \
5293 _(pg_enable_disable_reply)                              \
5294 _(ip_source_and_port_range_check_add_del_reply)         \
5295 _(ip_source_and_port_range_check_interface_add_del_reply)\
5296 _(delete_subif_reply)                                   \
5297 _(l2_interface_pbb_tag_rewrite_reply)                   \
5298 _(punt_reply)                                           \
5299 _(feature_enable_disable_reply)                         \
5300 _(sw_interface_tag_add_del_reply)                       \
5301 _(sw_interface_set_mtu_reply)                           \
5302 _(p2p_ethernet_add_reply)                               \
5303 _(p2p_ethernet_del_reply)                               \
5304 _(lldp_config_reply)                                    \
5305 _(sw_interface_set_lldp_reply)                          \
5306 _(tcp_configure_src_addresses_reply)                    \
5307 _(dns_enable_disable_reply)                             \
5308 _(dns_name_server_add_del_reply)                        \
5309 _(session_rule_add_del_reply)                           \
5310 _(ip_container_proxy_add_del_reply)
5311
5312 #define _(n)                                    \
5313     static void vl_api_##n##_t_handler          \
5314     (vl_api_##n##_t * mp)                       \
5315     {                                           \
5316         vat_main_t * vam = &vat_main;           \
5317         i32 retval = ntohl(mp->retval);         \
5318         if (vam->async_mode) {                  \
5319             vam->async_errors += (retval < 0);  \
5320         } else {                                \
5321             vam->retval = retval;               \
5322             vam->result_ready = 1;              \
5323         }                                       \
5324     }
5325 foreach_standard_reply_retval_handler;
5326 #undef _
5327
5328 #define _(n)                                    \
5329     static void vl_api_##n##_t_handler_json     \
5330     (vl_api_##n##_t * mp)                       \
5331     {                                           \
5332         vat_main_t * vam = &vat_main;           \
5333         vat_json_node_t node;                   \
5334         vat_json_init_object(&node);            \
5335         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5336         vat_json_print(vam->ofp, &node);        \
5337         vam->retval = ntohl(mp->retval);        \
5338         vam->result_ready = 1;                  \
5339     }
5340 foreach_standard_reply_retval_handler;
5341 #undef _
5342
5343 /*
5344  * Table of message reply handlers, must include boilerplate handlers
5345  * we just generated
5346  */
5347
5348 #define foreach_vpe_api_reply_msg                                       \
5349 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5350 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5351 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5352 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5353 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5354 _(CLI_REPLY, cli_reply)                                                 \
5355 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5356 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5357   sw_interface_add_del_address_reply)                                   \
5358 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5359 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5360 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5361 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5362 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5363 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5364 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5365 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5366   sw_interface_set_l2_xconnect_reply)                                   \
5367 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5368   sw_interface_set_l2_bridge_reply)                                     \
5369 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5370 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5371 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5372 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5373 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5374 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5375 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5376 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5377 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5378 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5379 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5380 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5381 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5382 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5383 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5384 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5385 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5386 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5387 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5388 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5389 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5390 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5391   proxy_arp_intfc_enable_disable_reply)                                 \
5392 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5393 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5394   sw_interface_set_unnumbered_reply)                                    \
5395 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5396 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5397 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5398 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5399 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5400 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5401 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5402 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5403 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5404 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5405 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5406   sw_interface_ip6_enable_disable_reply)                                \
5407 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5408   sw_interface_ip6_set_link_local_address_reply)                        \
5409 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5410 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5411 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5412   sw_interface_ip6nd_ra_prefix_reply)                                   \
5413 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5414   sw_interface_ip6nd_ra_config_reply)                                   \
5415 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5416 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5417 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5418 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5419 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5420 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5421 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5422 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5423 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5424 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5425 classify_set_interface_ip_table_reply)                                  \
5426 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5427   classify_set_interface_l2_tables_reply)                               \
5428 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5429 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5430 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5431 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5432 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5433   l2tpv3_interface_enable_disable_reply)                                \
5434 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5435 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5436 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5437 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5438 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5439 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5440 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5441 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5442 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5443 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5444 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5445 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5446 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5447 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5448 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5449 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5450 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5451 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5452 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5453 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5454 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5455 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5456 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5457 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5458 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5459 _(L2_MACS_EVENT, l2_macs_event)                                         \
5460 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5461 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5462 _(IP_DETAILS, ip_details)                                               \
5463 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5464 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5465 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5466 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5467 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5468 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5469 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5470 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5471 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5472 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5473 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5474 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5475 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5476 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5477 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5478 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5479 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5480 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5481 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5482 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5483 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5484 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5485 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5486 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5487 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5488 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5489 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5490 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5491 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5492 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5493 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5494 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5495 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5496 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5497 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5498 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5499 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5500 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5501 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5502 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5503 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5504 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5505 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5506 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5507 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5508 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5509 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5510 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5511   one_map_register_enable_disable_reply)                                \
5512 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5513 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5514 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5515 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5516   one_map_register_fallback_threshold_reply)                            \
5517 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5518   one_rloc_probe_enable_disable_reply)                                  \
5519 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5520 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5521 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5522 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5523 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5524 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5525 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5526 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5527 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5528 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5529 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5530 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5531 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5532 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5533 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5534 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5535   show_one_stats_enable_disable_reply)                                  \
5536 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5537 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5538 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5539 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5540 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5541 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5542 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5543 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5544   one_enable_disable_pitr_mode_reply)                                   \
5545 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5546   one_enable_disable_petr_mode_reply)                                   \
5547 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5548 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5549 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5550 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5551 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5552 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5553 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5554 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5555 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5556 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5557 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5558 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5559   gpe_add_del_native_fwd_rpath_reply)                                   \
5560 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5561   gpe_fwd_entry_path_details)                                           \
5562 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5563 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5564   one_add_del_map_request_itr_rlocs_reply)                              \
5565 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5566   one_get_map_request_itr_rlocs_reply)                                  \
5567 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5568 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5569 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5570 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5571 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5572 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5573   show_one_map_register_state_reply)                                    \
5574 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5575 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5576   show_one_map_register_fallback_threshold_reply)                       \
5577 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5578 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5579 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5580 _(POLICER_DETAILS, policer_details)                                     \
5581 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5582 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5583 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5584 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5585 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5586 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5587 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5588 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5589 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5590 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5591 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5592 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5593 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5594 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5595 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5596 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5597 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5598 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5599 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5600 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5601 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5602 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5603 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5604 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5605 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5606  ip_source_and_port_range_check_add_del_reply)                          \
5607 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5608  ip_source_and_port_range_check_interface_add_del_reply)                \
5609 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5610 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5611 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5612 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5613 _(PUNT_REPLY, punt_reply)                                               \
5614 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5615 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5616 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5617 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5618 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5619 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5620 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5621 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5622 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5623 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5624 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5625 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5626 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5627 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5628 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5629 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5630 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5631 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5632 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5633 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5634 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5635
5636 #define foreach_standalone_reply_msg                                    \
5637 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5638 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5639 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5640 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5641 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5642 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5643 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5644 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5645
5646 typedef struct
5647 {
5648   u8 *name;
5649   u32 value;
5650 } name_sort_t;
5651
5652
5653 #define STR_VTR_OP_CASE(op)     \
5654     case L2_VTR_ ## op:         \
5655         return "" # op;
5656
5657 static const char *
5658 str_vtr_op (u32 vtr_op)
5659 {
5660   switch (vtr_op)
5661     {
5662       STR_VTR_OP_CASE (DISABLED);
5663       STR_VTR_OP_CASE (PUSH_1);
5664       STR_VTR_OP_CASE (PUSH_2);
5665       STR_VTR_OP_CASE (POP_1);
5666       STR_VTR_OP_CASE (POP_2);
5667       STR_VTR_OP_CASE (TRANSLATE_1_1);
5668       STR_VTR_OP_CASE (TRANSLATE_1_2);
5669       STR_VTR_OP_CASE (TRANSLATE_2_1);
5670       STR_VTR_OP_CASE (TRANSLATE_2_2);
5671     }
5672
5673   return "UNKNOWN";
5674 }
5675
5676 static int
5677 dump_sub_interface_table (vat_main_t * vam)
5678 {
5679   const sw_interface_subif_t *sub = NULL;
5680
5681   if (vam->json_output)
5682     {
5683       clib_warning
5684         ("JSON output supported only for VPE API calls and dump_stats_table");
5685       return -99;
5686     }
5687
5688   print (vam->ofp,
5689          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5690          "Interface", "sw_if_index",
5691          "sub id", "dot1ad", "tags", "outer id",
5692          "inner id", "exact", "default", "outer any", "inner any");
5693
5694   vec_foreach (sub, vam->sw_if_subif_table)
5695   {
5696     print (vam->ofp,
5697            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5698            sub->interface_name,
5699            sub->sw_if_index,
5700            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5701            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5702            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5703            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5704     if (sub->vtr_op != L2_VTR_DISABLED)
5705       {
5706         print (vam->ofp,
5707                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5708                "tag1: %d tag2: %d ]",
5709                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5710                sub->vtr_tag1, sub->vtr_tag2);
5711       }
5712   }
5713
5714   return 0;
5715 }
5716
5717 static int
5718 name_sort_cmp (void *a1, void *a2)
5719 {
5720   name_sort_t *n1 = a1;
5721   name_sort_t *n2 = a2;
5722
5723   return strcmp ((char *) n1->name, (char *) n2->name);
5724 }
5725
5726 static int
5727 dump_interface_table (vat_main_t * vam)
5728 {
5729   hash_pair_t *p;
5730   name_sort_t *nses = 0, *ns;
5731
5732   if (vam->json_output)
5733     {
5734       clib_warning
5735         ("JSON output supported only for VPE API calls and dump_stats_table");
5736       return -99;
5737     }
5738
5739   /* *INDENT-OFF* */
5740   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5741   ({
5742     vec_add2 (nses, ns, 1);
5743     ns->name = (u8 *)(p->key);
5744     ns->value = (u32) p->value[0];
5745   }));
5746   /* *INDENT-ON* */
5747
5748   vec_sort_with_function (nses, name_sort_cmp);
5749
5750   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5751   vec_foreach (ns, nses)
5752   {
5753     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5754   }
5755   vec_free (nses);
5756   return 0;
5757 }
5758
5759 static int
5760 dump_ip_table (vat_main_t * vam, int is_ipv6)
5761 {
5762   const ip_details_t *det = NULL;
5763   const ip_address_details_t *address = NULL;
5764   u32 i = ~0;
5765
5766   print (vam->ofp, "%-12s", "sw_if_index");
5767
5768   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5769   {
5770     i++;
5771     if (!det->present)
5772       {
5773         continue;
5774       }
5775     print (vam->ofp, "%-12d", i);
5776     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5777     if (!det->addr)
5778       {
5779         continue;
5780       }
5781     vec_foreach (address, det->addr)
5782     {
5783       print (vam->ofp,
5784              "            %-30U%-13d",
5785              is_ipv6 ? format_ip6_address : format_ip4_address,
5786              address->ip, address->prefix_length);
5787     }
5788   }
5789
5790   return 0;
5791 }
5792
5793 static int
5794 dump_ipv4_table (vat_main_t * vam)
5795 {
5796   if (vam->json_output)
5797     {
5798       clib_warning
5799         ("JSON output supported only for VPE API calls and dump_stats_table");
5800       return -99;
5801     }
5802
5803   return dump_ip_table (vam, 0);
5804 }
5805
5806 static int
5807 dump_ipv6_table (vat_main_t * vam)
5808 {
5809   if (vam->json_output)
5810     {
5811       clib_warning
5812         ("JSON output supported only for VPE API calls and dump_stats_table");
5813       return -99;
5814     }
5815
5816   return dump_ip_table (vam, 1);
5817 }
5818
5819 static char *
5820 counter_type_to_str (u8 counter_type, u8 is_combined)
5821 {
5822   if (!is_combined)
5823     {
5824       switch (counter_type)
5825         {
5826         case VNET_INTERFACE_COUNTER_DROP:
5827           return "drop";
5828         case VNET_INTERFACE_COUNTER_PUNT:
5829           return "punt";
5830         case VNET_INTERFACE_COUNTER_IP4:
5831           return "ip4";
5832         case VNET_INTERFACE_COUNTER_IP6:
5833           return "ip6";
5834         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5835           return "rx-no-buf";
5836         case VNET_INTERFACE_COUNTER_RX_MISS:
5837           return "rx-miss";
5838         case VNET_INTERFACE_COUNTER_RX_ERROR:
5839           return "rx-error";
5840         case VNET_INTERFACE_COUNTER_TX_ERROR:
5841           return "tx-error";
5842         default:
5843           return "INVALID-COUNTER-TYPE";
5844         }
5845     }
5846   else
5847     {
5848       switch (counter_type)
5849         {
5850         case VNET_INTERFACE_COUNTER_RX:
5851           return "rx";
5852         case VNET_INTERFACE_COUNTER_TX:
5853           return "tx";
5854         default:
5855           return "INVALID-COUNTER-TYPE";
5856         }
5857     }
5858 }
5859
5860 static int
5861 dump_stats_table (vat_main_t * vam)
5862 {
5863   vat_json_node_t node;
5864   vat_json_node_t *msg_array;
5865   vat_json_node_t *msg;
5866   vat_json_node_t *counter_array;
5867   vat_json_node_t *counter;
5868   interface_counter_t c;
5869   u64 packets;
5870   ip4_fib_counter_t *c4;
5871   ip6_fib_counter_t *c6;
5872   ip4_nbr_counter_t *n4;
5873   ip6_nbr_counter_t *n6;
5874   int i, j;
5875
5876   if (!vam->json_output)
5877     {
5878       clib_warning ("dump_stats_table supported only in JSON format");
5879       return -99;
5880     }
5881
5882   vat_json_init_object (&node);
5883
5884   /* interface counters */
5885   msg_array = vat_json_object_add (&node, "interface_counters");
5886   vat_json_init_array (msg_array);
5887   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5888     {
5889       msg = vat_json_array_add (msg_array);
5890       vat_json_init_object (msg);
5891       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5892                                        (u8 *) counter_type_to_str (i, 0));
5893       vat_json_object_add_int (msg, "is_combined", 0);
5894       counter_array = vat_json_object_add (msg, "data");
5895       vat_json_init_array (counter_array);
5896       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5897         {
5898           packets = vam->simple_interface_counters[i][j];
5899           vat_json_array_add_uint (counter_array, packets);
5900         }
5901     }
5902   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5903     {
5904       msg = vat_json_array_add (msg_array);
5905       vat_json_init_object (msg);
5906       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5907                                        (u8 *) counter_type_to_str (i, 1));
5908       vat_json_object_add_int (msg, "is_combined", 1);
5909       counter_array = vat_json_object_add (msg, "data");
5910       vat_json_init_array (counter_array);
5911       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5912         {
5913           c = vam->combined_interface_counters[i][j];
5914           counter = vat_json_array_add (counter_array);
5915           vat_json_init_object (counter);
5916           vat_json_object_add_uint (counter, "packets", c.packets);
5917           vat_json_object_add_uint (counter, "bytes", c.bytes);
5918         }
5919     }
5920
5921   /* ip4 fib counters */
5922   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5923   vat_json_init_array (msg_array);
5924   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5925     {
5926       msg = vat_json_array_add (msg_array);
5927       vat_json_init_object (msg);
5928       vat_json_object_add_uint (msg, "vrf_id",
5929                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5930       counter_array = vat_json_object_add (msg, "c");
5931       vat_json_init_array (counter_array);
5932       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5933         {
5934           counter = vat_json_array_add (counter_array);
5935           vat_json_init_object (counter);
5936           c4 = &vam->ip4_fib_counters[i][j];
5937           vat_json_object_add_ip4 (counter, "address", c4->address);
5938           vat_json_object_add_uint (counter, "address_length",
5939                                     c4->address_length);
5940           vat_json_object_add_uint (counter, "packets", c4->packets);
5941           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5942         }
5943     }
5944
5945   /* ip6 fib counters */
5946   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5947   vat_json_init_array (msg_array);
5948   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5949     {
5950       msg = vat_json_array_add (msg_array);
5951       vat_json_init_object (msg);
5952       vat_json_object_add_uint (msg, "vrf_id",
5953                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5954       counter_array = vat_json_object_add (msg, "c");
5955       vat_json_init_array (counter_array);
5956       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5957         {
5958           counter = vat_json_array_add (counter_array);
5959           vat_json_init_object (counter);
5960           c6 = &vam->ip6_fib_counters[i][j];
5961           vat_json_object_add_ip6 (counter, "address", c6->address);
5962           vat_json_object_add_uint (counter, "address_length",
5963                                     c6->address_length);
5964           vat_json_object_add_uint (counter, "packets", c6->packets);
5965           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5966         }
5967     }
5968
5969   /* ip4 nbr counters */
5970   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5971   vat_json_init_array (msg_array);
5972   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5973     {
5974       msg = vat_json_array_add (msg_array);
5975       vat_json_init_object (msg);
5976       vat_json_object_add_uint (msg, "sw_if_index", i);
5977       counter_array = vat_json_object_add (msg, "c");
5978       vat_json_init_array (counter_array);
5979       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5980         {
5981           counter = vat_json_array_add (counter_array);
5982           vat_json_init_object (counter);
5983           n4 = &vam->ip4_nbr_counters[i][j];
5984           vat_json_object_add_ip4 (counter, "address", n4->address);
5985           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5986           vat_json_object_add_uint (counter, "packets", n4->packets);
5987           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5988         }
5989     }
5990
5991   /* ip6 nbr counters */
5992   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5993   vat_json_init_array (msg_array);
5994   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5995     {
5996       msg = vat_json_array_add (msg_array);
5997       vat_json_init_object (msg);
5998       vat_json_object_add_uint (msg, "sw_if_index", i);
5999       counter_array = vat_json_object_add (msg, "c");
6000       vat_json_init_array (counter_array);
6001       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6002         {
6003           counter = vat_json_array_add (counter_array);
6004           vat_json_init_object (counter);
6005           n6 = &vam->ip6_nbr_counters[i][j];
6006           vat_json_object_add_ip6 (counter, "address", n6->address);
6007           vat_json_object_add_uint (counter, "packets", n6->packets);
6008           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6009         }
6010     }
6011
6012   vat_json_print (vam->ofp, &node);
6013   vat_json_free (&node);
6014
6015   return 0;
6016 }
6017
6018 /*
6019  * Pass CLI buffers directly in the CLI_INBAND API message,
6020  * instead of an additional shared memory area.
6021  */
6022 static int
6023 exec_inband (vat_main_t * vam)
6024 {
6025   vl_api_cli_inband_t *mp;
6026   unformat_input_t *i = vam->input;
6027   int ret;
6028
6029   if (vec_len (i->buffer) == 0)
6030     return -1;
6031
6032   if (vam->exec_mode == 0 && unformat (i, "mode"))
6033     {
6034       vam->exec_mode = 1;
6035       return 0;
6036     }
6037   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6038     {
6039       vam->exec_mode = 0;
6040       return 0;
6041     }
6042
6043   /*
6044    * In order for the CLI command to work, it
6045    * must be a vector ending in \n, not a C-string ending
6046    * in \n\0.
6047    */
6048   u32 len = vec_len (vam->input->buffer);
6049   M2 (CLI_INBAND, mp, len);
6050   clib_memcpy (mp->cmd, vam->input->buffer, len);
6051   mp->length = htonl (len);
6052
6053   S (mp);
6054   W (ret);
6055   /* json responses may or may not include a useful reply... */
6056   if (vec_len (vam->cmd_reply))
6057     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6058   return ret;
6059 }
6060
6061 int
6062 exec (vat_main_t * vam)
6063 {
6064   return exec_inband (vam);
6065 }
6066
6067 static int
6068 api_create_loopback (vat_main_t * vam)
6069 {
6070   unformat_input_t *i = vam->input;
6071   vl_api_create_loopback_t *mp;
6072   vl_api_create_loopback_instance_t *mp_lbi;
6073   u8 mac_address[6];
6074   u8 mac_set = 0;
6075   u8 is_specified = 0;
6076   u32 user_instance = 0;
6077   int ret;
6078
6079   memset (mac_address, 0, sizeof (mac_address));
6080
6081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6082     {
6083       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6084         mac_set = 1;
6085       if (unformat (i, "instance %d", &user_instance))
6086         is_specified = 1;
6087       else
6088         break;
6089     }
6090
6091   if (is_specified)
6092     {
6093       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6094       mp_lbi->is_specified = is_specified;
6095       if (is_specified)
6096         mp_lbi->user_instance = htonl (user_instance);
6097       if (mac_set)
6098         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6099       S (mp_lbi);
6100     }
6101   else
6102     {
6103       /* Construct the API message */
6104       M (CREATE_LOOPBACK, mp);
6105       if (mac_set)
6106         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6107       S (mp);
6108     }
6109
6110   W (ret);
6111   return ret;
6112 }
6113
6114 static int
6115 api_delete_loopback (vat_main_t * vam)
6116 {
6117   unformat_input_t *i = vam->input;
6118   vl_api_delete_loopback_t *mp;
6119   u32 sw_if_index = ~0;
6120   int ret;
6121
6122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6123     {
6124       if (unformat (i, "sw_if_index %d", &sw_if_index))
6125         ;
6126       else
6127         break;
6128     }
6129
6130   if (sw_if_index == ~0)
6131     {
6132       errmsg ("missing sw_if_index");
6133       return -99;
6134     }
6135
6136   /* Construct the API message */
6137   M (DELETE_LOOPBACK, mp);
6138   mp->sw_if_index = ntohl (sw_if_index);
6139
6140   S (mp);
6141   W (ret);
6142   return ret;
6143 }
6144
6145 static int
6146 api_want_stats (vat_main_t * vam)
6147 {
6148   unformat_input_t *i = vam->input;
6149   vl_api_want_stats_t *mp;
6150   int enable = -1;
6151   int ret;
6152
6153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6154     {
6155       if (unformat (i, "enable"))
6156         enable = 1;
6157       else if (unformat (i, "disable"))
6158         enable = 0;
6159       else
6160         break;
6161     }
6162
6163   if (enable == -1)
6164     {
6165       errmsg ("missing enable|disable");
6166       return -99;
6167     }
6168
6169   M (WANT_STATS, mp);
6170   mp->enable_disable = enable;
6171
6172   S (mp);
6173   W (ret);
6174   return ret;
6175 }
6176
6177 static int
6178 api_want_interface_events (vat_main_t * vam)
6179 {
6180   unformat_input_t *i = vam->input;
6181   vl_api_want_interface_events_t *mp;
6182   int enable = -1;
6183   int ret;
6184
6185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6186     {
6187       if (unformat (i, "enable"))
6188         enable = 1;
6189       else if (unformat (i, "disable"))
6190         enable = 0;
6191       else
6192         break;
6193     }
6194
6195   if (enable == -1)
6196     {
6197       errmsg ("missing enable|disable");
6198       return -99;
6199     }
6200
6201   M (WANT_INTERFACE_EVENTS, mp);
6202   mp->enable_disable = enable;
6203
6204   vam->interface_event_display = enable;
6205
6206   S (mp);
6207   W (ret);
6208   return ret;
6209 }
6210
6211
6212 /* Note: non-static, called once to set up the initial intfc table */
6213 int
6214 api_sw_interface_dump (vat_main_t * vam)
6215 {
6216   vl_api_sw_interface_dump_t *mp;
6217   vl_api_control_ping_t *mp_ping;
6218   hash_pair_t *p;
6219   name_sort_t *nses = 0, *ns;
6220   sw_interface_subif_t *sub = NULL;
6221   int ret;
6222
6223   /* Toss the old name table */
6224   /* *INDENT-OFF* */
6225   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6226   ({
6227     vec_add2 (nses, ns, 1);
6228     ns->name = (u8 *)(p->key);
6229     ns->value = (u32) p->value[0];
6230   }));
6231   /* *INDENT-ON* */
6232
6233   hash_free (vam->sw_if_index_by_interface_name);
6234
6235   vec_foreach (ns, nses) vec_free (ns->name);
6236
6237   vec_free (nses);
6238
6239   vec_foreach (sub, vam->sw_if_subif_table)
6240   {
6241     vec_free (sub->interface_name);
6242   }
6243   vec_free (vam->sw_if_subif_table);
6244
6245   /* recreate the interface name hash table */
6246   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6247
6248   /* Get list of ethernets */
6249   M (SW_INTERFACE_DUMP, mp);
6250   mp->name_filter_valid = 1;
6251   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6252   S (mp);
6253
6254   /* and local / loopback interfaces */
6255   M (SW_INTERFACE_DUMP, mp);
6256   mp->name_filter_valid = 1;
6257   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6258   S (mp);
6259
6260   /* and packet-generator interfaces */
6261   M (SW_INTERFACE_DUMP, mp);
6262   mp->name_filter_valid = 1;
6263   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6264   S (mp);
6265
6266   /* and vxlan-gpe tunnel interfaces */
6267   M (SW_INTERFACE_DUMP, mp);
6268   mp->name_filter_valid = 1;
6269   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6270            sizeof (mp->name_filter) - 1);
6271   S (mp);
6272
6273   /* and vxlan tunnel interfaces */
6274   M (SW_INTERFACE_DUMP, mp);
6275   mp->name_filter_valid = 1;
6276   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6277   S (mp);
6278
6279   /* and geneve tunnel interfaces */
6280   M (SW_INTERFACE_DUMP, mp);
6281   mp->name_filter_valid = 1;
6282   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6283   S (mp);
6284
6285   /* and host (af_packet) interfaces */
6286   M (SW_INTERFACE_DUMP, mp);
6287   mp->name_filter_valid = 1;
6288   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6289   S (mp);
6290
6291   /* and l2tpv3 tunnel interfaces */
6292   M (SW_INTERFACE_DUMP, mp);
6293   mp->name_filter_valid = 1;
6294   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6295            sizeof (mp->name_filter) - 1);
6296   S (mp);
6297
6298   /* and GRE tunnel interfaces */
6299   M (SW_INTERFACE_DUMP, mp);
6300   mp->name_filter_valid = 1;
6301   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6302   S (mp);
6303
6304   /* and LISP-GPE interfaces */
6305   M (SW_INTERFACE_DUMP, mp);
6306   mp->name_filter_valid = 1;
6307   strncpy ((char *) mp->name_filter, "lisp_gpe",
6308            sizeof (mp->name_filter) - 1);
6309   S (mp);
6310
6311   /* and IPSEC tunnel interfaces */
6312   M (SW_INTERFACE_DUMP, mp);
6313   mp->name_filter_valid = 1;
6314   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6315   S (mp);
6316
6317   /* Use a control ping for synchronization */
6318   MPING (CONTROL_PING, mp_ping);
6319   S (mp_ping);
6320
6321   W (ret);
6322   return ret;
6323 }
6324
6325 static int
6326 api_sw_interface_set_flags (vat_main_t * vam)
6327 {
6328   unformat_input_t *i = vam->input;
6329   vl_api_sw_interface_set_flags_t *mp;
6330   u32 sw_if_index;
6331   u8 sw_if_index_set = 0;
6332   u8 admin_up = 0;
6333   int ret;
6334
6335   /* Parse args required to build the message */
6336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6337     {
6338       if (unformat (i, "admin-up"))
6339         admin_up = 1;
6340       else if (unformat (i, "admin-down"))
6341         admin_up = 0;
6342       else
6343         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6344         sw_if_index_set = 1;
6345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6346         sw_if_index_set = 1;
6347       else
6348         break;
6349     }
6350
6351   if (sw_if_index_set == 0)
6352     {
6353       errmsg ("missing interface name or sw_if_index");
6354       return -99;
6355     }
6356
6357   /* Construct the API message */
6358   M (SW_INTERFACE_SET_FLAGS, mp);
6359   mp->sw_if_index = ntohl (sw_if_index);
6360   mp->admin_up_down = admin_up;
6361
6362   /* send it... */
6363   S (mp);
6364
6365   /* Wait for a reply, return the good/bad news... */
6366   W (ret);
6367   return ret;
6368 }
6369
6370 static int
6371 api_sw_interface_set_rx_mode (vat_main_t * vam)
6372 {
6373   unformat_input_t *i = vam->input;
6374   vl_api_sw_interface_set_rx_mode_t *mp;
6375   u32 sw_if_index;
6376   u8 sw_if_index_set = 0;
6377   int ret;
6378   u8 queue_id_valid = 0;
6379   u32 queue_id;
6380   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6381
6382   /* Parse args required to build the message */
6383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6384     {
6385       if (unformat (i, "queue %d", &queue_id))
6386         queue_id_valid = 1;
6387       else if (unformat (i, "polling"))
6388         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6389       else if (unformat (i, "interrupt"))
6390         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6391       else if (unformat (i, "adaptive"))
6392         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6393       else
6394         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6395         sw_if_index_set = 1;
6396       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6397         sw_if_index_set = 1;
6398       else
6399         break;
6400     }
6401
6402   if (sw_if_index_set == 0)
6403     {
6404       errmsg ("missing interface name or sw_if_index");
6405       return -99;
6406     }
6407   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6408     {
6409       errmsg ("missing rx-mode");
6410       return -99;
6411     }
6412
6413   /* Construct the API message */
6414   M (SW_INTERFACE_SET_RX_MODE, mp);
6415   mp->sw_if_index = ntohl (sw_if_index);
6416   mp->mode = mode;
6417   mp->queue_id_valid = queue_id_valid;
6418   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6419
6420   /* send it... */
6421   S (mp);
6422
6423   /* Wait for a reply, return the good/bad news... */
6424   W (ret);
6425   return ret;
6426 }
6427
6428 static int
6429 api_sw_interface_clear_stats (vat_main_t * vam)
6430 {
6431   unformat_input_t *i = vam->input;
6432   vl_api_sw_interface_clear_stats_t *mp;
6433   u32 sw_if_index;
6434   u8 sw_if_index_set = 0;
6435   int ret;
6436
6437   /* Parse args required to build the message */
6438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6439     {
6440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6441         sw_if_index_set = 1;
6442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6443         sw_if_index_set = 1;
6444       else
6445         break;
6446     }
6447
6448   /* Construct the API message */
6449   M (SW_INTERFACE_CLEAR_STATS, mp);
6450
6451   if (sw_if_index_set == 1)
6452     mp->sw_if_index = ntohl (sw_if_index);
6453   else
6454     mp->sw_if_index = ~0;
6455
6456   /* send it... */
6457   S (mp);
6458
6459   /* Wait for a reply, return the good/bad news... */
6460   W (ret);
6461   return ret;
6462 }
6463
6464 static int
6465 api_sw_interface_add_del_address (vat_main_t * vam)
6466 {
6467   unformat_input_t *i = vam->input;
6468   vl_api_sw_interface_add_del_address_t *mp;
6469   u32 sw_if_index;
6470   u8 sw_if_index_set = 0;
6471   u8 is_add = 1, del_all = 0;
6472   u32 address_length = 0;
6473   u8 v4_address_set = 0;
6474   u8 v6_address_set = 0;
6475   ip4_address_t v4address;
6476   ip6_address_t v6address;
6477   int ret;
6478
6479   /* Parse args required to build the message */
6480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6481     {
6482       if (unformat (i, "del-all"))
6483         del_all = 1;
6484       else if (unformat (i, "del"))
6485         is_add = 0;
6486       else
6487         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6488         sw_if_index_set = 1;
6489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6490         sw_if_index_set = 1;
6491       else if (unformat (i, "%U/%d",
6492                          unformat_ip4_address, &v4address, &address_length))
6493         v4_address_set = 1;
6494       else if (unformat (i, "%U/%d",
6495                          unformat_ip6_address, &v6address, &address_length))
6496         v6_address_set = 1;
6497       else
6498         break;
6499     }
6500
6501   if (sw_if_index_set == 0)
6502     {
6503       errmsg ("missing interface name or sw_if_index");
6504       return -99;
6505     }
6506   if (v4_address_set && v6_address_set)
6507     {
6508       errmsg ("both v4 and v6 addresses set");
6509       return -99;
6510     }
6511   if (!v4_address_set && !v6_address_set && !del_all)
6512     {
6513       errmsg ("no addresses set");
6514       return -99;
6515     }
6516
6517   /* Construct the API message */
6518   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6519
6520   mp->sw_if_index = ntohl (sw_if_index);
6521   mp->is_add = is_add;
6522   mp->del_all = del_all;
6523   if (v6_address_set)
6524     {
6525       mp->is_ipv6 = 1;
6526       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6527     }
6528   else
6529     {
6530       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6531     }
6532   mp->address_length = address_length;
6533
6534   /* send it... */
6535   S (mp);
6536
6537   /* Wait for a reply, return good/bad news  */
6538   W (ret);
6539   return ret;
6540 }
6541
6542 static int
6543 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6544 {
6545   unformat_input_t *i = vam->input;
6546   vl_api_sw_interface_set_mpls_enable_t *mp;
6547   u32 sw_if_index;
6548   u8 sw_if_index_set = 0;
6549   u8 enable = 1;
6550   int ret;
6551
6552   /* Parse args required to build the message */
6553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6554     {
6555       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6556         sw_if_index_set = 1;
6557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6558         sw_if_index_set = 1;
6559       else if (unformat (i, "disable"))
6560         enable = 0;
6561       else if (unformat (i, "dis"))
6562         enable = 0;
6563       else
6564         break;
6565     }
6566
6567   if (sw_if_index_set == 0)
6568     {
6569       errmsg ("missing interface name or sw_if_index");
6570       return -99;
6571     }
6572
6573   /* Construct the API message */
6574   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6575
6576   mp->sw_if_index = ntohl (sw_if_index);
6577   mp->enable = enable;
6578
6579   /* send it... */
6580   S (mp);
6581
6582   /* Wait for a reply... */
6583   W (ret);
6584   return ret;
6585 }
6586
6587 static int
6588 api_sw_interface_set_table (vat_main_t * vam)
6589 {
6590   unformat_input_t *i = vam->input;
6591   vl_api_sw_interface_set_table_t *mp;
6592   u32 sw_if_index, vrf_id = 0;
6593   u8 sw_if_index_set = 0;
6594   u8 is_ipv6 = 0;
6595   int ret;
6596
6597   /* Parse args required to build the message */
6598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6599     {
6600       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6601         sw_if_index_set = 1;
6602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6603         sw_if_index_set = 1;
6604       else if (unformat (i, "vrf %d", &vrf_id))
6605         ;
6606       else if (unformat (i, "ipv6"))
6607         is_ipv6 = 1;
6608       else
6609         break;
6610     }
6611
6612   if (sw_if_index_set == 0)
6613     {
6614       errmsg ("missing interface name or sw_if_index");
6615       return -99;
6616     }
6617
6618   /* Construct the API message */
6619   M (SW_INTERFACE_SET_TABLE, mp);
6620
6621   mp->sw_if_index = ntohl (sw_if_index);
6622   mp->is_ipv6 = is_ipv6;
6623   mp->vrf_id = ntohl (vrf_id);
6624
6625   /* send it... */
6626   S (mp);
6627
6628   /* Wait for a reply... */
6629   W (ret);
6630   return ret;
6631 }
6632
6633 static void vl_api_sw_interface_get_table_reply_t_handler
6634   (vl_api_sw_interface_get_table_reply_t * mp)
6635 {
6636   vat_main_t *vam = &vat_main;
6637
6638   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6639
6640   vam->retval = ntohl (mp->retval);
6641   vam->result_ready = 1;
6642
6643 }
6644
6645 static void vl_api_sw_interface_get_table_reply_t_handler_json
6646   (vl_api_sw_interface_get_table_reply_t * mp)
6647 {
6648   vat_main_t *vam = &vat_main;
6649   vat_json_node_t node;
6650
6651   vat_json_init_object (&node);
6652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6653   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6654
6655   vat_json_print (vam->ofp, &node);
6656   vat_json_free (&node);
6657
6658   vam->retval = ntohl (mp->retval);
6659   vam->result_ready = 1;
6660 }
6661
6662 static int
6663 api_sw_interface_get_table (vat_main_t * vam)
6664 {
6665   unformat_input_t *i = vam->input;
6666   vl_api_sw_interface_get_table_t *mp;
6667   u32 sw_if_index;
6668   u8 sw_if_index_set = 0;
6669   u8 is_ipv6 = 0;
6670   int ret;
6671
6672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6673     {
6674       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6675         sw_if_index_set = 1;
6676       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6677         sw_if_index_set = 1;
6678       else if (unformat (i, "ipv6"))
6679         is_ipv6 = 1;
6680       else
6681         break;
6682     }
6683
6684   if (sw_if_index_set == 0)
6685     {
6686       errmsg ("missing interface name or sw_if_index");
6687       return -99;
6688     }
6689
6690   M (SW_INTERFACE_GET_TABLE, mp);
6691   mp->sw_if_index = htonl (sw_if_index);
6692   mp->is_ipv6 = is_ipv6;
6693
6694   S (mp);
6695   W (ret);
6696   return ret;
6697 }
6698
6699 static int
6700 api_sw_interface_set_vpath (vat_main_t * vam)
6701 {
6702   unformat_input_t *i = vam->input;
6703   vl_api_sw_interface_set_vpath_t *mp;
6704   u32 sw_if_index = 0;
6705   u8 sw_if_index_set = 0;
6706   u8 is_enable = 0;
6707   int ret;
6708
6709   /* Parse args required to build the message */
6710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6711     {
6712       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6713         sw_if_index_set = 1;
6714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6715         sw_if_index_set = 1;
6716       else if (unformat (i, "enable"))
6717         is_enable = 1;
6718       else if (unformat (i, "disable"))
6719         is_enable = 0;
6720       else
6721         break;
6722     }
6723
6724   if (sw_if_index_set == 0)
6725     {
6726       errmsg ("missing interface name or sw_if_index");
6727       return -99;
6728     }
6729
6730   /* Construct the API message */
6731   M (SW_INTERFACE_SET_VPATH, mp);
6732
6733   mp->sw_if_index = ntohl (sw_if_index);
6734   mp->enable = is_enable;
6735
6736   /* send it... */
6737   S (mp);
6738
6739   /* Wait for a reply... */
6740   W (ret);
6741   return ret;
6742 }
6743
6744 static int
6745 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6749   u32 sw_if_index = 0;
6750   u8 sw_if_index_set = 0;
6751   u8 is_enable = 1;
6752   u8 is_ipv6 = 0;
6753   int ret;
6754
6755   /* Parse args required to build the message */
6756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6757     {
6758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6759         sw_if_index_set = 1;
6760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6761         sw_if_index_set = 1;
6762       else if (unformat (i, "enable"))
6763         is_enable = 1;
6764       else if (unformat (i, "disable"))
6765         is_enable = 0;
6766       else if (unformat (i, "ip4"))
6767         is_ipv6 = 0;
6768       else if (unformat (i, "ip6"))
6769         is_ipv6 = 1;
6770       else
6771         break;
6772     }
6773
6774   if (sw_if_index_set == 0)
6775     {
6776       errmsg ("missing interface name or sw_if_index");
6777       return -99;
6778     }
6779
6780   /* Construct the API message */
6781   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6782
6783   mp->sw_if_index = ntohl (sw_if_index);
6784   mp->enable = is_enable;
6785   mp->is_ipv6 = is_ipv6;
6786
6787   /* send it... */
6788   S (mp);
6789
6790   /* Wait for a reply... */
6791   W (ret);
6792   return ret;
6793 }
6794
6795 static int
6796 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6797 {
6798   unformat_input_t *i = vam->input;
6799   vl_api_sw_interface_set_geneve_bypass_t *mp;
6800   u32 sw_if_index = 0;
6801   u8 sw_if_index_set = 0;
6802   u8 is_enable = 1;
6803   u8 is_ipv6 = 0;
6804   int ret;
6805
6806   /* Parse args required to build the message */
6807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6808     {
6809       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6810         sw_if_index_set = 1;
6811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6812         sw_if_index_set = 1;
6813       else if (unformat (i, "enable"))
6814         is_enable = 1;
6815       else if (unformat (i, "disable"))
6816         is_enable = 0;
6817       else if (unformat (i, "ip4"))
6818         is_ipv6 = 0;
6819       else if (unformat (i, "ip6"))
6820         is_ipv6 = 1;
6821       else
6822         break;
6823     }
6824
6825   if (sw_if_index_set == 0)
6826     {
6827       errmsg ("missing interface name or sw_if_index");
6828       return -99;
6829     }
6830
6831   /* Construct the API message */
6832   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6833
6834   mp->sw_if_index = ntohl (sw_if_index);
6835   mp->enable = is_enable;
6836   mp->is_ipv6 = is_ipv6;
6837
6838   /* send it... */
6839   S (mp);
6840
6841   /* Wait for a reply... */
6842   W (ret);
6843   return ret;
6844 }
6845
6846 static int
6847 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6848 {
6849   unformat_input_t *i = vam->input;
6850   vl_api_sw_interface_set_l2_xconnect_t *mp;
6851   u32 rx_sw_if_index;
6852   u8 rx_sw_if_index_set = 0;
6853   u32 tx_sw_if_index;
6854   u8 tx_sw_if_index_set = 0;
6855   u8 enable = 1;
6856   int ret;
6857
6858   /* Parse args required to build the message */
6859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6860     {
6861       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6862         rx_sw_if_index_set = 1;
6863       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6864         tx_sw_if_index_set = 1;
6865       else if (unformat (i, "rx"))
6866         {
6867           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6868             {
6869               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6870                             &rx_sw_if_index))
6871                 rx_sw_if_index_set = 1;
6872             }
6873           else
6874             break;
6875         }
6876       else if (unformat (i, "tx"))
6877         {
6878           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879             {
6880               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6881                             &tx_sw_if_index))
6882                 tx_sw_if_index_set = 1;
6883             }
6884           else
6885             break;
6886         }
6887       else if (unformat (i, "enable"))
6888         enable = 1;
6889       else if (unformat (i, "disable"))
6890         enable = 0;
6891       else
6892         break;
6893     }
6894
6895   if (rx_sw_if_index_set == 0)
6896     {
6897       errmsg ("missing rx interface name or rx_sw_if_index");
6898       return -99;
6899     }
6900
6901   if (enable && (tx_sw_if_index_set == 0))
6902     {
6903       errmsg ("missing tx interface name or tx_sw_if_index");
6904       return -99;
6905     }
6906
6907   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6908
6909   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6910   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6911   mp->enable = enable;
6912
6913   S (mp);
6914   W (ret);
6915   return ret;
6916 }
6917
6918 static int
6919 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6920 {
6921   unformat_input_t *i = vam->input;
6922   vl_api_sw_interface_set_l2_bridge_t *mp;
6923   u32 rx_sw_if_index;
6924   u8 rx_sw_if_index_set = 0;
6925   u32 bd_id;
6926   u8 bd_id_set = 0;
6927   u8 bvi = 0;
6928   u32 shg = 0;
6929   u8 enable = 1;
6930   int ret;
6931
6932   /* Parse args required to build the message */
6933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6934     {
6935       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6936         rx_sw_if_index_set = 1;
6937       else if (unformat (i, "bd_id %d", &bd_id))
6938         bd_id_set = 1;
6939       else
6940         if (unformat
6941             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6942         rx_sw_if_index_set = 1;
6943       else if (unformat (i, "shg %d", &shg))
6944         ;
6945       else if (unformat (i, "bvi"))
6946         bvi = 1;
6947       else if (unformat (i, "enable"))
6948         enable = 1;
6949       else if (unformat (i, "disable"))
6950         enable = 0;
6951       else
6952         break;
6953     }
6954
6955   if (rx_sw_if_index_set == 0)
6956     {
6957       errmsg ("missing rx interface name or sw_if_index");
6958       return -99;
6959     }
6960
6961   if (enable && (bd_id_set == 0))
6962     {
6963       errmsg ("missing bridge domain");
6964       return -99;
6965     }
6966
6967   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6968
6969   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6970   mp->bd_id = ntohl (bd_id);
6971   mp->shg = (u8) shg;
6972   mp->bvi = bvi;
6973   mp->enable = enable;
6974
6975   S (mp);
6976   W (ret);
6977   return ret;
6978 }
6979
6980 static int
6981 api_bridge_domain_dump (vat_main_t * vam)
6982 {
6983   unformat_input_t *i = vam->input;
6984   vl_api_bridge_domain_dump_t *mp;
6985   vl_api_control_ping_t *mp_ping;
6986   u32 bd_id = ~0;
6987   int ret;
6988
6989   /* Parse args required to build the message */
6990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6991     {
6992       if (unformat (i, "bd_id %d", &bd_id))
6993         ;
6994       else
6995         break;
6996     }
6997
6998   M (BRIDGE_DOMAIN_DUMP, mp);
6999   mp->bd_id = ntohl (bd_id);
7000   S (mp);
7001
7002   /* Use a control ping for synchronization */
7003   MPING (CONTROL_PING, mp_ping);
7004   S (mp_ping);
7005
7006   W (ret);
7007   return ret;
7008 }
7009
7010 static int
7011 api_bridge_domain_add_del (vat_main_t * vam)
7012 {
7013   unformat_input_t *i = vam->input;
7014   vl_api_bridge_domain_add_del_t *mp;
7015   u32 bd_id = ~0;
7016   u8 is_add = 1;
7017   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7018   u8 *bd_tag = NULL;
7019   u32 mac_age = 0;
7020   int ret;
7021
7022   /* Parse args required to build the message */
7023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7024     {
7025       if (unformat (i, "bd_id %d", &bd_id))
7026         ;
7027       else if (unformat (i, "flood %d", &flood))
7028         ;
7029       else if (unformat (i, "uu-flood %d", &uu_flood))
7030         ;
7031       else if (unformat (i, "forward %d", &forward))
7032         ;
7033       else if (unformat (i, "learn %d", &learn))
7034         ;
7035       else if (unformat (i, "arp-term %d", &arp_term))
7036         ;
7037       else if (unformat (i, "mac-age %d", &mac_age))
7038         ;
7039       else if (unformat (i, "bd-tag %s", &bd_tag))
7040         ;
7041       else if (unformat (i, "del"))
7042         {
7043           is_add = 0;
7044           flood = uu_flood = forward = learn = 0;
7045         }
7046       else
7047         break;
7048     }
7049
7050   if (bd_id == ~0)
7051     {
7052       errmsg ("missing bridge domain");
7053       ret = -99;
7054       goto done;
7055     }
7056
7057   if (mac_age > 255)
7058     {
7059       errmsg ("mac age must be less than 256 ");
7060       ret = -99;
7061       goto done;
7062     }
7063
7064   if ((bd_tag) && (vec_len (bd_tag) > 63))
7065     {
7066       errmsg ("bd-tag cannot be longer than 63");
7067       ret = -99;
7068       goto done;
7069     }
7070
7071   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7072
7073   mp->bd_id = ntohl (bd_id);
7074   mp->flood = flood;
7075   mp->uu_flood = uu_flood;
7076   mp->forward = forward;
7077   mp->learn = learn;
7078   mp->arp_term = arp_term;
7079   mp->is_add = is_add;
7080   mp->mac_age = (u8) mac_age;
7081   if (bd_tag)
7082     {
7083       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7084       mp->bd_tag[vec_len (bd_tag)] = 0;
7085     }
7086   S (mp);
7087   W (ret);
7088
7089 done:
7090   vec_free (bd_tag);
7091   return ret;
7092 }
7093
7094 static int
7095 api_l2fib_flush_bd (vat_main_t * vam)
7096 {
7097   unformat_input_t *i = vam->input;
7098   vl_api_l2fib_flush_bd_t *mp;
7099   u32 bd_id = ~0;
7100   int ret;
7101
7102   /* Parse args required to build the message */
7103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7104     {
7105       if (unformat (i, "bd_id %d", &bd_id));
7106       else
7107         break;
7108     }
7109
7110   if (bd_id == ~0)
7111     {
7112       errmsg ("missing bridge domain");
7113       return -99;
7114     }
7115
7116   M (L2FIB_FLUSH_BD, mp);
7117
7118   mp->bd_id = htonl (bd_id);
7119
7120   S (mp);
7121   W (ret);
7122   return ret;
7123 }
7124
7125 static int
7126 api_l2fib_flush_int (vat_main_t * vam)
7127 {
7128   unformat_input_t *i = vam->input;
7129   vl_api_l2fib_flush_int_t *mp;
7130   u32 sw_if_index = ~0;
7131   int ret;
7132
7133   /* Parse args required to build the message */
7134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7135     {
7136       if (unformat (i, "sw_if_index %d", &sw_if_index));
7137       else
7138         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7139       else
7140         break;
7141     }
7142
7143   if (sw_if_index == ~0)
7144     {
7145       errmsg ("missing interface name or sw_if_index");
7146       return -99;
7147     }
7148
7149   M (L2FIB_FLUSH_INT, mp);
7150
7151   mp->sw_if_index = ntohl (sw_if_index);
7152
7153   S (mp);
7154   W (ret);
7155   return ret;
7156 }
7157
7158 static int
7159 api_l2fib_add_del (vat_main_t * vam)
7160 {
7161   unformat_input_t *i = vam->input;
7162   vl_api_l2fib_add_del_t *mp;
7163   f64 timeout;
7164   u8 mac[6] = { 0 };
7165   u8 mac_set = 0;
7166   u32 bd_id;
7167   u8 bd_id_set = 0;
7168   u32 sw_if_index = ~0;
7169   u8 sw_if_index_set = 0;
7170   u8 is_add = 1;
7171   u8 static_mac = 0;
7172   u8 filter_mac = 0;
7173   u8 bvi_mac = 0;
7174   int count = 1;
7175   f64 before = 0;
7176   int j;
7177
7178   /* Parse args required to build the message */
7179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7180     {
7181       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7182         mac_set = 1;
7183       else if (unformat (i, "bd_id %d", &bd_id))
7184         bd_id_set = 1;
7185       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7186         sw_if_index_set = 1;
7187       else if (unformat (i, "sw_if"))
7188         {
7189           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7190             {
7191               if (unformat
7192                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7193                 sw_if_index_set = 1;
7194             }
7195           else
7196             break;
7197         }
7198       else if (unformat (i, "static"))
7199         static_mac = 1;
7200       else if (unformat (i, "filter"))
7201         {
7202           filter_mac = 1;
7203           static_mac = 1;
7204         }
7205       else if (unformat (i, "bvi"))
7206         {
7207           bvi_mac = 1;
7208           static_mac = 1;
7209         }
7210       else if (unformat (i, "del"))
7211         is_add = 0;
7212       else if (unformat (i, "count %d", &count))
7213         ;
7214       else
7215         break;
7216     }
7217
7218   if (mac_set == 0)
7219     {
7220       errmsg ("missing mac address");
7221       return -99;
7222     }
7223
7224   if (bd_id_set == 0)
7225     {
7226       errmsg ("missing bridge domain");
7227       return -99;
7228     }
7229
7230   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7231     {
7232       errmsg ("missing interface name or sw_if_index");
7233       return -99;
7234     }
7235
7236   if (count > 1)
7237     {
7238       /* Turn on async mode */
7239       vam->async_mode = 1;
7240       vam->async_errors = 0;
7241       before = vat_time_now (vam);
7242     }
7243
7244   for (j = 0; j < count; j++)
7245     {
7246       M (L2FIB_ADD_DEL, mp);
7247
7248       clib_memcpy (mp->mac, mac, 6);
7249       mp->bd_id = ntohl (bd_id);
7250       mp->is_add = is_add;
7251
7252       if (is_add)
7253         {
7254           mp->sw_if_index = ntohl (sw_if_index);
7255           mp->static_mac = static_mac;
7256           mp->filter_mac = filter_mac;
7257           mp->bvi_mac = bvi_mac;
7258         }
7259       increment_mac_address (mac);
7260       /* send it... */
7261       S (mp);
7262     }
7263
7264   if (count > 1)
7265     {
7266       vl_api_control_ping_t *mp_ping;
7267       f64 after;
7268
7269       /* Shut off async mode */
7270       vam->async_mode = 0;
7271
7272       MPING (CONTROL_PING, mp_ping);
7273       S (mp_ping);
7274
7275       timeout = vat_time_now (vam) + 1.0;
7276       while (vat_time_now (vam) < timeout)
7277         if (vam->result_ready == 1)
7278           goto out;
7279       vam->retval = -99;
7280
7281     out:
7282       if (vam->retval == -99)
7283         errmsg ("timeout");
7284
7285       if (vam->async_errors > 0)
7286         {
7287           errmsg ("%d asynchronous errors", vam->async_errors);
7288           vam->retval = -98;
7289         }
7290       vam->async_errors = 0;
7291       after = vat_time_now (vam);
7292
7293       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7294              count, after - before, count / (after - before));
7295     }
7296   else
7297     {
7298       int ret;
7299
7300       /* Wait for a reply... */
7301       W (ret);
7302       return ret;
7303     }
7304   /* Return the good/bad news */
7305   return (vam->retval);
7306 }
7307
7308 static int
7309 api_bridge_domain_set_mac_age (vat_main_t * vam)
7310 {
7311   unformat_input_t *i = vam->input;
7312   vl_api_bridge_domain_set_mac_age_t *mp;
7313   u32 bd_id = ~0;
7314   u32 mac_age = 0;
7315   int ret;
7316
7317   /* Parse args required to build the message */
7318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7319     {
7320       if (unformat (i, "bd_id %d", &bd_id));
7321       else if (unformat (i, "mac-age %d", &mac_age));
7322       else
7323         break;
7324     }
7325
7326   if (bd_id == ~0)
7327     {
7328       errmsg ("missing bridge domain");
7329       return -99;
7330     }
7331
7332   if (mac_age > 255)
7333     {
7334       errmsg ("mac age must be less than 256 ");
7335       return -99;
7336     }
7337
7338   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7339
7340   mp->bd_id = htonl (bd_id);
7341   mp->mac_age = (u8) mac_age;
7342
7343   S (mp);
7344   W (ret);
7345   return ret;
7346 }
7347
7348 static int
7349 api_l2_flags (vat_main_t * vam)
7350 {
7351   unformat_input_t *i = vam->input;
7352   vl_api_l2_flags_t *mp;
7353   u32 sw_if_index;
7354   u32 flags = 0;
7355   u8 sw_if_index_set = 0;
7356   u8 is_set = 0;
7357   int ret;
7358
7359   /* Parse args required to build the message */
7360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7361     {
7362       if (unformat (i, "sw_if_index %d", &sw_if_index))
7363         sw_if_index_set = 1;
7364       else if (unformat (i, "sw_if"))
7365         {
7366           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7367             {
7368               if (unformat
7369                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7370                 sw_if_index_set = 1;
7371             }
7372           else
7373             break;
7374         }
7375       else if (unformat (i, "learn"))
7376         flags |= L2_LEARN;
7377       else if (unformat (i, "forward"))
7378         flags |= L2_FWD;
7379       else if (unformat (i, "flood"))
7380         flags |= L2_FLOOD;
7381       else if (unformat (i, "uu-flood"))
7382         flags |= L2_UU_FLOOD;
7383       else if (unformat (i, "arp-term"))
7384         flags |= L2_ARP_TERM;
7385       else if (unformat (i, "off"))
7386         is_set = 0;
7387       else if (unformat (i, "disable"))
7388         is_set = 0;
7389       else
7390         break;
7391     }
7392
7393   if (sw_if_index_set == 0)
7394     {
7395       errmsg ("missing interface name or sw_if_index");
7396       return -99;
7397     }
7398
7399   M (L2_FLAGS, mp);
7400
7401   mp->sw_if_index = ntohl (sw_if_index);
7402   mp->feature_bitmap = ntohl (flags);
7403   mp->is_set = is_set;
7404
7405   S (mp);
7406   W (ret);
7407   return ret;
7408 }
7409
7410 static int
7411 api_bridge_flags (vat_main_t * vam)
7412 {
7413   unformat_input_t *i = vam->input;
7414   vl_api_bridge_flags_t *mp;
7415   u32 bd_id;
7416   u8 bd_id_set = 0;
7417   u8 is_set = 1;
7418   u32 flags = 0;
7419   int ret;
7420
7421   /* Parse args required to build the message */
7422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7423     {
7424       if (unformat (i, "bd_id %d", &bd_id))
7425         bd_id_set = 1;
7426       else if (unformat (i, "learn"))
7427         flags |= L2_LEARN;
7428       else if (unformat (i, "forward"))
7429         flags |= L2_FWD;
7430       else if (unformat (i, "flood"))
7431         flags |= L2_FLOOD;
7432       else if (unformat (i, "uu-flood"))
7433         flags |= L2_UU_FLOOD;
7434       else if (unformat (i, "arp-term"))
7435         flags |= L2_ARP_TERM;
7436       else if (unformat (i, "off"))
7437         is_set = 0;
7438       else if (unformat (i, "disable"))
7439         is_set = 0;
7440       else
7441         break;
7442     }
7443
7444   if (bd_id_set == 0)
7445     {
7446       errmsg ("missing bridge domain");
7447       return -99;
7448     }
7449
7450   M (BRIDGE_FLAGS, mp);
7451
7452   mp->bd_id = ntohl (bd_id);
7453   mp->feature_bitmap = ntohl (flags);
7454   mp->is_set = is_set;
7455
7456   S (mp);
7457   W (ret);
7458   return ret;
7459 }
7460
7461 static int
7462 api_bd_ip_mac_add_del (vat_main_t * vam)
7463 {
7464   unformat_input_t *i = vam->input;
7465   vl_api_bd_ip_mac_add_del_t *mp;
7466   u32 bd_id;
7467   u8 is_ipv6 = 0;
7468   u8 is_add = 1;
7469   u8 bd_id_set = 0;
7470   u8 ip_set = 0;
7471   u8 mac_set = 0;
7472   ip4_address_t v4addr;
7473   ip6_address_t v6addr;
7474   u8 macaddr[6];
7475   int ret;
7476
7477
7478   /* Parse args required to build the message */
7479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7480     {
7481       if (unformat (i, "bd_id %d", &bd_id))
7482         {
7483           bd_id_set++;
7484         }
7485       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7486         {
7487           ip_set++;
7488         }
7489       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7490         {
7491           ip_set++;
7492           is_ipv6++;
7493         }
7494       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7495         {
7496           mac_set++;
7497         }
7498       else if (unformat (i, "del"))
7499         is_add = 0;
7500       else
7501         break;
7502     }
7503
7504   if (bd_id_set == 0)
7505     {
7506       errmsg ("missing bridge domain");
7507       return -99;
7508     }
7509   else if (ip_set == 0)
7510     {
7511       errmsg ("missing IP address");
7512       return -99;
7513     }
7514   else if (mac_set == 0)
7515     {
7516       errmsg ("missing MAC address");
7517       return -99;
7518     }
7519
7520   M (BD_IP_MAC_ADD_DEL, mp);
7521
7522   mp->bd_id = ntohl (bd_id);
7523   mp->is_ipv6 = is_ipv6;
7524   mp->is_add = is_add;
7525   if (is_ipv6)
7526     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7527   else
7528     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7529   clib_memcpy (mp->mac_address, macaddr, 6);
7530   S (mp);
7531   W (ret);
7532   return ret;
7533 }
7534
7535 static int
7536 api_tap_connect (vat_main_t * vam)
7537 {
7538   unformat_input_t *i = vam->input;
7539   vl_api_tap_connect_t *mp;
7540   u8 mac_address[6];
7541   u8 random_mac = 1;
7542   u8 name_set = 0;
7543   u8 *tap_name;
7544   u8 *tag = 0;
7545   ip4_address_t ip4_address;
7546   u32 ip4_mask_width;
7547   int ip4_address_set = 0;
7548   ip6_address_t ip6_address;
7549   u32 ip6_mask_width;
7550   int ip6_address_set = 0;
7551   int ret;
7552
7553   memset (mac_address, 0, sizeof (mac_address));
7554
7555   /* Parse args required to build the message */
7556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7557     {
7558       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7559         {
7560           random_mac = 0;
7561         }
7562       else if (unformat (i, "random-mac"))
7563         random_mac = 1;
7564       else if (unformat (i, "tapname %s", &tap_name))
7565         name_set = 1;
7566       else if (unformat (i, "tag %s", &tag))
7567         ;
7568       else if (unformat (i, "address %U/%d",
7569                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7570         ip4_address_set = 1;
7571       else if (unformat (i, "address %U/%d",
7572                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7573         ip6_address_set = 1;
7574       else
7575         break;
7576     }
7577
7578   if (name_set == 0)
7579     {
7580       errmsg ("missing tap name");
7581       return -99;
7582     }
7583   if (vec_len (tap_name) > 63)
7584     {
7585       errmsg ("tap name too long");
7586       return -99;
7587     }
7588   vec_add1 (tap_name, 0);
7589
7590   if (vec_len (tag) > 63)
7591     {
7592       errmsg ("tag too long");
7593       return -99;
7594     }
7595
7596   /* Construct the API message */
7597   M (TAP_CONNECT, mp);
7598
7599   mp->use_random_mac = random_mac;
7600   clib_memcpy (mp->mac_address, mac_address, 6);
7601   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7602   if (tag)
7603     clib_memcpy (mp->tag, tag, vec_len (tag));
7604
7605   if (ip4_address_set)
7606     {
7607       mp->ip4_address_set = 1;
7608       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7609       mp->ip4_mask_width = ip4_mask_width;
7610     }
7611   if (ip6_address_set)
7612     {
7613       mp->ip6_address_set = 1;
7614       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7615       mp->ip6_mask_width = ip6_mask_width;
7616     }
7617
7618   vec_free (tap_name);
7619   vec_free (tag);
7620
7621   /* send it... */
7622   S (mp);
7623
7624   /* Wait for a reply... */
7625   W (ret);
7626   return ret;
7627 }
7628
7629 static int
7630 api_tap_modify (vat_main_t * vam)
7631 {
7632   unformat_input_t *i = vam->input;
7633   vl_api_tap_modify_t *mp;
7634   u8 mac_address[6];
7635   u8 random_mac = 1;
7636   u8 name_set = 0;
7637   u8 *tap_name;
7638   u32 sw_if_index = ~0;
7639   u8 sw_if_index_set = 0;
7640   int ret;
7641
7642   memset (mac_address, 0, sizeof (mac_address));
7643
7644   /* Parse args required to build the message */
7645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7646     {
7647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7648         sw_if_index_set = 1;
7649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7650         sw_if_index_set = 1;
7651       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7652         {
7653           random_mac = 0;
7654         }
7655       else if (unformat (i, "random-mac"))
7656         random_mac = 1;
7657       else if (unformat (i, "tapname %s", &tap_name))
7658         name_set = 1;
7659       else
7660         break;
7661     }
7662
7663   if (sw_if_index_set == 0)
7664     {
7665       errmsg ("missing vpp interface name");
7666       return -99;
7667     }
7668   if (name_set == 0)
7669     {
7670       errmsg ("missing tap name");
7671       return -99;
7672     }
7673   if (vec_len (tap_name) > 63)
7674     {
7675       errmsg ("tap name too long");
7676     }
7677   vec_add1 (tap_name, 0);
7678
7679   /* Construct the API message */
7680   M (TAP_MODIFY, mp);
7681
7682   mp->use_random_mac = random_mac;
7683   mp->sw_if_index = ntohl (sw_if_index);
7684   clib_memcpy (mp->mac_address, mac_address, 6);
7685   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7686   vec_free (tap_name);
7687
7688   /* send it... */
7689   S (mp);
7690
7691   /* Wait for a reply... */
7692   W (ret);
7693   return ret;
7694 }
7695
7696 static int
7697 api_tap_delete (vat_main_t * vam)
7698 {
7699   unformat_input_t *i = vam->input;
7700   vl_api_tap_delete_t *mp;
7701   u32 sw_if_index = ~0;
7702   u8 sw_if_index_set = 0;
7703   int ret;
7704
7705   /* Parse args required to build the message */
7706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7707     {
7708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7709         sw_if_index_set = 1;
7710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7711         sw_if_index_set = 1;
7712       else
7713         break;
7714     }
7715
7716   if (sw_if_index_set == 0)
7717     {
7718       errmsg ("missing vpp interface name");
7719       return -99;
7720     }
7721
7722   /* Construct the API message */
7723   M (TAP_DELETE, mp);
7724
7725   mp->sw_if_index = ntohl (sw_if_index);
7726
7727   /* send it... */
7728   S (mp);
7729
7730   /* Wait for a reply... */
7731   W (ret);
7732   return ret;
7733 }
7734
7735 static int
7736 api_ip_table_add_del (vat_main_t * vam)
7737 {
7738   unformat_input_t *i = vam->input;
7739   vl_api_ip_table_add_del_t *mp;
7740   u32 table_id = ~0;
7741   u8 is_ipv6 = 0;
7742   u8 is_add = 1;
7743   int ret = 0;
7744
7745   /* Parse args required to build the message */
7746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7747     {
7748       if (unformat (i, "ipv6"))
7749         is_ipv6 = 1;
7750       else if (unformat (i, "del"))
7751         is_add = 0;
7752       else if (unformat (i, "add"))
7753         is_add = 1;
7754       else if (unformat (i, "table %d", &table_id))
7755         ;
7756       else
7757         {
7758           clib_warning ("parse error '%U'", format_unformat_error, i);
7759           return -99;
7760         }
7761     }
7762
7763   if (~0 == table_id)
7764     {
7765       errmsg ("missing table-ID");
7766       return -99;
7767     }
7768
7769   /* Construct the API message */
7770   M (IP_TABLE_ADD_DEL, mp);
7771
7772   mp->table_id = ntohl (table_id);
7773   mp->is_ipv6 = is_ipv6;
7774   mp->is_add = is_add;
7775
7776   /* send it... */
7777   S (mp);
7778
7779   /* Wait for a reply... */
7780   W (ret);
7781
7782   return ret;
7783 }
7784
7785 static int
7786 api_ip_add_del_route (vat_main_t * vam)
7787 {
7788   unformat_input_t *i = vam->input;
7789   vl_api_ip_add_del_route_t *mp;
7790   u32 sw_if_index = ~0, vrf_id = 0;
7791   u8 is_ipv6 = 0;
7792   u8 is_local = 0, is_drop = 0;
7793   u8 is_unreach = 0, is_prohibit = 0;
7794   u8 create_vrf_if_needed = 0;
7795   u8 is_add = 1;
7796   u32 next_hop_weight = 1;
7797   u8 is_multipath = 0;
7798   u8 address_set = 0;
7799   u8 address_length_set = 0;
7800   u32 next_hop_table_id = 0;
7801   u32 resolve_attempts = 0;
7802   u32 dst_address_length = 0;
7803   u8 next_hop_set = 0;
7804   ip4_address_t v4_dst_address, v4_next_hop_address;
7805   ip6_address_t v6_dst_address, v6_next_hop_address;
7806   int count = 1;
7807   int j;
7808   f64 before = 0;
7809   u32 random_add_del = 0;
7810   u32 *random_vector = 0;
7811   uword *random_hash;
7812   u32 random_seed = 0xdeaddabe;
7813   u32 classify_table_index = ~0;
7814   u8 is_classify = 0;
7815   u8 resolve_host = 0, resolve_attached = 0;
7816   mpls_label_t *next_hop_out_label_stack = NULL;
7817   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7818   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7819
7820   /* Parse args required to build the message */
7821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7822     {
7823       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7824         ;
7825       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7826         ;
7827       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7828         {
7829           address_set = 1;
7830           is_ipv6 = 0;
7831         }
7832       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7833         {
7834           address_set = 1;
7835           is_ipv6 = 1;
7836         }
7837       else if (unformat (i, "/%d", &dst_address_length))
7838         {
7839           address_length_set = 1;
7840         }
7841
7842       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7843                                          &v4_next_hop_address))
7844         {
7845           next_hop_set = 1;
7846         }
7847       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7848                                          &v6_next_hop_address))
7849         {
7850           next_hop_set = 1;
7851         }
7852       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7853         ;
7854       else if (unformat (i, "weight %d", &next_hop_weight))
7855         ;
7856       else if (unformat (i, "drop"))
7857         {
7858           is_drop = 1;
7859         }
7860       else if (unformat (i, "null-send-unreach"))
7861         {
7862           is_unreach = 1;
7863         }
7864       else if (unformat (i, "null-send-prohibit"))
7865         {
7866           is_prohibit = 1;
7867         }
7868       else if (unformat (i, "local"))
7869         {
7870           is_local = 1;
7871         }
7872       else if (unformat (i, "classify %d", &classify_table_index))
7873         {
7874           is_classify = 1;
7875         }
7876       else if (unformat (i, "del"))
7877         is_add = 0;
7878       else if (unformat (i, "add"))
7879         is_add = 1;
7880       else if (unformat (i, "resolve-via-host"))
7881         resolve_host = 1;
7882       else if (unformat (i, "resolve-via-attached"))
7883         resolve_attached = 1;
7884       else if (unformat (i, "multipath"))
7885         is_multipath = 1;
7886       else if (unformat (i, "vrf %d", &vrf_id))
7887         ;
7888       else if (unformat (i, "create-vrf"))
7889         create_vrf_if_needed = 1;
7890       else if (unformat (i, "count %d", &count))
7891         ;
7892       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7893         ;
7894       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7895         ;
7896       else if (unformat (i, "out-label %d", &next_hop_out_label))
7897         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7898       else if (unformat (i, "via-label %d", &next_hop_via_label))
7899         ;
7900       else if (unformat (i, "random"))
7901         random_add_del = 1;
7902       else if (unformat (i, "seed %d", &random_seed))
7903         ;
7904       else
7905         {
7906           clib_warning ("parse error '%U'", format_unformat_error, i);
7907           return -99;
7908         }
7909     }
7910
7911   if (!next_hop_set && !is_drop && !is_local &&
7912       !is_classify && !is_unreach && !is_prohibit &&
7913       MPLS_LABEL_INVALID == next_hop_via_label)
7914     {
7915       errmsg
7916         ("next hop / local / drop / unreach / prohibit / classify not set");
7917       return -99;
7918     }
7919
7920   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7921     {
7922       errmsg ("next hop and next-hop via label set");
7923       return -99;
7924     }
7925   if (address_set == 0)
7926     {
7927       errmsg ("missing addresses");
7928       return -99;
7929     }
7930
7931   if (address_length_set == 0)
7932     {
7933       errmsg ("missing address length");
7934       return -99;
7935     }
7936
7937   /* Generate a pile of unique, random routes */
7938   if (random_add_del)
7939     {
7940       u32 this_random_address;
7941       random_hash = hash_create (count, sizeof (uword));
7942
7943       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7944       for (j = 0; j <= count; j++)
7945         {
7946           do
7947             {
7948               this_random_address = random_u32 (&random_seed);
7949               this_random_address =
7950                 clib_host_to_net_u32 (this_random_address);
7951             }
7952           while (hash_get (random_hash, this_random_address));
7953           vec_add1 (random_vector, this_random_address);
7954           hash_set (random_hash, this_random_address, 1);
7955         }
7956       hash_free (random_hash);
7957       v4_dst_address.as_u32 = random_vector[0];
7958     }
7959
7960   if (count > 1)
7961     {
7962       /* Turn on async mode */
7963       vam->async_mode = 1;
7964       vam->async_errors = 0;
7965       before = vat_time_now (vam);
7966     }
7967
7968   for (j = 0; j < count; j++)
7969     {
7970       /* Construct the API message */
7971       M2 (IP_ADD_DEL_ROUTE, mp,
7972           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7973
7974       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7975       mp->table_id = ntohl (vrf_id);
7976       mp->create_vrf_if_needed = create_vrf_if_needed;
7977
7978       mp->is_add = is_add;
7979       mp->is_drop = is_drop;
7980       mp->is_unreach = is_unreach;
7981       mp->is_prohibit = is_prohibit;
7982       mp->is_ipv6 = is_ipv6;
7983       mp->is_local = is_local;
7984       mp->is_classify = is_classify;
7985       mp->is_multipath = is_multipath;
7986       mp->is_resolve_host = resolve_host;
7987       mp->is_resolve_attached = resolve_attached;
7988       mp->next_hop_weight = next_hop_weight;
7989       mp->dst_address_length = dst_address_length;
7990       mp->next_hop_table_id = ntohl (next_hop_table_id);
7991       mp->classify_table_index = ntohl (classify_table_index);
7992       mp->next_hop_via_label = ntohl (next_hop_via_label);
7993       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7994       if (0 != mp->next_hop_n_out_labels)
7995         {
7996           memcpy (mp->next_hop_out_label_stack,
7997                   next_hop_out_label_stack,
7998                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7999           vec_free (next_hop_out_label_stack);
8000         }
8001
8002       if (is_ipv6)
8003         {
8004           clib_memcpy (mp->dst_address, &v6_dst_address,
8005                        sizeof (v6_dst_address));
8006           if (next_hop_set)
8007             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8008                          sizeof (v6_next_hop_address));
8009           increment_v6_address (&v6_dst_address);
8010         }
8011       else
8012         {
8013           clib_memcpy (mp->dst_address, &v4_dst_address,
8014                        sizeof (v4_dst_address));
8015           if (next_hop_set)
8016             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8017                          sizeof (v4_next_hop_address));
8018           if (random_add_del)
8019             v4_dst_address.as_u32 = random_vector[j + 1];
8020           else
8021             increment_v4_address (&v4_dst_address);
8022         }
8023       /* send it... */
8024       S (mp);
8025       /* If we receive SIGTERM, stop now... */
8026       if (vam->do_exit)
8027         break;
8028     }
8029
8030   /* When testing multiple add/del ops, use a control-ping to sync */
8031   if (count > 1)
8032     {
8033       vl_api_control_ping_t *mp_ping;
8034       f64 after;
8035       f64 timeout;
8036
8037       /* Shut off async mode */
8038       vam->async_mode = 0;
8039
8040       MPING (CONTROL_PING, mp_ping);
8041       S (mp_ping);
8042
8043       timeout = vat_time_now (vam) + 1.0;
8044       while (vat_time_now (vam) < timeout)
8045         if (vam->result_ready == 1)
8046           goto out;
8047       vam->retval = -99;
8048
8049     out:
8050       if (vam->retval == -99)
8051         errmsg ("timeout");
8052
8053       if (vam->async_errors > 0)
8054         {
8055           errmsg ("%d asynchronous errors", vam->async_errors);
8056           vam->retval = -98;
8057         }
8058       vam->async_errors = 0;
8059       after = vat_time_now (vam);
8060
8061       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8062       if (j > 0)
8063         count = j;
8064
8065       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8066              count, after - before, count / (after - before));
8067     }
8068   else
8069     {
8070       int ret;
8071
8072       /* Wait for a reply... */
8073       W (ret);
8074       return ret;
8075     }
8076
8077   /* Return the good/bad news */
8078   return (vam->retval);
8079 }
8080
8081 static int
8082 api_ip_mroute_add_del (vat_main_t * vam)
8083 {
8084   unformat_input_t *i = vam->input;
8085   vl_api_ip_mroute_add_del_t *mp;
8086   u32 sw_if_index = ~0, vrf_id = 0;
8087   u8 is_ipv6 = 0;
8088   u8 is_local = 0;
8089   u8 create_vrf_if_needed = 0;
8090   u8 is_add = 1;
8091   u8 address_set = 0;
8092   u32 grp_address_length = 0;
8093   ip4_address_t v4_grp_address, v4_src_address;
8094   ip6_address_t v6_grp_address, v6_src_address;
8095   mfib_itf_flags_t iflags = 0;
8096   mfib_entry_flags_t eflags = 0;
8097   int ret;
8098
8099   /* Parse args required to build the message */
8100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8101     {
8102       if (unformat (i, "sw_if_index %d", &sw_if_index))
8103         ;
8104       else if (unformat (i, "%U %U",
8105                          unformat_ip4_address, &v4_src_address,
8106                          unformat_ip4_address, &v4_grp_address))
8107         {
8108           grp_address_length = 64;
8109           address_set = 1;
8110           is_ipv6 = 0;
8111         }
8112       else if (unformat (i, "%U %U",
8113                          unformat_ip6_address, &v6_src_address,
8114                          unformat_ip6_address, &v6_grp_address))
8115         {
8116           grp_address_length = 256;
8117           address_set = 1;
8118           is_ipv6 = 1;
8119         }
8120       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8121         {
8122           memset (&v4_src_address, 0, sizeof (v4_src_address));
8123           grp_address_length = 32;
8124           address_set = 1;
8125           is_ipv6 = 0;
8126         }
8127       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8128         {
8129           memset (&v6_src_address, 0, sizeof (v6_src_address));
8130           grp_address_length = 128;
8131           address_set = 1;
8132           is_ipv6 = 1;
8133         }
8134       else if (unformat (i, "/%d", &grp_address_length))
8135         ;
8136       else if (unformat (i, "local"))
8137         {
8138           is_local = 1;
8139         }
8140       else if (unformat (i, "del"))
8141         is_add = 0;
8142       else if (unformat (i, "add"))
8143         is_add = 1;
8144       else if (unformat (i, "vrf %d", &vrf_id))
8145         ;
8146       else if (unformat (i, "create-vrf"))
8147         create_vrf_if_needed = 1;
8148       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8149         ;
8150       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8151         ;
8152       else
8153         {
8154           clib_warning ("parse error '%U'", format_unformat_error, i);
8155           return -99;
8156         }
8157     }
8158
8159   if (address_set == 0)
8160     {
8161       errmsg ("missing addresses\n");
8162       return -99;
8163     }
8164
8165   /* Construct the API message */
8166   M (IP_MROUTE_ADD_DEL, mp);
8167
8168   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8169   mp->table_id = ntohl (vrf_id);
8170   mp->create_vrf_if_needed = create_vrf_if_needed;
8171
8172   mp->is_add = is_add;
8173   mp->is_ipv6 = is_ipv6;
8174   mp->is_local = is_local;
8175   mp->itf_flags = ntohl (iflags);
8176   mp->entry_flags = ntohl (eflags);
8177   mp->grp_address_length = grp_address_length;
8178   mp->grp_address_length = ntohs (mp->grp_address_length);
8179
8180   if (is_ipv6)
8181     {
8182       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8183       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8184     }
8185   else
8186     {
8187       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8188       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8189
8190     }
8191
8192   /* send it... */
8193   S (mp);
8194   /* Wait for a reply... */
8195   W (ret);
8196   return ret;
8197 }
8198
8199 static int
8200 api_mpls_table_add_del (vat_main_t * vam)
8201 {
8202   unformat_input_t *i = vam->input;
8203   vl_api_mpls_table_add_del_t *mp;
8204   u32 table_id = ~0;
8205   u8 is_add = 1;
8206   int ret = 0;
8207
8208   /* Parse args required to build the message */
8209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8210     {
8211       if (unformat (i, "table %d", &table_id))
8212         ;
8213       else if (unformat (i, "del"))
8214         is_add = 0;
8215       else if (unformat (i, "add"))
8216         is_add = 1;
8217       else
8218         {
8219           clib_warning ("parse error '%U'", format_unformat_error, i);
8220           return -99;
8221         }
8222     }
8223
8224   if (~0 == table_id)
8225     {
8226       errmsg ("missing table-ID");
8227       return -99;
8228     }
8229
8230   /* Construct the API message */
8231   M (MPLS_TABLE_ADD_DEL, mp);
8232
8233   mp->mt_table_id = ntohl (table_id);
8234   mp->mt_is_add = is_add;
8235
8236   /* send it... */
8237   S (mp);
8238
8239   /* Wait for a reply... */
8240   W (ret);
8241
8242   return ret;
8243 }
8244
8245 static int
8246 api_mpls_route_add_del (vat_main_t * vam)
8247 {
8248   unformat_input_t *i = vam->input;
8249   vl_api_mpls_route_add_del_t *mp;
8250   u32 sw_if_index = ~0, table_id = 0;
8251   u8 create_table_if_needed = 0;
8252   u8 is_add = 1;
8253   u32 next_hop_weight = 1;
8254   u8 is_multipath = 0;
8255   u32 next_hop_table_id = 0;
8256   u8 next_hop_set = 0;
8257   ip4_address_t v4_next_hop_address = {
8258     .as_u32 = 0,
8259   };
8260   ip6_address_t v6_next_hop_address = { {0} };
8261   int count = 1;
8262   int j;
8263   f64 before = 0;
8264   u32 classify_table_index = ~0;
8265   u8 is_classify = 0;
8266   u8 resolve_host = 0, resolve_attached = 0;
8267   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8268   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8269   mpls_label_t *next_hop_out_label_stack = NULL;
8270   mpls_label_t local_label = MPLS_LABEL_INVALID;
8271   u8 is_eos = 0;
8272   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8273
8274   /* Parse args required to build the message */
8275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8276     {
8277       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8278         ;
8279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8280         ;
8281       else if (unformat (i, "%d", &local_label))
8282         ;
8283       else if (unformat (i, "eos"))
8284         is_eos = 1;
8285       else if (unformat (i, "non-eos"))
8286         is_eos = 0;
8287       else if (unformat (i, "via %U", unformat_ip4_address,
8288                          &v4_next_hop_address))
8289         {
8290           next_hop_set = 1;
8291           next_hop_proto = DPO_PROTO_IP4;
8292         }
8293       else if (unformat (i, "via %U", unformat_ip6_address,
8294                          &v6_next_hop_address))
8295         {
8296           next_hop_set = 1;
8297           next_hop_proto = DPO_PROTO_IP6;
8298         }
8299       else if (unformat (i, "weight %d", &next_hop_weight))
8300         ;
8301       else if (unformat (i, "create-table"))
8302         create_table_if_needed = 1;
8303       else if (unformat (i, "classify %d", &classify_table_index))
8304         {
8305           is_classify = 1;
8306         }
8307       else if (unformat (i, "del"))
8308         is_add = 0;
8309       else if (unformat (i, "add"))
8310         is_add = 1;
8311       else if (unformat (i, "resolve-via-host"))
8312         resolve_host = 1;
8313       else if (unformat (i, "resolve-via-attached"))
8314         resolve_attached = 1;
8315       else if (unformat (i, "multipath"))
8316         is_multipath = 1;
8317       else if (unformat (i, "count %d", &count))
8318         ;
8319       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8320         {
8321           next_hop_set = 1;
8322           next_hop_proto = DPO_PROTO_IP4;
8323         }
8324       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8325         {
8326           next_hop_set = 1;
8327           next_hop_proto = DPO_PROTO_IP6;
8328         }
8329       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8330         ;
8331       else if (unformat (i, "via-label %d", &next_hop_via_label))
8332         ;
8333       else if (unformat (i, "out-label %d", &next_hop_out_label))
8334         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8335       else
8336         {
8337           clib_warning ("parse error '%U'", format_unformat_error, i);
8338           return -99;
8339         }
8340     }
8341
8342   if (!next_hop_set && !is_classify)
8343     {
8344       errmsg ("next hop / classify not set");
8345       return -99;
8346     }
8347
8348   if (MPLS_LABEL_INVALID == local_label)
8349     {
8350       errmsg ("missing label");
8351       return -99;
8352     }
8353
8354   if (count > 1)
8355     {
8356       /* Turn on async mode */
8357       vam->async_mode = 1;
8358       vam->async_errors = 0;
8359       before = vat_time_now (vam);
8360     }
8361
8362   for (j = 0; j < count; j++)
8363     {
8364       /* Construct the API message */
8365       M2 (MPLS_ROUTE_ADD_DEL, mp,
8366           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8367
8368       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8369       mp->mr_table_id = ntohl (table_id);
8370       mp->mr_create_table_if_needed = create_table_if_needed;
8371
8372       mp->mr_is_add = is_add;
8373       mp->mr_next_hop_proto = next_hop_proto;
8374       mp->mr_is_classify = is_classify;
8375       mp->mr_is_multipath = is_multipath;
8376       mp->mr_is_resolve_host = resolve_host;
8377       mp->mr_is_resolve_attached = resolve_attached;
8378       mp->mr_next_hop_weight = next_hop_weight;
8379       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8380       mp->mr_classify_table_index = ntohl (classify_table_index);
8381       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8382       mp->mr_label = ntohl (local_label);
8383       mp->mr_eos = is_eos;
8384
8385       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8386       if (0 != mp->mr_next_hop_n_out_labels)
8387         {
8388           memcpy (mp->mr_next_hop_out_label_stack,
8389                   next_hop_out_label_stack,
8390                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8391           vec_free (next_hop_out_label_stack);
8392         }
8393
8394       if (next_hop_set)
8395         {
8396           if (DPO_PROTO_IP4 == next_hop_proto)
8397             {
8398               clib_memcpy (mp->mr_next_hop,
8399                            &v4_next_hop_address,
8400                            sizeof (v4_next_hop_address));
8401             }
8402           else if (DPO_PROTO_IP6 == next_hop_proto)
8403
8404             {
8405               clib_memcpy (mp->mr_next_hop,
8406                            &v6_next_hop_address,
8407                            sizeof (v6_next_hop_address));
8408             }
8409         }
8410       local_label++;
8411
8412       /* send it... */
8413       S (mp);
8414       /* If we receive SIGTERM, stop now... */
8415       if (vam->do_exit)
8416         break;
8417     }
8418
8419   /* When testing multiple add/del ops, use a control-ping to sync */
8420   if (count > 1)
8421     {
8422       vl_api_control_ping_t *mp_ping;
8423       f64 after;
8424       f64 timeout;
8425
8426       /* Shut off async mode */
8427       vam->async_mode = 0;
8428
8429       MPING (CONTROL_PING, mp_ping);
8430       S (mp_ping);
8431
8432       timeout = vat_time_now (vam) + 1.0;
8433       while (vat_time_now (vam) < timeout)
8434         if (vam->result_ready == 1)
8435           goto out;
8436       vam->retval = -99;
8437
8438     out:
8439       if (vam->retval == -99)
8440         errmsg ("timeout");
8441
8442       if (vam->async_errors > 0)
8443         {
8444           errmsg ("%d asynchronous errors", vam->async_errors);
8445           vam->retval = -98;
8446         }
8447       vam->async_errors = 0;
8448       after = vat_time_now (vam);
8449
8450       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8451       if (j > 0)
8452         count = j;
8453
8454       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8455              count, after - before, count / (after - before));
8456     }
8457   else
8458     {
8459       int ret;
8460
8461       /* Wait for a reply... */
8462       W (ret);
8463       return ret;
8464     }
8465
8466   /* Return the good/bad news */
8467   return (vam->retval);
8468 }
8469
8470 static int
8471 api_mpls_ip_bind_unbind (vat_main_t * vam)
8472 {
8473   unformat_input_t *i = vam->input;
8474   vl_api_mpls_ip_bind_unbind_t *mp;
8475   u32 ip_table_id = 0;
8476   u8 create_table_if_needed = 0;
8477   u8 is_bind = 1;
8478   u8 is_ip4 = 1;
8479   ip4_address_t v4_address;
8480   ip6_address_t v6_address;
8481   u32 address_length;
8482   u8 address_set = 0;
8483   mpls_label_t local_label = MPLS_LABEL_INVALID;
8484   int ret;
8485
8486   /* Parse args required to build the message */
8487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8488     {
8489       if (unformat (i, "%U/%d", unformat_ip4_address,
8490                     &v4_address, &address_length))
8491         {
8492           is_ip4 = 1;
8493           address_set = 1;
8494         }
8495       else if (unformat (i, "%U/%d", unformat_ip6_address,
8496                          &v6_address, &address_length))
8497         {
8498           is_ip4 = 0;
8499           address_set = 1;
8500         }
8501       else if (unformat (i, "%d", &local_label))
8502         ;
8503       else if (unformat (i, "create-table"))
8504         create_table_if_needed = 1;
8505       else if (unformat (i, "table-id %d", &ip_table_id))
8506         ;
8507       else if (unformat (i, "unbind"))
8508         is_bind = 0;
8509       else if (unformat (i, "bind"))
8510         is_bind = 1;
8511       else
8512         {
8513           clib_warning ("parse error '%U'", format_unformat_error, i);
8514           return -99;
8515         }
8516     }
8517
8518   if (!address_set)
8519     {
8520       errmsg ("IP addres not set");
8521       return -99;
8522     }
8523
8524   if (MPLS_LABEL_INVALID == local_label)
8525     {
8526       errmsg ("missing label");
8527       return -99;
8528     }
8529
8530   /* Construct the API message */
8531   M (MPLS_IP_BIND_UNBIND, mp);
8532
8533   mp->mb_create_table_if_needed = create_table_if_needed;
8534   mp->mb_is_bind = is_bind;
8535   mp->mb_is_ip4 = is_ip4;
8536   mp->mb_ip_table_id = ntohl (ip_table_id);
8537   mp->mb_mpls_table_id = 0;
8538   mp->mb_label = ntohl (local_label);
8539   mp->mb_address_length = address_length;
8540
8541   if (is_ip4)
8542     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8543   else
8544     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8545
8546   /* send it... */
8547   S (mp);
8548
8549   /* Wait for a reply... */
8550   W (ret);
8551   return ret;
8552 }
8553
8554 static int
8555 api_bier_table_add_del (vat_main_t * vam)
8556 {
8557   unformat_input_t *i = vam->input;
8558   vl_api_bier_table_add_del_t *mp;
8559   u8 is_add = 1;
8560   u32 set = 0, sub_domain = 0, hdr_len = 3;
8561   mpls_label_t local_label = MPLS_LABEL_INVALID;
8562   int ret;
8563
8564   /* Parse args required to build the message */
8565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8566     {
8567       if (unformat (i, "sub-domain %d", &sub_domain))
8568         ;
8569       else if (unformat (i, "set %d", &set))
8570         ;
8571       else if (unformat (i, "label %d", &local_label))
8572         ;
8573       else if (unformat (i, "hdr-len %d", &hdr_len))
8574         ;
8575       else if (unformat (i, "add"))
8576         is_add = 1;
8577       else if (unformat (i, "del"))
8578         is_add = 0;
8579       else
8580         {
8581           clib_warning ("parse error '%U'", format_unformat_error, i);
8582           return -99;
8583         }
8584     }
8585
8586   if (MPLS_LABEL_INVALID == local_label)
8587     {
8588       errmsg ("missing label\n");
8589       return -99;
8590     }
8591
8592   /* Construct the API message */
8593   M (BIER_TABLE_ADD_DEL, mp);
8594
8595   mp->bt_is_add = is_add;
8596   mp->bt_label = ntohl (local_label);
8597   mp->bt_tbl_id.bt_set = set;
8598   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8599   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8600
8601   /* send it... */
8602   S (mp);
8603
8604   /* Wait for a reply... */
8605   W (ret);
8606
8607   return (ret);
8608 }
8609
8610 static int
8611 api_bier_route_add_del (vat_main_t * vam)
8612 {
8613   unformat_input_t *i = vam->input;
8614   vl_api_bier_route_add_del_t *mp;
8615   u8 is_add = 1;
8616   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8617   ip4_address_t v4_next_hop_address;
8618   ip6_address_t v6_next_hop_address;
8619   u8 next_hop_set = 0;
8620   u8 next_hop_proto_is_ip4 = 1;
8621   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8622   int ret;
8623
8624   /* Parse args required to build the message */
8625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8626     {
8627       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8628         {
8629           next_hop_proto_is_ip4 = 1;
8630           next_hop_set = 1;
8631         }
8632       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8633         {
8634           next_hop_proto_is_ip4 = 0;
8635           next_hop_set = 1;
8636         }
8637       if (unformat (i, "sub-domain %d", &sub_domain))
8638         ;
8639       else if (unformat (i, "set %d", &set))
8640         ;
8641       else if (unformat (i, "hdr-len %d", &hdr_len))
8642         ;
8643       else if (unformat (i, "bp %d", &bp))
8644         ;
8645       else if (unformat (i, "add"))
8646         is_add = 1;
8647       else if (unformat (i, "del"))
8648         is_add = 0;
8649       else if (unformat (i, "out-label %d", &next_hop_out_label))
8650         ;
8651       else
8652         {
8653           clib_warning ("parse error '%U'", format_unformat_error, i);
8654           return -99;
8655         }
8656     }
8657
8658   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8659     {
8660       errmsg ("next hop / label set\n");
8661       return -99;
8662     }
8663   if (0 == bp)
8664     {
8665       errmsg ("bit=position not set\n");
8666       return -99;
8667     }
8668
8669   /* Construct the API message */
8670   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8671
8672   mp->br_is_add = is_add;
8673   mp->br_tbl_id.bt_set = set;
8674   mp->br_tbl_id.bt_sub_domain = sub_domain;
8675   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8676   mp->br_bp = ntohs (bp);
8677   mp->br_n_paths = 1;
8678   mp->br_paths[0].n_labels = 1;
8679   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8680   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8681
8682   if (next_hop_proto_is_ip4)
8683     {
8684       clib_memcpy (mp->br_paths[0].next_hop,
8685                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8686     }
8687   else
8688     {
8689       clib_memcpy (mp->br_paths[0].next_hop,
8690                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8691     }
8692
8693   /* send it... */
8694   S (mp);
8695
8696   /* Wait for a reply... */
8697   W (ret);
8698
8699   return (ret);
8700 }
8701
8702 static int
8703 api_proxy_arp_add_del (vat_main_t * vam)
8704 {
8705   unformat_input_t *i = vam->input;
8706   vl_api_proxy_arp_add_del_t *mp;
8707   u32 vrf_id = 0;
8708   u8 is_add = 1;
8709   ip4_address_t lo, hi;
8710   u8 range_set = 0;
8711   int ret;
8712
8713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8714     {
8715       if (unformat (i, "vrf %d", &vrf_id))
8716         ;
8717       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8718                          unformat_ip4_address, &hi))
8719         range_set = 1;
8720       else if (unformat (i, "del"))
8721         is_add = 0;
8722       else
8723         {
8724           clib_warning ("parse error '%U'", format_unformat_error, i);
8725           return -99;
8726         }
8727     }
8728
8729   if (range_set == 0)
8730     {
8731       errmsg ("address range not set");
8732       return -99;
8733     }
8734
8735   M (PROXY_ARP_ADD_DEL, mp);
8736
8737   mp->vrf_id = ntohl (vrf_id);
8738   mp->is_add = is_add;
8739   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8740   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8741
8742   S (mp);
8743   W (ret);
8744   return ret;
8745 }
8746
8747 static int
8748 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8749 {
8750   unformat_input_t *i = vam->input;
8751   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8752   u32 sw_if_index;
8753   u8 enable = 1;
8754   u8 sw_if_index_set = 0;
8755   int ret;
8756
8757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8758     {
8759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8760         sw_if_index_set = 1;
8761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8762         sw_if_index_set = 1;
8763       else if (unformat (i, "enable"))
8764         enable = 1;
8765       else if (unformat (i, "disable"))
8766         enable = 0;
8767       else
8768         {
8769           clib_warning ("parse error '%U'", format_unformat_error, i);
8770           return -99;
8771         }
8772     }
8773
8774   if (sw_if_index_set == 0)
8775     {
8776       errmsg ("missing interface name or sw_if_index");
8777       return -99;
8778     }
8779
8780   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8781
8782   mp->sw_if_index = ntohl (sw_if_index);
8783   mp->enable_disable = enable;
8784
8785   S (mp);
8786   W (ret);
8787   return ret;
8788 }
8789
8790 static int
8791 api_mpls_tunnel_add_del (vat_main_t * vam)
8792 {
8793   unformat_input_t *i = vam->input;
8794   vl_api_mpls_tunnel_add_del_t *mp;
8795
8796   u8 is_add = 1;
8797   u8 l2_only = 0;
8798   u32 sw_if_index = ~0;
8799   u32 next_hop_sw_if_index = ~0;
8800   u32 next_hop_proto_is_ip4 = 1;
8801
8802   u32 next_hop_table_id = 0;
8803   ip4_address_t v4_next_hop_address = {
8804     .as_u32 = 0,
8805   };
8806   ip6_address_t v6_next_hop_address = { {0} };
8807   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8808   int ret;
8809
8810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (unformat (i, "add"))
8813         is_add = 1;
8814       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8815         is_add = 0;
8816       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8817         ;
8818       else if (unformat (i, "via %U",
8819                          unformat_ip4_address, &v4_next_hop_address))
8820         {
8821           next_hop_proto_is_ip4 = 1;
8822         }
8823       else if (unformat (i, "via %U",
8824                          unformat_ip6_address, &v6_next_hop_address))
8825         {
8826           next_hop_proto_is_ip4 = 0;
8827         }
8828       else if (unformat (i, "l2-only"))
8829         l2_only = 1;
8830       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8831         ;
8832       else if (unformat (i, "out-label %d", &next_hop_out_label))
8833         vec_add1 (labels, ntohl (next_hop_out_label));
8834       else
8835         {
8836           clib_warning ("parse error '%U'", format_unformat_error, i);
8837           return -99;
8838         }
8839     }
8840
8841   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8842
8843   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8844   mp->mt_sw_if_index = ntohl (sw_if_index);
8845   mp->mt_is_add = is_add;
8846   mp->mt_l2_only = l2_only;
8847   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8848   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8849
8850   mp->mt_next_hop_n_out_labels = vec_len (labels);
8851
8852   if (0 != mp->mt_next_hop_n_out_labels)
8853     {
8854       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8855                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8856       vec_free (labels);
8857     }
8858
8859   if (next_hop_proto_is_ip4)
8860     {
8861       clib_memcpy (mp->mt_next_hop,
8862                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8863     }
8864   else
8865     {
8866       clib_memcpy (mp->mt_next_hop,
8867                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8868     }
8869
8870   S (mp);
8871   W (ret);
8872   return ret;
8873 }
8874
8875 static int
8876 api_sw_interface_set_unnumbered (vat_main_t * vam)
8877 {
8878   unformat_input_t *i = vam->input;
8879   vl_api_sw_interface_set_unnumbered_t *mp;
8880   u32 sw_if_index;
8881   u32 unnum_sw_index = ~0;
8882   u8 is_add = 1;
8883   u8 sw_if_index_set = 0;
8884   int ret;
8885
8886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8887     {
8888       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8889         sw_if_index_set = 1;
8890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8891         sw_if_index_set = 1;
8892       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8893         ;
8894       else if (unformat (i, "del"))
8895         is_add = 0;
8896       else
8897         {
8898           clib_warning ("parse error '%U'", format_unformat_error, i);
8899           return -99;
8900         }
8901     }
8902
8903   if (sw_if_index_set == 0)
8904     {
8905       errmsg ("missing interface name or sw_if_index");
8906       return -99;
8907     }
8908
8909   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8910
8911   mp->sw_if_index = ntohl (sw_if_index);
8912   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8913   mp->is_add = is_add;
8914
8915   S (mp);
8916   W (ret);
8917   return ret;
8918 }
8919
8920 static int
8921 api_ip_neighbor_add_del (vat_main_t * vam)
8922 {
8923   unformat_input_t *i = vam->input;
8924   vl_api_ip_neighbor_add_del_t *mp;
8925   u32 sw_if_index;
8926   u8 sw_if_index_set = 0;
8927   u8 is_add = 1;
8928   u8 is_static = 0;
8929   u8 is_no_fib_entry = 0;
8930   u8 mac_address[6];
8931   u8 mac_set = 0;
8932   u8 v4_address_set = 0;
8933   u8 v6_address_set = 0;
8934   ip4_address_t v4address;
8935   ip6_address_t v6address;
8936   int ret;
8937
8938   memset (mac_address, 0, sizeof (mac_address));
8939
8940   /* Parse args required to build the message */
8941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8942     {
8943       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8944         {
8945           mac_set = 1;
8946         }
8947       else if (unformat (i, "del"))
8948         is_add = 0;
8949       else
8950         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8951         sw_if_index_set = 1;
8952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8953         sw_if_index_set = 1;
8954       else if (unformat (i, "is_static"))
8955         is_static = 1;
8956       else if (unformat (i, "no-fib-entry"))
8957         is_no_fib_entry = 1;
8958       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8959         v4_address_set = 1;
8960       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8961         v6_address_set = 1;
8962       else
8963         {
8964           clib_warning ("parse error '%U'", format_unformat_error, i);
8965           return -99;
8966         }
8967     }
8968
8969   if (sw_if_index_set == 0)
8970     {
8971       errmsg ("missing interface name or sw_if_index");
8972       return -99;
8973     }
8974   if (v4_address_set && v6_address_set)
8975     {
8976       errmsg ("both v4 and v6 addresses set");
8977       return -99;
8978     }
8979   if (!v4_address_set && !v6_address_set)
8980     {
8981       errmsg ("no address set");
8982       return -99;
8983     }
8984
8985   /* Construct the API message */
8986   M (IP_NEIGHBOR_ADD_DEL, mp);
8987
8988   mp->sw_if_index = ntohl (sw_if_index);
8989   mp->is_add = is_add;
8990   mp->is_static = is_static;
8991   mp->is_no_adj_fib = is_no_fib_entry;
8992   if (mac_set)
8993     clib_memcpy (mp->mac_address, mac_address, 6);
8994   if (v6_address_set)
8995     {
8996       mp->is_ipv6 = 1;
8997       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8998     }
8999   else
9000     {
9001       /* mp->is_ipv6 = 0; via memset in M macro above */
9002       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9003     }
9004
9005   /* send it... */
9006   S (mp);
9007
9008   /* Wait for a reply, return good/bad news  */
9009   W (ret);
9010   return ret;
9011 }
9012
9013 static int
9014 api_create_vlan_subif (vat_main_t * vam)
9015 {
9016   unformat_input_t *i = vam->input;
9017   vl_api_create_vlan_subif_t *mp;
9018   u32 sw_if_index;
9019   u8 sw_if_index_set = 0;
9020   u32 vlan_id;
9021   u8 vlan_id_set = 0;
9022   int ret;
9023
9024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9025     {
9026       if (unformat (i, "sw_if_index %d", &sw_if_index))
9027         sw_if_index_set = 1;
9028       else
9029         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9030         sw_if_index_set = 1;
9031       else if (unformat (i, "vlan %d", &vlan_id))
9032         vlan_id_set = 1;
9033       else
9034         {
9035           clib_warning ("parse error '%U'", format_unformat_error, i);
9036           return -99;
9037         }
9038     }
9039
9040   if (sw_if_index_set == 0)
9041     {
9042       errmsg ("missing interface name or sw_if_index");
9043       return -99;
9044     }
9045
9046   if (vlan_id_set == 0)
9047     {
9048       errmsg ("missing vlan_id");
9049       return -99;
9050     }
9051   M (CREATE_VLAN_SUBIF, mp);
9052
9053   mp->sw_if_index = ntohl (sw_if_index);
9054   mp->vlan_id = ntohl (vlan_id);
9055
9056   S (mp);
9057   W (ret);
9058   return ret;
9059 }
9060
9061 #define foreach_create_subif_bit                \
9062 _(no_tags)                                      \
9063 _(one_tag)                                      \
9064 _(two_tags)                                     \
9065 _(dot1ad)                                       \
9066 _(exact_match)                                  \
9067 _(default_sub)                                  \
9068 _(outer_vlan_id_any)                            \
9069 _(inner_vlan_id_any)
9070
9071 static int
9072 api_create_subif (vat_main_t * vam)
9073 {
9074   unformat_input_t *i = vam->input;
9075   vl_api_create_subif_t *mp;
9076   u32 sw_if_index;
9077   u8 sw_if_index_set = 0;
9078   u32 sub_id;
9079   u8 sub_id_set = 0;
9080   u32 no_tags = 0;
9081   u32 one_tag = 0;
9082   u32 two_tags = 0;
9083   u32 dot1ad = 0;
9084   u32 exact_match = 0;
9085   u32 default_sub = 0;
9086   u32 outer_vlan_id_any = 0;
9087   u32 inner_vlan_id_any = 0;
9088   u32 tmp;
9089   u16 outer_vlan_id = 0;
9090   u16 inner_vlan_id = 0;
9091   int ret;
9092
9093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9094     {
9095       if (unformat (i, "sw_if_index %d", &sw_if_index))
9096         sw_if_index_set = 1;
9097       else
9098         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9099         sw_if_index_set = 1;
9100       else if (unformat (i, "sub_id %d", &sub_id))
9101         sub_id_set = 1;
9102       else if (unformat (i, "outer_vlan_id %d", &tmp))
9103         outer_vlan_id = tmp;
9104       else if (unformat (i, "inner_vlan_id %d", &tmp))
9105         inner_vlan_id = tmp;
9106
9107 #define _(a) else if (unformat (i, #a)) a = 1 ;
9108       foreach_create_subif_bit
9109 #undef _
9110         else
9111         {
9112           clib_warning ("parse error '%U'", format_unformat_error, i);
9113           return -99;
9114         }
9115     }
9116
9117   if (sw_if_index_set == 0)
9118     {
9119       errmsg ("missing interface name or sw_if_index");
9120       return -99;
9121     }
9122
9123   if (sub_id_set == 0)
9124     {
9125       errmsg ("missing sub_id");
9126       return -99;
9127     }
9128   M (CREATE_SUBIF, mp);
9129
9130   mp->sw_if_index = ntohl (sw_if_index);
9131   mp->sub_id = ntohl (sub_id);
9132
9133 #define _(a) mp->a = a;
9134   foreach_create_subif_bit;
9135 #undef _
9136
9137   mp->outer_vlan_id = ntohs (outer_vlan_id);
9138   mp->inner_vlan_id = ntohs (inner_vlan_id);
9139
9140   S (mp);
9141   W (ret);
9142   return ret;
9143 }
9144
9145 static int
9146 api_oam_add_del (vat_main_t * vam)
9147 {
9148   unformat_input_t *i = vam->input;
9149   vl_api_oam_add_del_t *mp;
9150   u32 vrf_id = 0;
9151   u8 is_add = 1;
9152   ip4_address_t src, dst;
9153   u8 src_set = 0;
9154   u8 dst_set = 0;
9155   int ret;
9156
9157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9158     {
9159       if (unformat (i, "vrf %d", &vrf_id))
9160         ;
9161       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9162         src_set = 1;
9163       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9164         dst_set = 1;
9165       else if (unformat (i, "del"))
9166         is_add = 0;
9167       else
9168         {
9169           clib_warning ("parse error '%U'", format_unformat_error, i);
9170           return -99;
9171         }
9172     }
9173
9174   if (src_set == 0)
9175     {
9176       errmsg ("missing src addr");
9177       return -99;
9178     }
9179
9180   if (dst_set == 0)
9181     {
9182       errmsg ("missing dst addr");
9183       return -99;
9184     }
9185
9186   M (OAM_ADD_DEL, mp);
9187
9188   mp->vrf_id = ntohl (vrf_id);
9189   mp->is_add = is_add;
9190   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9191   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9192
9193   S (mp);
9194   W (ret);
9195   return ret;
9196 }
9197
9198 static int
9199 api_reset_fib (vat_main_t * vam)
9200 {
9201   unformat_input_t *i = vam->input;
9202   vl_api_reset_fib_t *mp;
9203   u32 vrf_id = 0;
9204   u8 is_ipv6 = 0;
9205   u8 vrf_id_set = 0;
9206
9207   int ret;
9208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9209     {
9210       if (unformat (i, "vrf %d", &vrf_id))
9211         vrf_id_set = 1;
9212       else if (unformat (i, "ipv6"))
9213         is_ipv6 = 1;
9214       else
9215         {
9216           clib_warning ("parse error '%U'", format_unformat_error, i);
9217           return -99;
9218         }
9219     }
9220
9221   if (vrf_id_set == 0)
9222     {
9223       errmsg ("missing vrf id");
9224       return -99;
9225     }
9226
9227   M (RESET_FIB, mp);
9228
9229   mp->vrf_id = ntohl (vrf_id);
9230   mp->is_ipv6 = is_ipv6;
9231
9232   S (mp);
9233   W (ret);
9234   return ret;
9235 }
9236
9237 static int
9238 api_dhcp_proxy_config (vat_main_t * vam)
9239 {
9240   unformat_input_t *i = vam->input;
9241   vl_api_dhcp_proxy_config_t *mp;
9242   u32 rx_vrf_id = 0;
9243   u32 server_vrf_id = 0;
9244   u8 is_add = 1;
9245   u8 v4_address_set = 0;
9246   u8 v6_address_set = 0;
9247   ip4_address_t v4address;
9248   ip6_address_t v6address;
9249   u8 v4_src_address_set = 0;
9250   u8 v6_src_address_set = 0;
9251   ip4_address_t v4srcaddress;
9252   ip6_address_t v6srcaddress;
9253   int ret;
9254
9255   /* Parse args required to build the message */
9256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9257     {
9258       if (unformat (i, "del"))
9259         is_add = 0;
9260       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9261         ;
9262       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9263         ;
9264       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9265         v4_address_set = 1;
9266       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9267         v6_address_set = 1;
9268       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9269         v4_src_address_set = 1;
9270       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9271         v6_src_address_set = 1;
9272       else
9273         break;
9274     }
9275
9276   if (v4_address_set && v6_address_set)
9277     {
9278       errmsg ("both v4 and v6 server addresses set");
9279       return -99;
9280     }
9281   if (!v4_address_set && !v6_address_set)
9282     {
9283       errmsg ("no server addresses set");
9284       return -99;
9285     }
9286
9287   if (v4_src_address_set && v6_src_address_set)
9288     {
9289       errmsg ("both v4 and v6  src addresses set");
9290       return -99;
9291     }
9292   if (!v4_src_address_set && !v6_src_address_set)
9293     {
9294       errmsg ("no src addresses set");
9295       return -99;
9296     }
9297
9298   if (!(v4_src_address_set && v4_address_set) &&
9299       !(v6_src_address_set && v6_address_set))
9300     {
9301       errmsg ("no matching server and src addresses set");
9302       return -99;
9303     }
9304
9305   /* Construct the API message */
9306   M (DHCP_PROXY_CONFIG, mp);
9307
9308   mp->is_add = is_add;
9309   mp->rx_vrf_id = ntohl (rx_vrf_id);
9310   mp->server_vrf_id = ntohl (server_vrf_id);
9311   if (v6_address_set)
9312     {
9313       mp->is_ipv6 = 1;
9314       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9315       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9316     }
9317   else
9318     {
9319       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9320       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9321     }
9322
9323   /* send it... */
9324   S (mp);
9325
9326   /* Wait for a reply, return good/bad news  */
9327   W (ret);
9328   return ret;
9329 }
9330
9331 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9332 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9333
9334 static void
9335 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9336 {
9337   vat_main_t *vam = &vat_main;
9338   u32 i, count = mp->count;
9339   vl_api_dhcp_server_t *s;
9340
9341   if (mp->is_ipv6)
9342     print (vam->ofp,
9343            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9344            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9345            ntohl (mp->rx_vrf_id),
9346            format_ip6_address, mp->dhcp_src_address,
9347            mp->vss_type, mp->vss_vpn_ascii_id,
9348            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9349   else
9350     print (vam->ofp,
9351            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9352            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9353            ntohl (mp->rx_vrf_id),
9354            format_ip4_address, mp->dhcp_src_address,
9355            mp->vss_type, mp->vss_vpn_ascii_id,
9356            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9357
9358   for (i = 0; i < count; i++)
9359     {
9360       s = &mp->servers[i];
9361
9362       if (mp->is_ipv6)
9363         print (vam->ofp,
9364                " Server Table-ID %d, Server Address %U",
9365                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9366       else
9367         print (vam->ofp,
9368                " Server Table-ID %d, Server Address %U",
9369                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9370     }
9371 }
9372
9373 static void vl_api_dhcp_proxy_details_t_handler_json
9374   (vl_api_dhcp_proxy_details_t * mp)
9375 {
9376   vat_main_t *vam = &vat_main;
9377   vat_json_node_t *node = NULL;
9378   u32 i, count = mp->count;
9379   struct in_addr ip4;
9380   struct in6_addr ip6;
9381   vl_api_dhcp_server_t *s;
9382
9383   if (VAT_JSON_ARRAY != vam->json_tree.type)
9384     {
9385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9386       vat_json_init_array (&vam->json_tree);
9387     }
9388   node = vat_json_array_add (&vam->json_tree);
9389
9390   vat_json_init_object (node);
9391   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9392   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9393                              sizeof (mp->vss_type));
9394   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9395                                    mp->vss_vpn_ascii_id);
9396   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9397   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9398
9399   if (mp->is_ipv6)
9400     {
9401       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9402       vat_json_object_add_ip6 (node, "src_address", ip6);
9403     }
9404   else
9405     {
9406       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9407       vat_json_object_add_ip4 (node, "src_address", ip4);
9408     }
9409
9410   for (i = 0; i < count; i++)
9411     {
9412       s = &mp->servers[i];
9413
9414       vat_json_object_add_uint (node, "server-table-id",
9415                                 ntohl (s->server_vrf_id));
9416
9417       if (mp->is_ipv6)
9418         {
9419           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9420           vat_json_object_add_ip4 (node, "src_address", ip4);
9421         }
9422       else
9423         {
9424           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9425           vat_json_object_add_ip6 (node, "server_address", ip6);
9426         }
9427     }
9428 }
9429
9430 static int
9431 api_dhcp_proxy_dump (vat_main_t * vam)
9432 {
9433   unformat_input_t *i = vam->input;
9434   vl_api_control_ping_t *mp_ping;
9435   vl_api_dhcp_proxy_dump_t *mp;
9436   u8 is_ipv6 = 0;
9437   int ret;
9438
9439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9440     {
9441       if (unformat (i, "ipv6"))
9442         is_ipv6 = 1;
9443       else
9444         {
9445           clib_warning ("parse error '%U'", format_unformat_error, i);
9446           return -99;
9447         }
9448     }
9449
9450   M (DHCP_PROXY_DUMP, mp);
9451
9452   mp->is_ip6 = is_ipv6;
9453   S (mp);
9454
9455   /* Use a control ping for synchronization */
9456   MPING (CONTROL_PING, mp_ping);
9457   S (mp_ping);
9458
9459   W (ret);
9460   return ret;
9461 }
9462
9463 static int
9464 api_dhcp_proxy_set_vss (vat_main_t * vam)
9465 {
9466   unformat_input_t *i = vam->input;
9467   vl_api_dhcp_proxy_set_vss_t *mp;
9468   u8 is_ipv6 = 0;
9469   u8 is_add = 1;
9470   u32 tbl_id = ~0;
9471   u8 vss_type = VSS_TYPE_DEFAULT;
9472   u8 *vpn_ascii_id = 0;
9473   u32 oui = 0;
9474   u32 fib_id = 0;
9475   int ret;
9476
9477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9478     {
9479       if (unformat (i, "tbl_id %d", &tbl_id))
9480         ;
9481       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9482         vss_type = VSS_TYPE_ASCII;
9483       else if (unformat (i, "fib_id %d", &fib_id))
9484         vss_type = VSS_TYPE_VPN_ID;
9485       else if (unformat (i, "oui %d", &oui))
9486         vss_type = VSS_TYPE_VPN_ID;
9487       else if (unformat (i, "ipv6"))
9488         is_ipv6 = 1;
9489       else if (unformat (i, "del"))
9490         is_add = 0;
9491       else
9492         break;
9493     }
9494
9495   if (tbl_id == ~0)
9496     {
9497       errmsg ("missing tbl_id ");
9498       vec_free (vpn_ascii_id);
9499       return -99;
9500     }
9501
9502   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9503     {
9504       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9505       vec_free (vpn_ascii_id);
9506       return -99;
9507     }
9508
9509   M (DHCP_PROXY_SET_VSS, mp);
9510   mp->tbl_id = ntohl (tbl_id);
9511   mp->vss_type = vss_type;
9512   if (vpn_ascii_id)
9513     {
9514       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9515       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9516     }
9517   mp->vpn_index = ntohl (fib_id);
9518   mp->oui = ntohl (oui);
9519   mp->is_ipv6 = is_ipv6;
9520   mp->is_add = is_add;
9521
9522   S (mp);
9523   W (ret);
9524
9525   vec_free (vpn_ascii_id);
9526   return ret;
9527 }
9528
9529 static int
9530 api_dhcp_client_config (vat_main_t * vam)
9531 {
9532   unformat_input_t *i = vam->input;
9533   vl_api_dhcp_client_config_t *mp;
9534   u32 sw_if_index;
9535   u8 sw_if_index_set = 0;
9536   u8 is_add = 1;
9537   u8 *hostname = 0;
9538   u8 disable_event = 0;
9539   int ret;
9540
9541   /* Parse args required to build the message */
9542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9543     {
9544       if (unformat (i, "del"))
9545         is_add = 0;
9546       else
9547         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9548         sw_if_index_set = 1;
9549       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9550         sw_if_index_set = 1;
9551       else if (unformat (i, "hostname %s", &hostname))
9552         ;
9553       else if (unformat (i, "disable_event"))
9554         disable_event = 1;
9555       else
9556         break;
9557     }
9558
9559   if (sw_if_index_set == 0)
9560     {
9561       errmsg ("missing interface name or sw_if_index");
9562       return -99;
9563     }
9564
9565   if (vec_len (hostname) > 63)
9566     {
9567       errmsg ("hostname too long");
9568     }
9569   vec_add1 (hostname, 0);
9570
9571   /* Construct the API message */
9572   M (DHCP_CLIENT_CONFIG, mp);
9573
9574   mp->sw_if_index = htonl (sw_if_index);
9575   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9576   vec_free (hostname);
9577   mp->is_add = is_add;
9578   mp->want_dhcp_event = disable_event ? 0 : 1;
9579   mp->pid = htonl (getpid ());
9580
9581   /* send it... */
9582   S (mp);
9583
9584   /* Wait for a reply, return good/bad news  */
9585   W (ret);
9586   return ret;
9587 }
9588
9589 static int
9590 api_set_ip_flow_hash (vat_main_t * vam)
9591 {
9592   unformat_input_t *i = vam->input;
9593   vl_api_set_ip_flow_hash_t *mp;
9594   u32 vrf_id = 0;
9595   u8 is_ipv6 = 0;
9596   u8 vrf_id_set = 0;
9597   u8 src = 0;
9598   u8 dst = 0;
9599   u8 sport = 0;
9600   u8 dport = 0;
9601   u8 proto = 0;
9602   u8 reverse = 0;
9603   int ret;
9604
9605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9606     {
9607       if (unformat (i, "vrf %d", &vrf_id))
9608         vrf_id_set = 1;
9609       else if (unformat (i, "ipv6"))
9610         is_ipv6 = 1;
9611       else if (unformat (i, "src"))
9612         src = 1;
9613       else if (unformat (i, "dst"))
9614         dst = 1;
9615       else if (unformat (i, "sport"))
9616         sport = 1;
9617       else if (unformat (i, "dport"))
9618         dport = 1;
9619       else if (unformat (i, "proto"))
9620         proto = 1;
9621       else if (unformat (i, "reverse"))
9622         reverse = 1;
9623
9624       else
9625         {
9626           clib_warning ("parse error '%U'", format_unformat_error, i);
9627           return -99;
9628         }
9629     }
9630
9631   if (vrf_id_set == 0)
9632     {
9633       errmsg ("missing vrf id");
9634       return -99;
9635     }
9636
9637   M (SET_IP_FLOW_HASH, mp);
9638   mp->src = src;
9639   mp->dst = dst;
9640   mp->sport = sport;
9641   mp->dport = dport;
9642   mp->proto = proto;
9643   mp->reverse = reverse;
9644   mp->vrf_id = ntohl (vrf_id);
9645   mp->is_ipv6 = is_ipv6;
9646
9647   S (mp);
9648   W (ret);
9649   return ret;
9650 }
9651
9652 static int
9653 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9654 {
9655   unformat_input_t *i = vam->input;
9656   vl_api_sw_interface_ip6_enable_disable_t *mp;
9657   u32 sw_if_index;
9658   u8 sw_if_index_set = 0;
9659   u8 enable = 0;
9660   int ret;
9661
9662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9663     {
9664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9665         sw_if_index_set = 1;
9666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9667         sw_if_index_set = 1;
9668       else if (unformat (i, "enable"))
9669         enable = 1;
9670       else if (unformat (i, "disable"))
9671         enable = 0;
9672       else
9673         {
9674           clib_warning ("parse error '%U'", format_unformat_error, i);
9675           return -99;
9676         }
9677     }
9678
9679   if (sw_if_index_set == 0)
9680     {
9681       errmsg ("missing interface name or sw_if_index");
9682       return -99;
9683     }
9684
9685   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9686
9687   mp->sw_if_index = ntohl (sw_if_index);
9688   mp->enable = enable;
9689
9690   S (mp);
9691   W (ret);
9692   return ret;
9693 }
9694
9695 static int
9696 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9697 {
9698   unformat_input_t *i = vam->input;
9699   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9700   u32 sw_if_index;
9701   u8 sw_if_index_set = 0;
9702   u8 v6_address_set = 0;
9703   ip6_address_t v6address;
9704   int ret;
9705
9706   /* Parse args required to build the message */
9707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9708     {
9709       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9710         sw_if_index_set = 1;
9711       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9712         sw_if_index_set = 1;
9713       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9714         v6_address_set = 1;
9715       else
9716         break;
9717     }
9718
9719   if (sw_if_index_set == 0)
9720     {
9721       errmsg ("missing interface name or sw_if_index");
9722       return -99;
9723     }
9724   if (!v6_address_set)
9725     {
9726       errmsg ("no address set");
9727       return -99;
9728     }
9729
9730   /* Construct the API message */
9731   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9732
9733   mp->sw_if_index = ntohl (sw_if_index);
9734   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9735
9736   /* send it... */
9737   S (mp);
9738
9739   /* Wait for a reply, return good/bad news  */
9740   W (ret);
9741   return ret;
9742 }
9743
9744 static int
9745 api_ip6nd_proxy_add_del (vat_main_t * vam)
9746 {
9747   unformat_input_t *i = vam->input;
9748   vl_api_ip6nd_proxy_add_del_t *mp;
9749   u32 sw_if_index = ~0;
9750   u8 v6_address_set = 0;
9751   ip6_address_t v6address;
9752   u8 is_del = 0;
9753   int ret;
9754
9755   /* Parse args required to build the message */
9756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9757     {
9758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9759         ;
9760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9761         ;
9762       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9763         v6_address_set = 1;
9764       if (unformat (i, "del"))
9765         is_del = 1;
9766       else
9767         {
9768           clib_warning ("parse error '%U'", format_unformat_error, i);
9769           return -99;
9770         }
9771     }
9772
9773   if (sw_if_index == ~0)
9774     {
9775       errmsg ("missing interface name or sw_if_index");
9776       return -99;
9777     }
9778   if (!v6_address_set)
9779     {
9780       errmsg ("no address set");
9781       return -99;
9782     }
9783
9784   /* Construct the API message */
9785   M (IP6ND_PROXY_ADD_DEL, mp);
9786
9787   mp->is_del = is_del;
9788   mp->sw_if_index = ntohl (sw_if_index);
9789   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9790
9791   /* send it... */
9792   S (mp);
9793
9794   /* Wait for a reply, return good/bad news  */
9795   W (ret);
9796   return ret;
9797 }
9798
9799 static int
9800 api_ip6nd_proxy_dump (vat_main_t * vam)
9801 {
9802   vl_api_ip6nd_proxy_dump_t *mp;
9803   vl_api_control_ping_t *mp_ping;
9804   int ret;
9805
9806   M (IP6ND_PROXY_DUMP, mp);
9807
9808   S (mp);
9809
9810   /* Use a control ping for synchronization */
9811   MPING (CONTROL_PING, mp_ping);
9812   S (mp_ping);
9813
9814   W (ret);
9815   return ret;
9816 }
9817
9818 static void vl_api_ip6nd_proxy_details_t_handler
9819   (vl_api_ip6nd_proxy_details_t * mp)
9820 {
9821   vat_main_t *vam = &vat_main;
9822
9823   print (vam->ofp, "host %U sw_if_index %d",
9824          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9825 }
9826
9827 static void vl_api_ip6nd_proxy_details_t_handler_json
9828   (vl_api_ip6nd_proxy_details_t * mp)
9829 {
9830   vat_main_t *vam = &vat_main;
9831   struct in6_addr ip6;
9832   vat_json_node_t *node = NULL;
9833
9834   if (VAT_JSON_ARRAY != vam->json_tree.type)
9835     {
9836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9837       vat_json_init_array (&vam->json_tree);
9838     }
9839   node = vat_json_array_add (&vam->json_tree);
9840
9841   vat_json_init_object (node);
9842   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9843
9844   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9845   vat_json_object_add_ip6 (node, "host", ip6);
9846 }
9847
9848 static int
9849 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9850 {
9851   unformat_input_t *i = vam->input;
9852   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9853   u32 sw_if_index;
9854   u8 sw_if_index_set = 0;
9855   u32 address_length = 0;
9856   u8 v6_address_set = 0;
9857   ip6_address_t v6address;
9858   u8 use_default = 0;
9859   u8 no_advertise = 0;
9860   u8 off_link = 0;
9861   u8 no_autoconfig = 0;
9862   u8 no_onlink = 0;
9863   u8 is_no = 0;
9864   u32 val_lifetime = 0;
9865   u32 pref_lifetime = 0;
9866   int ret;
9867
9868   /* Parse args required to build the message */
9869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9870     {
9871       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9874         sw_if_index_set = 1;
9875       else if (unformat (i, "%U/%d",
9876                          unformat_ip6_address, &v6address, &address_length))
9877         v6_address_set = 1;
9878       else if (unformat (i, "val_life %d", &val_lifetime))
9879         ;
9880       else if (unformat (i, "pref_life %d", &pref_lifetime))
9881         ;
9882       else if (unformat (i, "def"))
9883         use_default = 1;
9884       else if (unformat (i, "noadv"))
9885         no_advertise = 1;
9886       else if (unformat (i, "offl"))
9887         off_link = 1;
9888       else if (unformat (i, "noauto"))
9889         no_autoconfig = 1;
9890       else if (unformat (i, "nolink"))
9891         no_onlink = 1;
9892       else if (unformat (i, "isno"))
9893         is_no = 1;
9894       else
9895         {
9896           clib_warning ("parse error '%U'", format_unformat_error, i);
9897           return -99;
9898         }
9899     }
9900
9901   if (sw_if_index_set == 0)
9902     {
9903       errmsg ("missing interface name or sw_if_index");
9904       return -99;
9905     }
9906   if (!v6_address_set)
9907     {
9908       errmsg ("no address set");
9909       return -99;
9910     }
9911
9912   /* Construct the API message */
9913   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9914
9915   mp->sw_if_index = ntohl (sw_if_index);
9916   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9917   mp->address_length = address_length;
9918   mp->use_default = use_default;
9919   mp->no_advertise = no_advertise;
9920   mp->off_link = off_link;
9921   mp->no_autoconfig = no_autoconfig;
9922   mp->no_onlink = no_onlink;
9923   mp->is_no = is_no;
9924   mp->val_lifetime = ntohl (val_lifetime);
9925   mp->pref_lifetime = ntohl (pref_lifetime);
9926
9927   /* send it... */
9928   S (mp);
9929
9930   /* Wait for a reply, return good/bad news  */
9931   W (ret);
9932   return ret;
9933 }
9934
9935 static int
9936 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9937 {
9938   unformat_input_t *i = vam->input;
9939   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9940   u32 sw_if_index;
9941   u8 sw_if_index_set = 0;
9942   u8 suppress = 0;
9943   u8 managed = 0;
9944   u8 other = 0;
9945   u8 ll_option = 0;
9946   u8 send_unicast = 0;
9947   u8 cease = 0;
9948   u8 is_no = 0;
9949   u8 default_router = 0;
9950   u32 max_interval = 0;
9951   u32 min_interval = 0;
9952   u32 lifetime = 0;
9953   u32 initial_count = 0;
9954   u32 initial_interval = 0;
9955   int ret;
9956
9957
9958   /* Parse args required to build the message */
9959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9960     {
9961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9962         sw_if_index_set = 1;
9963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9964         sw_if_index_set = 1;
9965       else if (unformat (i, "maxint %d", &max_interval))
9966         ;
9967       else if (unformat (i, "minint %d", &min_interval))
9968         ;
9969       else if (unformat (i, "life %d", &lifetime))
9970         ;
9971       else if (unformat (i, "count %d", &initial_count))
9972         ;
9973       else if (unformat (i, "interval %d", &initial_interval))
9974         ;
9975       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9976         suppress = 1;
9977       else if (unformat (i, "managed"))
9978         managed = 1;
9979       else if (unformat (i, "other"))
9980         other = 1;
9981       else if (unformat (i, "ll"))
9982         ll_option = 1;
9983       else if (unformat (i, "send"))
9984         send_unicast = 1;
9985       else if (unformat (i, "cease"))
9986         cease = 1;
9987       else if (unformat (i, "isno"))
9988         is_no = 1;
9989       else if (unformat (i, "def"))
9990         default_router = 1;
9991       else
9992         {
9993           clib_warning ("parse error '%U'", format_unformat_error, i);
9994           return -99;
9995         }
9996     }
9997
9998   if (sw_if_index_set == 0)
9999     {
10000       errmsg ("missing interface name or sw_if_index");
10001       return -99;
10002     }
10003
10004   /* Construct the API message */
10005   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10006
10007   mp->sw_if_index = ntohl (sw_if_index);
10008   mp->max_interval = ntohl (max_interval);
10009   mp->min_interval = ntohl (min_interval);
10010   mp->lifetime = ntohl (lifetime);
10011   mp->initial_count = ntohl (initial_count);
10012   mp->initial_interval = ntohl (initial_interval);
10013   mp->suppress = suppress;
10014   mp->managed = managed;
10015   mp->other = other;
10016   mp->ll_option = ll_option;
10017   mp->send_unicast = send_unicast;
10018   mp->cease = cease;
10019   mp->is_no = is_no;
10020   mp->default_router = default_router;
10021
10022   /* send it... */
10023   S (mp);
10024
10025   /* Wait for a reply, return good/bad news  */
10026   W (ret);
10027   return ret;
10028 }
10029
10030 static int
10031 api_set_arp_neighbor_limit (vat_main_t * vam)
10032 {
10033   unformat_input_t *i = vam->input;
10034   vl_api_set_arp_neighbor_limit_t *mp;
10035   u32 arp_nbr_limit;
10036   u8 limit_set = 0;
10037   u8 is_ipv6 = 0;
10038   int ret;
10039
10040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10041     {
10042       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10043         limit_set = 1;
10044       else if (unformat (i, "ipv6"))
10045         is_ipv6 = 1;
10046       else
10047         {
10048           clib_warning ("parse error '%U'", format_unformat_error, i);
10049           return -99;
10050         }
10051     }
10052
10053   if (limit_set == 0)
10054     {
10055       errmsg ("missing limit value");
10056       return -99;
10057     }
10058
10059   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10060
10061   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10062   mp->is_ipv6 = is_ipv6;
10063
10064   S (mp);
10065   W (ret);
10066   return ret;
10067 }
10068
10069 static int
10070 api_l2_patch_add_del (vat_main_t * vam)
10071 {
10072   unformat_input_t *i = vam->input;
10073   vl_api_l2_patch_add_del_t *mp;
10074   u32 rx_sw_if_index;
10075   u8 rx_sw_if_index_set = 0;
10076   u32 tx_sw_if_index;
10077   u8 tx_sw_if_index_set = 0;
10078   u8 is_add = 1;
10079   int ret;
10080
10081   /* Parse args required to build the message */
10082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10083     {
10084       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10085         rx_sw_if_index_set = 1;
10086       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10087         tx_sw_if_index_set = 1;
10088       else if (unformat (i, "rx"))
10089         {
10090           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10091             {
10092               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10093                             &rx_sw_if_index))
10094                 rx_sw_if_index_set = 1;
10095             }
10096           else
10097             break;
10098         }
10099       else if (unformat (i, "tx"))
10100         {
10101           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10102             {
10103               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10104                             &tx_sw_if_index))
10105                 tx_sw_if_index_set = 1;
10106             }
10107           else
10108             break;
10109         }
10110       else if (unformat (i, "del"))
10111         is_add = 0;
10112       else
10113         break;
10114     }
10115
10116   if (rx_sw_if_index_set == 0)
10117     {
10118       errmsg ("missing rx interface name or rx_sw_if_index");
10119       return -99;
10120     }
10121
10122   if (tx_sw_if_index_set == 0)
10123     {
10124       errmsg ("missing tx interface name or tx_sw_if_index");
10125       return -99;
10126     }
10127
10128   M (L2_PATCH_ADD_DEL, mp);
10129
10130   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10131   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10132   mp->is_add = is_add;
10133
10134   S (mp);
10135   W (ret);
10136   return ret;
10137 }
10138
10139 u8 is_del;
10140 u8 localsid_addr[16];
10141 u8 end_psp;
10142 u8 behavior;
10143 u32 sw_if_index;
10144 u32 vlan_index;
10145 u32 fib_table;
10146 u8 nh_addr[16];
10147
10148 static int
10149 api_sr_localsid_add_del (vat_main_t * vam)
10150 {
10151   unformat_input_t *i = vam->input;
10152   vl_api_sr_localsid_add_del_t *mp;
10153
10154   u8 is_del;
10155   ip6_address_t localsid;
10156   u8 end_psp = 0;
10157   u8 behavior = ~0;
10158   u32 sw_if_index;
10159   u32 fib_table = ~(u32) 0;
10160   ip6_address_t next_hop;
10161
10162   bool nexthop_set = 0;
10163
10164   int ret;
10165
10166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10167     {
10168       if (unformat (i, "del"))
10169         is_del = 1;
10170       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10171       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10172         nexthop_set = 1;
10173       else if (unformat (i, "behavior %u", &behavior));
10174       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10175       else if (unformat (i, "fib-table %u", &fib_table));
10176       else if (unformat (i, "end.psp %u", &behavior));
10177       else
10178         break;
10179     }
10180
10181   M (SR_LOCALSID_ADD_DEL, mp);
10182
10183   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10184   if (nexthop_set)
10185     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10186   mp->behavior = behavior;
10187   mp->sw_if_index = ntohl (sw_if_index);
10188   mp->fib_table = ntohl (fib_table);
10189   mp->end_psp = end_psp;
10190   mp->is_del = is_del;
10191
10192   S (mp);
10193   W (ret);
10194   return ret;
10195 }
10196
10197 static int
10198 api_ioam_enable (vat_main_t * vam)
10199 {
10200   unformat_input_t *input = vam->input;
10201   vl_api_ioam_enable_t *mp;
10202   u32 id = 0;
10203   int has_trace_option = 0;
10204   int has_pot_option = 0;
10205   int has_seqno_option = 0;
10206   int has_analyse_option = 0;
10207   int ret;
10208
10209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10210     {
10211       if (unformat (input, "trace"))
10212         has_trace_option = 1;
10213       else if (unformat (input, "pot"))
10214         has_pot_option = 1;
10215       else if (unformat (input, "seqno"))
10216         has_seqno_option = 1;
10217       else if (unformat (input, "analyse"))
10218         has_analyse_option = 1;
10219       else
10220         break;
10221     }
10222   M (IOAM_ENABLE, mp);
10223   mp->id = htons (id);
10224   mp->seqno = has_seqno_option;
10225   mp->analyse = has_analyse_option;
10226   mp->pot_enable = has_pot_option;
10227   mp->trace_enable = has_trace_option;
10228
10229   S (mp);
10230   W (ret);
10231   return ret;
10232 }
10233
10234
10235 static int
10236 api_ioam_disable (vat_main_t * vam)
10237 {
10238   vl_api_ioam_disable_t *mp;
10239   int ret;
10240
10241   M (IOAM_DISABLE, mp);
10242   S (mp);
10243   W (ret);
10244   return ret;
10245 }
10246
10247 #define foreach_tcp_proto_field                 \
10248 _(src_port)                                     \
10249 _(dst_port)
10250
10251 #define foreach_udp_proto_field                 \
10252 _(src_port)                                     \
10253 _(dst_port)
10254
10255 #define foreach_ip4_proto_field                 \
10256 _(src_address)                                  \
10257 _(dst_address)                                  \
10258 _(tos)                                          \
10259 _(length)                                       \
10260 _(fragment_id)                                  \
10261 _(ttl)                                          \
10262 _(protocol)                                     \
10263 _(checksum)
10264
10265 typedef struct
10266 {
10267   u16 src_port, dst_port;
10268 } tcpudp_header_t;
10269
10270 #if VPP_API_TEST_BUILTIN == 0
10271 uword
10272 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10273 {
10274   u8 **maskp = va_arg (*args, u8 **);
10275   u8 *mask = 0;
10276   u8 found_something = 0;
10277   tcp_header_t *tcp;
10278
10279 #define _(a) u8 a=0;
10280   foreach_tcp_proto_field;
10281 #undef _
10282
10283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10284     {
10285       if (0);
10286 #define _(a) else if (unformat (input, #a)) a=1;
10287       foreach_tcp_proto_field
10288 #undef _
10289         else
10290         break;
10291     }
10292
10293 #define _(a) found_something += a;
10294   foreach_tcp_proto_field;
10295 #undef _
10296
10297   if (found_something == 0)
10298     return 0;
10299
10300   vec_validate (mask, sizeof (*tcp) - 1);
10301
10302   tcp = (tcp_header_t *) mask;
10303
10304 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10305   foreach_tcp_proto_field;
10306 #undef _
10307
10308   *maskp = mask;
10309   return 1;
10310 }
10311
10312 uword
10313 unformat_udp_mask (unformat_input_t * input, va_list * args)
10314 {
10315   u8 **maskp = va_arg (*args, u8 **);
10316   u8 *mask = 0;
10317   u8 found_something = 0;
10318   udp_header_t *udp;
10319
10320 #define _(a) u8 a=0;
10321   foreach_udp_proto_field;
10322 #undef _
10323
10324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10325     {
10326       if (0);
10327 #define _(a) else if (unformat (input, #a)) a=1;
10328       foreach_udp_proto_field
10329 #undef _
10330         else
10331         break;
10332     }
10333
10334 #define _(a) found_something += a;
10335   foreach_udp_proto_field;
10336 #undef _
10337
10338   if (found_something == 0)
10339     return 0;
10340
10341   vec_validate (mask, sizeof (*udp) - 1);
10342
10343   udp = (udp_header_t *) mask;
10344
10345 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10346   foreach_udp_proto_field;
10347 #undef _
10348
10349   *maskp = mask;
10350   return 1;
10351 }
10352
10353 uword
10354 unformat_l4_mask (unformat_input_t * input, va_list * args)
10355 {
10356   u8 **maskp = va_arg (*args, u8 **);
10357   u16 src_port = 0, dst_port = 0;
10358   tcpudp_header_t *tcpudp;
10359
10360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10361     {
10362       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10363         return 1;
10364       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10365         return 1;
10366       else if (unformat (input, "src_port"))
10367         src_port = 0xFFFF;
10368       else if (unformat (input, "dst_port"))
10369         dst_port = 0xFFFF;
10370       else
10371         return 0;
10372     }
10373
10374   if (!src_port && !dst_port)
10375     return 0;
10376
10377   u8 *mask = 0;
10378   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10379
10380   tcpudp = (tcpudp_header_t *) mask;
10381   tcpudp->src_port = src_port;
10382   tcpudp->dst_port = dst_port;
10383
10384   *maskp = mask;
10385
10386   return 1;
10387 }
10388
10389 uword
10390 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10391 {
10392   u8 **maskp = va_arg (*args, u8 **);
10393   u8 *mask = 0;
10394   u8 found_something = 0;
10395   ip4_header_t *ip;
10396
10397 #define _(a) u8 a=0;
10398   foreach_ip4_proto_field;
10399 #undef _
10400   u8 version = 0;
10401   u8 hdr_length = 0;
10402
10403
10404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10405     {
10406       if (unformat (input, "version"))
10407         version = 1;
10408       else if (unformat (input, "hdr_length"))
10409         hdr_length = 1;
10410       else if (unformat (input, "src"))
10411         src_address = 1;
10412       else if (unformat (input, "dst"))
10413         dst_address = 1;
10414       else if (unformat (input, "proto"))
10415         protocol = 1;
10416
10417 #define _(a) else if (unformat (input, #a)) a=1;
10418       foreach_ip4_proto_field
10419 #undef _
10420         else
10421         break;
10422     }
10423
10424 #define _(a) found_something += a;
10425   foreach_ip4_proto_field;
10426 #undef _
10427
10428   if (found_something == 0)
10429     return 0;
10430
10431   vec_validate (mask, sizeof (*ip) - 1);
10432
10433   ip = (ip4_header_t *) mask;
10434
10435 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10436   foreach_ip4_proto_field;
10437 #undef _
10438
10439   ip->ip_version_and_header_length = 0;
10440
10441   if (version)
10442     ip->ip_version_and_header_length |= 0xF0;
10443
10444   if (hdr_length)
10445     ip->ip_version_and_header_length |= 0x0F;
10446
10447   *maskp = mask;
10448   return 1;
10449 }
10450
10451 #define foreach_ip6_proto_field                 \
10452 _(src_address)                                  \
10453 _(dst_address)                                  \
10454 _(payload_length)                               \
10455 _(hop_limit)                                    \
10456 _(protocol)
10457
10458 uword
10459 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10460 {
10461   u8 **maskp = va_arg (*args, u8 **);
10462   u8 *mask = 0;
10463   u8 found_something = 0;
10464   ip6_header_t *ip;
10465   u32 ip_version_traffic_class_and_flow_label;
10466
10467 #define _(a) u8 a=0;
10468   foreach_ip6_proto_field;
10469 #undef _
10470   u8 version = 0;
10471   u8 traffic_class = 0;
10472   u8 flow_label = 0;
10473
10474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10475     {
10476       if (unformat (input, "version"))
10477         version = 1;
10478       else if (unformat (input, "traffic-class"))
10479         traffic_class = 1;
10480       else if (unformat (input, "flow-label"))
10481         flow_label = 1;
10482       else if (unformat (input, "src"))
10483         src_address = 1;
10484       else if (unformat (input, "dst"))
10485         dst_address = 1;
10486       else if (unformat (input, "proto"))
10487         protocol = 1;
10488
10489 #define _(a) else if (unformat (input, #a)) a=1;
10490       foreach_ip6_proto_field
10491 #undef _
10492         else
10493         break;
10494     }
10495
10496 #define _(a) found_something += a;
10497   foreach_ip6_proto_field;
10498 #undef _
10499
10500   if (found_something == 0)
10501     return 0;
10502
10503   vec_validate (mask, sizeof (*ip) - 1);
10504
10505   ip = (ip6_header_t *) mask;
10506
10507 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10508   foreach_ip6_proto_field;
10509 #undef _
10510
10511   ip_version_traffic_class_and_flow_label = 0;
10512
10513   if (version)
10514     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10515
10516   if (traffic_class)
10517     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10518
10519   if (flow_label)
10520     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10521
10522   ip->ip_version_traffic_class_and_flow_label =
10523     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10524
10525   *maskp = mask;
10526   return 1;
10527 }
10528
10529 uword
10530 unformat_l3_mask (unformat_input_t * input, va_list * args)
10531 {
10532   u8 **maskp = va_arg (*args, u8 **);
10533
10534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10535     {
10536       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10537         return 1;
10538       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10539         return 1;
10540       else
10541         break;
10542     }
10543   return 0;
10544 }
10545
10546 uword
10547 unformat_l2_mask (unformat_input_t * input, va_list * args)
10548 {
10549   u8 **maskp = va_arg (*args, u8 **);
10550   u8 *mask = 0;
10551   u8 src = 0;
10552   u8 dst = 0;
10553   u8 proto = 0;
10554   u8 tag1 = 0;
10555   u8 tag2 = 0;
10556   u8 ignore_tag1 = 0;
10557   u8 ignore_tag2 = 0;
10558   u8 cos1 = 0;
10559   u8 cos2 = 0;
10560   u8 dot1q = 0;
10561   u8 dot1ad = 0;
10562   int len = 14;
10563
10564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10565     {
10566       if (unformat (input, "src"))
10567         src = 1;
10568       else if (unformat (input, "dst"))
10569         dst = 1;
10570       else if (unformat (input, "proto"))
10571         proto = 1;
10572       else if (unformat (input, "tag1"))
10573         tag1 = 1;
10574       else if (unformat (input, "tag2"))
10575         tag2 = 1;
10576       else if (unformat (input, "ignore-tag1"))
10577         ignore_tag1 = 1;
10578       else if (unformat (input, "ignore-tag2"))
10579         ignore_tag2 = 1;
10580       else if (unformat (input, "cos1"))
10581         cos1 = 1;
10582       else if (unformat (input, "cos2"))
10583         cos2 = 1;
10584       else if (unformat (input, "dot1q"))
10585         dot1q = 1;
10586       else if (unformat (input, "dot1ad"))
10587         dot1ad = 1;
10588       else
10589         break;
10590     }
10591   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10592        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10593     return 0;
10594
10595   if (tag1 || ignore_tag1 || cos1 || dot1q)
10596     len = 18;
10597   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10598     len = 22;
10599
10600   vec_validate (mask, len - 1);
10601
10602   if (dst)
10603     memset (mask, 0xff, 6);
10604
10605   if (src)
10606     memset (mask + 6, 0xff, 6);
10607
10608   if (tag2 || dot1ad)
10609     {
10610       /* inner vlan tag */
10611       if (tag2)
10612         {
10613           mask[19] = 0xff;
10614           mask[18] = 0x0f;
10615         }
10616       if (cos2)
10617         mask[18] |= 0xe0;
10618       if (proto)
10619         mask[21] = mask[20] = 0xff;
10620       if (tag1)
10621         {
10622           mask[15] = 0xff;
10623           mask[14] = 0x0f;
10624         }
10625       if (cos1)
10626         mask[14] |= 0xe0;
10627       *maskp = mask;
10628       return 1;
10629     }
10630   if (tag1 | dot1q)
10631     {
10632       if (tag1)
10633         {
10634           mask[15] = 0xff;
10635           mask[14] = 0x0f;
10636         }
10637       if (cos1)
10638         mask[14] |= 0xe0;
10639       if (proto)
10640         mask[16] = mask[17] = 0xff;
10641
10642       *maskp = mask;
10643       return 1;
10644     }
10645   if (cos2)
10646     mask[18] |= 0xe0;
10647   if (cos1)
10648     mask[14] |= 0xe0;
10649   if (proto)
10650     mask[12] = mask[13] = 0xff;
10651
10652   *maskp = mask;
10653   return 1;
10654 }
10655
10656 uword
10657 unformat_classify_mask (unformat_input_t * input, va_list * args)
10658 {
10659   u8 **maskp = va_arg (*args, u8 **);
10660   u32 *skipp = va_arg (*args, u32 *);
10661   u32 *matchp = va_arg (*args, u32 *);
10662   u32 match;
10663   u8 *mask = 0;
10664   u8 *l2 = 0;
10665   u8 *l3 = 0;
10666   u8 *l4 = 0;
10667   int i;
10668
10669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10670     {
10671       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10672         ;
10673       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10674         ;
10675       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10676         ;
10677       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10678         ;
10679       else
10680         break;
10681     }
10682
10683   if (l4 && !l3)
10684     {
10685       vec_free (mask);
10686       vec_free (l2);
10687       vec_free (l4);
10688       return 0;
10689     }
10690
10691   if (mask || l2 || l3 || l4)
10692     {
10693       if (l2 || l3 || l4)
10694         {
10695           /* "With a free Ethernet header in every package" */
10696           if (l2 == 0)
10697             vec_validate (l2, 13);
10698           mask = l2;
10699           if (vec_len (l3))
10700             {
10701               vec_append (mask, l3);
10702               vec_free (l3);
10703             }
10704           if (vec_len (l4))
10705             {
10706               vec_append (mask, l4);
10707               vec_free (l4);
10708             }
10709         }
10710
10711       /* Scan forward looking for the first significant mask octet */
10712       for (i = 0; i < vec_len (mask); i++)
10713         if (mask[i])
10714           break;
10715
10716       /* compute (skip, match) params */
10717       *skipp = i / sizeof (u32x4);
10718       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10719
10720       /* Pad mask to an even multiple of the vector size */
10721       while (vec_len (mask) % sizeof (u32x4))
10722         vec_add1 (mask, 0);
10723
10724       match = vec_len (mask) / sizeof (u32x4);
10725
10726       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10727         {
10728           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10729           if (*tmp || *(tmp + 1))
10730             break;
10731           match--;
10732         }
10733       if (match == 0)
10734         clib_warning ("BUG: match 0");
10735
10736       _vec_len (mask) = match * sizeof (u32x4);
10737
10738       *matchp = match;
10739       *maskp = mask;
10740
10741       return 1;
10742     }
10743
10744   return 0;
10745 }
10746 #endif /* VPP_API_TEST_BUILTIN */
10747
10748 #define foreach_l2_next                         \
10749 _(drop, DROP)                                   \
10750 _(ethernet, ETHERNET_INPUT)                     \
10751 _(ip4, IP4_INPUT)                               \
10752 _(ip6, IP6_INPUT)
10753
10754 uword
10755 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10756 {
10757   u32 *miss_next_indexp = va_arg (*args, u32 *);
10758   u32 next_index = 0;
10759   u32 tmp;
10760
10761 #define _(n,N) \
10762   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10763   foreach_l2_next;
10764 #undef _
10765
10766   if (unformat (input, "%d", &tmp))
10767     {
10768       next_index = tmp;
10769       goto out;
10770     }
10771
10772   return 0;
10773
10774 out:
10775   *miss_next_indexp = next_index;
10776   return 1;
10777 }
10778
10779 #define foreach_ip_next                         \
10780 _(drop, DROP)                                   \
10781 _(local, LOCAL)                                 \
10782 _(rewrite, REWRITE)
10783
10784 uword
10785 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10786 {
10787   u32 *miss_next_indexp = va_arg (*args, u32 *);
10788   u32 next_index = 0;
10789   u32 tmp;
10790
10791 #define _(n,N) \
10792   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10793   foreach_ip_next;
10794 #undef _
10795
10796   if (unformat (input, "%d", &tmp))
10797     {
10798       next_index = tmp;
10799       goto out;
10800     }
10801
10802   return 0;
10803
10804 out:
10805   *miss_next_indexp = next_index;
10806   return 1;
10807 }
10808
10809 #define foreach_acl_next                        \
10810 _(deny, DENY)
10811
10812 uword
10813 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10814 {
10815   u32 *miss_next_indexp = va_arg (*args, u32 *);
10816   u32 next_index = 0;
10817   u32 tmp;
10818
10819 #define _(n,N) \
10820   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10821   foreach_acl_next;
10822 #undef _
10823
10824   if (unformat (input, "permit"))
10825     {
10826       next_index = ~0;
10827       goto out;
10828     }
10829   else if (unformat (input, "%d", &tmp))
10830     {
10831       next_index = tmp;
10832       goto out;
10833     }
10834
10835   return 0;
10836
10837 out:
10838   *miss_next_indexp = next_index;
10839   return 1;
10840 }
10841
10842 uword
10843 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10844 {
10845   u32 *r = va_arg (*args, u32 *);
10846
10847   if (unformat (input, "conform-color"))
10848     *r = POLICE_CONFORM;
10849   else if (unformat (input, "exceed-color"))
10850     *r = POLICE_EXCEED;
10851   else
10852     return 0;
10853
10854   return 1;
10855 }
10856
10857 static int
10858 api_classify_add_del_table (vat_main_t * vam)
10859 {
10860   unformat_input_t *i = vam->input;
10861   vl_api_classify_add_del_table_t *mp;
10862
10863   u32 nbuckets = 2;
10864   u32 skip = ~0;
10865   u32 match = ~0;
10866   int is_add = 1;
10867   int del_chain = 0;
10868   u32 table_index = ~0;
10869   u32 next_table_index = ~0;
10870   u32 miss_next_index = ~0;
10871   u32 memory_size = 32 << 20;
10872   u8 *mask = 0;
10873   u32 current_data_flag = 0;
10874   int current_data_offset = 0;
10875   int ret;
10876
10877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10878     {
10879       if (unformat (i, "del"))
10880         is_add = 0;
10881       else if (unformat (i, "del-chain"))
10882         {
10883           is_add = 0;
10884           del_chain = 1;
10885         }
10886       else if (unformat (i, "buckets %d", &nbuckets))
10887         ;
10888       else if (unformat (i, "memory_size %d", &memory_size))
10889         ;
10890       else if (unformat (i, "skip %d", &skip))
10891         ;
10892       else if (unformat (i, "match %d", &match))
10893         ;
10894       else if (unformat (i, "table %d", &table_index))
10895         ;
10896       else if (unformat (i, "mask %U", unformat_classify_mask,
10897                          &mask, &skip, &match))
10898         ;
10899       else if (unformat (i, "next-table %d", &next_table_index))
10900         ;
10901       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10902                          &miss_next_index))
10903         ;
10904       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10905                          &miss_next_index))
10906         ;
10907       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10908                          &miss_next_index))
10909         ;
10910       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10911         ;
10912       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10913         ;
10914       else
10915         break;
10916     }
10917
10918   if (is_add && mask == 0)
10919     {
10920       errmsg ("Mask required");
10921       return -99;
10922     }
10923
10924   if (is_add && skip == ~0)
10925     {
10926       errmsg ("skip count required");
10927       return -99;
10928     }
10929
10930   if (is_add && match == ~0)
10931     {
10932       errmsg ("match count required");
10933       return -99;
10934     }
10935
10936   if (!is_add && table_index == ~0)
10937     {
10938       errmsg ("table index required for delete");
10939       return -99;
10940     }
10941
10942   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10943
10944   mp->is_add = is_add;
10945   mp->del_chain = del_chain;
10946   mp->table_index = ntohl (table_index);
10947   mp->nbuckets = ntohl (nbuckets);
10948   mp->memory_size = ntohl (memory_size);
10949   mp->skip_n_vectors = ntohl (skip);
10950   mp->match_n_vectors = ntohl (match);
10951   mp->next_table_index = ntohl (next_table_index);
10952   mp->miss_next_index = ntohl (miss_next_index);
10953   mp->current_data_flag = ntohl (current_data_flag);
10954   mp->current_data_offset = ntohl (current_data_offset);
10955   clib_memcpy (mp->mask, mask, vec_len (mask));
10956
10957   vec_free (mask);
10958
10959   S (mp);
10960   W (ret);
10961   return ret;
10962 }
10963
10964 #if VPP_API_TEST_BUILTIN == 0
10965 uword
10966 unformat_l4_match (unformat_input_t * input, va_list * args)
10967 {
10968   u8 **matchp = va_arg (*args, u8 **);
10969
10970   u8 *proto_header = 0;
10971   int src_port = 0;
10972   int dst_port = 0;
10973
10974   tcpudp_header_t h;
10975
10976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10977     {
10978       if (unformat (input, "src_port %d", &src_port))
10979         ;
10980       else if (unformat (input, "dst_port %d", &dst_port))
10981         ;
10982       else
10983         return 0;
10984     }
10985
10986   h.src_port = clib_host_to_net_u16 (src_port);
10987   h.dst_port = clib_host_to_net_u16 (dst_port);
10988   vec_validate (proto_header, sizeof (h) - 1);
10989   memcpy (proto_header, &h, sizeof (h));
10990
10991   *matchp = proto_header;
10992
10993   return 1;
10994 }
10995
10996 uword
10997 unformat_ip4_match (unformat_input_t * input, va_list * args)
10998 {
10999   u8 **matchp = va_arg (*args, u8 **);
11000   u8 *match = 0;
11001   ip4_header_t *ip;
11002   int version = 0;
11003   u32 version_val;
11004   int hdr_length = 0;
11005   u32 hdr_length_val;
11006   int src = 0, dst = 0;
11007   ip4_address_t src_val, dst_val;
11008   int proto = 0;
11009   u32 proto_val;
11010   int tos = 0;
11011   u32 tos_val;
11012   int length = 0;
11013   u32 length_val;
11014   int fragment_id = 0;
11015   u32 fragment_id_val;
11016   int ttl = 0;
11017   int ttl_val;
11018   int checksum = 0;
11019   u32 checksum_val;
11020
11021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11022     {
11023       if (unformat (input, "version %d", &version_val))
11024         version = 1;
11025       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11026         hdr_length = 1;
11027       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11028         src = 1;
11029       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11030         dst = 1;
11031       else if (unformat (input, "proto %d", &proto_val))
11032         proto = 1;
11033       else if (unformat (input, "tos %d", &tos_val))
11034         tos = 1;
11035       else if (unformat (input, "length %d", &length_val))
11036         length = 1;
11037       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11038         fragment_id = 1;
11039       else if (unformat (input, "ttl %d", &ttl_val))
11040         ttl = 1;
11041       else if (unformat (input, "checksum %d", &checksum_val))
11042         checksum = 1;
11043       else
11044         break;
11045     }
11046
11047   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11048       + ttl + checksum == 0)
11049     return 0;
11050
11051   /*
11052    * Aligned because we use the real comparison functions
11053    */
11054   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11055
11056   ip = (ip4_header_t *) match;
11057
11058   /* These are realistically matched in practice */
11059   if (src)
11060     ip->src_address.as_u32 = src_val.as_u32;
11061
11062   if (dst)
11063     ip->dst_address.as_u32 = dst_val.as_u32;
11064
11065   if (proto)
11066     ip->protocol = proto_val;
11067
11068
11069   /* These are not, but they're included for completeness */
11070   if (version)
11071     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11072
11073   if (hdr_length)
11074     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11075
11076   if (tos)
11077     ip->tos = tos_val;
11078
11079   if (length)
11080     ip->length = clib_host_to_net_u16 (length_val);
11081
11082   if (ttl)
11083     ip->ttl = ttl_val;
11084
11085   if (checksum)
11086     ip->checksum = clib_host_to_net_u16 (checksum_val);
11087
11088   *matchp = match;
11089   return 1;
11090 }
11091
11092 uword
11093 unformat_ip6_match (unformat_input_t * input, va_list * args)
11094 {
11095   u8 **matchp = va_arg (*args, u8 **);
11096   u8 *match = 0;
11097   ip6_header_t *ip;
11098   int version = 0;
11099   u32 version_val;
11100   u8 traffic_class = 0;
11101   u32 traffic_class_val = 0;
11102   u8 flow_label = 0;
11103   u8 flow_label_val;
11104   int src = 0, dst = 0;
11105   ip6_address_t src_val, dst_val;
11106   int proto = 0;
11107   u32 proto_val;
11108   int payload_length = 0;
11109   u32 payload_length_val;
11110   int hop_limit = 0;
11111   int hop_limit_val;
11112   u32 ip_version_traffic_class_and_flow_label;
11113
11114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11115     {
11116       if (unformat (input, "version %d", &version_val))
11117         version = 1;
11118       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11119         traffic_class = 1;
11120       else if (unformat (input, "flow_label %d", &flow_label_val))
11121         flow_label = 1;
11122       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11123         src = 1;
11124       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11125         dst = 1;
11126       else if (unformat (input, "proto %d", &proto_val))
11127         proto = 1;
11128       else if (unformat (input, "payload_length %d", &payload_length_val))
11129         payload_length = 1;
11130       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11131         hop_limit = 1;
11132       else
11133         break;
11134     }
11135
11136   if (version + traffic_class + flow_label + src + dst + proto +
11137       payload_length + hop_limit == 0)
11138     return 0;
11139
11140   /*
11141    * Aligned because we use the real comparison functions
11142    */
11143   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11144
11145   ip = (ip6_header_t *) match;
11146
11147   if (src)
11148     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11149
11150   if (dst)
11151     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11152
11153   if (proto)
11154     ip->protocol = proto_val;
11155
11156   ip_version_traffic_class_and_flow_label = 0;
11157
11158   if (version)
11159     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11160
11161   if (traffic_class)
11162     ip_version_traffic_class_and_flow_label |=
11163       (traffic_class_val & 0xFF) << 20;
11164
11165   if (flow_label)
11166     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11167
11168   ip->ip_version_traffic_class_and_flow_label =
11169     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11170
11171   if (payload_length)
11172     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11173
11174   if (hop_limit)
11175     ip->hop_limit = hop_limit_val;
11176
11177   *matchp = match;
11178   return 1;
11179 }
11180
11181 uword
11182 unformat_l3_match (unformat_input_t * input, va_list * args)
11183 {
11184   u8 **matchp = va_arg (*args, u8 **);
11185
11186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11187     {
11188       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11189         return 1;
11190       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11191         return 1;
11192       else
11193         break;
11194     }
11195   return 0;
11196 }
11197
11198 uword
11199 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11200 {
11201   u8 *tagp = va_arg (*args, u8 *);
11202   u32 tag;
11203
11204   if (unformat (input, "%d", &tag))
11205     {
11206       tagp[0] = (tag >> 8) & 0x0F;
11207       tagp[1] = tag & 0xFF;
11208       return 1;
11209     }
11210
11211   return 0;
11212 }
11213
11214 uword
11215 unformat_l2_match (unformat_input_t * input, va_list * args)
11216 {
11217   u8 **matchp = va_arg (*args, u8 **);
11218   u8 *match = 0;
11219   u8 src = 0;
11220   u8 src_val[6];
11221   u8 dst = 0;
11222   u8 dst_val[6];
11223   u8 proto = 0;
11224   u16 proto_val;
11225   u8 tag1 = 0;
11226   u8 tag1_val[2];
11227   u8 tag2 = 0;
11228   u8 tag2_val[2];
11229   int len = 14;
11230   u8 ignore_tag1 = 0;
11231   u8 ignore_tag2 = 0;
11232   u8 cos1 = 0;
11233   u8 cos2 = 0;
11234   u32 cos1_val = 0;
11235   u32 cos2_val = 0;
11236
11237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11238     {
11239       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11240         src = 1;
11241       else
11242         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11243         dst = 1;
11244       else if (unformat (input, "proto %U",
11245                          unformat_ethernet_type_host_byte_order, &proto_val))
11246         proto = 1;
11247       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11248         tag1 = 1;
11249       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11250         tag2 = 1;
11251       else if (unformat (input, "ignore-tag1"))
11252         ignore_tag1 = 1;
11253       else if (unformat (input, "ignore-tag2"))
11254         ignore_tag2 = 1;
11255       else if (unformat (input, "cos1 %d", &cos1_val))
11256         cos1 = 1;
11257       else if (unformat (input, "cos2 %d", &cos2_val))
11258         cos2 = 1;
11259       else
11260         break;
11261     }
11262   if ((src + dst + proto + tag1 + tag2 +
11263        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11264     return 0;
11265
11266   if (tag1 || ignore_tag1 || cos1)
11267     len = 18;
11268   if (tag2 || ignore_tag2 || cos2)
11269     len = 22;
11270
11271   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11272
11273   if (dst)
11274     clib_memcpy (match, dst_val, 6);
11275
11276   if (src)
11277     clib_memcpy (match + 6, src_val, 6);
11278
11279   if (tag2)
11280     {
11281       /* inner vlan tag */
11282       match[19] = tag2_val[1];
11283       match[18] = tag2_val[0];
11284       if (cos2)
11285         match[18] |= (cos2_val & 0x7) << 5;
11286       if (proto)
11287         {
11288           match[21] = proto_val & 0xff;
11289           match[20] = proto_val >> 8;
11290         }
11291       if (tag1)
11292         {
11293           match[15] = tag1_val[1];
11294           match[14] = tag1_val[0];
11295         }
11296       if (cos1)
11297         match[14] |= (cos1_val & 0x7) << 5;
11298       *matchp = match;
11299       return 1;
11300     }
11301   if (tag1)
11302     {
11303       match[15] = tag1_val[1];
11304       match[14] = tag1_val[0];
11305       if (proto)
11306         {
11307           match[17] = proto_val & 0xff;
11308           match[16] = proto_val >> 8;
11309         }
11310       if (cos1)
11311         match[14] |= (cos1_val & 0x7) << 5;
11312
11313       *matchp = match;
11314       return 1;
11315     }
11316   if (cos2)
11317     match[18] |= (cos2_val & 0x7) << 5;
11318   if (cos1)
11319     match[14] |= (cos1_val & 0x7) << 5;
11320   if (proto)
11321     {
11322       match[13] = proto_val & 0xff;
11323       match[12] = proto_val >> 8;
11324     }
11325
11326   *matchp = match;
11327   return 1;
11328 }
11329 #endif
11330
11331 uword
11332 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11333 {
11334   u8 **matchp = va_arg (*args, u8 **);
11335   u32 skip_n_vectors = va_arg (*args, u32);
11336   u32 match_n_vectors = va_arg (*args, u32);
11337
11338   u8 *match = 0;
11339   u8 *l2 = 0;
11340   u8 *l3 = 0;
11341   u8 *l4 = 0;
11342
11343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11344     {
11345       if (unformat (input, "hex %U", unformat_hex_string, &match))
11346         ;
11347       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11348         ;
11349       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11350         ;
11351       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11352         ;
11353       else
11354         break;
11355     }
11356
11357   if (l4 && !l3)
11358     {
11359       vec_free (match);
11360       vec_free (l2);
11361       vec_free (l4);
11362       return 0;
11363     }
11364
11365   if (match || l2 || l3 || l4)
11366     {
11367       if (l2 || l3 || l4)
11368         {
11369           /* "Win a free Ethernet header in every packet" */
11370           if (l2 == 0)
11371             vec_validate_aligned (l2, 13, sizeof (u32x4));
11372           match = l2;
11373           if (vec_len (l3))
11374             {
11375               vec_append_aligned (match, l3, sizeof (u32x4));
11376               vec_free (l3);
11377             }
11378           if (vec_len (l4))
11379             {
11380               vec_append_aligned (match, l4, sizeof (u32x4));
11381               vec_free (l4);
11382             }
11383         }
11384
11385       /* Make sure the vector is big enough even if key is all 0's */
11386       vec_validate_aligned
11387         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11388          sizeof (u32x4));
11389
11390       /* Set size, include skipped vectors */
11391       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11392
11393       *matchp = match;
11394
11395       return 1;
11396     }
11397
11398   return 0;
11399 }
11400
11401 static int
11402 api_classify_add_del_session (vat_main_t * vam)
11403 {
11404   unformat_input_t *i = vam->input;
11405   vl_api_classify_add_del_session_t *mp;
11406   int is_add = 1;
11407   u32 table_index = ~0;
11408   u32 hit_next_index = ~0;
11409   u32 opaque_index = ~0;
11410   u8 *match = 0;
11411   i32 advance = 0;
11412   u32 skip_n_vectors = 0;
11413   u32 match_n_vectors = 0;
11414   u32 action = 0;
11415   u32 metadata = 0;
11416   int ret;
11417
11418   /*
11419    * Warning: you have to supply skip_n and match_n
11420    * because the API client cant simply look at the classify
11421    * table object.
11422    */
11423
11424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11425     {
11426       if (unformat (i, "del"))
11427         is_add = 0;
11428       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11429                          &hit_next_index))
11430         ;
11431       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11432                          &hit_next_index))
11433         ;
11434       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11435                          &hit_next_index))
11436         ;
11437       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11438         ;
11439       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11440         ;
11441       else if (unformat (i, "opaque-index %d", &opaque_index))
11442         ;
11443       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11444         ;
11445       else if (unformat (i, "match_n %d", &match_n_vectors))
11446         ;
11447       else if (unformat (i, "match %U", api_unformat_classify_match,
11448                          &match, skip_n_vectors, match_n_vectors))
11449         ;
11450       else if (unformat (i, "advance %d", &advance))
11451         ;
11452       else if (unformat (i, "table-index %d", &table_index))
11453         ;
11454       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11455         action = 1;
11456       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11457         action = 2;
11458       else if (unformat (i, "action %d", &action))
11459         ;
11460       else if (unformat (i, "metadata %d", &metadata))
11461         ;
11462       else
11463         break;
11464     }
11465
11466   if (table_index == ~0)
11467     {
11468       errmsg ("Table index required");
11469       return -99;
11470     }
11471
11472   if (is_add && match == 0)
11473     {
11474       errmsg ("Match value required");
11475       return -99;
11476     }
11477
11478   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11479
11480   mp->is_add = is_add;
11481   mp->table_index = ntohl (table_index);
11482   mp->hit_next_index = ntohl (hit_next_index);
11483   mp->opaque_index = ntohl (opaque_index);
11484   mp->advance = ntohl (advance);
11485   mp->action = action;
11486   mp->metadata = ntohl (metadata);
11487   clib_memcpy (mp->match, match, vec_len (match));
11488   vec_free (match);
11489
11490   S (mp);
11491   W (ret);
11492   return ret;
11493 }
11494
11495 static int
11496 api_classify_set_interface_ip_table (vat_main_t * vam)
11497 {
11498   unformat_input_t *i = vam->input;
11499   vl_api_classify_set_interface_ip_table_t *mp;
11500   u32 sw_if_index;
11501   int sw_if_index_set;
11502   u32 table_index = ~0;
11503   u8 is_ipv6 = 0;
11504   int ret;
11505
11506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11507     {
11508       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11509         sw_if_index_set = 1;
11510       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11511         sw_if_index_set = 1;
11512       else if (unformat (i, "table %d", &table_index))
11513         ;
11514       else
11515         {
11516           clib_warning ("parse error '%U'", format_unformat_error, i);
11517           return -99;
11518         }
11519     }
11520
11521   if (sw_if_index_set == 0)
11522     {
11523       errmsg ("missing interface name or sw_if_index");
11524       return -99;
11525     }
11526
11527
11528   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11529
11530   mp->sw_if_index = ntohl (sw_if_index);
11531   mp->table_index = ntohl (table_index);
11532   mp->is_ipv6 = is_ipv6;
11533
11534   S (mp);
11535   W (ret);
11536   return ret;
11537 }
11538
11539 static int
11540 api_classify_set_interface_l2_tables (vat_main_t * vam)
11541 {
11542   unformat_input_t *i = vam->input;
11543   vl_api_classify_set_interface_l2_tables_t *mp;
11544   u32 sw_if_index;
11545   int sw_if_index_set;
11546   u32 ip4_table_index = ~0;
11547   u32 ip6_table_index = ~0;
11548   u32 other_table_index = ~0;
11549   u32 is_input = 1;
11550   int ret;
11551
11552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11553     {
11554       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11555         sw_if_index_set = 1;
11556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11557         sw_if_index_set = 1;
11558       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11559         ;
11560       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11561         ;
11562       else if (unformat (i, "other-table %d", &other_table_index))
11563         ;
11564       else if (unformat (i, "is-input %d", &is_input))
11565         ;
11566       else
11567         {
11568           clib_warning ("parse error '%U'", format_unformat_error, i);
11569           return -99;
11570         }
11571     }
11572
11573   if (sw_if_index_set == 0)
11574     {
11575       errmsg ("missing interface name or sw_if_index");
11576       return -99;
11577     }
11578
11579
11580   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11581
11582   mp->sw_if_index = ntohl (sw_if_index);
11583   mp->ip4_table_index = ntohl (ip4_table_index);
11584   mp->ip6_table_index = ntohl (ip6_table_index);
11585   mp->other_table_index = ntohl (other_table_index);
11586   mp->is_input = (u8) is_input;
11587
11588   S (mp);
11589   W (ret);
11590   return ret;
11591 }
11592
11593 static int
11594 api_set_ipfix_exporter (vat_main_t * vam)
11595 {
11596   unformat_input_t *i = vam->input;
11597   vl_api_set_ipfix_exporter_t *mp;
11598   ip4_address_t collector_address;
11599   u8 collector_address_set = 0;
11600   u32 collector_port = ~0;
11601   ip4_address_t src_address;
11602   u8 src_address_set = 0;
11603   u32 vrf_id = ~0;
11604   u32 path_mtu = ~0;
11605   u32 template_interval = ~0;
11606   u8 udp_checksum = 0;
11607   int ret;
11608
11609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11610     {
11611       if (unformat (i, "collector_address %U", unformat_ip4_address,
11612                     &collector_address))
11613         collector_address_set = 1;
11614       else if (unformat (i, "collector_port %d", &collector_port))
11615         ;
11616       else if (unformat (i, "src_address %U", unformat_ip4_address,
11617                          &src_address))
11618         src_address_set = 1;
11619       else if (unformat (i, "vrf_id %d", &vrf_id))
11620         ;
11621       else if (unformat (i, "path_mtu %d", &path_mtu))
11622         ;
11623       else if (unformat (i, "template_interval %d", &template_interval))
11624         ;
11625       else if (unformat (i, "udp_checksum"))
11626         udp_checksum = 1;
11627       else
11628         break;
11629     }
11630
11631   if (collector_address_set == 0)
11632     {
11633       errmsg ("collector_address required");
11634       return -99;
11635     }
11636
11637   if (src_address_set == 0)
11638     {
11639       errmsg ("src_address required");
11640       return -99;
11641     }
11642
11643   M (SET_IPFIX_EXPORTER, mp);
11644
11645   memcpy (mp->collector_address, collector_address.data,
11646           sizeof (collector_address.data));
11647   mp->collector_port = htons ((u16) collector_port);
11648   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11649   mp->vrf_id = htonl (vrf_id);
11650   mp->path_mtu = htonl (path_mtu);
11651   mp->template_interval = htonl (template_interval);
11652   mp->udp_checksum = udp_checksum;
11653
11654   S (mp);
11655   W (ret);
11656   return ret;
11657 }
11658
11659 static int
11660 api_set_ipfix_classify_stream (vat_main_t * vam)
11661 {
11662   unformat_input_t *i = vam->input;
11663   vl_api_set_ipfix_classify_stream_t *mp;
11664   u32 domain_id = 0;
11665   u32 src_port = UDP_DST_PORT_ipfix;
11666   int ret;
11667
11668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11669     {
11670       if (unformat (i, "domain %d", &domain_id))
11671         ;
11672       else if (unformat (i, "src_port %d", &src_port))
11673         ;
11674       else
11675         {
11676           errmsg ("unknown input `%U'", format_unformat_error, i);
11677           return -99;
11678         }
11679     }
11680
11681   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11682
11683   mp->domain_id = htonl (domain_id);
11684   mp->src_port = htons ((u16) src_port);
11685
11686   S (mp);
11687   W (ret);
11688   return ret;
11689 }
11690
11691 static int
11692 api_ipfix_classify_table_add_del (vat_main_t * vam)
11693 {
11694   unformat_input_t *i = vam->input;
11695   vl_api_ipfix_classify_table_add_del_t *mp;
11696   int is_add = -1;
11697   u32 classify_table_index = ~0;
11698   u8 ip_version = 0;
11699   u8 transport_protocol = 255;
11700   int ret;
11701
11702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11703     {
11704       if (unformat (i, "add"))
11705         is_add = 1;
11706       else if (unformat (i, "del"))
11707         is_add = 0;
11708       else if (unformat (i, "table %d", &classify_table_index))
11709         ;
11710       else if (unformat (i, "ip4"))
11711         ip_version = 4;
11712       else if (unformat (i, "ip6"))
11713         ip_version = 6;
11714       else if (unformat (i, "tcp"))
11715         transport_protocol = 6;
11716       else if (unformat (i, "udp"))
11717         transport_protocol = 17;
11718       else
11719         {
11720           errmsg ("unknown input `%U'", format_unformat_error, i);
11721           return -99;
11722         }
11723     }
11724
11725   if (is_add == -1)
11726     {
11727       errmsg ("expecting: add|del");
11728       return -99;
11729     }
11730   if (classify_table_index == ~0)
11731     {
11732       errmsg ("classifier table not specified");
11733       return -99;
11734     }
11735   if (ip_version == 0)
11736     {
11737       errmsg ("IP version not specified");
11738       return -99;
11739     }
11740
11741   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11742
11743   mp->is_add = is_add;
11744   mp->table_id = htonl (classify_table_index);
11745   mp->ip_version = ip_version;
11746   mp->transport_protocol = transport_protocol;
11747
11748   S (mp);
11749   W (ret);
11750   return ret;
11751 }
11752
11753 static int
11754 api_get_node_index (vat_main_t * vam)
11755 {
11756   unformat_input_t *i = vam->input;
11757   vl_api_get_node_index_t *mp;
11758   u8 *name = 0;
11759   int ret;
11760
11761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11762     {
11763       if (unformat (i, "node %s", &name))
11764         ;
11765       else
11766         break;
11767     }
11768   if (name == 0)
11769     {
11770       errmsg ("node name required");
11771       return -99;
11772     }
11773   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11774     {
11775       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11776       return -99;
11777     }
11778
11779   M (GET_NODE_INDEX, mp);
11780   clib_memcpy (mp->node_name, name, vec_len (name));
11781   vec_free (name);
11782
11783   S (mp);
11784   W (ret);
11785   return ret;
11786 }
11787
11788 static int
11789 api_get_next_index (vat_main_t * vam)
11790 {
11791   unformat_input_t *i = vam->input;
11792   vl_api_get_next_index_t *mp;
11793   u8 *node_name = 0, *next_node_name = 0;
11794   int ret;
11795
11796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11797     {
11798       if (unformat (i, "node-name %s", &node_name))
11799         ;
11800       else if (unformat (i, "next-node-name %s", &next_node_name))
11801         break;
11802     }
11803
11804   if (node_name == 0)
11805     {
11806       errmsg ("node name required");
11807       return -99;
11808     }
11809   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11810     {
11811       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11812       return -99;
11813     }
11814
11815   if (next_node_name == 0)
11816     {
11817       errmsg ("next node name required");
11818       return -99;
11819     }
11820   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11821     {
11822       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11823       return -99;
11824     }
11825
11826   M (GET_NEXT_INDEX, mp);
11827   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11828   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11829   vec_free (node_name);
11830   vec_free (next_node_name);
11831
11832   S (mp);
11833   W (ret);
11834   return ret;
11835 }
11836
11837 static int
11838 api_add_node_next (vat_main_t * vam)
11839 {
11840   unformat_input_t *i = vam->input;
11841   vl_api_add_node_next_t *mp;
11842   u8 *name = 0;
11843   u8 *next = 0;
11844   int ret;
11845
11846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11847     {
11848       if (unformat (i, "node %s", &name))
11849         ;
11850       else if (unformat (i, "next %s", &next))
11851         ;
11852       else
11853         break;
11854     }
11855   if (name == 0)
11856     {
11857       errmsg ("node name required");
11858       return -99;
11859     }
11860   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11861     {
11862       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11863       return -99;
11864     }
11865   if (next == 0)
11866     {
11867       errmsg ("next node required");
11868       return -99;
11869     }
11870   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11871     {
11872       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11873       return -99;
11874     }
11875
11876   M (ADD_NODE_NEXT, mp);
11877   clib_memcpy (mp->node_name, name, vec_len (name));
11878   clib_memcpy (mp->next_name, next, vec_len (next));
11879   vec_free (name);
11880   vec_free (next);
11881
11882   S (mp);
11883   W (ret);
11884   return ret;
11885 }
11886
11887 static int
11888 api_l2tpv3_create_tunnel (vat_main_t * vam)
11889 {
11890   unformat_input_t *i = vam->input;
11891   ip6_address_t client_address, our_address;
11892   int client_address_set = 0;
11893   int our_address_set = 0;
11894   u32 local_session_id = 0;
11895   u32 remote_session_id = 0;
11896   u64 local_cookie = 0;
11897   u64 remote_cookie = 0;
11898   u8 l2_sublayer_present = 0;
11899   vl_api_l2tpv3_create_tunnel_t *mp;
11900   int ret;
11901
11902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11903     {
11904       if (unformat (i, "client_address %U", unformat_ip6_address,
11905                     &client_address))
11906         client_address_set = 1;
11907       else if (unformat (i, "our_address %U", unformat_ip6_address,
11908                          &our_address))
11909         our_address_set = 1;
11910       else if (unformat (i, "local_session_id %d", &local_session_id))
11911         ;
11912       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11913         ;
11914       else if (unformat (i, "local_cookie %lld", &local_cookie))
11915         ;
11916       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11917         ;
11918       else if (unformat (i, "l2-sublayer-present"))
11919         l2_sublayer_present = 1;
11920       else
11921         break;
11922     }
11923
11924   if (client_address_set == 0)
11925     {
11926       errmsg ("client_address required");
11927       return -99;
11928     }
11929
11930   if (our_address_set == 0)
11931     {
11932       errmsg ("our_address required");
11933       return -99;
11934     }
11935
11936   M (L2TPV3_CREATE_TUNNEL, mp);
11937
11938   clib_memcpy (mp->client_address, client_address.as_u8,
11939                sizeof (mp->client_address));
11940
11941   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11942
11943   mp->local_session_id = ntohl (local_session_id);
11944   mp->remote_session_id = ntohl (remote_session_id);
11945   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11946   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11947   mp->l2_sublayer_present = l2_sublayer_present;
11948   mp->is_ipv6 = 1;
11949
11950   S (mp);
11951   W (ret);
11952   return ret;
11953 }
11954
11955 static int
11956 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11957 {
11958   unformat_input_t *i = vam->input;
11959   u32 sw_if_index;
11960   u8 sw_if_index_set = 0;
11961   u64 new_local_cookie = 0;
11962   u64 new_remote_cookie = 0;
11963   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11964   int ret;
11965
11966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11967     {
11968       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11969         sw_if_index_set = 1;
11970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11971         sw_if_index_set = 1;
11972       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11973         ;
11974       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11975         ;
11976       else
11977         break;
11978     }
11979
11980   if (sw_if_index_set == 0)
11981     {
11982       errmsg ("missing interface name or sw_if_index");
11983       return -99;
11984     }
11985
11986   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11987
11988   mp->sw_if_index = ntohl (sw_if_index);
11989   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11990   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11991
11992   S (mp);
11993   W (ret);
11994   return ret;
11995 }
11996
11997 static int
11998 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11999 {
12000   unformat_input_t *i = vam->input;
12001   vl_api_l2tpv3_interface_enable_disable_t *mp;
12002   u32 sw_if_index;
12003   u8 sw_if_index_set = 0;
12004   u8 enable_disable = 1;
12005   int ret;
12006
12007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12008     {
12009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12010         sw_if_index_set = 1;
12011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12012         sw_if_index_set = 1;
12013       else if (unformat (i, "enable"))
12014         enable_disable = 1;
12015       else if (unformat (i, "disable"))
12016         enable_disable = 0;
12017       else
12018         break;
12019     }
12020
12021   if (sw_if_index_set == 0)
12022     {
12023       errmsg ("missing interface name or sw_if_index");
12024       return -99;
12025     }
12026
12027   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12028
12029   mp->sw_if_index = ntohl (sw_if_index);
12030   mp->enable_disable = enable_disable;
12031
12032   S (mp);
12033   W (ret);
12034   return ret;
12035 }
12036
12037 static int
12038 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12039 {
12040   unformat_input_t *i = vam->input;
12041   vl_api_l2tpv3_set_lookup_key_t *mp;
12042   u8 key = ~0;
12043   int ret;
12044
12045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12046     {
12047       if (unformat (i, "lookup_v6_src"))
12048         key = L2T_LOOKUP_SRC_ADDRESS;
12049       else if (unformat (i, "lookup_v6_dst"))
12050         key = L2T_LOOKUP_DST_ADDRESS;
12051       else if (unformat (i, "lookup_session_id"))
12052         key = L2T_LOOKUP_SESSION_ID;
12053       else
12054         break;
12055     }
12056
12057   if (key == (u8) ~ 0)
12058     {
12059       errmsg ("l2tp session lookup key unset");
12060       return -99;
12061     }
12062
12063   M (L2TPV3_SET_LOOKUP_KEY, mp);
12064
12065   mp->key = key;
12066
12067   S (mp);
12068   W (ret);
12069   return ret;
12070 }
12071
12072 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12073   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12074 {
12075   vat_main_t *vam = &vat_main;
12076
12077   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12078          format_ip6_address, mp->our_address,
12079          format_ip6_address, mp->client_address,
12080          clib_net_to_host_u32 (mp->sw_if_index));
12081
12082   print (vam->ofp,
12083          "   local cookies %016llx %016llx remote cookie %016llx",
12084          clib_net_to_host_u64 (mp->local_cookie[0]),
12085          clib_net_to_host_u64 (mp->local_cookie[1]),
12086          clib_net_to_host_u64 (mp->remote_cookie));
12087
12088   print (vam->ofp, "   local session-id %d remote session-id %d",
12089          clib_net_to_host_u32 (mp->local_session_id),
12090          clib_net_to_host_u32 (mp->remote_session_id));
12091
12092   print (vam->ofp, "   l2 specific sublayer %s\n",
12093          mp->l2_sublayer_present ? "preset" : "absent");
12094
12095 }
12096
12097 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12098   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12099 {
12100   vat_main_t *vam = &vat_main;
12101   vat_json_node_t *node = NULL;
12102   struct in6_addr addr;
12103
12104   if (VAT_JSON_ARRAY != vam->json_tree.type)
12105     {
12106       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12107       vat_json_init_array (&vam->json_tree);
12108     }
12109   node = vat_json_array_add (&vam->json_tree);
12110
12111   vat_json_init_object (node);
12112
12113   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12114   vat_json_object_add_ip6 (node, "our_address", addr);
12115   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12116   vat_json_object_add_ip6 (node, "client_address", addr);
12117
12118   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12119   vat_json_init_array (lc);
12120   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12121   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12122   vat_json_object_add_uint (node, "remote_cookie",
12123                             clib_net_to_host_u64 (mp->remote_cookie));
12124
12125   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12126   vat_json_object_add_uint (node, "local_session_id",
12127                             clib_net_to_host_u32 (mp->local_session_id));
12128   vat_json_object_add_uint (node, "remote_session_id",
12129                             clib_net_to_host_u32 (mp->remote_session_id));
12130   vat_json_object_add_string_copy (node, "l2_sublayer",
12131                                    mp->l2_sublayer_present ? (u8 *) "present"
12132                                    : (u8 *) "absent");
12133 }
12134
12135 static int
12136 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12137 {
12138   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12139   vl_api_control_ping_t *mp_ping;
12140   int ret;
12141
12142   /* Get list of l2tpv3-tunnel interfaces */
12143   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12144   S (mp);
12145
12146   /* Use a control ping for synchronization */
12147   MPING (CONTROL_PING, mp_ping);
12148   S (mp_ping);
12149
12150   W (ret);
12151   return ret;
12152 }
12153
12154
12155 static void vl_api_sw_interface_tap_details_t_handler
12156   (vl_api_sw_interface_tap_details_t * mp)
12157 {
12158   vat_main_t *vam = &vat_main;
12159
12160   print (vam->ofp, "%-16s %d",
12161          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12162 }
12163
12164 static void vl_api_sw_interface_tap_details_t_handler_json
12165   (vl_api_sw_interface_tap_details_t * mp)
12166 {
12167   vat_main_t *vam = &vat_main;
12168   vat_json_node_t *node = NULL;
12169
12170   if (VAT_JSON_ARRAY != vam->json_tree.type)
12171     {
12172       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12173       vat_json_init_array (&vam->json_tree);
12174     }
12175   node = vat_json_array_add (&vam->json_tree);
12176
12177   vat_json_init_object (node);
12178   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12179   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12180 }
12181
12182 static int
12183 api_sw_interface_tap_dump (vat_main_t * vam)
12184 {
12185   vl_api_sw_interface_tap_dump_t *mp;
12186   vl_api_control_ping_t *mp_ping;
12187   int ret;
12188
12189   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12190   /* Get list of tap interfaces */
12191   M (SW_INTERFACE_TAP_DUMP, mp);
12192   S (mp);
12193
12194   /* Use a control ping for synchronization */
12195   MPING (CONTROL_PING, mp_ping);
12196   S (mp_ping);
12197
12198   W (ret);
12199   return ret;
12200 }
12201
12202 static uword unformat_vxlan_decap_next
12203   (unformat_input_t * input, va_list * args)
12204 {
12205   u32 *result = va_arg (*args, u32 *);
12206   u32 tmp;
12207
12208   if (unformat (input, "l2"))
12209     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12210   else if (unformat (input, "%d", &tmp))
12211     *result = tmp;
12212   else
12213     return 0;
12214   return 1;
12215 }
12216
12217 static int
12218 api_vxlan_add_del_tunnel (vat_main_t * vam)
12219 {
12220   unformat_input_t *line_input = vam->input;
12221   vl_api_vxlan_add_del_tunnel_t *mp;
12222   ip46_address_t src, dst;
12223   u8 is_add = 1;
12224   u8 ipv4_set = 0, ipv6_set = 0;
12225   u8 src_set = 0;
12226   u8 dst_set = 0;
12227   u8 grp_set = 0;
12228   u32 mcast_sw_if_index = ~0;
12229   u32 encap_vrf_id = 0;
12230   u32 decap_next_index = ~0;
12231   u32 vni = 0;
12232   int ret;
12233
12234   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12235   memset (&src, 0, sizeof src);
12236   memset (&dst, 0, sizeof dst);
12237
12238   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12239     {
12240       if (unformat (line_input, "del"))
12241         is_add = 0;
12242       else
12243         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12244         {
12245           ipv4_set = 1;
12246           src_set = 1;
12247         }
12248       else
12249         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12250         {
12251           ipv4_set = 1;
12252           dst_set = 1;
12253         }
12254       else
12255         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12256         {
12257           ipv6_set = 1;
12258           src_set = 1;
12259         }
12260       else
12261         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12262         {
12263           ipv6_set = 1;
12264           dst_set = 1;
12265         }
12266       else if (unformat (line_input, "group %U %U",
12267                          unformat_ip4_address, &dst.ip4,
12268                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12269         {
12270           grp_set = dst_set = 1;
12271           ipv4_set = 1;
12272         }
12273       else if (unformat (line_input, "group %U",
12274                          unformat_ip4_address, &dst.ip4))
12275         {
12276           grp_set = dst_set = 1;
12277           ipv4_set = 1;
12278         }
12279       else if (unformat (line_input, "group %U %U",
12280                          unformat_ip6_address, &dst.ip6,
12281                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12282         {
12283           grp_set = dst_set = 1;
12284           ipv6_set = 1;
12285         }
12286       else if (unformat (line_input, "group %U",
12287                          unformat_ip6_address, &dst.ip6))
12288         {
12289           grp_set = dst_set = 1;
12290           ipv6_set = 1;
12291         }
12292       else
12293         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12294         ;
12295       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12296         ;
12297       else if (unformat (line_input, "decap-next %U",
12298                          unformat_vxlan_decap_next, &decap_next_index))
12299         ;
12300       else if (unformat (line_input, "vni %d", &vni))
12301         ;
12302       else
12303         {
12304           errmsg ("parse error '%U'", format_unformat_error, line_input);
12305           return -99;
12306         }
12307     }
12308
12309   if (src_set == 0)
12310     {
12311       errmsg ("tunnel src address not specified");
12312       return -99;
12313     }
12314   if (dst_set == 0)
12315     {
12316       errmsg ("tunnel dst address not specified");
12317       return -99;
12318     }
12319
12320   if (grp_set && !ip46_address_is_multicast (&dst))
12321     {
12322       errmsg ("tunnel group address not multicast");
12323       return -99;
12324     }
12325   if (grp_set && mcast_sw_if_index == ~0)
12326     {
12327       errmsg ("tunnel nonexistent multicast device");
12328       return -99;
12329     }
12330   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12331     {
12332       errmsg ("tunnel dst address must be unicast");
12333       return -99;
12334     }
12335
12336
12337   if (ipv4_set && ipv6_set)
12338     {
12339       errmsg ("both IPv4 and IPv6 addresses specified");
12340       return -99;
12341     }
12342
12343   if ((vni == 0) || (vni >> 24))
12344     {
12345       errmsg ("vni not specified or out of range");
12346       return -99;
12347     }
12348
12349   M (VXLAN_ADD_DEL_TUNNEL, mp);
12350
12351   if (ipv6_set)
12352     {
12353       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12354       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12355     }
12356   else
12357     {
12358       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12359       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12360     }
12361   mp->encap_vrf_id = ntohl (encap_vrf_id);
12362   mp->decap_next_index = ntohl (decap_next_index);
12363   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12364   mp->vni = ntohl (vni);
12365   mp->is_add = is_add;
12366   mp->is_ipv6 = ipv6_set;
12367
12368   S (mp);
12369   W (ret);
12370   return ret;
12371 }
12372
12373 static void vl_api_vxlan_tunnel_details_t_handler
12374   (vl_api_vxlan_tunnel_details_t * mp)
12375 {
12376   vat_main_t *vam = &vat_main;
12377   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12378   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12379
12380   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12381          ntohl (mp->sw_if_index),
12382          format_ip46_address, &src, IP46_TYPE_ANY,
12383          format_ip46_address, &dst, IP46_TYPE_ANY,
12384          ntohl (mp->encap_vrf_id),
12385          ntohl (mp->decap_next_index), ntohl (mp->vni),
12386          ntohl (mp->mcast_sw_if_index));
12387 }
12388
12389 static void vl_api_vxlan_tunnel_details_t_handler_json
12390   (vl_api_vxlan_tunnel_details_t * mp)
12391 {
12392   vat_main_t *vam = &vat_main;
12393   vat_json_node_t *node = NULL;
12394
12395   if (VAT_JSON_ARRAY != vam->json_tree.type)
12396     {
12397       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12398       vat_json_init_array (&vam->json_tree);
12399     }
12400   node = vat_json_array_add (&vam->json_tree);
12401
12402   vat_json_init_object (node);
12403   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12404   if (mp->is_ipv6)
12405     {
12406       struct in6_addr ip6;
12407
12408       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12409       vat_json_object_add_ip6 (node, "src_address", ip6);
12410       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12411       vat_json_object_add_ip6 (node, "dst_address", ip6);
12412     }
12413   else
12414     {
12415       struct in_addr ip4;
12416
12417       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12418       vat_json_object_add_ip4 (node, "src_address", ip4);
12419       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12420       vat_json_object_add_ip4 (node, "dst_address", ip4);
12421     }
12422   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12423   vat_json_object_add_uint (node, "decap_next_index",
12424                             ntohl (mp->decap_next_index));
12425   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12426   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12427   vat_json_object_add_uint (node, "mcast_sw_if_index",
12428                             ntohl (mp->mcast_sw_if_index));
12429 }
12430
12431 static int
12432 api_vxlan_tunnel_dump (vat_main_t * vam)
12433 {
12434   unformat_input_t *i = vam->input;
12435   vl_api_vxlan_tunnel_dump_t *mp;
12436   vl_api_control_ping_t *mp_ping;
12437   u32 sw_if_index;
12438   u8 sw_if_index_set = 0;
12439   int ret;
12440
12441   /* Parse args required to build the message */
12442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12443     {
12444       if (unformat (i, "sw_if_index %d", &sw_if_index))
12445         sw_if_index_set = 1;
12446       else
12447         break;
12448     }
12449
12450   if (sw_if_index_set == 0)
12451     {
12452       sw_if_index = ~0;
12453     }
12454
12455   if (!vam->json_output)
12456     {
12457       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12458              "sw_if_index", "src_address", "dst_address",
12459              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12460     }
12461
12462   /* Get list of vxlan-tunnel interfaces */
12463   M (VXLAN_TUNNEL_DUMP, mp);
12464
12465   mp->sw_if_index = htonl (sw_if_index);
12466
12467   S (mp);
12468
12469   /* Use a control ping for synchronization */
12470   MPING (CONTROL_PING, mp_ping);
12471   S (mp_ping);
12472
12473   W (ret);
12474   return ret;
12475 }
12476
12477 static uword unformat_geneve_decap_next
12478   (unformat_input_t * input, va_list * args)
12479 {
12480   u32 *result = va_arg (*args, u32 *);
12481   u32 tmp;
12482
12483   if (unformat (input, "l2"))
12484     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12485   else if (unformat (input, "%d", &tmp))
12486     *result = tmp;
12487   else
12488     return 0;
12489   return 1;
12490 }
12491
12492 static int
12493 api_geneve_add_del_tunnel (vat_main_t * vam)
12494 {
12495   unformat_input_t *line_input = vam->input;
12496   vl_api_geneve_add_del_tunnel_t *mp;
12497   ip46_address_t src, dst;
12498   u8 is_add = 1;
12499   u8 ipv4_set = 0, ipv6_set = 0;
12500   u8 src_set = 0;
12501   u8 dst_set = 0;
12502   u8 grp_set = 0;
12503   u32 mcast_sw_if_index = ~0;
12504   u32 encap_vrf_id = 0;
12505   u32 decap_next_index = ~0;
12506   u32 vni = 0;
12507   int ret;
12508
12509   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12510   memset (&src, 0, sizeof src);
12511   memset (&dst, 0, sizeof dst);
12512
12513   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12514     {
12515       if (unformat (line_input, "del"))
12516         is_add = 0;
12517       else
12518         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12519         {
12520           ipv4_set = 1;
12521           src_set = 1;
12522         }
12523       else
12524         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12525         {
12526           ipv4_set = 1;
12527           dst_set = 1;
12528         }
12529       else
12530         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12531         {
12532           ipv6_set = 1;
12533           src_set = 1;
12534         }
12535       else
12536         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12537         {
12538           ipv6_set = 1;
12539           dst_set = 1;
12540         }
12541       else if (unformat (line_input, "group %U %U",
12542                          unformat_ip4_address, &dst.ip4,
12543                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12544         {
12545           grp_set = dst_set = 1;
12546           ipv4_set = 1;
12547         }
12548       else if (unformat (line_input, "group %U",
12549                          unformat_ip4_address, &dst.ip4))
12550         {
12551           grp_set = dst_set = 1;
12552           ipv4_set = 1;
12553         }
12554       else if (unformat (line_input, "group %U %U",
12555                          unformat_ip6_address, &dst.ip6,
12556                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12557         {
12558           grp_set = dst_set = 1;
12559           ipv6_set = 1;
12560         }
12561       else if (unformat (line_input, "group %U",
12562                          unformat_ip6_address, &dst.ip6))
12563         {
12564           grp_set = dst_set = 1;
12565           ipv6_set = 1;
12566         }
12567       else
12568         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12569         ;
12570       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12571         ;
12572       else if (unformat (line_input, "decap-next %U",
12573                          unformat_geneve_decap_next, &decap_next_index))
12574         ;
12575       else if (unformat (line_input, "vni %d", &vni))
12576         ;
12577       else
12578         {
12579           errmsg ("parse error '%U'", format_unformat_error, line_input);
12580           return -99;
12581         }
12582     }
12583
12584   if (src_set == 0)
12585     {
12586       errmsg ("tunnel src address not specified");
12587       return -99;
12588     }
12589   if (dst_set == 0)
12590     {
12591       errmsg ("tunnel dst address not specified");
12592       return -99;
12593     }
12594
12595   if (grp_set && !ip46_address_is_multicast (&dst))
12596     {
12597       errmsg ("tunnel group address not multicast");
12598       return -99;
12599     }
12600   if (grp_set && mcast_sw_if_index == ~0)
12601     {
12602       errmsg ("tunnel nonexistent multicast device");
12603       return -99;
12604     }
12605   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12606     {
12607       errmsg ("tunnel dst address must be unicast");
12608       return -99;
12609     }
12610
12611
12612   if (ipv4_set && ipv6_set)
12613     {
12614       errmsg ("both IPv4 and IPv6 addresses specified");
12615       return -99;
12616     }
12617
12618   if ((vni == 0) || (vni >> 24))
12619     {
12620       errmsg ("vni not specified or out of range");
12621       return -99;
12622     }
12623
12624   M (GENEVE_ADD_DEL_TUNNEL, mp);
12625
12626   if (ipv6_set)
12627     {
12628       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12629       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12630     }
12631   else
12632     {
12633       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12634       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12635     }
12636   mp->encap_vrf_id = ntohl (encap_vrf_id);
12637   mp->decap_next_index = ntohl (decap_next_index);
12638   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12639   mp->vni = ntohl (vni);
12640   mp->is_add = is_add;
12641   mp->is_ipv6 = ipv6_set;
12642
12643   S (mp);
12644   W (ret);
12645   return ret;
12646 }
12647
12648 static void vl_api_geneve_tunnel_details_t_handler
12649   (vl_api_geneve_tunnel_details_t * mp)
12650 {
12651   vat_main_t *vam = &vat_main;
12652   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12653   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12654
12655   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12656          ntohl (mp->sw_if_index),
12657          format_ip46_address, &src, IP46_TYPE_ANY,
12658          format_ip46_address, &dst, IP46_TYPE_ANY,
12659          ntohl (mp->encap_vrf_id),
12660          ntohl (mp->decap_next_index), ntohl (mp->vni),
12661          ntohl (mp->mcast_sw_if_index));
12662 }
12663
12664 static void vl_api_geneve_tunnel_details_t_handler_json
12665   (vl_api_geneve_tunnel_details_t * mp)
12666 {
12667   vat_main_t *vam = &vat_main;
12668   vat_json_node_t *node = NULL;
12669
12670   if (VAT_JSON_ARRAY != vam->json_tree.type)
12671     {
12672       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12673       vat_json_init_array (&vam->json_tree);
12674     }
12675   node = vat_json_array_add (&vam->json_tree);
12676
12677   vat_json_init_object (node);
12678   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12679   if (mp->is_ipv6)
12680     {
12681       struct in6_addr ip6;
12682
12683       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12684       vat_json_object_add_ip6 (node, "src_address", ip6);
12685       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12686       vat_json_object_add_ip6 (node, "dst_address", ip6);
12687     }
12688   else
12689     {
12690       struct in_addr ip4;
12691
12692       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12693       vat_json_object_add_ip4 (node, "src_address", ip4);
12694       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12695       vat_json_object_add_ip4 (node, "dst_address", ip4);
12696     }
12697   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12698   vat_json_object_add_uint (node, "decap_next_index",
12699                             ntohl (mp->decap_next_index));
12700   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12701   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12702   vat_json_object_add_uint (node, "mcast_sw_if_index",
12703                             ntohl (mp->mcast_sw_if_index));
12704 }
12705
12706 static int
12707 api_geneve_tunnel_dump (vat_main_t * vam)
12708 {
12709   unformat_input_t *i = vam->input;
12710   vl_api_geneve_tunnel_dump_t *mp;
12711   vl_api_control_ping_t *mp_ping;
12712   u32 sw_if_index;
12713   u8 sw_if_index_set = 0;
12714   int ret;
12715
12716   /* Parse args required to build the message */
12717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12718     {
12719       if (unformat (i, "sw_if_index %d", &sw_if_index))
12720         sw_if_index_set = 1;
12721       else
12722         break;
12723     }
12724
12725   if (sw_if_index_set == 0)
12726     {
12727       sw_if_index = ~0;
12728     }
12729
12730   if (!vam->json_output)
12731     {
12732       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12733              "sw_if_index", "local_address", "remote_address",
12734              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12735     }
12736
12737   /* Get list of geneve-tunnel interfaces */
12738   M (GENEVE_TUNNEL_DUMP, mp);
12739
12740   mp->sw_if_index = htonl (sw_if_index);
12741
12742   S (mp);
12743
12744   /* Use a control ping for synchronization */
12745   M (CONTROL_PING, mp_ping);
12746   S (mp_ping);
12747
12748   W (ret);
12749   return ret;
12750 }
12751
12752 static int
12753 api_gre_add_del_tunnel (vat_main_t * vam)
12754 {
12755   unformat_input_t *line_input = vam->input;
12756   vl_api_gre_add_del_tunnel_t *mp;
12757   ip4_address_t src4, dst4;
12758   ip6_address_t src6, dst6;
12759   u8 is_add = 1;
12760   u8 ipv4_set = 0;
12761   u8 ipv6_set = 0;
12762   u8 teb = 0;
12763   u8 src_set = 0;
12764   u8 dst_set = 0;
12765   u32 outer_fib_id = 0;
12766   int ret;
12767
12768   memset (&src4, 0, sizeof src4);
12769   memset (&dst4, 0, sizeof dst4);
12770   memset (&src6, 0, sizeof src6);
12771   memset (&dst6, 0, sizeof dst6);
12772
12773   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12774     {
12775       if (unformat (line_input, "del"))
12776         is_add = 0;
12777       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12778         {
12779           src_set = 1;
12780           ipv4_set = 1;
12781         }
12782       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12783         {
12784           dst_set = 1;
12785           ipv4_set = 1;
12786         }
12787       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12788         {
12789           src_set = 1;
12790           ipv6_set = 1;
12791         }
12792       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12793         {
12794           dst_set = 1;
12795           ipv6_set = 1;
12796         }
12797       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12798         ;
12799       else if (unformat (line_input, "teb"))
12800         teb = 1;
12801       else
12802         {
12803           errmsg ("parse error '%U'", format_unformat_error, line_input);
12804           return -99;
12805         }
12806     }
12807
12808   if (src_set == 0)
12809     {
12810       errmsg ("tunnel src address not specified");
12811       return -99;
12812     }
12813   if (dst_set == 0)
12814     {
12815       errmsg ("tunnel dst address not specified");
12816       return -99;
12817     }
12818   if (ipv4_set && ipv6_set)
12819     {
12820       errmsg ("both IPv4 and IPv6 addresses specified");
12821       return -99;
12822     }
12823
12824
12825   M (GRE_ADD_DEL_TUNNEL, mp);
12826
12827   if (ipv4_set)
12828     {
12829       clib_memcpy (&mp->src_address, &src4, 4);
12830       clib_memcpy (&mp->dst_address, &dst4, 4);
12831     }
12832   else
12833     {
12834       clib_memcpy (&mp->src_address, &src6, 16);
12835       clib_memcpy (&mp->dst_address, &dst6, 16);
12836     }
12837   mp->outer_fib_id = ntohl (outer_fib_id);
12838   mp->is_add = is_add;
12839   mp->teb = teb;
12840   mp->is_ipv6 = ipv6_set;
12841
12842   S (mp);
12843   W (ret);
12844   return ret;
12845 }
12846
12847 static void vl_api_gre_tunnel_details_t_handler
12848   (vl_api_gre_tunnel_details_t * mp)
12849 {
12850   vat_main_t *vam = &vat_main;
12851   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12852   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12853
12854   print (vam->ofp, "%11d%24U%24U%6d%14d",
12855          ntohl (mp->sw_if_index),
12856          format_ip46_address, &src, IP46_TYPE_ANY,
12857          format_ip46_address, &dst, IP46_TYPE_ANY,
12858          mp->teb, ntohl (mp->outer_fib_id));
12859 }
12860
12861 static void vl_api_gre_tunnel_details_t_handler_json
12862   (vl_api_gre_tunnel_details_t * mp)
12863 {
12864   vat_main_t *vam = &vat_main;
12865   vat_json_node_t *node = NULL;
12866   struct in_addr ip4;
12867   struct in6_addr ip6;
12868
12869   if (VAT_JSON_ARRAY != vam->json_tree.type)
12870     {
12871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12872       vat_json_init_array (&vam->json_tree);
12873     }
12874   node = vat_json_array_add (&vam->json_tree);
12875
12876   vat_json_init_object (node);
12877   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12878   if (!mp->is_ipv6)
12879     {
12880       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12881       vat_json_object_add_ip4 (node, "src_address", ip4);
12882       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12883       vat_json_object_add_ip4 (node, "dst_address", ip4);
12884     }
12885   else
12886     {
12887       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12888       vat_json_object_add_ip6 (node, "src_address", ip6);
12889       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12890       vat_json_object_add_ip6 (node, "dst_address", ip6);
12891     }
12892   vat_json_object_add_uint (node, "teb", mp->teb);
12893   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12894   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12895 }
12896
12897 static int
12898 api_gre_tunnel_dump (vat_main_t * vam)
12899 {
12900   unformat_input_t *i = vam->input;
12901   vl_api_gre_tunnel_dump_t *mp;
12902   vl_api_control_ping_t *mp_ping;
12903   u32 sw_if_index;
12904   u8 sw_if_index_set = 0;
12905   int ret;
12906
12907   /* Parse args required to build the message */
12908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12909     {
12910       if (unformat (i, "sw_if_index %d", &sw_if_index))
12911         sw_if_index_set = 1;
12912       else
12913         break;
12914     }
12915
12916   if (sw_if_index_set == 0)
12917     {
12918       sw_if_index = ~0;
12919     }
12920
12921   if (!vam->json_output)
12922     {
12923       print (vam->ofp, "%11s%24s%24s%6s%14s",
12924              "sw_if_index", "src_address", "dst_address", "teb",
12925              "outer_fib_id");
12926     }
12927
12928   /* Get list of gre-tunnel interfaces */
12929   M (GRE_TUNNEL_DUMP, mp);
12930
12931   mp->sw_if_index = htonl (sw_if_index);
12932
12933   S (mp);
12934
12935   /* Use a control ping for synchronization */
12936   MPING (CONTROL_PING, mp_ping);
12937   S (mp_ping);
12938
12939   W (ret);
12940   return ret;
12941 }
12942
12943 static int
12944 api_l2_fib_clear_table (vat_main_t * vam)
12945 {
12946 //  unformat_input_t * i = vam->input;
12947   vl_api_l2_fib_clear_table_t *mp;
12948   int ret;
12949
12950   M (L2_FIB_CLEAR_TABLE, mp);
12951
12952   S (mp);
12953   W (ret);
12954   return ret;
12955 }
12956
12957 static int
12958 api_l2_interface_efp_filter (vat_main_t * vam)
12959 {
12960   unformat_input_t *i = vam->input;
12961   vl_api_l2_interface_efp_filter_t *mp;
12962   u32 sw_if_index;
12963   u8 enable = 1;
12964   u8 sw_if_index_set = 0;
12965   int ret;
12966
12967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12968     {
12969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12970         sw_if_index_set = 1;
12971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12972         sw_if_index_set = 1;
12973       else if (unformat (i, "enable"))
12974         enable = 1;
12975       else if (unformat (i, "disable"))
12976         enable = 0;
12977       else
12978         {
12979           clib_warning ("parse error '%U'", format_unformat_error, i);
12980           return -99;
12981         }
12982     }
12983
12984   if (sw_if_index_set == 0)
12985     {
12986       errmsg ("missing sw_if_index");
12987       return -99;
12988     }
12989
12990   M (L2_INTERFACE_EFP_FILTER, mp);
12991
12992   mp->sw_if_index = ntohl (sw_if_index);
12993   mp->enable_disable = enable;
12994
12995   S (mp);
12996   W (ret);
12997   return ret;
12998 }
12999
13000 #define foreach_vtr_op                          \
13001 _("disable",  L2_VTR_DISABLED)                  \
13002 _("push-1",  L2_VTR_PUSH_1)                     \
13003 _("push-2",  L2_VTR_PUSH_2)                     \
13004 _("pop-1",  L2_VTR_POP_1)                       \
13005 _("pop-2",  L2_VTR_POP_2)                       \
13006 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13007 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13008 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13009 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13010
13011 static int
13012 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13013 {
13014   unformat_input_t *i = vam->input;
13015   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13016   u32 sw_if_index;
13017   u8 sw_if_index_set = 0;
13018   u8 vtr_op_set = 0;
13019   u32 vtr_op = 0;
13020   u32 push_dot1q = 1;
13021   u32 tag1 = ~0;
13022   u32 tag2 = ~0;
13023   int ret;
13024
13025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13028         sw_if_index_set = 1;
13029       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13030         sw_if_index_set = 1;
13031       else if (unformat (i, "vtr_op %d", &vtr_op))
13032         vtr_op_set = 1;
13033 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13034       foreach_vtr_op
13035 #undef _
13036         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13037         ;
13038       else if (unformat (i, "tag1 %d", &tag1))
13039         ;
13040       else if (unformat (i, "tag2 %d", &tag2))
13041         ;
13042       else
13043         {
13044           clib_warning ("parse error '%U'", format_unformat_error, i);
13045           return -99;
13046         }
13047     }
13048
13049   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13050     {
13051       errmsg ("missing vtr operation or sw_if_index");
13052       return -99;
13053     }
13054
13055   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13056   mp->sw_if_index = ntohl (sw_if_index);
13057   mp->vtr_op = ntohl (vtr_op);
13058   mp->push_dot1q = ntohl (push_dot1q);
13059   mp->tag1 = ntohl (tag1);
13060   mp->tag2 = ntohl (tag2);
13061
13062   S (mp);
13063   W (ret);
13064   return ret;
13065 }
13066
13067 static int
13068 api_create_vhost_user_if (vat_main_t * vam)
13069 {
13070   unformat_input_t *i = vam->input;
13071   vl_api_create_vhost_user_if_t *mp;
13072   u8 *file_name;
13073   u8 is_server = 0;
13074   u8 file_name_set = 0;
13075   u32 custom_dev_instance = ~0;
13076   u8 hwaddr[6];
13077   u8 use_custom_mac = 0;
13078   u8 *tag = 0;
13079   int ret;
13080
13081   /* Shut up coverity */
13082   memset (hwaddr, 0, sizeof (hwaddr));
13083
13084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13085     {
13086       if (unformat (i, "socket %s", &file_name))
13087         {
13088           file_name_set = 1;
13089         }
13090       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13091         ;
13092       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13093         use_custom_mac = 1;
13094       else if (unformat (i, "server"))
13095         is_server = 1;
13096       else if (unformat (i, "tag %s", &tag))
13097         ;
13098       else
13099         break;
13100     }
13101
13102   if (file_name_set == 0)
13103     {
13104       errmsg ("missing socket file name");
13105       return -99;
13106     }
13107
13108   if (vec_len (file_name) > 255)
13109     {
13110       errmsg ("socket file name too long");
13111       return -99;
13112     }
13113   vec_add1 (file_name, 0);
13114
13115   M (CREATE_VHOST_USER_IF, mp);
13116
13117   mp->is_server = is_server;
13118   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13119   vec_free (file_name);
13120   if (custom_dev_instance != ~0)
13121     {
13122       mp->renumber = 1;
13123       mp->custom_dev_instance = ntohl (custom_dev_instance);
13124     }
13125   mp->use_custom_mac = use_custom_mac;
13126   clib_memcpy (mp->mac_address, hwaddr, 6);
13127   if (tag)
13128     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13129   vec_free (tag);
13130
13131   S (mp);
13132   W (ret);
13133   return ret;
13134 }
13135
13136 static int
13137 api_modify_vhost_user_if (vat_main_t * vam)
13138 {
13139   unformat_input_t *i = vam->input;
13140   vl_api_modify_vhost_user_if_t *mp;
13141   u8 *file_name;
13142   u8 is_server = 0;
13143   u8 file_name_set = 0;
13144   u32 custom_dev_instance = ~0;
13145   u8 sw_if_index_set = 0;
13146   u32 sw_if_index = (u32) ~ 0;
13147   int ret;
13148
13149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13150     {
13151       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13152         sw_if_index_set = 1;
13153       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13154         sw_if_index_set = 1;
13155       else if (unformat (i, "socket %s", &file_name))
13156         {
13157           file_name_set = 1;
13158         }
13159       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13160         ;
13161       else if (unformat (i, "server"))
13162         is_server = 1;
13163       else
13164         break;
13165     }
13166
13167   if (sw_if_index_set == 0)
13168     {
13169       errmsg ("missing sw_if_index or interface name");
13170       return -99;
13171     }
13172
13173   if (file_name_set == 0)
13174     {
13175       errmsg ("missing socket file name");
13176       return -99;
13177     }
13178
13179   if (vec_len (file_name) > 255)
13180     {
13181       errmsg ("socket file name too long");
13182       return -99;
13183     }
13184   vec_add1 (file_name, 0);
13185
13186   M (MODIFY_VHOST_USER_IF, mp);
13187
13188   mp->sw_if_index = ntohl (sw_if_index);
13189   mp->is_server = is_server;
13190   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13191   vec_free (file_name);
13192   if (custom_dev_instance != ~0)
13193     {
13194       mp->renumber = 1;
13195       mp->custom_dev_instance = ntohl (custom_dev_instance);
13196     }
13197
13198   S (mp);
13199   W (ret);
13200   return ret;
13201 }
13202
13203 static int
13204 api_delete_vhost_user_if (vat_main_t * vam)
13205 {
13206   unformat_input_t *i = vam->input;
13207   vl_api_delete_vhost_user_if_t *mp;
13208   u32 sw_if_index = ~0;
13209   u8 sw_if_index_set = 0;
13210   int ret;
13211
13212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13213     {
13214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13215         sw_if_index_set = 1;
13216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13217         sw_if_index_set = 1;
13218       else
13219         break;
13220     }
13221
13222   if (sw_if_index_set == 0)
13223     {
13224       errmsg ("missing sw_if_index or interface name");
13225       return -99;
13226     }
13227
13228
13229   M (DELETE_VHOST_USER_IF, mp);
13230
13231   mp->sw_if_index = ntohl (sw_if_index);
13232
13233   S (mp);
13234   W (ret);
13235   return ret;
13236 }
13237
13238 static void vl_api_sw_interface_vhost_user_details_t_handler
13239   (vl_api_sw_interface_vhost_user_details_t * mp)
13240 {
13241   vat_main_t *vam = &vat_main;
13242
13243   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13244          (char *) mp->interface_name,
13245          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13246          clib_net_to_host_u64 (mp->features), mp->is_server,
13247          ntohl (mp->num_regions), (char *) mp->sock_filename);
13248   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13249 }
13250
13251 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13252   (vl_api_sw_interface_vhost_user_details_t * mp)
13253 {
13254   vat_main_t *vam = &vat_main;
13255   vat_json_node_t *node = NULL;
13256
13257   if (VAT_JSON_ARRAY != vam->json_tree.type)
13258     {
13259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13260       vat_json_init_array (&vam->json_tree);
13261     }
13262   node = vat_json_array_add (&vam->json_tree);
13263
13264   vat_json_init_object (node);
13265   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13266   vat_json_object_add_string_copy (node, "interface_name",
13267                                    mp->interface_name);
13268   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13269                             ntohl (mp->virtio_net_hdr_sz));
13270   vat_json_object_add_uint (node, "features",
13271                             clib_net_to_host_u64 (mp->features));
13272   vat_json_object_add_uint (node, "is_server", mp->is_server);
13273   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13274   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13275   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13276 }
13277
13278 static int
13279 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13280 {
13281   vl_api_sw_interface_vhost_user_dump_t *mp;
13282   vl_api_control_ping_t *mp_ping;
13283   int ret;
13284   print (vam->ofp,
13285          "Interface name            idx hdr_sz features server regions filename");
13286
13287   /* Get list of vhost-user interfaces */
13288   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13289   S (mp);
13290
13291   /* Use a control ping for synchronization */
13292   MPING (CONTROL_PING, mp_ping);
13293   S (mp_ping);
13294
13295   W (ret);
13296   return ret;
13297 }
13298
13299 static int
13300 api_show_version (vat_main_t * vam)
13301 {
13302   vl_api_show_version_t *mp;
13303   int ret;
13304
13305   M (SHOW_VERSION, mp);
13306
13307   S (mp);
13308   W (ret);
13309   return ret;
13310 }
13311
13312
13313 static int
13314 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13315 {
13316   unformat_input_t *line_input = vam->input;
13317   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13318   ip4_address_t local4, remote4;
13319   ip6_address_t local6, remote6;
13320   u8 is_add = 1;
13321   u8 ipv4_set = 0, ipv6_set = 0;
13322   u8 local_set = 0;
13323   u8 remote_set = 0;
13324   u8 grp_set = 0;
13325   u32 mcast_sw_if_index = ~0;
13326   u32 encap_vrf_id = 0;
13327   u32 decap_vrf_id = 0;
13328   u8 protocol = ~0;
13329   u32 vni;
13330   u8 vni_set = 0;
13331   int ret;
13332
13333   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13334   memset (&local4, 0, sizeof local4);
13335   memset (&remote4, 0, sizeof remote4);
13336   memset (&local6, 0, sizeof local6);
13337   memset (&remote6, 0, sizeof remote6);
13338
13339   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13340     {
13341       if (unformat (line_input, "del"))
13342         is_add = 0;
13343       else if (unformat (line_input, "local %U",
13344                          unformat_ip4_address, &local4))
13345         {
13346           local_set = 1;
13347           ipv4_set = 1;
13348         }
13349       else if (unformat (line_input, "remote %U",
13350                          unformat_ip4_address, &remote4))
13351         {
13352           remote_set = 1;
13353           ipv4_set = 1;
13354         }
13355       else if (unformat (line_input, "local %U",
13356                          unformat_ip6_address, &local6))
13357         {
13358           local_set = 1;
13359           ipv6_set = 1;
13360         }
13361       else if (unformat (line_input, "remote %U",
13362                          unformat_ip6_address, &remote6))
13363         {
13364           remote_set = 1;
13365           ipv6_set = 1;
13366         }
13367       else if (unformat (line_input, "group %U %U",
13368                          unformat_ip4_address, &remote4,
13369                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13370         {
13371           grp_set = remote_set = 1;
13372           ipv4_set = 1;
13373         }
13374       else if (unformat (line_input, "group %U",
13375                          unformat_ip4_address, &remote4))
13376         {
13377           grp_set = remote_set = 1;
13378           ipv4_set = 1;
13379         }
13380       else if (unformat (line_input, "group %U %U",
13381                          unformat_ip6_address, &remote6,
13382                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13383         {
13384           grp_set = remote_set = 1;
13385           ipv6_set = 1;
13386         }
13387       else if (unformat (line_input, "group %U",
13388                          unformat_ip6_address, &remote6))
13389         {
13390           grp_set = remote_set = 1;
13391           ipv6_set = 1;
13392         }
13393       else
13394         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13395         ;
13396       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13397         ;
13398       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13399         ;
13400       else if (unformat (line_input, "vni %d", &vni))
13401         vni_set = 1;
13402       else if (unformat (line_input, "next-ip4"))
13403         protocol = 1;
13404       else if (unformat (line_input, "next-ip6"))
13405         protocol = 2;
13406       else if (unformat (line_input, "next-ethernet"))
13407         protocol = 3;
13408       else if (unformat (line_input, "next-nsh"))
13409         protocol = 4;
13410       else
13411         {
13412           errmsg ("parse error '%U'", format_unformat_error, line_input);
13413           return -99;
13414         }
13415     }
13416
13417   if (local_set == 0)
13418     {
13419       errmsg ("tunnel local address not specified");
13420       return -99;
13421     }
13422   if (remote_set == 0)
13423     {
13424       errmsg ("tunnel remote address not specified");
13425       return -99;
13426     }
13427   if (grp_set && mcast_sw_if_index == ~0)
13428     {
13429       errmsg ("tunnel nonexistent multicast device");
13430       return -99;
13431     }
13432   if (ipv4_set && ipv6_set)
13433     {
13434       errmsg ("both IPv4 and IPv6 addresses specified");
13435       return -99;
13436     }
13437
13438   if (vni_set == 0)
13439     {
13440       errmsg ("vni not specified");
13441       return -99;
13442     }
13443
13444   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13445
13446
13447   if (ipv6_set)
13448     {
13449       clib_memcpy (&mp->local, &local6, sizeof (local6));
13450       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13451     }
13452   else
13453     {
13454       clib_memcpy (&mp->local, &local4, sizeof (local4));
13455       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13456     }
13457
13458   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13459   mp->encap_vrf_id = ntohl (encap_vrf_id);
13460   mp->decap_vrf_id = ntohl (decap_vrf_id);
13461   mp->protocol = protocol;
13462   mp->vni = ntohl (vni);
13463   mp->is_add = is_add;
13464   mp->is_ipv6 = ipv6_set;
13465
13466   S (mp);
13467   W (ret);
13468   return ret;
13469 }
13470
13471 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13472   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13473 {
13474   vat_main_t *vam = &vat_main;
13475   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13476   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13477
13478   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13479          ntohl (mp->sw_if_index),
13480          format_ip46_address, &local, IP46_TYPE_ANY,
13481          format_ip46_address, &remote, IP46_TYPE_ANY,
13482          ntohl (mp->vni), mp->protocol,
13483          ntohl (mp->mcast_sw_if_index),
13484          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13485 }
13486
13487
13488 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13489   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13490 {
13491   vat_main_t *vam = &vat_main;
13492   vat_json_node_t *node = NULL;
13493   struct in_addr ip4;
13494   struct in6_addr ip6;
13495
13496   if (VAT_JSON_ARRAY != vam->json_tree.type)
13497     {
13498       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13499       vat_json_init_array (&vam->json_tree);
13500     }
13501   node = vat_json_array_add (&vam->json_tree);
13502
13503   vat_json_init_object (node);
13504   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13505   if (mp->is_ipv6)
13506     {
13507       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13508       vat_json_object_add_ip6 (node, "local", ip6);
13509       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13510       vat_json_object_add_ip6 (node, "remote", ip6);
13511     }
13512   else
13513     {
13514       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13515       vat_json_object_add_ip4 (node, "local", ip4);
13516       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13517       vat_json_object_add_ip4 (node, "remote", ip4);
13518     }
13519   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13520   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13521   vat_json_object_add_uint (node, "mcast_sw_if_index",
13522                             ntohl (mp->mcast_sw_if_index));
13523   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13524   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13525   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13526 }
13527
13528 static int
13529 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13530 {
13531   unformat_input_t *i = vam->input;
13532   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13533   vl_api_control_ping_t *mp_ping;
13534   u32 sw_if_index;
13535   u8 sw_if_index_set = 0;
13536   int ret;
13537
13538   /* Parse args required to build the message */
13539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13540     {
13541       if (unformat (i, "sw_if_index %d", &sw_if_index))
13542         sw_if_index_set = 1;
13543       else
13544         break;
13545     }
13546
13547   if (sw_if_index_set == 0)
13548     {
13549       sw_if_index = ~0;
13550     }
13551
13552   if (!vam->json_output)
13553     {
13554       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13555              "sw_if_index", "local", "remote", "vni",
13556              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13557     }
13558
13559   /* Get list of vxlan-tunnel interfaces */
13560   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13561
13562   mp->sw_if_index = htonl (sw_if_index);
13563
13564   S (mp);
13565
13566   /* Use a control ping for synchronization */
13567   MPING (CONTROL_PING, mp_ping);
13568   S (mp_ping);
13569
13570   W (ret);
13571   return ret;
13572 }
13573
13574 static void vl_api_l2_fib_table_details_t_handler
13575   (vl_api_l2_fib_table_details_t * mp)
13576 {
13577   vat_main_t *vam = &vat_main;
13578
13579   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13580          "       %d       %d     %d",
13581          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13582          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13583          mp->bvi_mac);
13584 }
13585
13586 static void vl_api_l2_fib_table_details_t_handler_json
13587   (vl_api_l2_fib_table_details_t * mp)
13588 {
13589   vat_main_t *vam = &vat_main;
13590   vat_json_node_t *node = NULL;
13591
13592   if (VAT_JSON_ARRAY != vam->json_tree.type)
13593     {
13594       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13595       vat_json_init_array (&vam->json_tree);
13596     }
13597   node = vat_json_array_add (&vam->json_tree);
13598
13599   vat_json_init_object (node);
13600   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13601   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13602   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13603   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13604   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13605   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13606 }
13607
13608 static int
13609 api_l2_fib_table_dump (vat_main_t * vam)
13610 {
13611   unformat_input_t *i = vam->input;
13612   vl_api_l2_fib_table_dump_t *mp;
13613   vl_api_control_ping_t *mp_ping;
13614   u32 bd_id;
13615   u8 bd_id_set = 0;
13616   int ret;
13617
13618   /* Parse args required to build the message */
13619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13620     {
13621       if (unformat (i, "bd_id %d", &bd_id))
13622         bd_id_set = 1;
13623       else
13624         break;
13625     }
13626
13627   if (bd_id_set == 0)
13628     {
13629       errmsg ("missing bridge domain");
13630       return -99;
13631     }
13632
13633   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13634
13635   /* Get list of l2 fib entries */
13636   M (L2_FIB_TABLE_DUMP, mp);
13637
13638   mp->bd_id = ntohl (bd_id);
13639   S (mp);
13640
13641   /* Use a control ping for synchronization */
13642   MPING (CONTROL_PING, mp_ping);
13643   S (mp_ping);
13644
13645   W (ret);
13646   return ret;
13647 }
13648
13649
13650 static int
13651 api_interface_name_renumber (vat_main_t * vam)
13652 {
13653   unformat_input_t *line_input = vam->input;
13654   vl_api_interface_name_renumber_t *mp;
13655   u32 sw_if_index = ~0;
13656   u32 new_show_dev_instance = ~0;
13657   int ret;
13658
13659   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13660     {
13661       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13662                     &sw_if_index))
13663         ;
13664       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13665         ;
13666       else if (unformat (line_input, "new_show_dev_instance %d",
13667                          &new_show_dev_instance))
13668         ;
13669       else
13670         break;
13671     }
13672
13673   if (sw_if_index == ~0)
13674     {
13675       errmsg ("missing interface name or sw_if_index");
13676       return -99;
13677     }
13678
13679   if (new_show_dev_instance == ~0)
13680     {
13681       errmsg ("missing new_show_dev_instance");
13682       return -99;
13683     }
13684
13685   M (INTERFACE_NAME_RENUMBER, mp);
13686
13687   mp->sw_if_index = ntohl (sw_if_index);
13688   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13689
13690   S (mp);
13691   W (ret);
13692   return ret;
13693 }
13694
13695 static int
13696 api_want_ip4_arp_events (vat_main_t * vam)
13697 {
13698   unformat_input_t *line_input = vam->input;
13699   vl_api_want_ip4_arp_events_t *mp;
13700   ip4_address_t address;
13701   int address_set = 0;
13702   u32 enable_disable = 1;
13703   int ret;
13704
13705   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13706     {
13707       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13708         address_set = 1;
13709       else if (unformat (line_input, "del"))
13710         enable_disable = 0;
13711       else
13712         break;
13713     }
13714
13715   if (address_set == 0)
13716     {
13717       errmsg ("missing addresses");
13718       return -99;
13719     }
13720
13721   M (WANT_IP4_ARP_EVENTS, mp);
13722   mp->enable_disable = enable_disable;
13723   mp->pid = htonl (getpid ());
13724   mp->address = address.as_u32;
13725
13726   S (mp);
13727   W (ret);
13728   return ret;
13729 }
13730
13731 static int
13732 api_want_ip6_nd_events (vat_main_t * vam)
13733 {
13734   unformat_input_t *line_input = vam->input;
13735   vl_api_want_ip6_nd_events_t *mp;
13736   ip6_address_t address;
13737   int address_set = 0;
13738   u32 enable_disable = 1;
13739   int ret;
13740
13741   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13742     {
13743       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13744         address_set = 1;
13745       else if (unformat (line_input, "del"))
13746         enable_disable = 0;
13747       else
13748         break;
13749     }
13750
13751   if (address_set == 0)
13752     {
13753       errmsg ("missing addresses");
13754       return -99;
13755     }
13756
13757   M (WANT_IP6_ND_EVENTS, mp);
13758   mp->enable_disable = enable_disable;
13759   mp->pid = htonl (getpid ());
13760   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13761
13762   S (mp);
13763   W (ret);
13764   return ret;
13765 }
13766
13767 static int
13768 api_want_l2_macs_events (vat_main_t * vam)
13769 {
13770   unformat_input_t *line_input = vam->input;
13771   vl_api_want_l2_macs_events_t *mp;
13772   u8 enable_disable = 1;
13773   u32 scan_delay = 0;
13774   u32 max_macs_in_event = 0;
13775   u32 learn_limit = 0;
13776   int ret;
13777
13778   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13779     {
13780       if (unformat (line_input, "learn-limit %d", &learn_limit))
13781         ;
13782       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13783         ;
13784       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13785         ;
13786       else if (unformat (line_input, "disable"))
13787         enable_disable = 0;
13788       else
13789         break;
13790     }
13791
13792   M (WANT_L2_MACS_EVENTS, mp);
13793   mp->enable_disable = enable_disable;
13794   mp->pid = htonl (getpid ());
13795   mp->learn_limit = htonl (learn_limit);
13796   mp->scan_delay = (u8) scan_delay;
13797   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13798   S (mp);
13799   W (ret);
13800   return ret;
13801 }
13802
13803 static int
13804 api_input_acl_set_interface (vat_main_t * vam)
13805 {
13806   unformat_input_t *i = vam->input;
13807   vl_api_input_acl_set_interface_t *mp;
13808   u32 sw_if_index;
13809   int sw_if_index_set;
13810   u32 ip4_table_index = ~0;
13811   u32 ip6_table_index = ~0;
13812   u32 l2_table_index = ~0;
13813   u8 is_add = 1;
13814   int ret;
13815
13816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13817     {
13818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13819         sw_if_index_set = 1;
13820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13821         sw_if_index_set = 1;
13822       else if (unformat (i, "del"))
13823         is_add = 0;
13824       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13825         ;
13826       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13827         ;
13828       else if (unformat (i, "l2-table %d", &l2_table_index))
13829         ;
13830       else
13831         {
13832           clib_warning ("parse error '%U'", format_unformat_error, i);
13833           return -99;
13834         }
13835     }
13836
13837   if (sw_if_index_set == 0)
13838     {
13839       errmsg ("missing interface name or sw_if_index");
13840       return -99;
13841     }
13842
13843   M (INPUT_ACL_SET_INTERFACE, mp);
13844
13845   mp->sw_if_index = ntohl (sw_if_index);
13846   mp->ip4_table_index = ntohl (ip4_table_index);
13847   mp->ip6_table_index = ntohl (ip6_table_index);
13848   mp->l2_table_index = ntohl (l2_table_index);
13849   mp->is_add = is_add;
13850
13851   S (mp);
13852   W (ret);
13853   return ret;
13854 }
13855
13856 static int
13857 api_ip_address_dump (vat_main_t * vam)
13858 {
13859   unformat_input_t *i = vam->input;
13860   vl_api_ip_address_dump_t *mp;
13861   vl_api_control_ping_t *mp_ping;
13862   u32 sw_if_index = ~0;
13863   u8 sw_if_index_set = 0;
13864   u8 ipv4_set = 0;
13865   u8 ipv6_set = 0;
13866   int ret;
13867
13868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13869     {
13870       if (unformat (i, "sw_if_index %d", &sw_if_index))
13871         sw_if_index_set = 1;
13872       else
13873         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13874         sw_if_index_set = 1;
13875       else if (unformat (i, "ipv4"))
13876         ipv4_set = 1;
13877       else if (unformat (i, "ipv6"))
13878         ipv6_set = 1;
13879       else
13880         break;
13881     }
13882
13883   if (ipv4_set && ipv6_set)
13884     {
13885       errmsg ("ipv4 and ipv6 flags cannot be both set");
13886       return -99;
13887     }
13888
13889   if ((!ipv4_set) && (!ipv6_set))
13890     {
13891       errmsg ("no ipv4 nor ipv6 flag set");
13892       return -99;
13893     }
13894
13895   if (sw_if_index_set == 0)
13896     {
13897       errmsg ("missing interface name or sw_if_index");
13898       return -99;
13899     }
13900
13901   vam->current_sw_if_index = sw_if_index;
13902   vam->is_ipv6 = ipv6_set;
13903
13904   M (IP_ADDRESS_DUMP, mp);
13905   mp->sw_if_index = ntohl (sw_if_index);
13906   mp->is_ipv6 = ipv6_set;
13907   S (mp);
13908
13909   /* Use a control ping for synchronization */
13910   MPING (CONTROL_PING, mp_ping);
13911   S (mp_ping);
13912
13913   W (ret);
13914   return ret;
13915 }
13916
13917 static int
13918 api_ip_dump (vat_main_t * vam)
13919 {
13920   vl_api_ip_dump_t *mp;
13921   vl_api_control_ping_t *mp_ping;
13922   unformat_input_t *in = vam->input;
13923   int ipv4_set = 0;
13924   int ipv6_set = 0;
13925   int is_ipv6;
13926   int i;
13927   int ret;
13928
13929   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13930     {
13931       if (unformat (in, "ipv4"))
13932         ipv4_set = 1;
13933       else if (unformat (in, "ipv6"))
13934         ipv6_set = 1;
13935       else
13936         break;
13937     }
13938
13939   if (ipv4_set && ipv6_set)
13940     {
13941       errmsg ("ipv4 and ipv6 flags cannot be both set");
13942       return -99;
13943     }
13944
13945   if ((!ipv4_set) && (!ipv6_set))
13946     {
13947       errmsg ("no ipv4 nor ipv6 flag set");
13948       return -99;
13949     }
13950
13951   is_ipv6 = ipv6_set;
13952   vam->is_ipv6 = is_ipv6;
13953
13954   /* free old data */
13955   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13956     {
13957       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13958     }
13959   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13960
13961   M (IP_DUMP, mp);
13962   mp->is_ipv6 = ipv6_set;
13963   S (mp);
13964
13965   /* Use a control ping for synchronization */
13966   MPING (CONTROL_PING, mp_ping);
13967   S (mp_ping);
13968
13969   W (ret);
13970   return ret;
13971 }
13972
13973 static int
13974 api_ipsec_spd_add_del (vat_main_t * vam)
13975 {
13976   unformat_input_t *i = vam->input;
13977   vl_api_ipsec_spd_add_del_t *mp;
13978   u32 spd_id = ~0;
13979   u8 is_add = 1;
13980   int ret;
13981
13982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13983     {
13984       if (unformat (i, "spd_id %d", &spd_id))
13985         ;
13986       else if (unformat (i, "del"))
13987         is_add = 0;
13988       else
13989         {
13990           clib_warning ("parse error '%U'", format_unformat_error, i);
13991           return -99;
13992         }
13993     }
13994   if (spd_id == ~0)
13995     {
13996       errmsg ("spd_id must be set");
13997       return -99;
13998     }
13999
14000   M (IPSEC_SPD_ADD_DEL, mp);
14001
14002   mp->spd_id = ntohl (spd_id);
14003   mp->is_add = is_add;
14004
14005   S (mp);
14006   W (ret);
14007   return ret;
14008 }
14009
14010 static int
14011 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14012 {
14013   unformat_input_t *i = vam->input;
14014   vl_api_ipsec_interface_add_del_spd_t *mp;
14015   u32 sw_if_index;
14016   u8 sw_if_index_set = 0;
14017   u32 spd_id = (u32) ~ 0;
14018   u8 is_add = 1;
14019   int ret;
14020
14021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14022     {
14023       if (unformat (i, "del"))
14024         is_add = 0;
14025       else if (unformat (i, "spd_id %d", &spd_id))
14026         ;
14027       else
14028         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14029         sw_if_index_set = 1;
14030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14031         sw_if_index_set = 1;
14032       else
14033         {
14034           clib_warning ("parse error '%U'", format_unformat_error, i);
14035           return -99;
14036         }
14037
14038     }
14039
14040   if (spd_id == (u32) ~ 0)
14041     {
14042       errmsg ("spd_id must be set");
14043       return -99;
14044     }
14045
14046   if (sw_if_index_set == 0)
14047     {
14048       errmsg ("missing interface name or sw_if_index");
14049       return -99;
14050     }
14051
14052   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14053
14054   mp->spd_id = ntohl (spd_id);
14055   mp->sw_if_index = ntohl (sw_if_index);
14056   mp->is_add = is_add;
14057
14058   S (mp);
14059   W (ret);
14060   return ret;
14061 }
14062
14063 static int
14064 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14065 {
14066   unformat_input_t *i = vam->input;
14067   vl_api_ipsec_spd_add_del_entry_t *mp;
14068   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14069   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14070   i32 priority = 0;
14071   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14072   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14073   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14074   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14075   int ret;
14076
14077   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14078   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14079   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14080   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14081   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14082   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14083
14084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14085     {
14086       if (unformat (i, "del"))
14087         is_add = 0;
14088       if (unformat (i, "outbound"))
14089         is_outbound = 1;
14090       if (unformat (i, "inbound"))
14091         is_outbound = 0;
14092       else if (unformat (i, "spd_id %d", &spd_id))
14093         ;
14094       else if (unformat (i, "sa_id %d", &sa_id))
14095         ;
14096       else if (unformat (i, "priority %d", &priority))
14097         ;
14098       else if (unformat (i, "protocol %d", &protocol))
14099         ;
14100       else if (unformat (i, "lport_start %d", &lport_start))
14101         ;
14102       else if (unformat (i, "lport_stop %d", &lport_stop))
14103         ;
14104       else if (unformat (i, "rport_start %d", &rport_start))
14105         ;
14106       else if (unformat (i, "rport_stop %d", &rport_stop))
14107         ;
14108       else
14109         if (unformat
14110             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14111         {
14112           is_ipv6 = 0;
14113           is_ip_any = 0;
14114         }
14115       else
14116         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14117         {
14118           is_ipv6 = 0;
14119           is_ip_any = 0;
14120         }
14121       else
14122         if (unformat
14123             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14124         {
14125           is_ipv6 = 0;
14126           is_ip_any = 0;
14127         }
14128       else
14129         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14130         {
14131           is_ipv6 = 0;
14132           is_ip_any = 0;
14133         }
14134       else
14135         if (unformat
14136             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14137         {
14138           is_ipv6 = 1;
14139           is_ip_any = 0;
14140         }
14141       else
14142         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14143         {
14144           is_ipv6 = 1;
14145           is_ip_any = 0;
14146         }
14147       else
14148         if (unformat
14149             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14150         {
14151           is_ipv6 = 1;
14152           is_ip_any = 0;
14153         }
14154       else
14155         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14156         {
14157           is_ipv6 = 1;
14158           is_ip_any = 0;
14159         }
14160       else
14161         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14162         {
14163           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14164             {
14165               clib_warning ("unsupported action: 'resolve'");
14166               return -99;
14167             }
14168         }
14169       else
14170         {
14171           clib_warning ("parse error '%U'", format_unformat_error, i);
14172           return -99;
14173         }
14174
14175     }
14176
14177   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14178
14179   mp->spd_id = ntohl (spd_id);
14180   mp->priority = ntohl (priority);
14181   mp->is_outbound = is_outbound;
14182
14183   mp->is_ipv6 = is_ipv6;
14184   if (is_ipv6 || is_ip_any)
14185     {
14186       clib_memcpy (mp->remote_address_start, &raddr6_start,
14187                    sizeof (ip6_address_t));
14188       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14189                    sizeof (ip6_address_t));
14190       clib_memcpy (mp->local_address_start, &laddr6_start,
14191                    sizeof (ip6_address_t));
14192       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14193                    sizeof (ip6_address_t));
14194     }
14195   else
14196     {
14197       clib_memcpy (mp->remote_address_start, &raddr4_start,
14198                    sizeof (ip4_address_t));
14199       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14200                    sizeof (ip4_address_t));
14201       clib_memcpy (mp->local_address_start, &laddr4_start,
14202                    sizeof (ip4_address_t));
14203       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14204                    sizeof (ip4_address_t));
14205     }
14206   mp->protocol = (u8) protocol;
14207   mp->local_port_start = ntohs ((u16) lport_start);
14208   mp->local_port_stop = ntohs ((u16) lport_stop);
14209   mp->remote_port_start = ntohs ((u16) rport_start);
14210   mp->remote_port_stop = ntohs ((u16) rport_stop);
14211   mp->policy = (u8) policy;
14212   mp->sa_id = ntohl (sa_id);
14213   mp->is_add = is_add;
14214   mp->is_ip_any = is_ip_any;
14215   S (mp);
14216   W (ret);
14217   return ret;
14218 }
14219
14220 static int
14221 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14222 {
14223   unformat_input_t *i = vam->input;
14224   vl_api_ipsec_sad_add_del_entry_t *mp;
14225   u32 sad_id = 0, spi = 0;
14226   u8 *ck = 0, *ik = 0;
14227   u8 is_add = 1;
14228
14229   u8 protocol = IPSEC_PROTOCOL_AH;
14230   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14231   u32 crypto_alg = 0, integ_alg = 0;
14232   ip4_address_t tun_src4;
14233   ip4_address_t tun_dst4;
14234   ip6_address_t tun_src6;
14235   ip6_address_t tun_dst6;
14236   int ret;
14237
14238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14239     {
14240       if (unformat (i, "del"))
14241         is_add = 0;
14242       else if (unformat (i, "sad_id %d", &sad_id))
14243         ;
14244       else if (unformat (i, "spi %d", &spi))
14245         ;
14246       else if (unformat (i, "esp"))
14247         protocol = IPSEC_PROTOCOL_ESP;
14248       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14249         {
14250           is_tunnel = 1;
14251           is_tunnel_ipv6 = 0;
14252         }
14253       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14254         {
14255           is_tunnel = 1;
14256           is_tunnel_ipv6 = 0;
14257         }
14258       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14259         {
14260           is_tunnel = 1;
14261           is_tunnel_ipv6 = 1;
14262         }
14263       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14264         {
14265           is_tunnel = 1;
14266           is_tunnel_ipv6 = 1;
14267         }
14268       else
14269         if (unformat
14270             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14271         {
14272           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14273               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14274             {
14275               clib_warning ("unsupported crypto-alg: '%U'",
14276                             format_ipsec_crypto_alg, crypto_alg);
14277               return -99;
14278             }
14279         }
14280       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14281         ;
14282       else
14283         if (unformat
14284             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14285         {
14286           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14287               integ_alg >= IPSEC_INTEG_N_ALG)
14288             {
14289               clib_warning ("unsupported integ-alg: '%U'",
14290                             format_ipsec_integ_alg, integ_alg);
14291               return -99;
14292             }
14293         }
14294       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14295         ;
14296       else
14297         {
14298           clib_warning ("parse error '%U'", format_unformat_error, i);
14299           return -99;
14300         }
14301
14302     }
14303
14304   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14305
14306   mp->sad_id = ntohl (sad_id);
14307   mp->is_add = is_add;
14308   mp->protocol = protocol;
14309   mp->spi = ntohl (spi);
14310   mp->is_tunnel = is_tunnel;
14311   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14312   mp->crypto_algorithm = crypto_alg;
14313   mp->integrity_algorithm = integ_alg;
14314   mp->crypto_key_length = vec_len (ck);
14315   mp->integrity_key_length = vec_len (ik);
14316
14317   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14318     mp->crypto_key_length = sizeof (mp->crypto_key);
14319
14320   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14321     mp->integrity_key_length = sizeof (mp->integrity_key);
14322
14323   if (ck)
14324     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14325   if (ik)
14326     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14327
14328   if (is_tunnel)
14329     {
14330       if (is_tunnel_ipv6)
14331         {
14332           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14333                        sizeof (ip6_address_t));
14334           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14335                        sizeof (ip6_address_t));
14336         }
14337       else
14338         {
14339           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14340                        sizeof (ip4_address_t));
14341           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14342                        sizeof (ip4_address_t));
14343         }
14344     }
14345
14346   S (mp);
14347   W (ret);
14348   return ret;
14349 }
14350
14351 static int
14352 api_ipsec_sa_set_key (vat_main_t * vam)
14353 {
14354   unformat_input_t *i = vam->input;
14355   vl_api_ipsec_sa_set_key_t *mp;
14356   u32 sa_id;
14357   u8 *ck = 0, *ik = 0;
14358   int ret;
14359
14360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14361     {
14362       if (unformat (i, "sa_id %d", &sa_id))
14363         ;
14364       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14365         ;
14366       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14367         ;
14368       else
14369         {
14370           clib_warning ("parse error '%U'", format_unformat_error, i);
14371           return -99;
14372         }
14373     }
14374
14375   M (IPSEC_SA_SET_KEY, mp);
14376
14377   mp->sa_id = ntohl (sa_id);
14378   mp->crypto_key_length = vec_len (ck);
14379   mp->integrity_key_length = vec_len (ik);
14380
14381   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14382     mp->crypto_key_length = sizeof (mp->crypto_key);
14383
14384   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14385     mp->integrity_key_length = sizeof (mp->integrity_key);
14386
14387   if (ck)
14388     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14389   if (ik)
14390     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14391
14392   S (mp);
14393   W (ret);
14394   return ret;
14395 }
14396
14397 static int
14398 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14399 {
14400   unformat_input_t *i = vam->input;
14401   vl_api_ipsec_tunnel_if_add_del_t *mp;
14402   u32 local_spi = 0, remote_spi = 0;
14403   u32 crypto_alg = 0, integ_alg = 0;
14404   u8 *lck = NULL, *rck = NULL;
14405   u8 *lik = NULL, *rik = NULL;
14406   ip4_address_t local_ip = { {0} };
14407   ip4_address_t remote_ip = { {0} };
14408   u8 is_add = 1;
14409   u8 esn = 0;
14410   u8 anti_replay = 0;
14411   int ret;
14412
14413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14414     {
14415       if (unformat (i, "del"))
14416         is_add = 0;
14417       else if (unformat (i, "esn"))
14418         esn = 1;
14419       else if (unformat (i, "anti_replay"))
14420         anti_replay = 1;
14421       else if (unformat (i, "local_spi %d", &local_spi))
14422         ;
14423       else if (unformat (i, "remote_spi %d", &remote_spi))
14424         ;
14425       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14426         ;
14427       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14428         ;
14429       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14430         ;
14431       else
14432         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14433         ;
14434       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14435         ;
14436       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14437         ;
14438       else
14439         if (unformat
14440             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14441         {
14442           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14443               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14444             {
14445               errmsg ("unsupported crypto-alg: '%U'\n",
14446                       format_ipsec_crypto_alg, crypto_alg);
14447               return -99;
14448             }
14449         }
14450       else
14451         if (unformat
14452             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14453         {
14454           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14455               integ_alg >= IPSEC_INTEG_N_ALG)
14456             {
14457               errmsg ("unsupported integ-alg: '%U'\n",
14458                       format_ipsec_integ_alg, integ_alg);
14459               return -99;
14460             }
14461         }
14462       else
14463         {
14464           errmsg ("parse error '%U'\n", format_unformat_error, i);
14465           return -99;
14466         }
14467     }
14468
14469   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14470
14471   mp->is_add = is_add;
14472   mp->esn = esn;
14473   mp->anti_replay = anti_replay;
14474
14475   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14476   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14477
14478   mp->local_spi = htonl (local_spi);
14479   mp->remote_spi = htonl (remote_spi);
14480   mp->crypto_alg = (u8) crypto_alg;
14481
14482   mp->local_crypto_key_len = 0;
14483   if (lck)
14484     {
14485       mp->local_crypto_key_len = vec_len (lck);
14486       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14487         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14488       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14489     }
14490
14491   mp->remote_crypto_key_len = 0;
14492   if (rck)
14493     {
14494       mp->remote_crypto_key_len = vec_len (rck);
14495       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14496         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14497       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14498     }
14499
14500   mp->integ_alg = (u8) integ_alg;
14501
14502   mp->local_integ_key_len = 0;
14503   if (lik)
14504     {
14505       mp->local_integ_key_len = vec_len (lik);
14506       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14507         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14508       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14509     }
14510
14511   mp->remote_integ_key_len = 0;
14512   if (rik)
14513     {
14514       mp->remote_integ_key_len = vec_len (rik);
14515       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14516         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14517       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14518     }
14519
14520   S (mp);
14521   W (ret);
14522   return ret;
14523 }
14524
14525 static void
14526 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14527 {
14528   vat_main_t *vam = &vat_main;
14529
14530   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14531          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14532          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14533          "tunnel_src_addr %U tunnel_dst_addr %U "
14534          "salt %u seq_outbound %lu last_seq_inbound %lu "
14535          "replay_window %lu total_data_size %lu\n",
14536          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14537          mp->protocol,
14538          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14539          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14540          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14541          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14542          mp->tunnel_src_addr,
14543          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14544          mp->tunnel_dst_addr,
14545          ntohl (mp->salt),
14546          clib_net_to_host_u64 (mp->seq_outbound),
14547          clib_net_to_host_u64 (mp->last_seq_inbound),
14548          clib_net_to_host_u64 (mp->replay_window),
14549          clib_net_to_host_u64 (mp->total_data_size));
14550 }
14551
14552 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14553 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14554
14555 static void vl_api_ipsec_sa_details_t_handler_json
14556   (vl_api_ipsec_sa_details_t * mp)
14557 {
14558   vat_main_t *vam = &vat_main;
14559   vat_json_node_t *node = NULL;
14560   struct in_addr src_ip4, dst_ip4;
14561   struct in6_addr src_ip6, dst_ip6;
14562
14563   if (VAT_JSON_ARRAY != vam->json_tree.type)
14564     {
14565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14566       vat_json_init_array (&vam->json_tree);
14567     }
14568   node = vat_json_array_add (&vam->json_tree);
14569
14570   vat_json_init_object (node);
14571   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14572   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14573   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14574   vat_json_object_add_uint (node, "proto", mp->protocol);
14575   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14576   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14577   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14578   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14579   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14580   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14581   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14582                              mp->crypto_key_len);
14583   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14584                              mp->integ_key_len);
14585   if (mp->is_tunnel_ip6)
14586     {
14587       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14588       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14589       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14590       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14591     }
14592   else
14593     {
14594       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14595       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14596       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14597       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14598     }
14599   vat_json_object_add_uint (node, "replay_window",
14600                             clib_net_to_host_u64 (mp->replay_window));
14601   vat_json_object_add_uint (node, "total_data_size",
14602                             clib_net_to_host_u64 (mp->total_data_size));
14603
14604 }
14605
14606 static int
14607 api_ipsec_sa_dump (vat_main_t * vam)
14608 {
14609   unformat_input_t *i = vam->input;
14610   vl_api_ipsec_sa_dump_t *mp;
14611   vl_api_control_ping_t *mp_ping;
14612   u32 sa_id = ~0;
14613   int ret;
14614
14615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14616     {
14617       if (unformat (i, "sa_id %d", &sa_id))
14618         ;
14619       else
14620         {
14621           clib_warning ("parse error '%U'", format_unformat_error, i);
14622           return -99;
14623         }
14624     }
14625
14626   M (IPSEC_SA_DUMP, mp);
14627
14628   mp->sa_id = ntohl (sa_id);
14629
14630   S (mp);
14631
14632   /* Use a control ping for synchronization */
14633   M (CONTROL_PING, mp_ping);
14634   S (mp_ping);
14635
14636   W (ret);
14637   return ret;
14638 }
14639
14640 static int
14641 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14642 {
14643   unformat_input_t *i = vam->input;
14644   vl_api_ipsec_tunnel_if_set_key_t *mp;
14645   u32 sw_if_index = ~0;
14646   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14647   u8 *key = 0;
14648   u32 alg = ~0;
14649   int ret;
14650
14651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14652     {
14653       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14654         ;
14655       else
14656         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14657         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14658       else
14659         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14660         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14661       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14662         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14663       else
14664         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14665         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14666       else if (unformat (i, "%U", unformat_hex_string, &key))
14667         ;
14668       else
14669         {
14670           clib_warning ("parse error '%U'", format_unformat_error, i);
14671           return -99;
14672         }
14673     }
14674
14675   if (sw_if_index == ~0)
14676     {
14677       errmsg ("interface must be specified");
14678       return -99;
14679     }
14680
14681   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14682     {
14683       errmsg ("key type must be specified");
14684       return -99;
14685     }
14686
14687   if (alg == ~0)
14688     {
14689       errmsg ("algorithm must be specified");
14690       return -99;
14691     }
14692
14693   if (vec_len (key) == 0)
14694     {
14695       errmsg ("key must be specified");
14696       return -99;
14697     }
14698
14699   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14700
14701   mp->sw_if_index = htonl (sw_if_index);
14702   mp->alg = alg;
14703   mp->key_type = key_type;
14704   mp->key_len = vec_len (key);
14705   clib_memcpy (mp->key, key, vec_len (key));
14706
14707   S (mp);
14708   W (ret);
14709
14710   return ret;
14711 }
14712
14713 static int
14714 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14715 {
14716   unformat_input_t *i = vam->input;
14717   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14718   u32 sw_if_index = ~0;
14719   u32 sa_id = ~0;
14720   u8 is_outbound = (u8) ~ 0;
14721   int ret;
14722
14723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14726         ;
14727       else if (unformat (i, "sa_id %d", &sa_id))
14728         ;
14729       else if (unformat (i, "outbound"))
14730         is_outbound = 1;
14731       else if (unformat (i, "inbound"))
14732         is_outbound = 0;
14733       else
14734         {
14735           clib_warning ("parse error '%U'", format_unformat_error, i);
14736           return -99;
14737         }
14738     }
14739
14740   if (sw_if_index == ~0)
14741     {
14742       errmsg ("interface must be specified");
14743       return -99;
14744     }
14745
14746   if (sa_id == ~0)
14747     {
14748       errmsg ("SA ID must be specified");
14749       return -99;
14750     }
14751
14752   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14753
14754   mp->sw_if_index = htonl (sw_if_index);
14755   mp->sa_id = htonl (sa_id);
14756   mp->is_outbound = is_outbound;
14757
14758   S (mp);
14759   W (ret);
14760
14761   return ret;
14762 }
14763
14764 static int
14765 api_ikev2_profile_add_del (vat_main_t * vam)
14766 {
14767   unformat_input_t *i = vam->input;
14768   vl_api_ikev2_profile_add_del_t *mp;
14769   u8 is_add = 1;
14770   u8 *name = 0;
14771   int ret;
14772
14773   const char *valid_chars = "a-zA-Z0-9_";
14774
14775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14776     {
14777       if (unformat (i, "del"))
14778         is_add = 0;
14779       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14780         vec_add1 (name, 0);
14781       else
14782         {
14783           errmsg ("parse error '%U'", format_unformat_error, i);
14784           return -99;
14785         }
14786     }
14787
14788   if (!vec_len (name))
14789     {
14790       errmsg ("profile name must be specified");
14791       return -99;
14792     }
14793
14794   if (vec_len (name) > 64)
14795     {
14796       errmsg ("profile name too long");
14797       return -99;
14798     }
14799
14800   M (IKEV2_PROFILE_ADD_DEL, mp);
14801
14802   clib_memcpy (mp->name, name, vec_len (name));
14803   mp->is_add = is_add;
14804   vec_free (name);
14805
14806   S (mp);
14807   W (ret);
14808   return ret;
14809 }
14810
14811 static int
14812 api_ikev2_profile_set_auth (vat_main_t * vam)
14813 {
14814   unformat_input_t *i = vam->input;
14815   vl_api_ikev2_profile_set_auth_t *mp;
14816   u8 *name = 0;
14817   u8 *data = 0;
14818   u32 auth_method = 0;
14819   u8 is_hex = 0;
14820   int ret;
14821
14822   const char *valid_chars = "a-zA-Z0-9_";
14823
14824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14825     {
14826       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14827         vec_add1 (name, 0);
14828       else if (unformat (i, "auth_method %U",
14829                          unformat_ikev2_auth_method, &auth_method))
14830         ;
14831       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14832         is_hex = 1;
14833       else if (unformat (i, "auth_data %v", &data))
14834         ;
14835       else
14836         {
14837           errmsg ("parse error '%U'", format_unformat_error, i);
14838           return -99;
14839         }
14840     }
14841
14842   if (!vec_len (name))
14843     {
14844       errmsg ("profile name must be specified");
14845       return -99;
14846     }
14847
14848   if (vec_len (name) > 64)
14849     {
14850       errmsg ("profile name too long");
14851       return -99;
14852     }
14853
14854   if (!vec_len (data))
14855     {
14856       errmsg ("auth_data must be specified");
14857       return -99;
14858     }
14859
14860   if (!auth_method)
14861     {
14862       errmsg ("auth_method must be specified");
14863       return -99;
14864     }
14865
14866   M (IKEV2_PROFILE_SET_AUTH, mp);
14867
14868   mp->is_hex = is_hex;
14869   mp->auth_method = (u8) auth_method;
14870   mp->data_len = vec_len (data);
14871   clib_memcpy (mp->name, name, vec_len (name));
14872   clib_memcpy (mp->data, data, vec_len (data));
14873   vec_free (name);
14874   vec_free (data);
14875
14876   S (mp);
14877   W (ret);
14878   return ret;
14879 }
14880
14881 static int
14882 api_ikev2_profile_set_id (vat_main_t * vam)
14883 {
14884   unformat_input_t *i = vam->input;
14885   vl_api_ikev2_profile_set_id_t *mp;
14886   u8 *name = 0;
14887   u8 *data = 0;
14888   u8 is_local = 0;
14889   u32 id_type = 0;
14890   ip4_address_t ip4;
14891   int ret;
14892
14893   const char *valid_chars = "a-zA-Z0-9_";
14894
14895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14896     {
14897       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14898         vec_add1 (name, 0);
14899       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14900         ;
14901       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14902         {
14903           data = vec_new (u8, 4);
14904           clib_memcpy (data, ip4.as_u8, 4);
14905         }
14906       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14907         ;
14908       else if (unformat (i, "id_data %v", &data))
14909         ;
14910       else if (unformat (i, "local"))
14911         is_local = 1;
14912       else if (unformat (i, "remote"))
14913         is_local = 0;
14914       else
14915         {
14916           errmsg ("parse error '%U'", format_unformat_error, i);
14917           return -99;
14918         }
14919     }
14920
14921   if (!vec_len (name))
14922     {
14923       errmsg ("profile name must be specified");
14924       return -99;
14925     }
14926
14927   if (vec_len (name) > 64)
14928     {
14929       errmsg ("profile name too long");
14930       return -99;
14931     }
14932
14933   if (!vec_len (data))
14934     {
14935       errmsg ("id_data must be specified");
14936       return -99;
14937     }
14938
14939   if (!id_type)
14940     {
14941       errmsg ("id_type must be specified");
14942       return -99;
14943     }
14944
14945   M (IKEV2_PROFILE_SET_ID, mp);
14946
14947   mp->is_local = is_local;
14948   mp->id_type = (u8) id_type;
14949   mp->data_len = vec_len (data);
14950   clib_memcpy (mp->name, name, vec_len (name));
14951   clib_memcpy (mp->data, data, vec_len (data));
14952   vec_free (name);
14953   vec_free (data);
14954
14955   S (mp);
14956   W (ret);
14957   return ret;
14958 }
14959
14960 static int
14961 api_ikev2_profile_set_ts (vat_main_t * vam)
14962 {
14963   unformat_input_t *i = vam->input;
14964   vl_api_ikev2_profile_set_ts_t *mp;
14965   u8 *name = 0;
14966   u8 is_local = 0;
14967   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14968   ip4_address_t start_addr, end_addr;
14969
14970   const char *valid_chars = "a-zA-Z0-9_";
14971   int ret;
14972
14973   start_addr.as_u32 = 0;
14974   end_addr.as_u32 = (u32) ~ 0;
14975
14976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14977     {
14978       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14979         vec_add1 (name, 0);
14980       else if (unformat (i, "protocol %d", &proto))
14981         ;
14982       else if (unformat (i, "start_port %d", &start_port))
14983         ;
14984       else if (unformat (i, "end_port %d", &end_port))
14985         ;
14986       else
14987         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14988         ;
14989       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14990         ;
14991       else if (unformat (i, "local"))
14992         is_local = 1;
14993       else if (unformat (i, "remote"))
14994         is_local = 0;
14995       else
14996         {
14997           errmsg ("parse error '%U'", format_unformat_error, i);
14998           return -99;
14999         }
15000     }
15001
15002   if (!vec_len (name))
15003     {
15004       errmsg ("profile name must be specified");
15005       return -99;
15006     }
15007
15008   if (vec_len (name) > 64)
15009     {
15010       errmsg ("profile name too long");
15011       return -99;
15012     }
15013
15014   M (IKEV2_PROFILE_SET_TS, mp);
15015
15016   mp->is_local = is_local;
15017   mp->proto = (u8) proto;
15018   mp->start_port = (u16) start_port;
15019   mp->end_port = (u16) end_port;
15020   mp->start_addr = start_addr.as_u32;
15021   mp->end_addr = end_addr.as_u32;
15022   clib_memcpy (mp->name, name, vec_len (name));
15023   vec_free (name);
15024
15025   S (mp);
15026   W (ret);
15027   return ret;
15028 }
15029
15030 static int
15031 api_ikev2_set_local_key (vat_main_t * vam)
15032 {
15033   unformat_input_t *i = vam->input;
15034   vl_api_ikev2_set_local_key_t *mp;
15035   u8 *file = 0;
15036   int ret;
15037
15038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15039     {
15040       if (unformat (i, "file %v", &file))
15041         vec_add1 (file, 0);
15042       else
15043         {
15044           errmsg ("parse error '%U'", format_unformat_error, i);
15045           return -99;
15046         }
15047     }
15048
15049   if (!vec_len (file))
15050     {
15051       errmsg ("RSA key file must be specified");
15052       return -99;
15053     }
15054
15055   if (vec_len (file) > 256)
15056     {
15057       errmsg ("file name too long");
15058       return -99;
15059     }
15060
15061   M (IKEV2_SET_LOCAL_KEY, mp);
15062
15063   clib_memcpy (mp->key_file, file, vec_len (file));
15064   vec_free (file);
15065
15066   S (mp);
15067   W (ret);
15068   return ret;
15069 }
15070
15071 static int
15072 api_ikev2_set_responder (vat_main_t * vam)
15073 {
15074   unformat_input_t *i = vam->input;
15075   vl_api_ikev2_set_responder_t *mp;
15076   int ret;
15077   u8 *name = 0;
15078   u32 sw_if_index = ~0;
15079   ip4_address_t address;
15080
15081   const char *valid_chars = "a-zA-Z0-9_";
15082
15083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15084     {
15085       if (unformat
15086           (i, "%U interface %d address %U", unformat_token, valid_chars,
15087            &name, &sw_if_index, unformat_ip4_address, &address))
15088         vec_add1 (name, 0);
15089       else
15090         {
15091           errmsg ("parse error '%U'", format_unformat_error, i);
15092           return -99;
15093         }
15094     }
15095
15096   if (!vec_len (name))
15097     {
15098       errmsg ("profile name must be specified");
15099       return -99;
15100     }
15101
15102   if (vec_len (name) > 64)
15103     {
15104       errmsg ("profile name too long");
15105       return -99;
15106     }
15107
15108   M (IKEV2_SET_RESPONDER, mp);
15109
15110   clib_memcpy (mp->name, name, vec_len (name));
15111   vec_free (name);
15112
15113   mp->sw_if_index = sw_if_index;
15114   clib_memcpy (mp->address, &address, sizeof (address));
15115
15116   S (mp);
15117   W (ret);
15118   return ret;
15119 }
15120
15121 static int
15122 api_ikev2_set_ike_transforms (vat_main_t * vam)
15123 {
15124   unformat_input_t *i = vam->input;
15125   vl_api_ikev2_set_ike_transforms_t *mp;
15126   int ret;
15127   u8 *name = 0;
15128   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15129
15130   const char *valid_chars = "a-zA-Z0-9_";
15131
15132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15133     {
15134       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15135                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15136         vec_add1 (name, 0);
15137       else
15138         {
15139           errmsg ("parse error '%U'", format_unformat_error, i);
15140           return -99;
15141         }
15142     }
15143
15144   if (!vec_len (name))
15145     {
15146       errmsg ("profile name must be specified");
15147       return -99;
15148     }
15149
15150   if (vec_len (name) > 64)
15151     {
15152       errmsg ("profile name too long");
15153       return -99;
15154     }
15155
15156   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15157
15158   clib_memcpy (mp->name, name, vec_len (name));
15159   vec_free (name);
15160   mp->crypto_alg = crypto_alg;
15161   mp->crypto_key_size = crypto_key_size;
15162   mp->integ_alg = integ_alg;
15163   mp->dh_group = dh_group;
15164
15165   S (mp);
15166   W (ret);
15167   return ret;
15168 }
15169
15170
15171 static int
15172 api_ikev2_set_esp_transforms (vat_main_t * vam)
15173 {
15174   unformat_input_t *i = vam->input;
15175   vl_api_ikev2_set_esp_transforms_t *mp;
15176   int ret;
15177   u8 *name = 0;
15178   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15179
15180   const char *valid_chars = "a-zA-Z0-9_";
15181
15182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15183     {
15184       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15185                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15186         vec_add1 (name, 0);
15187       else
15188         {
15189           errmsg ("parse error '%U'", format_unformat_error, i);
15190           return -99;
15191         }
15192     }
15193
15194   if (!vec_len (name))
15195     {
15196       errmsg ("profile name must be specified");
15197       return -99;
15198     }
15199
15200   if (vec_len (name) > 64)
15201     {
15202       errmsg ("profile name too long");
15203       return -99;
15204     }
15205
15206   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15207
15208   clib_memcpy (mp->name, name, vec_len (name));
15209   vec_free (name);
15210   mp->crypto_alg = crypto_alg;
15211   mp->crypto_key_size = crypto_key_size;
15212   mp->integ_alg = integ_alg;
15213   mp->dh_group = dh_group;
15214
15215   S (mp);
15216   W (ret);
15217   return ret;
15218 }
15219
15220 static int
15221 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15222 {
15223   unformat_input_t *i = vam->input;
15224   vl_api_ikev2_set_sa_lifetime_t *mp;
15225   int ret;
15226   u8 *name = 0;
15227   u64 lifetime, lifetime_maxdata;
15228   u32 lifetime_jitter, handover;
15229
15230   const char *valid_chars = "a-zA-Z0-9_";
15231
15232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15233     {
15234       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15235                     &lifetime, &lifetime_jitter, &handover,
15236                     &lifetime_maxdata))
15237         vec_add1 (name, 0);
15238       else
15239         {
15240           errmsg ("parse error '%U'", format_unformat_error, i);
15241           return -99;
15242         }
15243     }
15244
15245   if (!vec_len (name))
15246     {
15247       errmsg ("profile name must be specified");
15248       return -99;
15249     }
15250
15251   if (vec_len (name) > 64)
15252     {
15253       errmsg ("profile name too long");
15254       return -99;
15255     }
15256
15257   M (IKEV2_SET_SA_LIFETIME, mp);
15258
15259   clib_memcpy (mp->name, name, vec_len (name));
15260   vec_free (name);
15261   mp->lifetime = lifetime;
15262   mp->lifetime_jitter = lifetime_jitter;
15263   mp->handover = handover;
15264   mp->lifetime_maxdata = lifetime_maxdata;
15265
15266   S (mp);
15267   W (ret);
15268   return ret;
15269 }
15270
15271 static int
15272 api_ikev2_initiate_sa_init (vat_main_t * vam)
15273 {
15274   unformat_input_t *i = vam->input;
15275   vl_api_ikev2_initiate_sa_init_t *mp;
15276   int ret;
15277   u8 *name = 0;
15278
15279   const char *valid_chars = "a-zA-Z0-9_";
15280
15281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15282     {
15283       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15284         vec_add1 (name, 0);
15285       else
15286         {
15287           errmsg ("parse error '%U'", format_unformat_error, i);
15288           return -99;
15289         }
15290     }
15291
15292   if (!vec_len (name))
15293     {
15294       errmsg ("profile name must be specified");
15295       return -99;
15296     }
15297
15298   if (vec_len (name) > 64)
15299     {
15300       errmsg ("profile name too long");
15301       return -99;
15302     }
15303
15304   M (IKEV2_INITIATE_SA_INIT, mp);
15305
15306   clib_memcpy (mp->name, name, vec_len (name));
15307   vec_free (name);
15308
15309   S (mp);
15310   W (ret);
15311   return ret;
15312 }
15313
15314 static int
15315 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15316 {
15317   unformat_input_t *i = vam->input;
15318   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15319   int ret;
15320   u64 ispi;
15321
15322
15323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15324     {
15325       if (unformat (i, "%lx", &ispi))
15326         ;
15327       else
15328         {
15329           errmsg ("parse error '%U'", format_unformat_error, i);
15330           return -99;
15331         }
15332     }
15333
15334   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15335
15336   mp->ispi = ispi;
15337
15338   S (mp);
15339   W (ret);
15340   return ret;
15341 }
15342
15343 static int
15344 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15345 {
15346   unformat_input_t *i = vam->input;
15347   vl_api_ikev2_initiate_del_child_sa_t *mp;
15348   int ret;
15349   u32 ispi;
15350
15351
15352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15353     {
15354       if (unformat (i, "%x", &ispi))
15355         ;
15356       else
15357         {
15358           errmsg ("parse error '%U'", format_unformat_error, i);
15359           return -99;
15360         }
15361     }
15362
15363   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15364
15365   mp->ispi = ispi;
15366
15367   S (mp);
15368   W (ret);
15369   return ret;
15370 }
15371
15372 static int
15373 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15374 {
15375   unformat_input_t *i = vam->input;
15376   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15377   int ret;
15378   u32 ispi;
15379
15380
15381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15382     {
15383       if (unformat (i, "%x", &ispi))
15384         ;
15385       else
15386         {
15387           errmsg ("parse error '%U'", format_unformat_error, i);
15388           return -99;
15389         }
15390     }
15391
15392   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15393
15394   mp->ispi = ispi;
15395
15396   S (mp);
15397   W (ret);
15398   return ret;
15399 }
15400
15401 /*
15402  * MAP
15403  */
15404 static int
15405 api_map_add_domain (vat_main_t * vam)
15406 {
15407   unformat_input_t *i = vam->input;
15408   vl_api_map_add_domain_t *mp;
15409
15410   ip4_address_t ip4_prefix;
15411   ip6_address_t ip6_prefix;
15412   ip6_address_t ip6_src;
15413   u32 num_m_args = 0;
15414   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15415     0, psid_length = 0;
15416   u8 is_translation = 0;
15417   u32 mtu = 0;
15418   u32 ip6_src_len = 128;
15419   int ret;
15420
15421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15422     {
15423       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15424                     &ip4_prefix, &ip4_prefix_len))
15425         num_m_args++;
15426       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15427                          &ip6_prefix, &ip6_prefix_len))
15428         num_m_args++;
15429       else
15430         if (unformat
15431             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15432              &ip6_src_len))
15433         num_m_args++;
15434       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15435         num_m_args++;
15436       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15437         num_m_args++;
15438       else if (unformat (i, "psid-offset %d", &psid_offset))
15439         num_m_args++;
15440       else if (unformat (i, "psid-len %d", &psid_length))
15441         num_m_args++;
15442       else if (unformat (i, "mtu %d", &mtu))
15443         num_m_args++;
15444       else if (unformat (i, "map-t"))
15445         is_translation = 1;
15446       else
15447         {
15448           clib_warning ("parse error '%U'", format_unformat_error, i);
15449           return -99;
15450         }
15451     }
15452
15453   if (num_m_args < 3)
15454     {
15455       errmsg ("mandatory argument(s) missing");
15456       return -99;
15457     }
15458
15459   /* Construct the API message */
15460   M (MAP_ADD_DOMAIN, mp);
15461
15462   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15463   mp->ip4_prefix_len = ip4_prefix_len;
15464
15465   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15466   mp->ip6_prefix_len = ip6_prefix_len;
15467
15468   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15469   mp->ip6_src_prefix_len = ip6_src_len;
15470
15471   mp->ea_bits_len = ea_bits_len;
15472   mp->psid_offset = psid_offset;
15473   mp->psid_length = psid_length;
15474   mp->is_translation = is_translation;
15475   mp->mtu = htons (mtu);
15476
15477   /* send it... */
15478   S (mp);
15479
15480   /* Wait for a reply, return good/bad news  */
15481   W (ret);
15482   return ret;
15483 }
15484
15485 static int
15486 api_map_del_domain (vat_main_t * vam)
15487 {
15488   unformat_input_t *i = vam->input;
15489   vl_api_map_del_domain_t *mp;
15490
15491   u32 num_m_args = 0;
15492   u32 index;
15493   int ret;
15494
15495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15496     {
15497       if (unformat (i, "index %d", &index))
15498         num_m_args++;
15499       else
15500         {
15501           clib_warning ("parse error '%U'", format_unformat_error, i);
15502           return -99;
15503         }
15504     }
15505
15506   if (num_m_args != 1)
15507     {
15508       errmsg ("mandatory argument(s) missing");
15509       return -99;
15510     }
15511
15512   /* Construct the API message */
15513   M (MAP_DEL_DOMAIN, mp);
15514
15515   mp->index = ntohl (index);
15516
15517   /* send it... */
15518   S (mp);
15519
15520   /* Wait for a reply, return good/bad news  */
15521   W (ret);
15522   return ret;
15523 }
15524
15525 static int
15526 api_map_add_del_rule (vat_main_t * vam)
15527 {
15528   unformat_input_t *i = vam->input;
15529   vl_api_map_add_del_rule_t *mp;
15530   u8 is_add = 1;
15531   ip6_address_t ip6_dst;
15532   u32 num_m_args = 0, index, psid = 0;
15533   int ret;
15534
15535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15536     {
15537       if (unformat (i, "index %d", &index))
15538         num_m_args++;
15539       else if (unformat (i, "psid %d", &psid))
15540         num_m_args++;
15541       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15542         num_m_args++;
15543       else if (unformat (i, "del"))
15544         {
15545           is_add = 0;
15546         }
15547       else
15548         {
15549           clib_warning ("parse error '%U'", format_unformat_error, i);
15550           return -99;
15551         }
15552     }
15553
15554   /* Construct the API message */
15555   M (MAP_ADD_DEL_RULE, mp);
15556
15557   mp->index = ntohl (index);
15558   mp->is_add = is_add;
15559   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15560   mp->psid = ntohs (psid);
15561
15562   /* send it... */
15563   S (mp);
15564
15565   /* Wait for a reply, return good/bad news  */
15566   W (ret);
15567   return ret;
15568 }
15569
15570 static int
15571 api_map_domain_dump (vat_main_t * vam)
15572 {
15573   vl_api_map_domain_dump_t *mp;
15574   vl_api_control_ping_t *mp_ping;
15575   int ret;
15576
15577   /* Construct the API message */
15578   M (MAP_DOMAIN_DUMP, mp);
15579
15580   /* send it... */
15581   S (mp);
15582
15583   /* Use a control ping for synchronization */
15584   MPING (CONTROL_PING, mp_ping);
15585   S (mp_ping);
15586
15587   W (ret);
15588   return ret;
15589 }
15590
15591 static int
15592 api_map_rule_dump (vat_main_t * vam)
15593 {
15594   unformat_input_t *i = vam->input;
15595   vl_api_map_rule_dump_t *mp;
15596   vl_api_control_ping_t *mp_ping;
15597   u32 domain_index = ~0;
15598   int ret;
15599
15600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15601     {
15602       if (unformat (i, "index %u", &domain_index))
15603         ;
15604       else
15605         break;
15606     }
15607
15608   if (domain_index == ~0)
15609     {
15610       clib_warning ("parse error: domain index expected");
15611       return -99;
15612     }
15613
15614   /* Construct the API message */
15615   M (MAP_RULE_DUMP, mp);
15616
15617   mp->domain_index = htonl (domain_index);
15618
15619   /* send it... */
15620   S (mp);
15621
15622   /* Use a control ping for synchronization */
15623   MPING (CONTROL_PING, mp_ping);
15624   S (mp_ping);
15625
15626   W (ret);
15627   return ret;
15628 }
15629
15630 static void vl_api_map_add_domain_reply_t_handler
15631   (vl_api_map_add_domain_reply_t * mp)
15632 {
15633   vat_main_t *vam = &vat_main;
15634   i32 retval = ntohl (mp->retval);
15635
15636   if (vam->async_mode)
15637     {
15638       vam->async_errors += (retval < 0);
15639     }
15640   else
15641     {
15642       vam->retval = retval;
15643       vam->result_ready = 1;
15644     }
15645 }
15646
15647 static void vl_api_map_add_domain_reply_t_handler_json
15648   (vl_api_map_add_domain_reply_t * mp)
15649 {
15650   vat_main_t *vam = &vat_main;
15651   vat_json_node_t node;
15652
15653   vat_json_init_object (&node);
15654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15655   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15656
15657   vat_json_print (vam->ofp, &node);
15658   vat_json_free (&node);
15659
15660   vam->retval = ntohl (mp->retval);
15661   vam->result_ready = 1;
15662 }
15663
15664 static int
15665 api_get_first_msg_id (vat_main_t * vam)
15666 {
15667   vl_api_get_first_msg_id_t *mp;
15668   unformat_input_t *i = vam->input;
15669   u8 *name;
15670   u8 name_set = 0;
15671   int ret;
15672
15673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15674     {
15675       if (unformat (i, "client %s", &name))
15676         name_set = 1;
15677       else
15678         break;
15679     }
15680
15681   if (name_set == 0)
15682     {
15683       errmsg ("missing client name");
15684       return -99;
15685     }
15686   vec_add1 (name, 0);
15687
15688   if (vec_len (name) > 63)
15689     {
15690       errmsg ("client name too long");
15691       return -99;
15692     }
15693
15694   M (GET_FIRST_MSG_ID, mp);
15695   clib_memcpy (mp->name, name, vec_len (name));
15696   S (mp);
15697   W (ret);
15698   return ret;
15699 }
15700
15701 static int
15702 api_cop_interface_enable_disable (vat_main_t * vam)
15703 {
15704   unformat_input_t *line_input = vam->input;
15705   vl_api_cop_interface_enable_disable_t *mp;
15706   u32 sw_if_index = ~0;
15707   u8 enable_disable = 1;
15708   int ret;
15709
15710   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15711     {
15712       if (unformat (line_input, "disable"))
15713         enable_disable = 0;
15714       if (unformat (line_input, "enable"))
15715         enable_disable = 1;
15716       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15717                          vam, &sw_if_index))
15718         ;
15719       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15720         ;
15721       else
15722         break;
15723     }
15724
15725   if (sw_if_index == ~0)
15726     {
15727       errmsg ("missing interface name or sw_if_index");
15728       return -99;
15729     }
15730
15731   /* Construct the API message */
15732   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15733   mp->sw_if_index = ntohl (sw_if_index);
15734   mp->enable_disable = enable_disable;
15735
15736   /* send it... */
15737   S (mp);
15738   /* Wait for the reply */
15739   W (ret);
15740   return ret;
15741 }
15742
15743 static int
15744 api_cop_whitelist_enable_disable (vat_main_t * vam)
15745 {
15746   unformat_input_t *line_input = vam->input;
15747   vl_api_cop_whitelist_enable_disable_t *mp;
15748   u32 sw_if_index = ~0;
15749   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15750   u32 fib_id = 0;
15751   int ret;
15752
15753   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15754     {
15755       if (unformat (line_input, "ip4"))
15756         ip4 = 1;
15757       else if (unformat (line_input, "ip6"))
15758         ip6 = 1;
15759       else if (unformat (line_input, "default"))
15760         default_cop = 1;
15761       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15762                          vam, &sw_if_index))
15763         ;
15764       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15765         ;
15766       else if (unformat (line_input, "fib-id %d", &fib_id))
15767         ;
15768       else
15769         break;
15770     }
15771
15772   if (sw_if_index == ~0)
15773     {
15774       errmsg ("missing interface name or sw_if_index");
15775       return -99;
15776     }
15777
15778   /* Construct the API message */
15779   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15780   mp->sw_if_index = ntohl (sw_if_index);
15781   mp->fib_id = ntohl (fib_id);
15782   mp->ip4 = ip4;
15783   mp->ip6 = ip6;
15784   mp->default_cop = default_cop;
15785
15786   /* send it... */
15787   S (mp);
15788   /* Wait for the reply */
15789   W (ret);
15790   return ret;
15791 }
15792
15793 static int
15794 api_get_node_graph (vat_main_t * vam)
15795 {
15796   vl_api_get_node_graph_t *mp;
15797   int ret;
15798
15799   M (GET_NODE_GRAPH, mp);
15800
15801   /* send it... */
15802   S (mp);
15803   /* Wait for the reply */
15804   W (ret);
15805   return ret;
15806 }
15807
15808 /* *INDENT-OFF* */
15809 /** Used for parsing LISP eids */
15810 typedef CLIB_PACKED(struct{
15811   u8 addr[16];   /**< eid address */
15812   u32 len;       /**< prefix length if IP */
15813   u8 type;      /**< type of eid */
15814 }) lisp_eid_vat_t;
15815 /* *INDENT-ON* */
15816
15817 static uword
15818 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15819 {
15820   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15821
15822   memset (a, 0, sizeof (a[0]));
15823
15824   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15825     {
15826       a->type = 0;              /* ipv4 type */
15827     }
15828   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15829     {
15830       a->type = 1;              /* ipv6 type */
15831     }
15832   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15833     {
15834       a->type = 2;              /* mac type */
15835     }
15836   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15837     {
15838       a->type = 3;              /* NSH type */
15839       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15840       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15841     }
15842   else
15843     {
15844       return 0;
15845     }
15846
15847   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15848     {
15849       return 0;
15850     }
15851
15852   return 1;
15853 }
15854
15855 static int
15856 lisp_eid_size_vat (u8 type)
15857 {
15858   switch (type)
15859     {
15860     case 0:
15861       return 4;
15862     case 1:
15863       return 16;
15864     case 2:
15865       return 6;
15866     case 3:
15867       return 5;
15868     }
15869   return 0;
15870 }
15871
15872 static void
15873 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15874 {
15875   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15876 }
15877
15878 static int
15879 api_one_add_del_locator_set (vat_main_t * vam)
15880 {
15881   unformat_input_t *input = vam->input;
15882   vl_api_one_add_del_locator_set_t *mp;
15883   u8 is_add = 1;
15884   u8 *locator_set_name = NULL;
15885   u8 locator_set_name_set = 0;
15886   vl_api_local_locator_t locator, *locators = 0;
15887   u32 sw_if_index, priority, weight;
15888   u32 data_len = 0;
15889
15890   int ret;
15891   /* Parse args required to build the message */
15892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15893     {
15894       if (unformat (input, "del"))
15895         {
15896           is_add = 0;
15897         }
15898       else if (unformat (input, "locator-set %s", &locator_set_name))
15899         {
15900           locator_set_name_set = 1;
15901         }
15902       else if (unformat (input, "sw_if_index %u p %u w %u",
15903                          &sw_if_index, &priority, &weight))
15904         {
15905           locator.sw_if_index = htonl (sw_if_index);
15906           locator.priority = priority;
15907           locator.weight = weight;
15908           vec_add1 (locators, locator);
15909         }
15910       else
15911         if (unformat
15912             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15913              &sw_if_index, &priority, &weight))
15914         {
15915           locator.sw_if_index = htonl (sw_if_index);
15916           locator.priority = priority;
15917           locator.weight = weight;
15918           vec_add1 (locators, locator);
15919         }
15920       else
15921         break;
15922     }
15923
15924   if (locator_set_name_set == 0)
15925     {
15926       errmsg ("missing locator-set name");
15927       vec_free (locators);
15928       return -99;
15929     }
15930
15931   if (vec_len (locator_set_name) > 64)
15932     {
15933       errmsg ("locator-set name too long");
15934       vec_free (locator_set_name);
15935       vec_free (locators);
15936       return -99;
15937     }
15938   vec_add1 (locator_set_name, 0);
15939
15940   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15941
15942   /* Construct the API message */
15943   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15944
15945   mp->is_add = is_add;
15946   clib_memcpy (mp->locator_set_name, locator_set_name,
15947                vec_len (locator_set_name));
15948   vec_free (locator_set_name);
15949
15950   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15951   if (locators)
15952     clib_memcpy (mp->locators, locators, data_len);
15953   vec_free (locators);
15954
15955   /* send it... */
15956   S (mp);
15957
15958   /* Wait for a reply... */
15959   W (ret);
15960   return ret;
15961 }
15962
15963 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15964
15965 static int
15966 api_one_add_del_locator (vat_main_t * vam)
15967 {
15968   unformat_input_t *input = vam->input;
15969   vl_api_one_add_del_locator_t *mp;
15970   u32 tmp_if_index = ~0;
15971   u32 sw_if_index = ~0;
15972   u8 sw_if_index_set = 0;
15973   u8 sw_if_index_if_name_set = 0;
15974   u32 priority = ~0;
15975   u8 priority_set = 0;
15976   u32 weight = ~0;
15977   u8 weight_set = 0;
15978   u8 is_add = 1;
15979   u8 *locator_set_name = NULL;
15980   u8 locator_set_name_set = 0;
15981   int ret;
15982
15983   /* Parse args required to build the message */
15984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15985     {
15986       if (unformat (input, "del"))
15987         {
15988           is_add = 0;
15989         }
15990       else if (unformat (input, "locator-set %s", &locator_set_name))
15991         {
15992           locator_set_name_set = 1;
15993         }
15994       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15995                          &tmp_if_index))
15996         {
15997           sw_if_index_if_name_set = 1;
15998           sw_if_index = tmp_if_index;
15999         }
16000       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16001         {
16002           sw_if_index_set = 1;
16003           sw_if_index = tmp_if_index;
16004         }
16005       else if (unformat (input, "p %d", &priority))
16006         {
16007           priority_set = 1;
16008         }
16009       else if (unformat (input, "w %d", &weight))
16010         {
16011           weight_set = 1;
16012         }
16013       else
16014         break;
16015     }
16016
16017   if (locator_set_name_set == 0)
16018     {
16019       errmsg ("missing locator-set name");
16020       return -99;
16021     }
16022
16023   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16024     {
16025       errmsg ("missing sw_if_index");
16026       vec_free (locator_set_name);
16027       return -99;
16028     }
16029
16030   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16031     {
16032       errmsg ("cannot use both params interface name and sw_if_index");
16033       vec_free (locator_set_name);
16034       return -99;
16035     }
16036
16037   if (priority_set == 0)
16038     {
16039       errmsg ("missing locator-set priority");
16040       vec_free (locator_set_name);
16041       return -99;
16042     }
16043
16044   if (weight_set == 0)
16045     {
16046       errmsg ("missing locator-set weight");
16047       vec_free (locator_set_name);
16048       return -99;
16049     }
16050
16051   if (vec_len (locator_set_name) > 64)
16052     {
16053       errmsg ("locator-set name too long");
16054       vec_free (locator_set_name);
16055       return -99;
16056     }
16057   vec_add1 (locator_set_name, 0);
16058
16059   /* Construct the API message */
16060   M (ONE_ADD_DEL_LOCATOR, mp);
16061
16062   mp->is_add = is_add;
16063   mp->sw_if_index = ntohl (sw_if_index);
16064   mp->priority = priority;
16065   mp->weight = weight;
16066   clib_memcpy (mp->locator_set_name, locator_set_name,
16067                vec_len (locator_set_name));
16068   vec_free (locator_set_name);
16069
16070   /* send it... */
16071   S (mp);
16072
16073   /* Wait for a reply... */
16074   W (ret);
16075   return ret;
16076 }
16077
16078 #define api_lisp_add_del_locator api_one_add_del_locator
16079
16080 uword
16081 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16082 {
16083   u32 *key_id = va_arg (*args, u32 *);
16084   u8 *s = 0;
16085
16086   if (unformat (input, "%s", &s))
16087     {
16088       if (!strcmp ((char *) s, "sha1"))
16089         key_id[0] = HMAC_SHA_1_96;
16090       else if (!strcmp ((char *) s, "sha256"))
16091         key_id[0] = HMAC_SHA_256_128;
16092       else
16093         {
16094           clib_warning ("invalid key_id: '%s'", s);
16095           key_id[0] = HMAC_NO_KEY;
16096         }
16097     }
16098   else
16099     return 0;
16100
16101   vec_free (s);
16102   return 1;
16103 }
16104
16105 static int
16106 api_one_add_del_local_eid (vat_main_t * vam)
16107 {
16108   unformat_input_t *input = vam->input;
16109   vl_api_one_add_del_local_eid_t *mp;
16110   u8 is_add = 1;
16111   u8 eid_set = 0;
16112   lisp_eid_vat_t _eid, *eid = &_eid;
16113   u8 *locator_set_name = 0;
16114   u8 locator_set_name_set = 0;
16115   u32 vni = 0;
16116   u16 key_id = 0;
16117   u8 *key = 0;
16118   int ret;
16119
16120   /* Parse args required to build the message */
16121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16122     {
16123       if (unformat (input, "del"))
16124         {
16125           is_add = 0;
16126         }
16127       else if (unformat (input, "vni %d", &vni))
16128         {
16129           ;
16130         }
16131       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16132         {
16133           eid_set = 1;
16134         }
16135       else if (unformat (input, "locator-set %s", &locator_set_name))
16136         {
16137           locator_set_name_set = 1;
16138         }
16139       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16140         ;
16141       else if (unformat (input, "secret-key %_%v%_", &key))
16142         ;
16143       else
16144         break;
16145     }
16146
16147   if (locator_set_name_set == 0)
16148     {
16149       errmsg ("missing locator-set name");
16150       return -99;
16151     }
16152
16153   if (0 == eid_set)
16154     {
16155       errmsg ("EID address not set!");
16156       vec_free (locator_set_name);
16157       return -99;
16158     }
16159
16160   if (key && (0 == key_id))
16161     {
16162       errmsg ("invalid key_id!");
16163       return -99;
16164     }
16165
16166   if (vec_len (key) > 64)
16167     {
16168       errmsg ("key too long");
16169       vec_free (key);
16170       return -99;
16171     }
16172
16173   if (vec_len (locator_set_name) > 64)
16174     {
16175       errmsg ("locator-set name too long");
16176       vec_free (locator_set_name);
16177       return -99;
16178     }
16179   vec_add1 (locator_set_name, 0);
16180
16181   /* Construct the API message */
16182   M (ONE_ADD_DEL_LOCAL_EID, mp);
16183
16184   mp->is_add = is_add;
16185   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16186   mp->eid_type = eid->type;
16187   mp->prefix_len = eid->len;
16188   mp->vni = clib_host_to_net_u32 (vni);
16189   mp->key_id = clib_host_to_net_u16 (key_id);
16190   clib_memcpy (mp->locator_set_name, locator_set_name,
16191                vec_len (locator_set_name));
16192   clib_memcpy (mp->key, key, vec_len (key));
16193
16194   vec_free (locator_set_name);
16195   vec_free (key);
16196
16197   /* send it... */
16198   S (mp);
16199
16200   /* Wait for a reply... */
16201   W (ret);
16202   return ret;
16203 }
16204
16205 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16206
16207 static int
16208 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16209 {
16210   u32 dp_table = 0, vni = 0;;
16211   unformat_input_t *input = vam->input;
16212   vl_api_gpe_add_del_fwd_entry_t *mp;
16213   u8 is_add = 1;
16214   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16215   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16216   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16217   u32 action = ~0, w;
16218   ip4_address_t rmt_rloc4, lcl_rloc4;
16219   ip6_address_t rmt_rloc6, lcl_rloc6;
16220   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16221   int ret;
16222
16223   memset (&rloc, 0, sizeof (rloc));
16224
16225   /* Parse args required to build the message */
16226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16227     {
16228       if (unformat (input, "del"))
16229         is_add = 0;
16230       else if (unformat (input, "add"))
16231         is_add = 1;
16232       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16233         {
16234           rmt_eid_set = 1;
16235         }
16236       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16237         {
16238           lcl_eid_set = 1;
16239         }
16240       else if (unformat (input, "vrf %d", &dp_table))
16241         ;
16242       else if (unformat (input, "bd %d", &dp_table))
16243         ;
16244       else if (unformat (input, "vni %d", &vni))
16245         ;
16246       else if (unformat (input, "w %d", &w))
16247         {
16248           if (!curr_rloc)
16249             {
16250               errmsg ("No RLOC configured for setting priority/weight!");
16251               return -99;
16252             }
16253           curr_rloc->weight = w;
16254         }
16255       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16256                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16257         {
16258           rloc.is_ip4 = 1;
16259
16260           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16261           rloc.weight = 0;
16262           vec_add1 (lcl_locs, rloc);
16263
16264           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16265           vec_add1 (rmt_locs, rloc);
16266           /* weight saved in rmt loc */
16267           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16268         }
16269       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16270                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16271         {
16272           rloc.is_ip4 = 0;
16273           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16274           rloc.weight = 0;
16275           vec_add1 (lcl_locs, rloc);
16276
16277           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16278           vec_add1 (rmt_locs, rloc);
16279           /* weight saved in rmt loc */
16280           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16281         }
16282       else if (unformat (input, "action %d", &action))
16283         {
16284           ;
16285         }
16286       else
16287         {
16288           clib_warning ("parse error '%U'", format_unformat_error, input);
16289           return -99;
16290         }
16291     }
16292
16293   if (!rmt_eid_set)
16294     {
16295       errmsg ("remote eid addresses not set");
16296       return -99;
16297     }
16298
16299   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16300     {
16301       errmsg ("eid types don't match");
16302       return -99;
16303     }
16304
16305   if (0 == rmt_locs && (u32) ~ 0 == action)
16306     {
16307       errmsg ("action not set for negative mapping");
16308       return -99;
16309     }
16310
16311   /* Construct the API message */
16312   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16313       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16314
16315   mp->is_add = is_add;
16316   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16317   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16318   mp->eid_type = rmt_eid->type;
16319   mp->dp_table = clib_host_to_net_u32 (dp_table);
16320   mp->vni = clib_host_to_net_u32 (vni);
16321   mp->rmt_len = rmt_eid->len;
16322   mp->lcl_len = lcl_eid->len;
16323   mp->action = action;
16324
16325   if (0 != rmt_locs && 0 != lcl_locs)
16326     {
16327       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16328       clib_memcpy (mp->locs, lcl_locs,
16329                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16330
16331       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16332       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16333                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16334     }
16335   vec_free (lcl_locs);
16336   vec_free (rmt_locs);
16337
16338   /* send it... */
16339   S (mp);
16340
16341   /* Wait for a reply... */
16342   W (ret);
16343   return ret;
16344 }
16345
16346 static int
16347 api_one_add_del_map_server (vat_main_t * vam)
16348 {
16349   unformat_input_t *input = vam->input;
16350   vl_api_one_add_del_map_server_t *mp;
16351   u8 is_add = 1;
16352   u8 ipv4_set = 0;
16353   u8 ipv6_set = 0;
16354   ip4_address_t ipv4;
16355   ip6_address_t ipv6;
16356   int ret;
16357
16358   /* Parse args required to build the message */
16359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16360     {
16361       if (unformat (input, "del"))
16362         {
16363           is_add = 0;
16364         }
16365       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16366         {
16367           ipv4_set = 1;
16368         }
16369       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16370         {
16371           ipv6_set = 1;
16372         }
16373       else
16374         break;
16375     }
16376
16377   if (ipv4_set && ipv6_set)
16378     {
16379       errmsg ("both eid v4 and v6 addresses set");
16380       return -99;
16381     }
16382
16383   if (!ipv4_set && !ipv6_set)
16384     {
16385       errmsg ("eid addresses not set");
16386       return -99;
16387     }
16388
16389   /* Construct the API message */
16390   M (ONE_ADD_DEL_MAP_SERVER, mp);
16391
16392   mp->is_add = is_add;
16393   if (ipv6_set)
16394     {
16395       mp->is_ipv6 = 1;
16396       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16397     }
16398   else
16399     {
16400       mp->is_ipv6 = 0;
16401       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16402     }
16403
16404   /* send it... */
16405   S (mp);
16406
16407   /* Wait for a reply... */
16408   W (ret);
16409   return ret;
16410 }
16411
16412 #define api_lisp_add_del_map_server api_one_add_del_map_server
16413
16414 static int
16415 api_one_add_del_map_resolver (vat_main_t * vam)
16416 {
16417   unformat_input_t *input = vam->input;
16418   vl_api_one_add_del_map_resolver_t *mp;
16419   u8 is_add = 1;
16420   u8 ipv4_set = 0;
16421   u8 ipv6_set = 0;
16422   ip4_address_t ipv4;
16423   ip6_address_t ipv6;
16424   int ret;
16425
16426   /* Parse args required to build the message */
16427   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16428     {
16429       if (unformat (input, "del"))
16430         {
16431           is_add = 0;
16432         }
16433       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16434         {
16435           ipv4_set = 1;
16436         }
16437       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16438         {
16439           ipv6_set = 1;
16440         }
16441       else
16442         break;
16443     }
16444
16445   if (ipv4_set && ipv6_set)
16446     {
16447       errmsg ("both eid v4 and v6 addresses set");
16448       return -99;
16449     }
16450
16451   if (!ipv4_set && !ipv6_set)
16452     {
16453       errmsg ("eid addresses not set");
16454       return -99;
16455     }
16456
16457   /* Construct the API message */
16458   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16459
16460   mp->is_add = is_add;
16461   if (ipv6_set)
16462     {
16463       mp->is_ipv6 = 1;
16464       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16465     }
16466   else
16467     {
16468       mp->is_ipv6 = 0;
16469       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16470     }
16471
16472   /* send it... */
16473   S (mp);
16474
16475   /* Wait for a reply... */
16476   W (ret);
16477   return ret;
16478 }
16479
16480 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16481
16482 static int
16483 api_lisp_gpe_enable_disable (vat_main_t * vam)
16484 {
16485   unformat_input_t *input = vam->input;
16486   vl_api_gpe_enable_disable_t *mp;
16487   u8 is_set = 0;
16488   u8 is_en = 1;
16489   int ret;
16490
16491   /* Parse args required to build the message */
16492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16493     {
16494       if (unformat (input, "enable"))
16495         {
16496           is_set = 1;
16497           is_en = 1;
16498         }
16499       else if (unformat (input, "disable"))
16500         {
16501           is_set = 1;
16502           is_en = 0;
16503         }
16504       else
16505         break;
16506     }
16507
16508   if (is_set == 0)
16509     {
16510       errmsg ("Value not set");
16511       return -99;
16512     }
16513
16514   /* Construct the API message */
16515   M (GPE_ENABLE_DISABLE, mp);
16516
16517   mp->is_en = is_en;
16518
16519   /* send it... */
16520   S (mp);
16521
16522   /* Wait for a reply... */
16523   W (ret);
16524   return ret;
16525 }
16526
16527 static int
16528 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16529 {
16530   unformat_input_t *input = vam->input;
16531   vl_api_one_rloc_probe_enable_disable_t *mp;
16532   u8 is_set = 0;
16533   u8 is_en = 0;
16534   int ret;
16535
16536   /* Parse args required to build the message */
16537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16538     {
16539       if (unformat (input, "enable"))
16540         {
16541           is_set = 1;
16542           is_en = 1;
16543         }
16544       else if (unformat (input, "disable"))
16545         is_set = 1;
16546       else
16547         break;
16548     }
16549
16550   if (!is_set)
16551     {
16552       errmsg ("Value not set");
16553       return -99;
16554     }
16555
16556   /* Construct the API message */
16557   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16558
16559   mp->is_enabled = is_en;
16560
16561   /* send it... */
16562   S (mp);
16563
16564   /* Wait for a reply... */
16565   W (ret);
16566   return ret;
16567 }
16568
16569 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16570
16571 static int
16572 api_one_map_register_enable_disable (vat_main_t * vam)
16573 {
16574   unformat_input_t *input = vam->input;
16575   vl_api_one_map_register_enable_disable_t *mp;
16576   u8 is_set = 0;
16577   u8 is_en = 0;
16578   int ret;
16579
16580   /* Parse args required to build the message */
16581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16582     {
16583       if (unformat (input, "enable"))
16584         {
16585           is_set = 1;
16586           is_en = 1;
16587         }
16588       else if (unformat (input, "disable"))
16589         is_set = 1;
16590       else
16591         break;
16592     }
16593
16594   if (!is_set)
16595     {
16596       errmsg ("Value not set");
16597       return -99;
16598     }
16599
16600   /* Construct the API message */
16601   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16602
16603   mp->is_enabled = is_en;
16604
16605   /* send it... */
16606   S (mp);
16607
16608   /* Wait for a reply... */
16609   W (ret);
16610   return ret;
16611 }
16612
16613 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16614
16615 static int
16616 api_one_enable_disable (vat_main_t * vam)
16617 {
16618   unformat_input_t *input = vam->input;
16619   vl_api_one_enable_disable_t *mp;
16620   u8 is_set = 0;
16621   u8 is_en = 0;
16622   int ret;
16623
16624   /* Parse args required to build the message */
16625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16626     {
16627       if (unformat (input, "enable"))
16628         {
16629           is_set = 1;
16630           is_en = 1;
16631         }
16632       else if (unformat (input, "disable"))
16633         {
16634           is_set = 1;
16635         }
16636       else
16637         break;
16638     }
16639
16640   if (!is_set)
16641     {
16642       errmsg ("Value not set");
16643       return -99;
16644     }
16645
16646   /* Construct the API message */
16647   M (ONE_ENABLE_DISABLE, mp);
16648
16649   mp->is_en = is_en;
16650
16651   /* send it... */
16652   S (mp);
16653
16654   /* Wait for a reply... */
16655   W (ret);
16656   return ret;
16657 }
16658
16659 #define api_lisp_enable_disable api_one_enable_disable
16660
16661 static int
16662 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16663 {
16664   unformat_input_t *input = vam->input;
16665   vl_api_one_enable_disable_xtr_mode_t *mp;
16666   u8 is_set = 0;
16667   u8 is_en = 0;
16668   int ret;
16669
16670   /* Parse args required to build the message */
16671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16672     {
16673       if (unformat (input, "enable"))
16674         {
16675           is_set = 1;
16676           is_en = 1;
16677         }
16678       else if (unformat (input, "disable"))
16679         {
16680           is_set = 1;
16681         }
16682       else
16683         break;
16684     }
16685
16686   if (!is_set)
16687     {
16688       errmsg ("Value not set");
16689       return -99;
16690     }
16691
16692   /* Construct the API message */
16693   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16694
16695   mp->is_en = is_en;
16696
16697   /* send it... */
16698   S (mp);
16699
16700   /* Wait for a reply... */
16701   W (ret);
16702   return ret;
16703 }
16704
16705 static int
16706 api_one_show_xtr_mode (vat_main_t * vam)
16707 {
16708   vl_api_one_show_xtr_mode_t *mp;
16709   int ret;
16710
16711   /* Construct the API message */
16712   M (ONE_SHOW_XTR_MODE, mp);
16713
16714   /* send it... */
16715   S (mp);
16716
16717   /* Wait for a reply... */
16718   W (ret);
16719   return ret;
16720 }
16721
16722 static int
16723 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16724 {
16725   unformat_input_t *input = vam->input;
16726   vl_api_one_enable_disable_pitr_mode_t *mp;
16727   u8 is_set = 0;
16728   u8 is_en = 0;
16729   int ret;
16730
16731   /* Parse args required to build the message */
16732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16733     {
16734       if (unformat (input, "enable"))
16735         {
16736           is_set = 1;
16737           is_en = 1;
16738         }
16739       else if (unformat (input, "disable"))
16740         {
16741           is_set = 1;
16742         }
16743       else
16744         break;
16745     }
16746
16747   if (!is_set)
16748     {
16749       errmsg ("Value not set");
16750       return -99;
16751     }
16752
16753   /* Construct the API message */
16754   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16755
16756   mp->is_en = is_en;
16757
16758   /* send it... */
16759   S (mp);
16760
16761   /* Wait for a reply... */
16762   W (ret);
16763   return ret;
16764 }
16765
16766 static int
16767 api_one_show_pitr_mode (vat_main_t * vam)
16768 {
16769   vl_api_one_show_pitr_mode_t *mp;
16770   int ret;
16771
16772   /* Construct the API message */
16773   M (ONE_SHOW_PITR_MODE, mp);
16774
16775   /* send it... */
16776   S (mp);
16777
16778   /* Wait for a reply... */
16779   W (ret);
16780   return ret;
16781 }
16782
16783 static int
16784 api_one_enable_disable_petr_mode (vat_main_t * vam)
16785 {
16786   unformat_input_t *input = vam->input;
16787   vl_api_one_enable_disable_petr_mode_t *mp;
16788   u8 is_set = 0;
16789   u8 is_en = 0;
16790   int ret;
16791
16792   /* Parse args required to build the message */
16793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16794     {
16795       if (unformat (input, "enable"))
16796         {
16797           is_set = 1;
16798           is_en = 1;
16799         }
16800       else if (unformat (input, "disable"))
16801         {
16802           is_set = 1;
16803         }
16804       else
16805         break;
16806     }
16807
16808   if (!is_set)
16809     {
16810       errmsg ("Value not set");
16811       return -99;
16812     }
16813
16814   /* Construct the API message */
16815   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16816
16817   mp->is_en = is_en;
16818
16819   /* send it... */
16820   S (mp);
16821
16822   /* Wait for a reply... */
16823   W (ret);
16824   return ret;
16825 }
16826
16827 static int
16828 api_one_show_petr_mode (vat_main_t * vam)
16829 {
16830   vl_api_one_show_petr_mode_t *mp;
16831   int ret;
16832
16833   /* Construct the API message */
16834   M (ONE_SHOW_PETR_MODE, mp);
16835
16836   /* send it... */
16837   S (mp);
16838
16839   /* Wait for a reply... */
16840   W (ret);
16841   return ret;
16842 }
16843
16844 static int
16845 api_show_one_map_register_state (vat_main_t * vam)
16846 {
16847   vl_api_show_one_map_register_state_t *mp;
16848   int ret;
16849
16850   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16851
16852   /* send */
16853   S (mp);
16854
16855   /* wait for reply */
16856   W (ret);
16857   return ret;
16858 }
16859
16860 #define api_show_lisp_map_register_state api_show_one_map_register_state
16861
16862 static int
16863 api_show_one_rloc_probe_state (vat_main_t * vam)
16864 {
16865   vl_api_show_one_rloc_probe_state_t *mp;
16866   int ret;
16867
16868   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16869
16870   /* send */
16871   S (mp);
16872
16873   /* wait for reply */
16874   W (ret);
16875   return ret;
16876 }
16877
16878 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16879
16880 static int
16881 api_one_add_del_ndp_entry (vat_main_t * vam)
16882 {
16883   vl_api_one_add_del_ndp_entry_t *mp;
16884   unformat_input_t *input = vam->input;
16885   u8 is_add = 1;
16886   u8 mac_set = 0;
16887   u8 bd_set = 0;
16888   u8 ip_set = 0;
16889   u8 mac[6] = { 0, };
16890   u8 ip6[16] = { 0, };
16891   u32 bd = ~0;
16892   int ret;
16893
16894   /* Parse args required to build the message */
16895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16896     {
16897       if (unformat (input, "del"))
16898         is_add = 0;
16899       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16900         mac_set = 1;
16901       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16902         ip_set = 1;
16903       else if (unformat (input, "bd %d", &bd))
16904         bd_set = 1;
16905       else
16906         {
16907           errmsg ("parse error '%U'", format_unformat_error, input);
16908           return -99;
16909         }
16910     }
16911
16912   if (!bd_set || !ip_set || (!mac_set && is_add))
16913     {
16914       errmsg ("Missing BD, IP or MAC!");
16915       return -99;
16916     }
16917
16918   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16919   mp->is_add = is_add;
16920   clib_memcpy (mp->mac, mac, 6);
16921   mp->bd = clib_host_to_net_u32 (bd);
16922   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16923
16924   /* send */
16925   S (mp);
16926
16927   /* wait for reply */
16928   W (ret);
16929   return ret;
16930 }
16931
16932 static int
16933 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16934 {
16935   vl_api_one_add_del_l2_arp_entry_t *mp;
16936   unformat_input_t *input = vam->input;
16937   u8 is_add = 1;
16938   u8 mac_set = 0;
16939   u8 bd_set = 0;
16940   u8 ip_set = 0;
16941   u8 mac[6] = { 0, };
16942   u32 ip4 = 0, bd = ~0;
16943   int ret;
16944
16945   /* Parse args required to build the message */
16946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16947     {
16948       if (unformat (input, "del"))
16949         is_add = 0;
16950       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16951         mac_set = 1;
16952       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16953         ip_set = 1;
16954       else if (unformat (input, "bd %d", &bd))
16955         bd_set = 1;
16956       else
16957         {
16958           errmsg ("parse error '%U'", format_unformat_error, input);
16959           return -99;
16960         }
16961     }
16962
16963   if (!bd_set || !ip_set || (!mac_set && is_add))
16964     {
16965       errmsg ("Missing BD, IP or MAC!");
16966       return -99;
16967     }
16968
16969   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16970   mp->is_add = is_add;
16971   clib_memcpy (mp->mac, mac, 6);
16972   mp->bd = clib_host_to_net_u32 (bd);
16973   mp->ip4 = ip4;
16974
16975   /* send */
16976   S (mp);
16977
16978   /* wait for reply */
16979   W (ret);
16980   return ret;
16981 }
16982
16983 static int
16984 api_one_ndp_bd_get (vat_main_t * vam)
16985 {
16986   vl_api_one_ndp_bd_get_t *mp;
16987   int ret;
16988
16989   M (ONE_NDP_BD_GET, mp);
16990
16991   /* send */
16992   S (mp);
16993
16994   /* wait for reply */
16995   W (ret);
16996   return ret;
16997 }
16998
16999 static int
17000 api_one_ndp_entries_get (vat_main_t * vam)
17001 {
17002   vl_api_one_ndp_entries_get_t *mp;
17003   unformat_input_t *input = vam->input;
17004   u8 bd_set = 0;
17005   u32 bd = ~0;
17006   int ret;
17007
17008   /* Parse args required to build the message */
17009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17010     {
17011       if (unformat (input, "bd %d", &bd))
17012         bd_set = 1;
17013       else
17014         {
17015           errmsg ("parse error '%U'", format_unformat_error, input);
17016           return -99;
17017         }
17018     }
17019
17020   if (!bd_set)
17021     {
17022       errmsg ("Expected bridge domain!");
17023       return -99;
17024     }
17025
17026   M (ONE_NDP_ENTRIES_GET, mp);
17027   mp->bd = clib_host_to_net_u32 (bd);
17028
17029   /* send */
17030   S (mp);
17031
17032   /* wait for reply */
17033   W (ret);
17034   return ret;
17035 }
17036
17037 static int
17038 api_one_l2_arp_bd_get (vat_main_t * vam)
17039 {
17040   vl_api_one_l2_arp_bd_get_t *mp;
17041   int ret;
17042
17043   M (ONE_L2_ARP_BD_GET, mp);
17044
17045   /* send */
17046   S (mp);
17047
17048   /* wait for reply */
17049   W (ret);
17050   return ret;
17051 }
17052
17053 static int
17054 api_one_l2_arp_entries_get (vat_main_t * vam)
17055 {
17056   vl_api_one_l2_arp_entries_get_t *mp;
17057   unformat_input_t *input = vam->input;
17058   u8 bd_set = 0;
17059   u32 bd = ~0;
17060   int ret;
17061
17062   /* Parse args required to build the message */
17063   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17064     {
17065       if (unformat (input, "bd %d", &bd))
17066         bd_set = 1;
17067       else
17068         {
17069           errmsg ("parse error '%U'", format_unformat_error, input);
17070           return -99;
17071         }
17072     }
17073
17074   if (!bd_set)
17075     {
17076       errmsg ("Expected bridge domain!");
17077       return -99;
17078     }
17079
17080   M (ONE_L2_ARP_ENTRIES_GET, mp);
17081   mp->bd = clib_host_to_net_u32 (bd);
17082
17083   /* send */
17084   S (mp);
17085
17086   /* wait for reply */
17087   W (ret);
17088   return ret;
17089 }
17090
17091 static int
17092 api_one_stats_enable_disable (vat_main_t * vam)
17093 {
17094   vl_api_one_stats_enable_disable_t *mp;
17095   unformat_input_t *input = vam->input;
17096   u8 is_set = 0;
17097   u8 is_en = 0;
17098   int ret;
17099
17100   /* Parse args required to build the message */
17101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17102     {
17103       if (unformat (input, "enable"))
17104         {
17105           is_set = 1;
17106           is_en = 1;
17107         }
17108       else if (unformat (input, "disable"))
17109         {
17110           is_set = 1;
17111         }
17112       else
17113         break;
17114     }
17115
17116   if (!is_set)
17117     {
17118       errmsg ("Value not set");
17119       return -99;
17120     }
17121
17122   M (ONE_STATS_ENABLE_DISABLE, mp);
17123   mp->is_en = is_en;
17124
17125   /* send */
17126   S (mp);
17127
17128   /* wait for reply */
17129   W (ret);
17130   return ret;
17131 }
17132
17133 static int
17134 api_show_one_stats_enable_disable (vat_main_t * vam)
17135 {
17136   vl_api_show_one_stats_enable_disable_t *mp;
17137   int ret;
17138
17139   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17140
17141   /* send */
17142   S (mp);
17143
17144   /* wait for reply */
17145   W (ret);
17146   return ret;
17147 }
17148
17149 static int
17150 api_show_one_map_request_mode (vat_main_t * vam)
17151 {
17152   vl_api_show_one_map_request_mode_t *mp;
17153   int ret;
17154
17155   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17156
17157   /* send */
17158   S (mp);
17159
17160   /* wait for reply */
17161   W (ret);
17162   return ret;
17163 }
17164
17165 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17166
17167 static int
17168 api_one_map_request_mode (vat_main_t * vam)
17169 {
17170   unformat_input_t *input = vam->input;
17171   vl_api_one_map_request_mode_t *mp;
17172   u8 mode = 0;
17173   int ret;
17174
17175   /* Parse args required to build the message */
17176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17177     {
17178       if (unformat (input, "dst-only"))
17179         mode = 0;
17180       else if (unformat (input, "src-dst"))
17181         mode = 1;
17182       else
17183         {
17184           errmsg ("parse error '%U'", format_unformat_error, input);
17185           return -99;
17186         }
17187     }
17188
17189   M (ONE_MAP_REQUEST_MODE, mp);
17190
17191   mp->mode = mode;
17192
17193   /* send */
17194   S (mp);
17195
17196   /* wait for reply */
17197   W (ret);
17198   return ret;
17199 }
17200
17201 #define api_lisp_map_request_mode api_one_map_request_mode
17202
17203 /**
17204  * Enable/disable ONE proxy ITR.
17205  *
17206  * @param vam vpp API test context
17207  * @return return code
17208  */
17209 static int
17210 api_one_pitr_set_locator_set (vat_main_t * vam)
17211 {
17212   u8 ls_name_set = 0;
17213   unformat_input_t *input = vam->input;
17214   vl_api_one_pitr_set_locator_set_t *mp;
17215   u8 is_add = 1;
17216   u8 *ls_name = 0;
17217   int ret;
17218
17219   /* Parse args required to build the message */
17220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17221     {
17222       if (unformat (input, "del"))
17223         is_add = 0;
17224       else if (unformat (input, "locator-set %s", &ls_name))
17225         ls_name_set = 1;
17226       else
17227         {
17228           errmsg ("parse error '%U'", format_unformat_error, input);
17229           return -99;
17230         }
17231     }
17232
17233   if (!ls_name_set)
17234     {
17235       errmsg ("locator-set name not set!");
17236       return -99;
17237     }
17238
17239   M (ONE_PITR_SET_LOCATOR_SET, mp);
17240
17241   mp->is_add = is_add;
17242   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17243   vec_free (ls_name);
17244
17245   /* send */
17246   S (mp);
17247
17248   /* wait for reply */
17249   W (ret);
17250   return ret;
17251 }
17252
17253 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17254
17255 static int
17256 api_one_nsh_set_locator_set (vat_main_t * vam)
17257 {
17258   u8 ls_name_set = 0;
17259   unformat_input_t *input = vam->input;
17260   vl_api_one_nsh_set_locator_set_t *mp;
17261   u8 is_add = 1;
17262   u8 *ls_name = 0;
17263   int ret;
17264
17265   /* Parse args required to build the message */
17266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17267     {
17268       if (unformat (input, "del"))
17269         is_add = 0;
17270       else if (unformat (input, "ls %s", &ls_name))
17271         ls_name_set = 1;
17272       else
17273         {
17274           errmsg ("parse error '%U'", format_unformat_error, input);
17275           return -99;
17276         }
17277     }
17278
17279   if (!ls_name_set && is_add)
17280     {
17281       errmsg ("locator-set name not set!");
17282       return -99;
17283     }
17284
17285   M (ONE_NSH_SET_LOCATOR_SET, mp);
17286
17287   mp->is_add = is_add;
17288   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17289   vec_free (ls_name);
17290
17291   /* send */
17292   S (mp);
17293
17294   /* wait for reply */
17295   W (ret);
17296   return ret;
17297 }
17298
17299 static int
17300 api_show_one_pitr (vat_main_t * vam)
17301 {
17302   vl_api_show_one_pitr_t *mp;
17303   int ret;
17304
17305   if (!vam->json_output)
17306     {
17307       print (vam->ofp, "%=20s", "lisp status:");
17308     }
17309
17310   M (SHOW_ONE_PITR, mp);
17311   /* send it... */
17312   S (mp);
17313
17314   /* Wait for a reply... */
17315   W (ret);
17316   return ret;
17317 }
17318
17319 #define api_show_lisp_pitr api_show_one_pitr
17320
17321 static int
17322 api_one_use_petr (vat_main_t * vam)
17323 {
17324   unformat_input_t *input = vam->input;
17325   vl_api_one_use_petr_t *mp;
17326   u8 is_add = 0;
17327   ip_address_t ip;
17328   int ret;
17329
17330   memset (&ip, 0, sizeof (ip));
17331
17332   /* Parse args required to build the message */
17333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17334     {
17335       if (unformat (input, "disable"))
17336         is_add = 0;
17337       else
17338         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17339         {
17340           is_add = 1;
17341           ip_addr_version (&ip) = IP4;
17342         }
17343       else
17344         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17345         {
17346           is_add = 1;
17347           ip_addr_version (&ip) = IP6;
17348         }
17349       else
17350         {
17351           errmsg ("parse error '%U'", format_unformat_error, input);
17352           return -99;
17353         }
17354     }
17355
17356   M (ONE_USE_PETR, mp);
17357
17358   mp->is_add = is_add;
17359   if (is_add)
17360     {
17361       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17362       if (mp->is_ip4)
17363         clib_memcpy (mp->address, &ip, 4);
17364       else
17365         clib_memcpy (mp->address, &ip, 16);
17366     }
17367
17368   /* send */
17369   S (mp);
17370
17371   /* wait for reply */
17372   W (ret);
17373   return ret;
17374 }
17375
17376 #define api_lisp_use_petr api_one_use_petr
17377
17378 static int
17379 api_show_one_nsh_mapping (vat_main_t * vam)
17380 {
17381   vl_api_show_one_use_petr_t *mp;
17382   int ret;
17383
17384   if (!vam->json_output)
17385     {
17386       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17387     }
17388
17389   M (SHOW_ONE_NSH_MAPPING, mp);
17390   /* send it... */
17391   S (mp);
17392
17393   /* Wait for a reply... */
17394   W (ret);
17395   return ret;
17396 }
17397
17398 static int
17399 api_show_one_use_petr (vat_main_t * vam)
17400 {
17401   vl_api_show_one_use_petr_t *mp;
17402   int ret;
17403
17404   if (!vam->json_output)
17405     {
17406       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17407     }
17408
17409   M (SHOW_ONE_USE_PETR, mp);
17410   /* send it... */
17411   S (mp);
17412
17413   /* Wait for a reply... */
17414   W (ret);
17415   return ret;
17416 }
17417
17418 #define api_show_lisp_use_petr api_show_one_use_petr
17419
17420 /**
17421  * Add/delete mapping between vni and vrf
17422  */
17423 static int
17424 api_one_eid_table_add_del_map (vat_main_t * vam)
17425 {
17426   unformat_input_t *input = vam->input;
17427   vl_api_one_eid_table_add_del_map_t *mp;
17428   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17429   u32 vni, vrf, bd_index;
17430   int ret;
17431
17432   /* Parse args required to build the message */
17433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17434     {
17435       if (unformat (input, "del"))
17436         is_add = 0;
17437       else if (unformat (input, "vrf %d", &vrf))
17438         vrf_set = 1;
17439       else if (unformat (input, "bd_index %d", &bd_index))
17440         bd_index_set = 1;
17441       else if (unformat (input, "vni %d", &vni))
17442         vni_set = 1;
17443       else
17444         break;
17445     }
17446
17447   if (!vni_set || (!vrf_set && !bd_index_set))
17448     {
17449       errmsg ("missing arguments!");
17450       return -99;
17451     }
17452
17453   if (vrf_set && bd_index_set)
17454     {
17455       errmsg ("error: both vrf and bd entered!");
17456       return -99;
17457     }
17458
17459   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17460
17461   mp->is_add = is_add;
17462   mp->vni = htonl (vni);
17463   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17464   mp->is_l2 = bd_index_set;
17465
17466   /* send */
17467   S (mp);
17468
17469   /* wait for reply */
17470   W (ret);
17471   return ret;
17472 }
17473
17474 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17475
17476 uword
17477 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17478 {
17479   u32 *action = va_arg (*args, u32 *);
17480   u8 *s = 0;
17481
17482   if (unformat (input, "%s", &s))
17483     {
17484       if (!strcmp ((char *) s, "no-action"))
17485         action[0] = 0;
17486       else if (!strcmp ((char *) s, "natively-forward"))
17487         action[0] = 1;
17488       else if (!strcmp ((char *) s, "send-map-request"))
17489         action[0] = 2;
17490       else if (!strcmp ((char *) s, "drop"))
17491         action[0] = 3;
17492       else
17493         {
17494           clib_warning ("invalid action: '%s'", s);
17495           action[0] = 3;
17496         }
17497     }
17498   else
17499     return 0;
17500
17501   vec_free (s);
17502   return 1;
17503 }
17504
17505 /**
17506  * Add/del remote mapping to/from ONE control plane
17507  *
17508  * @param vam vpp API test context
17509  * @return return code
17510  */
17511 static int
17512 api_one_add_del_remote_mapping (vat_main_t * vam)
17513 {
17514   unformat_input_t *input = vam->input;
17515   vl_api_one_add_del_remote_mapping_t *mp;
17516   u32 vni = 0;
17517   lisp_eid_vat_t _eid, *eid = &_eid;
17518   lisp_eid_vat_t _seid, *seid = &_seid;
17519   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17520   u32 action = ~0, p, w, data_len;
17521   ip4_address_t rloc4;
17522   ip6_address_t rloc6;
17523   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17524   int ret;
17525
17526   memset (&rloc, 0, sizeof (rloc));
17527
17528   /* Parse args required to build the message */
17529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17530     {
17531       if (unformat (input, "del-all"))
17532         {
17533           del_all = 1;
17534         }
17535       else if (unformat (input, "del"))
17536         {
17537           is_add = 0;
17538         }
17539       else if (unformat (input, "add"))
17540         {
17541           is_add = 1;
17542         }
17543       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17544         {
17545           eid_set = 1;
17546         }
17547       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17548         {
17549           seid_set = 1;
17550         }
17551       else if (unformat (input, "vni %d", &vni))
17552         {
17553           ;
17554         }
17555       else if (unformat (input, "p %d w %d", &p, &w))
17556         {
17557           if (!curr_rloc)
17558             {
17559               errmsg ("No RLOC configured for setting priority/weight!");
17560               return -99;
17561             }
17562           curr_rloc->priority = p;
17563           curr_rloc->weight = w;
17564         }
17565       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17566         {
17567           rloc.is_ip4 = 1;
17568           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17569           vec_add1 (rlocs, rloc);
17570           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17571         }
17572       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17573         {
17574           rloc.is_ip4 = 0;
17575           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17576           vec_add1 (rlocs, rloc);
17577           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17578         }
17579       else if (unformat (input, "action %U",
17580                          unformat_negative_mapping_action, &action))
17581         {
17582           ;
17583         }
17584       else
17585         {
17586           clib_warning ("parse error '%U'", format_unformat_error, input);
17587           return -99;
17588         }
17589     }
17590
17591   if (0 == eid_set)
17592     {
17593       errmsg ("missing params!");
17594       return -99;
17595     }
17596
17597   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17598     {
17599       errmsg ("no action set for negative map-reply!");
17600       return -99;
17601     }
17602
17603   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17604
17605   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17606   mp->is_add = is_add;
17607   mp->vni = htonl (vni);
17608   mp->action = (u8) action;
17609   mp->is_src_dst = seid_set;
17610   mp->eid_len = eid->len;
17611   mp->seid_len = seid->len;
17612   mp->del_all = del_all;
17613   mp->eid_type = eid->type;
17614   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17615   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17616
17617   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17618   clib_memcpy (mp->rlocs, rlocs, data_len);
17619   vec_free (rlocs);
17620
17621   /* send it... */
17622   S (mp);
17623
17624   /* Wait for a reply... */
17625   W (ret);
17626   return ret;
17627 }
17628
17629 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17630
17631 /**
17632  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17633  * forwarding entries in data-plane accordingly.
17634  *
17635  * @param vam vpp API test context
17636  * @return return code
17637  */
17638 static int
17639 api_one_add_del_adjacency (vat_main_t * vam)
17640 {
17641   unformat_input_t *input = vam->input;
17642   vl_api_one_add_del_adjacency_t *mp;
17643   u32 vni = 0;
17644   ip4_address_t leid4, reid4;
17645   ip6_address_t leid6, reid6;
17646   u8 reid_mac[6] = { 0 };
17647   u8 leid_mac[6] = { 0 };
17648   u8 reid_type, leid_type;
17649   u32 leid_len = 0, reid_len = 0, len;
17650   u8 is_add = 1;
17651   int ret;
17652
17653   leid_type = reid_type = (u8) ~ 0;
17654
17655   /* Parse args required to build the message */
17656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17657     {
17658       if (unformat (input, "del"))
17659         {
17660           is_add = 0;
17661         }
17662       else if (unformat (input, "add"))
17663         {
17664           is_add = 1;
17665         }
17666       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17667                          &reid4, &len))
17668         {
17669           reid_type = 0;        /* ipv4 */
17670           reid_len = len;
17671         }
17672       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17673                          &reid6, &len))
17674         {
17675           reid_type = 1;        /* ipv6 */
17676           reid_len = len;
17677         }
17678       else if (unformat (input, "reid %U", unformat_ethernet_address,
17679                          reid_mac))
17680         {
17681           reid_type = 2;        /* mac */
17682         }
17683       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17684                          &leid4, &len))
17685         {
17686           leid_type = 0;        /* ipv4 */
17687           leid_len = len;
17688         }
17689       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17690                          &leid6, &len))
17691         {
17692           leid_type = 1;        /* ipv6 */
17693           leid_len = len;
17694         }
17695       else if (unformat (input, "leid %U", unformat_ethernet_address,
17696                          leid_mac))
17697         {
17698           leid_type = 2;        /* mac */
17699         }
17700       else if (unformat (input, "vni %d", &vni))
17701         {
17702           ;
17703         }
17704       else
17705         {
17706           errmsg ("parse error '%U'", format_unformat_error, input);
17707           return -99;
17708         }
17709     }
17710
17711   if ((u8) ~ 0 == reid_type)
17712     {
17713       errmsg ("missing params!");
17714       return -99;
17715     }
17716
17717   if (leid_type != reid_type)
17718     {
17719       errmsg ("remote and local EIDs are of different types!");
17720       return -99;
17721     }
17722
17723   M (ONE_ADD_DEL_ADJACENCY, mp);
17724   mp->is_add = is_add;
17725   mp->vni = htonl (vni);
17726   mp->leid_len = leid_len;
17727   mp->reid_len = reid_len;
17728   mp->eid_type = reid_type;
17729
17730   switch (mp->eid_type)
17731     {
17732     case 0:
17733       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17734       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17735       break;
17736     case 1:
17737       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17738       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17739       break;
17740     case 2:
17741       clib_memcpy (mp->leid, leid_mac, 6);
17742       clib_memcpy (mp->reid, reid_mac, 6);
17743       break;
17744     default:
17745       errmsg ("unknown EID type %d!", mp->eid_type);
17746       return 0;
17747     }
17748
17749   /* send it... */
17750   S (mp);
17751
17752   /* Wait for a reply... */
17753   W (ret);
17754   return ret;
17755 }
17756
17757 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17758
17759 uword
17760 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17761 {
17762   u32 *mode = va_arg (*args, u32 *);
17763
17764   if (unformat (input, "lisp"))
17765     *mode = 0;
17766   else if (unformat (input, "vxlan"))
17767     *mode = 1;
17768   else
17769     return 0;
17770
17771   return 1;
17772 }
17773
17774 static int
17775 api_gpe_get_encap_mode (vat_main_t * vam)
17776 {
17777   vl_api_gpe_get_encap_mode_t *mp;
17778   int ret;
17779
17780   /* Construct the API message */
17781   M (GPE_GET_ENCAP_MODE, mp);
17782
17783   /* send it... */
17784   S (mp);
17785
17786   /* Wait for a reply... */
17787   W (ret);
17788   return ret;
17789 }
17790
17791 static int
17792 api_gpe_set_encap_mode (vat_main_t * vam)
17793 {
17794   unformat_input_t *input = vam->input;
17795   vl_api_gpe_set_encap_mode_t *mp;
17796   int ret;
17797   u32 mode = 0;
17798
17799   /* Parse args required to build the message */
17800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17801     {
17802       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17803         ;
17804       else
17805         break;
17806     }
17807
17808   /* Construct the API message */
17809   M (GPE_SET_ENCAP_MODE, mp);
17810
17811   mp->mode = mode;
17812
17813   /* send it... */
17814   S (mp);
17815
17816   /* Wait for a reply... */
17817   W (ret);
17818   return ret;
17819 }
17820
17821 static int
17822 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17823 {
17824   unformat_input_t *input = vam->input;
17825   vl_api_gpe_add_del_iface_t *mp;
17826   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17827   u32 dp_table = 0, vni = 0;
17828   int ret;
17829
17830   /* Parse args required to build the message */
17831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17832     {
17833       if (unformat (input, "up"))
17834         {
17835           action_set = 1;
17836           is_add = 1;
17837         }
17838       else if (unformat (input, "down"))
17839         {
17840           action_set = 1;
17841           is_add = 0;
17842         }
17843       else if (unformat (input, "table_id %d", &dp_table))
17844         {
17845           dp_table_set = 1;
17846         }
17847       else if (unformat (input, "bd_id %d", &dp_table))
17848         {
17849           dp_table_set = 1;
17850           is_l2 = 1;
17851         }
17852       else if (unformat (input, "vni %d", &vni))
17853         {
17854           vni_set = 1;
17855         }
17856       else
17857         break;
17858     }
17859
17860   if (action_set == 0)
17861     {
17862       errmsg ("Action not set");
17863       return -99;
17864     }
17865   if (dp_table_set == 0 || vni_set == 0)
17866     {
17867       errmsg ("vni and dp_table must be set");
17868       return -99;
17869     }
17870
17871   /* Construct the API message */
17872   M (GPE_ADD_DEL_IFACE, mp);
17873
17874   mp->is_add = is_add;
17875   mp->dp_table = clib_host_to_net_u32 (dp_table);
17876   mp->is_l2 = is_l2;
17877   mp->vni = clib_host_to_net_u32 (vni);
17878
17879   /* send it... */
17880   S (mp);
17881
17882   /* Wait for a reply... */
17883   W (ret);
17884   return ret;
17885 }
17886
17887 static int
17888 api_one_map_register_fallback_threshold (vat_main_t * vam)
17889 {
17890   unformat_input_t *input = vam->input;
17891   vl_api_one_map_register_fallback_threshold_t *mp;
17892   u32 value = 0;
17893   u8 is_set = 0;
17894   int ret;
17895
17896   /* Parse args required to build the message */
17897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17898     {
17899       if (unformat (input, "%u", &value))
17900         is_set = 1;
17901       else
17902         {
17903           clib_warning ("parse error '%U'", format_unformat_error, input);
17904           return -99;
17905         }
17906     }
17907
17908   if (!is_set)
17909     {
17910       errmsg ("fallback threshold value is missing!");
17911       return -99;
17912     }
17913
17914   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17915   mp->value = clib_host_to_net_u32 (value);
17916
17917   /* send it... */
17918   S (mp);
17919
17920   /* Wait for a reply... */
17921   W (ret);
17922   return ret;
17923 }
17924
17925 static int
17926 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17927 {
17928   vl_api_show_one_map_register_fallback_threshold_t *mp;
17929   int ret;
17930
17931   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17932
17933   /* send it... */
17934   S (mp);
17935
17936   /* Wait for a reply... */
17937   W (ret);
17938   return ret;
17939 }
17940
17941 uword
17942 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17943 {
17944   u32 *proto = va_arg (*args, u32 *);
17945
17946   if (unformat (input, "udp"))
17947     *proto = 1;
17948   else if (unformat (input, "api"))
17949     *proto = 2;
17950   else
17951     return 0;
17952
17953   return 1;
17954 }
17955
17956 static int
17957 api_one_set_transport_protocol (vat_main_t * vam)
17958 {
17959   unformat_input_t *input = vam->input;
17960   vl_api_one_set_transport_protocol_t *mp;
17961   u8 is_set = 0;
17962   u32 protocol = 0;
17963   int ret;
17964
17965   /* Parse args required to build the message */
17966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17967     {
17968       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17969         is_set = 1;
17970       else
17971         {
17972           clib_warning ("parse error '%U'", format_unformat_error, input);
17973           return -99;
17974         }
17975     }
17976
17977   if (!is_set)
17978     {
17979       errmsg ("Transport protocol missing!");
17980       return -99;
17981     }
17982
17983   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17984   mp->protocol = (u8) protocol;
17985
17986   /* send it... */
17987   S (mp);
17988
17989   /* Wait for a reply... */
17990   W (ret);
17991   return ret;
17992 }
17993
17994 static int
17995 api_one_get_transport_protocol (vat_main_t * vam)
17996 {
17997   vl_api_one_get_transport_protocol_t *mp;
17998   int ret;
17999
18000   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18001
18002   /* send it... */
18003   S (mp);
18004
18005   /* Wait for a reply... */
18006   W (ret);
18007   return ret;
18008 }
18009
18010 static int
18011 api_one_map_register_set_ttl (vat_main_t * vam)
18012 {
18013   unformat_input_t *input = vam->input;
18014   vl_api_one_map_register_set_ttl_t *mp;
18015   u32 ttl = 0;
18016   u8 is_set = 0;
18017   int ret;
18018
18019   /* Parse args required to build the message */
18020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18021     {
18022       if (unformat (input, "%u", &ttl))
18023         is_set = 1;
18024       else
18025         {
18026           clib_warning ("parse error '%U'", format_unformat_error, input);
18027           return -99;
18028         }
18029     }
18030
18031   if (!is_set)
18032     {
18033       errmsg ("TTL value missing!");
18034       return -99;
18035     }
18036
18037   M (ONE_MAP_REGISTER_SET_TTL, mp);
18038   mp->ttl = clib_host_to_net_u32 (ttl);
18039
18040   /* send it... */
18041   S (mp);
18042
18043   /* Wait for a reply... */
18044   W (ret);
18045   return ret;
18046 }
18047
18048 static int
18049 api_show_one_map_register_ttl (vat_main_t * vam)
18050 {
18051   vl_api_show_one_map_register_ttl_t *mp;
18052   int ret;
18053
18054   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18055
18056   /* send it... */
18057   S (mp);
18058
18059   /* Wait for a reply... */
18060   W (ret);
18061   return ret;
18062 }
18063
18064 /**
18065  * Add/del map request itr rlocs from ONE control plane and updates
18066  *
18067  * @param vam vpp API test context
18068  * @return return code
18069  */
18070 static int
18071 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18072 {
18073   unformat_input_t *input = vam->input;
18074   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18075   u8 *locator_set_name = 0;
18076   u8 locator_set_name_set = 0;
18077   u8 is_add = 1;
18078   int ret;
18079
18080   /* Parse args required to build the message */
18081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18082     {
18083       if (unformat (input, "del"))
18084         {
18085           is_add = 0;
18086         }
18087       else if (unformat (input, "%_%v%_", &locator_set_name))
18088         {
18089           locator_set_name_set = 1;
18090         }
18091       else
18092         {
18093           clib_warning ("parse error '%U'", format_unformat_error, input);
18094           return -99;
18095         }
18096     }
18097
18098   if (is_add && !locator_set_name_set)
18099     {
18100       errmsg ("itr-rloc is not set!");
18101       return -99;
18102     }
18103
18104   if (is_add && vec_len (locator_set_name) > 64)
18105     {
18106       errmsg ("itr-rloc locator-set name too long");
18107       vec_free (locator_set_name);
18108       return -99;
18109     }
18110
18111   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18112   mp->is_add = is_add;
18113   if (is_add)
18114     {
18115       clib_memcpy (mp->locator_set_name, locator_set_name,
18116                    vec_len (locator_set_name));
18117     }
18118   else
18119     {
18120       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18121     }
18122   vec_free (locator_set_name);
18123
18124   /* send it... */
18125   S (mp);
18126
18127   /* Wait for a reply... */
18128   W (ret);
18129   return ret;
18130 }
18131
18132 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18133
18134 static int
18135 api_one_locator_dump (vat_main_t * vam)
18136 {
18137   unformat_input_t *input = vam->input;
18138   vl_api_one_locator_dump_t *mp;
18139   vl_api_control_ping_t *mp_ping;
18140   u8 is_index_set = 0, is_name_set = 0;
18141   u8 *ls_name = 0;
18142   u32 ls_index = ~0;
18143   int ret;
18144
18145   /* Parse args required to build the message */
18146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18147     {
18148       if (unformat (input, "ls_name %_%v%_", &ls_name))
18149         {
18150           is_name_set = 1;
18151         }
18152       else if (unformat (input, "ls_index %d", &ls_index))
18153         {
18154           is_index_set = 1;
18155         }
18156       else
18157         {
18158           errmsg ("parse error '%U'", format_unformat_error, input);
18159           return -99;
18160         }
18161     }
18162
18163   if (!is_index_set && !is_name_set)
18164     {
18165       errmsg ("error: expected one of index or name!");
18166       return -99;
18167     }
18168
18169   if (is_index_set && is_name_set)
18170     {
18171       errmsg ("error: only one param expected!");
18172       return -99;
18173     }
18174
18175   if (vec_len (ls_name) > 62)
18176     {
18177       errmsg ("error: locator set name too long!");
18178       return -99;
18179     }
18180
18181   if (!vam->json_output)
18182     {
18183       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18184     }
18185
18186   M (ONE_LOCATOR_DUMP, mp);
18187   mp->is_index_set = is_index_set;
18188
18189   if (is_index_set)
18190     mp->ls_index = clib_host_to_net_u32 (ls_index);
18191   else
18192     {
18193       vec_add1 (ls_name, 0);
18194       strncpy ((char *) mp->ls_name, (char *) ls_name,
18195                sizeof (mp->ls_name) - 1);
18196     }
18197
18198   /* send it... */
18199   S (mp);
18200
18201   /* Use a control ping for synchronization */
18202   MPING (CONTROL_PING, mp_ping);
18203   S (mp_ping);
18204
18205   /* Wait for a reply... */
18206   W (ret);
18207   return ret;
18208 }
18209
18210 #define api_lisp_locator_dump api_one_locator_dump
18211
18212 static int
18213 api_one_locator_set_dump (vat_main_t * vam)
18214 {
18215   vl_api_one_locator_set_dump_t *mp;
18216   vl_api_control_ping_t *mp_ping;
18217   unformat_input_t *input = vam->input;
18218   u8 filter = 0;
18219   int ret;
18220
18221   /* Parse args required to build the message */
18222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18223     {
18224       if (unformat (input, "local"))
18225         {
18226           filter = 1;
18227         }
18228       else if (unformat (input, "remote"))
18229         {
18230           filter = 2;
18231         }
18232       else
18233         {
18234           errmsg ("parse error '%U'", format_unformat_error, input);
18235           return -99;
18236         }
18237     }
18238
18239   if (!vam->json_output)
18240     {
18241       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18242     }
18243
18244   M (ONE_LOCATOR_SET_DUMP, mp);
18245
18246   mp->filter = filter;
18247
18248   /* send it... */
18249   S (mp);
18250
18251   /* Use a control ping for synchronization */
18252   MPING (CONTROL_PING, mp_ping);
18253   S (mp_ping);
18254
18255   /* Wait for a reply... */
18256   W (ret);
18257   return ret;
18258 }
18259
18260 #define api_lisp_locator_set_dump api_one_locator_set_dump
18261
18262 static int
18263 api_one_eid_table_map_dump (vat_main_t * vam)
18264 {
18265   u8 is_l2 = 0;
18266   u8 mode_set = 0;
18267   unformat_input_t *input = vam->input;
18268   vl_api_one_eid_table_map_dump_t *mp;
18269   vl_api_control_ping_t *mp_ping;
18270   int ret;
18271
18272   /* Parse args required to build the message */
18273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18274     {
18275       if (unformat (input, "l2"))
18276         {
18277           is_l2 = 1;
18278           mode_set = 1;
18279         }
18280       else if (unformat (input, "l3"))
18281         {
18282           is_l2 = 0;
18283           mode_set = 1;
18284         }
18285       else
18286         {
18287           errmsg ("parse error '%U'", format_unformat_error, input);
18288           return -99;
18289         }
18290     }
18291
18292   if (!mode_set)
18293     {
18294       errmsg ("expected one of 'l2' or 'l3' parameter!");
18295       return -99;
18296     }
18297
18298   if (!vam->json_output)
18299     {
18300       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18301     }
18302
18303   M (ONE_EID_TABLE_MAP_DUMP, mp);
18304   mp->is_l2 = is_l2;
18305
18306   /* send it... */
18307   S (mp);
18308
18309   /* Use a control ping for synchronization */
18310   MPING (CONTROL_PING, mp_ping);
18311   S (mp_ping);
18312
18313   /* Wait for a reply... */
18314   W (ret);
18315   return ret;
18316 }
18317
18318 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18319
18320 static int
18321 api_one_eid_table_vni_dump (vat_main_t * vam)
18322 {
18323   vl_api_one_eid_table_vni_dump_t *mp;
18324   vl_api_control_ping_t *mp_ping;
18325   int ret;
18326
18327   if (!vam->json_output)
18328     {
18329       print (vam->ofp, "VNI");
18330     }
18331
18332   M (ONE_EID_TABLE_VNI_DUMP, mp);
18333
18334   /* send it... */
18335   S (mp);
18336
18337   /* Use a control ping for synchronization */
18338   MPING (CONTROL_PING, mp_ping);
18339   S (mp_ping);
18340
18341   /* Wait for a reply... */
18342   W (ret);
18343   return ret;
18344 }
18345
18346 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18347
18348 static int
18349 api_one_eid_table_dump (vat_main_t * vam)
18350 {
18351   unformat_input_t *i = vam->input;
18352   vl_api_one_eid_table_dump_t *mp;
18353   vl_api_control_ping_t *mp_ping;
18354   struct in_addr ip4;
18355   struct in6_addr ip6;
18356   u8 mac[6];
18357   u8 eid_type = ~0, eid_set = 0;
18358   u32 prefix_length = ~0, t, vni = 0;
18359   u8 filter = 0;
18360   int ret;
18361   lisp_nsh_api_t nsh;
18362
18363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18364     {
18365       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18366         {
18367           eid_set = 1;
18368           eid_type = 0;
18369           prefix_length = t;
18370         }
18371       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18372         {
18373           eid_set = 1;
18374           eid_type = 1;
18375           prefix_length = t;
18376         }
18377       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18378         {
18379           eid_set = 1;
18380           eid_type = 2;
18381         }
18382       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18383         {
18384           eid_set = 1;
18385           eid_type = 3;
18386         }
18387       else if (unformat (i, "vni %d", &t))
18388         {
18389           vni = t;
18390         }
18391       else if (unformat (i, "local"))
18392         {
18393           filter = 1;
18394         }
18395       else if (unformat (i, "remote"))
18396         {
18397           filter = 2;
18398         }
18399       else
18400         {
18401           errmsg ("parse error '%U'", format_unformat_error, i);
18402           return -99;
18403         }
18404     }
18405
18406   if (!vam->json_output)
18407     {
18408       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18409              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18410     }
18411
18412   M (ONE_EID_TABLE_DUMP, mp);
18413
18414   mp->filter = filter;
18415   if (eid_set)
18416     {
18417       mp->eid_set = 1;
18418       mp->vni = htonl (vni);
18419       mp->eid_type = eid_type;
18420       switch (eid_type)
18421         {
18422         case 0:
18423           mp->prefix_length = prefix_length;
18424           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18425           break;
18426         case 1:
18427           mp->prefix_length = prefix_length;
18428           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18429           break;
18430         case 2:
18431           clib_memcpy (mp->eid, mac, sizeof (mac));
18432           break;
18433         case 3:
18434           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18435           break;
18436         default:
18437           errmsg ("unknown EID type %d!", eid_type);
18438           return -99;
18439         }
18440     }
18441
18442   /* send it... */
18443   S (mp);
18444
18445   /* Use a control ping for synchronization */
18446   MPING (CONTROL_PING, mp_ping);
18447   S (mp_ping);
18448
18449   /* Wait for a reply... */
18450   W (ret);
18451   return ret;
18452 }
18453
18454 #define api_lisp_eid_table_dump api_one_eid_table_dump
18455
18456 static int
18457 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18458 {
18459   unformat_input_t *i = vam->input;
18460   vl_api_gpe_fwd_entries_get_t *mp;
18461   u8 vni_set = 0;
18462   u32 vni = ~0;
18463   int ret;
18464
18465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18466     {
18467       if (unformat (i, "vni %d", &vni))
18468         {
18469           vni_set = 1;
18470         }
18471       else
18472         {
18473           errmsg ("parse error '%U'", format_unformat_error, i);
18474           return -99;
18475         }
18476     }
18477
18478   if (!vni_set)
18479     {
18480       errmsg ("vni not set!");
18481       return -99;
18482     }
18483
18484   if (!vam->json_output)
18485     {
18486       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18487              "leid", "reid");
18488     }
18489
18490   M (GPE_FWD_ENTRIES_GET, mp);
18491   mp->vni = clib_host_to_net_u32 (vni);
18492
18493   /* send it... */
18494   S (mp);
18495
18496   /* Wait for a reply... */
18497   W (ret);
18498   return ret;
18499 }
18500
18501 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18502 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18503 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18504 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18505 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18506 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18507 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18508 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18509
18510 static int
18511 api_one_adjacencies_get (vat_main_t * vam)
18512 {
18513   unformat_input_t *i = vam->input;
18514   vl_api_one_adjacencies_get_t *mp;
18515   u8 vni_set = 0;
18516   u32 vni = ~0;
18517   int ret;
18518
18519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18520     {
18521       if (unformat (i, "vni %d", &vni))
18522         {
18523           vni_set = 1;
18524         }
18525       else
18526         {
18527           errmsg ("parse error '%U'", format_unformat_error, i);
18528           return -99;
18529         }
18530     }
18531
18532   if (!vni_set)
18533     {
18534       errmsg ("vni not set!");
18535       return -99;
18536     }
18537
18538   if (!vam->json_output)
18539     {
18540       print (vam->ofp, "%s %40s", "leid", "reid");
18541     }
18542
18543   M (ONE_ADJACENCIES_GET, mp);
18544   mp->vni = clib_host_to_net_u32 (vni);
18545
18546   /* send it... */
18547   S (mp);
18548
18549   /* Wait for a reply... */
18550   W (ret);
18551   return ret;
18552 }
18553
18554 #define api_lisp_adjacencies_get api_one_adjacencies_get
18555
18556 static int
18557 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18558 {
18559   unformat_input_t *i = vam->input;
18560   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18561   int ret;
18562   u8 ip_family_set = 0, is_ip4 = 1;
18563
18564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18565     {
18566       if (unformat (i, "ip4"))
18567         {
18568           ip_family_set = 1;
18569           is_ip4 = 1;
18570         }
18571       else if (unformat (i, "ip6"))
18572         {
18573           ip_family_set = 1;
18574           is_ip4 = 0;
18575         }
18576       else
18577         {
18578           errmsg ("parse error '%U'", format_unformat_error, i);
18579           return -99;
18580         }
18581     }
18582
18583   if (!ip_family_set)
18584     {
18585       errmsg ("ip family not set!");
18586       return -99;
18587     }
18588
18589   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18590   mp->is_ip4 = is_ip4;
18591
18592   /* send it... */
18593   S (mp);
18594
18595   /* Wait for a reply... */
18596   W (ret);
18597   return ret;
18598 }
18599
18600 static int
18601 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18602 {
18603   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18604   int ret;
18605
18606   if (!vam->json_output)
18607     {
18608       print (vam->ofp, "VNIs");
18609     }
18610
18611   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18612
18613   /* send it... */
18614   S (mp);
18615
18616   /* Wait for a reply... */
18617   W (ret);
18618   return ret;
18619 }
18620
18621 static int
18622 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18623 {
18624   unformat_input_t *i = vam->input;
18625   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18626   int ret = 0;
18627   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18628   struct in_addr ip4;
18629   struct in6_addr ip6;
18630   u32 table_id = 0, nh_sw_if_index = ~0;
18631
18632   memset (&ip4, 0, sizeof (ip4));
18633   memset (&ip6, 0, sizeof (ip6));
18634
18635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18636     {
18637       if (unformat (i, "del"))
18638         is_add = 0;
18639       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18640                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18641         {
18642           ip_set = 1;
18643           is_ip4 = 1;
18644         }
18645       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18646                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18647         {
18648           ip_set = 1;
18649           is_ip4 = 0;
18650         }
18651       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18652         {
18653           ip_set = 1;
18654           is_ip4 = 1;
18655           nh_sw_if_index = ~0;
18656         }
18657       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18658         {
18659           ip_set = 1;
18660           is_ip4 = 0;
18661           nh_sw_if_index = ~0;
18662         }
18663       else if (unformat (i, "table %d", &table_id))
18664         ;
18665       else
18666         {
18667           errmsg ("parse error '%U'", format_unformat_error, i);
18668           return -99;
18669         }
18670     }
18671
18672   if (!ip_set)
18673     {
18674       errmsg ("nh addr not set!");
18675       return -99;
18676     }
18677
18678   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18679   mp->is_add = is_add;
18680   mp->table_id = clib_host_to_net_u32 (table_id);
18681   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18682   mp->is_ip4 = is_ip4;
18683   if (is_ip4)
18684     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18685   else
18686     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18687
18688   /* send it... */
18689   S (mp);
18690
18691   /* Wait for a reply... */
18692   W (ret);
18693   return ret;
18694 }
18695
18696 static int
18697 api_one_map_server_dump (vat_main_t * vam)
18698 {
18699   vl_api_one_map_server_dump_t *mp;
18700   vl_api_control_ping_t *mp_ping;
18701   int ret;
18702
18703   if (!vam->json_output)
18704     {
18705       print (vam->ofp, "%=20s", "Map server");
18706     }
18707
18708   M (ONE_MAP_SERVER_DUMP, mp);
18709   /* send it... */
18710   S (mp);
18711
18712   /* Use a control ping for synchronization */
18713   MPING (CONTROL_PING, mp_ping);
18714   S (mp_ping);
18715
18716   /* Wait for a reply... */
18717   W (ret);
18718   return ret;
18719 }
18720
18721 #define api_lisp_map_server_dump api_one_map_server_dump
18722
18723 static int
18724 api_one_map_resolver_dump (vat_main_t * vam)
18725 {
18726   vl_api_one_map_resolver_dump_t *mp;
18727   vl_api_control_ping_t *mp_ping;
18728   int ret;
18729
18730   if (!vam->json_output)
18731     {
18732       print (vam->ofp, "%=20s", "Map resolver");
18733     }
18734
18735   M (ONE_MAP_RESOLVER_DUMP, mp);
18736   /* send it... */
18737   S (mp);
18738
18739   /* Use a control ping for synchronization */
18740   MPING (CONTROL_PING, mp_ping);
18741   S (mp_ping);
18742
18743   /* Wait for a reply... */
18744   W (ret);
18745   return ret;
18746 }
18747
18748 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18749
18750 static int
18751 api_one_stats_flush (vat_main_t * vam)
18752 {
18753   vl_api_one_stats_flush_t *mp;
18754   int ret = 0;
18755
18756   M (ONE_STATS_FLUSH, mp);
18757   S (mp);
18758   W (ret);
18759   return ret;
18760 }
18761
18762 static int
18763 api_one_stats_dump (vat_main_t * vam)
18764 {
18765   vl_api_one_stats_dump_t *mp;
18766   vl_api_control_ping_t *mp_ping;
18767   int ret;
18768
18769   M (ONE_STATS_DUMP, mp);
18770   /* send it... */
18771   S (mp);
18772
18773   /* Use a control ping for synchronization */
18774   MPING (CONTROL_PING, mp_ping);
18775   S (mp_ping);
18776
18777   /* Wait for a reply... */
18778   W (ret);
18779   return ret;
18780 }
18781
18782 static int
18783 api_show_one_status (vat_main_t * vam)
18784 {
18785   vl_api_show_one_status_t *mp;
18786   int ret;
18787
18788   if (!vam->json_output)
18789     {
18790       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18791     }
18792
18793   M (SHOW_ONE_STATUS, mp);
18794   /* send it... */
18795   S (mp);
18796   /* Wait for a reply... */
18797   W (ret);
18798   return ret;
18799 }
18800
18801 #define api_show_lisp_status api_show_one_status
18802
18803 static int
18804 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18805 {
18806   vl_api_gpe_fwd_entry_path_dump_t *mp;
18807   vl_api_control_ping_t *mp_ping;
18808   unformat_input_t *i = vam->input;
18809   u32 fwd_entry_index = ~0;
18810   int ret;
18811
18812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18813     {
18814       if (unformat (i, "index %d", &fwd_entry_index))
18815         ;
18816       else
18817         break;
18818     }
18819
18820   if (~0 == fwd_entry_index)
18821     {
18822       errmsg ("no index specified!");
18823       return -99;
18824     }
18825
18826   if (!vam->json_output)
18827     {
18828       print (vam->ofp, "first line");
18829     }
18830
18831   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18832
18833   /* send it... */
18834   S (mp);
18835   /* Use a control ping for synchronization */
18836   MPING (CONTROL_PING, mp_ping);
18837   S (mp_ping);
18838
18839   /* Wait for a reply... */
18840   W (ret);
18841   return ret;
18842 }
18843
18844 static int
18845 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18846 {
18847   vl_api_one_get_map_request_itr_rlocs_t *mp;
18848   int ret;
18849
18850   if (!vam->json_output)
18851     {
18852       print (vam->ofp, "%=20s", "itr-rlocs:");
18853     }
18854
18855   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18856   /* send it... */
18857   S (mp);
18858   /* Wait for a reply... */
18859   W (ret);
18860   return ret;
18861 }
18862
18863 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18864
18865 static int
18866 api_af_packet_create (vat_main_t * vam)
18867 {
18868   unformat_input_t *i = vam->input;
18869   vl_api_af_packet_create_t *mp;
18870   u8 *host_if_name = 0;
18871   u8 hw_addr[6];
18872   u8 random_hw_addr = 1;
18873   int ret;
18874
18875   memset (hw_addr, 0, sizeof (hw_addr));
18876
18877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18878     {
18879       if (unformat (i, "name %s", &host_if_name))
18880         vec_add1 (host_if_name, 0);
18881       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18882         random_hw_addr = 0;
18883       else
18884         break;
18885     }
18886
18887   if (!vec_len (host_if_name))
18888     {
18889       errmsg ("host-interface name must be specified");
18890       return -99;
18891     }
18892
18893   if (vec_len (host_if_name) > 64)
18894     {
18895       errmsg ("host-interface name too long");
18896       return -99;
18897     }
18898
18899   M (AF_PACKET_CREATE, mp);
18900
18901   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18902   clib_memcpy (mp->hw_addr, hw_addr, 6);
18903   mp->use_random_hw_addr = random_hw_addr;
18904   vec_free (host_if_name);
18905
18906   S (mp);
18907
18908   /* *INDENT-OFF* */
18909   W2 (ret,
18910       ({
18911         if (ret == 0)
18912           fprintf (vam->ofp ? vam->ofp : stderr,
18913                    " new sw_if_index = %d\n", vam->sw_if_index);
18914       }));
18915   /* *INDENT-ON* */
18916   return ret;
18917 }
18918
18919 static int
18920 api_af_packet_delete (vat_main_t * vam)
18921 {
18922   unformat_input_t *i = vam->input;
18923   vl_api_af_packet_delete_t *mp;
18924   u8 *host_if_name = 0;
18925   int ret;
18926
18927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18928     {
18929       if (unformat (i, "name %s", &host_if_name))
18930         vec_add1 (host_if_name, 0);
18931       else
18932         break;
18933     }
18934
18935   if (!vec_len (host_if_name))
18936     {
18937       errmsg ("host-interface name must be specified");
18938       return -99;
18939     }
18940
18941   if (vec_len (host_if_name) > 64)
18942     {
18943       errmsg ("host-interface name too long");
18944       return -99;
18945     }
18946
18947   M (AF_PACKET_DELETE, mp);
18948
18949   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18950   vec_free (host_if_name);
18951
18952   S (mp);
18953   W (ret);
18954   return ret;
18955 }
18956
18957 static int
18958 api_policer_add_del (vat_main_t * vam)
18959 {
18960   unformat_input_t *i = vam->input;
18961   vl_api_policer_add_del_t *mp;
18962   u8 is_add = 1;
18963   u8 *name = 0;
18964   u32 cir = 0;
18965   u32 eir = 0;
18966   u64 cb = 0;
18967   u64 eb = 0;
18968   u8 rate_type = 0;
18969   u8 round_type = 0;
18970   u8 type = 0;
18971   u8 color_aware = 0;
18972   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18973   int ret;
18974
18975   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18976   conform_action.dscp = 0;
18977   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18978   exceed_action.dscp = 0;
18979   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18980   violate_action.dscp = 0;
18981
18982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18983     {
18984       if (unformat (i, "del"))
18985         is_add = 0;
18986       else if (unformat (i, "name %s", &name))
18987         vec_add1 (name, 0);
18988       else if (unformat (i, "cir %u", &cir))
18989         ;
18990       else if (unformat (i, "eir %u", &eir))
18991         ;
18992       else if (unformat (i, "cb %u", &cb))
18993         ;
18994       else if (unformat (i, "eb %u", &eb))
18995         ;
18996       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18997                          &rate_type))
18998         ;
18999       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19000                          &round_type))
19001         ;
19002       else if (unformat (i, "type %U", unformat_policer_type, &type))
19003         ;
19004       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19005                          &conform_action))
19006         ;
19007       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19008                          &exceed_action))
19009         ;
19010       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19011                          &violate_action))
19012         ;
19013       else if (unformat (i, "color-aware"))
19014         color_aware = 1;
19015       else
19016         break;
19017     }
19018
19019   if (!vec_len (name))
19020     {
19021       errmsg ("policer name must be specified");
19022       return -99;
19023     }
19024
19025   if (vec_len (name) > 64)
19026     {
19027       errmsg ("policer name too long");
19028       return -99;
19029     }
19030
19031   M (POLICER_ADD_DEL, mp);
19032
19033   clib_memcpy (mp->name, name, vec_len (name));
19034   vec_free (name);
19035   mp->is_add = is_add;
19036   mp->cir = ntohl (cir);
19037   mp->eir = ntohl (eir);
19038   mp->cb = clib_net_to_host_u64 (cb);
19039   mp->eb = clib_net_to_host_u64 (eb);
19040   mp->rate_type = rate_type;
19041   mp->round_type = round_type;
19042   mp->type = type;
19043   mp->conform_action_type = conform_action.action_type;
19044   mp->conform_dscp = conform_action.dscp;
19045   mp->exceed_action_type = exceed_action.action_type;
19046   mp->exceed_dscp = exceed_action.dscp;
19047   mp->violate_action_type = violate_action.action_type;
19048   mp->violate_dscp = violate_action.dscp;
19049   mp->color_aware = color_aware;
19050
19051   S (mp);
19052   W (ret);
19053   return ret;
19054 }
19055
19056 static int
19057 api_policer_dump (vat_main_t * vam)
19058 {
19059   unformat_input_t *i = vam->input;
19060   vl_api_policer_dump_t *mp;
19061   vl_api_control_ping_t *mp_ping;
19062   u8 *match_name = 0;
19063   u8 match_name_valid = 0;
19064   int ret;
19065
19066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19067     {
19068       if (unformat (i, "name %s", &match_name))
19069         {
19070           vec_add1 (match_name, 0);
19071           match_name_valid = 1;
19072         }
19073       else
19074         break;
19075     }
19076
19077   M (POLICER_DUMP, mp);
19078   mp->match_name_valid = match_name_valid;
19079   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19080   vec_free (match_name);
19081   /* send it... */
19082   S (mp);
19083
19084   /* Use a control ping for synchronization */
19085   MPING (CONTROL_PING, mp_ping);
19086   S (mp_ping);
19087
19088   /* Wait for a reply... */
19089   W (ret);
19090   return ret;
19091 }
19092
19093 static int
19094 api_policer_classify_set_interface (vat_main_t * vam)
19095 {
19096   unformat_input_t *i = vam->input;
19097   vl_api_policer_classify_set_interface_t *mp;
19098   u32 sw_if_index;
19099   int sw_if_index_set;
19100   u32 ip4_table_index = ~0;
19101   u32 ip6_table_index = ~0;
19102   u32 l2_table_index = ~0;
19103   u8 is_add = 1;
19104   int ret;
19105
19106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19107     {
19108       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19109         sw_if_index_set = 1;
19110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19111         sw_if_index_set = 1;
19112       else if (unformat (i, "del"))
19113         is_add = 0;
19114       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19115         ;
19116       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19117         ;
19118       else if (unformat (i, "l2-table %d", &l2_table_index))
19119         ;
19120       else
19121         {
19122           clib_warning ("parse error '%U'", format_unformat_error, i);
19123           return -99;
19124         }
19125     }
19126
19127   if (sw_if_index_set == 0)
19128     {
19129       errmsg ("missing interface name or sw_if_index");
19130       return -99;
19131     }
19132
19133   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19134
19135   mp->sw_if_index = ntohl (sw_if_index);
19136   mp->ip4_table_index = ntohl (ip4_table_index);
19137   mp->ip6_table_index = ntohl (ip6_table_index);
19138   mp->l2_table_index = ntohl (l2_table_index);
19139   mp->is_add = is_add;
19140
19141   S (mp);
19142   W (ret);
19143   return ret;
19144 }
19145
19146 static int
19147 api_policer_classify_dump (vat_main_t * vam)
19148 {
19149   unformat_input_t *i = vam->input;
19150   vl_api_policer_classify_dump_t *mp;
19151   vl_api_control_ping_t *mp_ping;
19152   u8 type = POLICER_CLASSIFY_N_TABLES;
19153   int ret;
19154
19155   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19156     ;
19157   else
19158     {
19159       errmsg ("classify table type must be specified");
19160       return -99;
19161     }
19162
19163   if (!vam->json_output)
19164     {
19165       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19166     }
19167
19168   M (POLICER_CLASSIFY_DUMP, mp);
19169   mp->type = type;
19170   /* send it... */
19171   S (mp);
19172
19173   /* Use a control ping for synchronization */
19174   MPING (CONTROL_PING, mp_ping);
19175   S (mp_ping);
19176
19177   /* Wait for a reply... */
19178   W (ret);
19179   return ret;
19180 }
19181
19182 static int
19183 api_netmap_create (vat_main_t * vam)
19184 {
19185   unformat_input_t *i = vam->input;
19186   vl_api_netmap_create_t *mp;
19187   u8 *if_name = 0;
19188   u8 hw_addr[6];
19189   u8 random_hw_addr = 1;
19190   u8 is_pipe = 0;
19191   u8 is_master = 0;
19192   int ret;
19193
19194   memset (hw_addr, 0, sizeof (hw_addr));
19195
19196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19197     {
19198       if (unformat (i, "name %s", &if_name))
19199         vec_add1 (if_name, 0);
19200       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19201         random_hw_addr = 0;
19202       else if (unformat (i, "pipe"))
19203         is_pipe = 1;
19204       else if (unformat (i, "master"))
19205         is_master = 1;
19206       else if (unformat (i, "slave"))
19207         is_master = 0;
19208       else
19209         break;
19210     }
19211
19212   if (!vec_len (if_name))
19213     {
19214       errmsg ("interface name must be specified");
19215       return -99;
19216     }
19217
19218   if (vec_len (if_name) > 64)
19219     {
19220       errmsg ("interface name too long");
19221       return -99;
19222     }
19223
19224   M (NETMAP_CREATE, mp);
19225
19226   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19227   clib_memcpy (mp->hw_addr, hw_addr, 6);
19228   mp->use_random_hw_addr = random_hw_addr;
19229   mp->is_pipe = is_pipe;
19230   mp->is_master = is_master;
19231   vec_free (if_name);
19232
19233   S (mp);
19234   W (ret);
19235   return ret;
19236 }
19237
19238 static int
19239 api_netmap_delete (vat_main_t * vam)
19240 {
19241   unformat_input_t *i = vam->input;
19242   vl_api_netmap_delete_t *mp;
19243   u8 *if_name = 0;
19244   int ret;
19245
19246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19247     {
19248       if (unformat (i, "name %s", &if_name))
19249         vec_add1 (if_name, 0);
19250       else
19251         break;
19252     }
19253
19254   if (!vec_len (if_name))
19255     {
19256       errmsg ("interface name must be specified");
19257       return -99;
19258     }
19259
19260   if (vec_len (if_name) > 64)
19261     {
19262       errmsg ("interface name too long");
19263       return -99;
19264     }
19265
19266   M (NETMAP_DELETE, mp);
19267
19268   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19269   vec_free (if_name);
19270
19271   S (mp);
19272   W (ret);
19273   return ret;
19274 }
19275
19276 static void
19277 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19278 {
19279   if (fp->afi == IP46_TYPE_IP6)
19280     print (vam->ofp,
19281            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19282            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19283            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19284            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19285            format_ip6_address, fp->next_hop);
19286   else if (fp->afi == IP46_TYPE_IP4)
19287     print (vam->ofp,
19288            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19289            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19290            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19291            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19292            format_ip4_address, fp->next_hop);
19293 }
19294
19295 static void
19296 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19297                                  vl_api_fib_path2_t * fp)
19298 {
19299   struct in_addr ip4;
19300   struct in6_addr ip6;
19301
19302   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19303   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19304   vat_json_object_add_uint (node, "is_local", fp->is_local);
19305   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19306   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19307   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19308   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19309   if (fp->afi == IP46_TYPE_IP4)
19310     {
19311       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19312       vat_json_object_add_ip4 (node, "next_hop", ip4);
19313     }
19314   else if (fp->afi == IP46_TYPE_IP6)
19315     {
19316       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19317       vat_json_object_add_ip6 (node, "next_hop", ip6);
19318     }
19319 }
19320
19321 static void
19322 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19323 {
19324   vat_main_t *vam = &vat_main;
19325   int count = ntohl (mp->mt_count);
19326   vl_api_fib_path2_t *fp;
19327   i32 i;
19328
19329   print (vam->ofp, "[%d]: sw_if_index %d via:",
19330          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19331   fp = mp->mt_paths;
19332   for (i = 0; i < count; i++)
19333     {
19334       vl_api_mpls_fib_path_print (vam, fp);
19335       fp++;
19336     }
19337
19338   print (vam->ofp, "");
19339 }
19340
19341 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19342 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19343
19344 static void
19345 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19346 {
19347   vat_main_t *vam = &vat_main;
19348   vat_json_node_t *node = NULL;
19349   int count = ntohl (mp->mt_count);
19350   vl_api_fib_path2_t *fp;
19351   i32 i;
19352
19353   if (VAT_JSON_ARRAY != vam->json_tree.type)
19354     {
19355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19356       vat_json_init_array (&vam->json_tree);
19357     }
19358   node = vat_json_array_add (&vam->json_tree);
19359
19360   vat_json_init_object (node);
19361   vat_json_object_add_uint (node, "tunnel_index",
19362                             ntohl (mp->mt_tunnel_index));
19363   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19364
19365   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19366
19367   fp = mp->mt_paths;
19368   for (i = 0; i < count; i++)
19369     {
19370       vl_api_mpls_fib_path_json_print (node, fp);
19371       fp++;
19372     }
19373 }
19374
19375 static int
19376 api_mpls_tunnel_dump (vat_main_t * vam)
19377 {
19378   vl_api_mpls_tunnel_dump_t *mp;
19379   vl_api_control_ping_t *mp_ping;
19380   i32 index = -1;
19381   int ret;
19382
19383   /* Parse args required to build the message */
19384   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19385     {
19386       if (!unformat (vam->input, "tunnel_index %d", &index))
19387         {
19388           index = -1;
19389           break;
19390         }
19391     }
19392
19393   print (vam->ofp, "  tunnel_index %d", index);
19394
19395   M (MPLS_TUNNEL_DUMP, mp);
19396   mp->tunnel_index = htonl (index);
19397   S (mp);
19398
19399   /* Use a control ping for synchronization */
19400   MPING (CONTROL_PING, mp_ping);
19401   S (mp_ping);
19402
19403   W (ret);
19404   return ret;
19405 }
19406
19407 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19408 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19409
19410
19411 static void
19412 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19413 {
19414   vat_main_t *vam = &vat_main;
19415   int count = ntohl (mp->count);
19416   vl_api_fib_path2_t *fp;
19417   int i;
19418
19419   print (vam->ofp,
19420          "table-id %d, label %u, ess_bit %u",
19421          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19422   fp = mp->path;
19423   for (i = 0; i < count; i++)
19424     {
19425       vl_api_mpls_fib_path_print (vam, fp);
19426       fp++;
19427     }
19428 }
19429
19430 static void vl_api_mpls_fib_details_t_handler_json
19431   (vl_api_mpls_fib_details_t * mp)
19432 {
19433   vat_main_t *vam = &vat_main;
19434   int count = ntohl (mp->count);
19435   vat_json_node_t *node = NULL;
19436   vl_api_fib_path2_t *fp;
19437   int i;
19438
19439   if (VAT_JSON_ARRAY != vam->json_tree.type)
19440     {
19441       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19442       vat_json_init_array (&vam->json_tree);
19443     }
19444   node = vat_json_array_add (&vam->json_tree);
19445
19446   vat_json_init_object (node);
19447   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19448   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19449   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19450   vat_json_object_add_uint (node, "path_count", count);
19451   fp = mp->path;
19452   for (i = 0; i < count; i++)
19453     {
19454       vl_api_mpls_fib_path_json_print (node, fp);
19455       fp++;
19456     }
19457 }
19458
19459 static int
19460 api_mpls_fib_dump (vat_main_t * vam)
19461 {
19462   vl_api_mpls_fib_dump_t *mp;
19463   vl_api_control_ping_t *mp_ping;
19464   int ret;
19465
19466   M (MPLS_FIB_DUMP, mp);
19467   S (mp);
19468
19469   /* Use a control ping for synchronization */
19470   MPING (CONTROL_PING, mp_ping);
19471   S (mp_ping);
19472
19473   W (ret);
19474   return ret;
19475 }
19476
19477 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19478 #define vl_api_ip_fib_details_t_print vl_noop_handler
19479
19480 static void
19481 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19482 {
19483   vat_main_t *vam = &vat_main;
19484   int count = ntohl (mp->count);
19485   vl_api_fib_path_t *fp;
19486   int i;
19487
19488   print (vam->ofp,
19489          "table-id %d, prefix %U/%d",
19490          ntohl (mp->table_id), format_ip4_address, mp->address,
19491          mp->address_length);
19492   fp = mp->path;
19493   for (i = 0; i < count; i++)
19494     {
19495       if (fp->afi == IP46_TYPE_IP6)
19496         print (vam->ofp,
19497                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19498                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19499                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19500                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19501                format_ip6_address, fp->next_hop);
19502       else if (fp->afi == IP46_TYPE_IP4)
19503         print (vam->ofp,
19504                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19505                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19506                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19507                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19508                format_ip4_address, fp->next_hop);
19509       fp++;
19510     }
19511 }
19512
19513 static void vl_api_ip_fib_details_t_handler_json
19514   (vl_api_ip_fib_details_t * mp)
19515 {
19516   vat_main_t *vam = &vat_main;
19517   int count = ntohl (mp->count);
19518   vat_json_node_t *node = NULL;
19519   struct in_addr ip4;
19520   struct in6_addr ip6;
19521   vl_api_fib_path_t *fp;
19522   int i;
19523
19524   if (VAT_JSON_ARRAY != vam->json_tree.type)
19525     {
19526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19527       vat_json_init_array (&vam->json_tree);
19528     }
19529   node = vat_json_array_add (&vam->json_tree);
19530
19531   vat_json_init_object (node);
19532   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19533   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19534   vat_json_object_add_ip4 (node, "prefix", ip4);
19535   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19536   vat_json_object_add_uint (node, "path_count", count);
19537   fp = mp->path;
19538   for (i = 0; i < count; i++)
19539     {
19540       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19541       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19542       vat_json_object_add_uint (node, "is_local", fp->is_local);
19543       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19544       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19545       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19546       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19547       if (fp->afi == IP46_TYPE_IP4)
19548         {
19549           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19550           vat_json_object_add_ip4 (node, "next_hop", ip4);
19551         }
19552       else if (fp->afi == IP46_TYPE_IP6)
19553         {
19554           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19555           vat_json_object_add_ip6 (node, "next_hop", ip6);
19556         }
19557     }
19558 }
19559
19560 static int
19561 api_ip_fib_dump (vat_main_t * vam)
19562 {
19563   vl_api_ip_fib_dump_t *mp;
19564   vl_api_control_ping_t *mp_ping;
19565   int ret;
19566
19567   M (IP_FIB_DUMP, mp);
19568   S (mp);
19569
19570   /* Use a control ping for synchronization */
19571   MPING (CONTROL_PING, mp_ping);
19572   S (mp_ping);
19573
19574   W (ret);
19575   return ret;
19576 }
19577
19578 static int
19579 api_ip_mfib_dump (vat_main_t * vam)
19580 {
19581   vl_api_ip_mfib_dump_t *mp;
19582   vl_api_control_ping_t *mp_ping;
19583   int ret;
19584
19585   M (IP_MFIB_DUMP, mp);
19586   S (mp);
19587
19588   /* Use a control ping for synchronization */
19589   MPING (CONTROL_PING, mp_ping);
19590   S (mp_ping);
19591
19592   W (ret);
19593   return ret;
19594 }
19595
19596 static void vl_api_ip_neighbor_details_t_handler
19597   (vl_api_ip_neighbor_details_t * mp)
19598 {
19599   vat_main_t *vam = &vat_main;
19600
19601   print (vam->ofp, "%c %U %U",
19602          (mp->is_static) ? 'S' : 'D',
19603          format_ethernet_address, &mp->mac_address,
19604          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19605          &mp->ip_address);
19606 }
19607
19608 static void vl_api_ip_neighbor_details_t_handler_json
19609   (vl_api_ip_neighbor_details_t * mp)
19610 {
19611
19612   vat_main_t *vam = &vat_main;
19613   vat_json_node_t *node;
19614   struct in_addr ip4;
19615   struct in6_addr ip6;
19616
19617   if (VAT_JSON_ARRAY != vam->json_tree.type)
19618     {
19619       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19620       vat_json_init_array (&vam->json_tree);
19621     }
19622   node = vat_json_array_add (&vam->json_tree);
19623
19624   vat_json_init_object (node);
19625   vat_json_object_add_string_copy (node, "flag",
19626                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19627                                    "dynamic");
19628
19629   vat_json_object_add_string_copy (node, "link_layer",
19630                                    format (0, "%U", format_ethernet_address,
19631                                            &mp->mac_address));
19632
19633   if (mp->is_ipv6)
19634     {
19635       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19636       vat_json_object_add_ip6 (node, "ip_address", ip6);
19637     }
19638   else
19639     {
19640       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19641       vat_json_object_add_ip4 (node, "ip_address", ip4);
19642     }
19643 }
19644
19645 static int
19646 api_ip_neighbor_dump (vat_main_t * vam)
19647 {
19648   unformat_input_t *i = vam->input;
19649   vl_api_ip_neighbor_dump_t *mp;
19650   vl_api_control_ping_t *mp_ping;
19651   u8 is_ipv6 = 0;
19652   u32 sw_if_index = ~0;
19653   int ret;
19654
19655   /* Parse args required to build the message */
19656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19657     {
19658       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19659         ;
19660       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19661         ;
19662       else if (unformat (i, "ip6"))
19663         is_ipv6 = 1;
19664       else
19665         break;
19666     }
19667
19668   if (sw_if_index == ~0)
19669     {
19670       errmsg ("missing interface name or sw_if_index");
19671       return -99;
19672     }
19673
19674   M (IP_NEIGHBOR_DUMP, mp);
19675   mp->is_ipv6 = (u8) is_ipv6;
19676   mp->sw_if_index = ntohl (sw_if_index);
19677   S (mp);
19678
19679   /* Use a control ping for synchronization */
19680   MPING (CONTROL_PING, mp_ping);
19681   S (mp_ping);
19682
19683   W (ret);
19684   return ret;
19685 }
19686
19687 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19688 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19689
19690 static void
19691 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19692 {
19693   vat_main_t *vam = &vat_main;
19694   int count = ntohl (mp->count);
19695   vl_api_fib_path_t *fp;
19696   int i;
19697
19698   print (vam->ofp,
19699          "table-id %d, prefix %U/%d",
19700          ntohl (mp->table_id), format_ip6_address, mp->address,
19701          mp->address_length);
19702   fp = mp->path;
19703   for (i = 0; i < count; i++)
19704     {
19705       if (fp->afi == IP46_TYPE_IP6)
19706         print (vam->ofp,
19707                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19708                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19709                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19710                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19711                format_ip6_address, fp->next_hop);
19712       else if (fp->afi == IP46_TYPE_IP4)
19713         print (vam->ofp,
19714                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19715                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19716                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19717                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19718                format_ip4_address, fp->next_hop);
19719       fp++;
19720     }
19721 }
19722
19723 static void vl_api_ip6_fib_details_t_handler_json
19724   (vl_api_ip6_fib_details_t * mp)
19725 {
19726   vat_main_t *vam = &vat_main;
19727   int count = ntohl (mp->count);
19728   vat_json_node_t *node = NULL;
19729   struct in_addr ip4;
19730   struct in6_addr ip6;
19731   vl_api_fib_path_t *fp;
19732   int i;
19733
19734   if (VAT_JSON_ARRAY != vam->json_tree.type)
19735     {
19736       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19737       vat_json_init_array (&vam->json_tree);
19738     }
19739   node = vat_json_array_add (&vam->json_tree);
19740
19741   vat_json_init_object (node);
19742   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19743   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19744   vat_json_object_add_ip6 (node, "prefix", ip6);
19745   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19746   vat_json_object_add_uint (node, "path_count", count);
19747   fp = mp->path;
19748   for (i = 0; i < count; i++)
19749     {
19750       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19751       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19752       vat_json_object_add_uint (node, "is_local", fp->is_local);
19753       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19754       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19755       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19756       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19757       if (fp->afi == IP46_TYPE_IP4)
19758         {
19759           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19760           vat_json_object_add_ip4 (node, "next_hop", ip4);
19761         }
19762       else if (fp->afi == IP46_TYPE_IP6)
19763         {
19764           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19765           vat_json_object_add_ip6 (node, "next_hop", ip6);
19766         }
19767     }
19768 }
19769
19770 static int
19771 api_ip6_fib_dump (vat_main_t * vam)
19772 {
19773   vl_api_ip6_fib_dump_t *mp;
19774   vl_api_control_ping_t *mp_ping;
19775   int ret;
19776
19777   M (IP6_FIB_DUMP, mp);
19778   S (mp);
19779
19780   /* Use a control ping for synchronization */
19781   MPING (CONTROL_PING, mp_ping);
19782   S (mp_ping);
19783
19784   W (ret);
19785   return ret;
19786 }
19787
19788 static int
19789 api_ip6_mfib_dump (vat_main_t * vam)
19790 {
19791   vl_api_ip6_mfib_dump_t *mp;
19792   vl_api_control_ping_t *mp_ping;
19793   int ret;
19794
19795   M (IP6_MFIB_DUMP, mp);
19796   S (mp);
19797
19798   /* Use a control ping for synchronization */
19799   MPING (CONTROL_PING, mp_ping);
19800   S (mp_ping);
19801
19802   W (ret);
19803   return ret;
19804 }
19805
19806 int
19807 api_classify_table_ids (vat_main_t * vam)
19808 {
19809   vl_api_classify_table_ids_t *mp;
19810   int ret;
19811
19812   /* Construct the API message */
19813   M (CLASSIFY_TABLE_IDS, mp);
19814   mp->context = 0;
19815
19816   S (mp);
19817   W (ret);
19818   return ret;
19819 }
19820
19821 int
19822 api_classify_table_by_interface (vat_main_t * vam)
19823 {
19824   unformat_input_t *input = vam->input;
19825   vl_api_classify_table_by_interface_t *mp;
19826
19827   u32 sw_if_index = ~0;
19828   int ret;
19829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19830     {
19831       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19832         ;
19833       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19834         ;
19835       else
19836         break;
19837     }
19838   if (sw_if_index == ~0)
19839     {
19840       errmsg ("missing interface name or sw_if_index");
19841       return -99;
19842     }
19843
19844   /* Construct the API message */
19845   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19846   mp->context = 0;
19847   mp->sw_if_index = ntohl (sw_if_index);
19848
19849   S (mp);
19850   W (ret);
19851   return ret;
19852 }
19853
19854 int
19855 api_classify_table_info (vat_main_t * vam)
19856 {
19857   unformat_input_t *input = vam->input;
19858   vl_api_classify_table_info_t *mp;
19859
19860   u32 table_id = ~0;
19861   int ret;
19862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19863     {
19864       if (unformat (input, "table_id %d", &table_id))
19865         ;
19866       else
19867         break;
19868     }
19869   if (table_id == ~0)
19870     {
19871       errmsg ("missing table id");
19872       return -99;
19873     }
19874
19875   /* Construct the API message */
19876   M (CLASSIFY_TABLE_INFO, mp);
19877   mp->context = 0;
19878   mp->table_id = ntohl (table_id);
19879
19880   S (mp);
19881   W (ret);
19882   return ret;
19883 }
19884
19885 int
19886 api_classify_session_dump (vat_main_t * vam)
19887 {
19888   unformat_input_t *input = vam->input;
19889   vl_api_classify_session_dump_t *mp;
19890   vl_api_control_ping_t *mp_ping;
19891
19892   u32 table_id = ~0;
19893   int ret;
19894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19895     {
19896       if (unformat (input, "table_id %d", &table_id))
19897         ;
19898       else
19899         break;
19900     }
19901   if (table_id == ~0)
19902     {
19903       errmsg ("missing table id");
19904       return -99;
19905     }
19906
19907   /* Construct the API message */
19908   M (CLASSIFY_SESSION_DUMP, mp);
19909   mp->context = 0;
19910   mp->table_id = ntohl (table_id);
19911   S (mp);
19912
19913   /* Use a control ping for synchronization */
19914   MPING (CONTROL_PING, mp_ping);
19915   S (mp_ping);
19916
19917   W (ret);
19918   return ret;
19919 }
19920
19921 static void
19922 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19923 {
19924   vat_main_t *vam = &vat_main;
19925
19926   print (vam->ofp, "collector_address %U, collector_port %d, "
19927          "src_address %U, vrf_id %d, path_mtu %u, "
19928          "template_interval %u, udp_checksum %d",
19929          format_ip4_address, mp->collector_address,
19930          ntohs (mp->collector_port),
19931          format_ip4_address, mp->src_address,
19932          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19933          ntohl (mp->template_interval), mp->udp_checksum);
19934
19935   vam->retval = 0;
19936   vam->result_ready = 1;
19937 }
19938
19939 static void
19940   vl_api_ipfix_exporter_details_t_handler_json
19941   (vl_api_ipfix_exporter_details_t * mp)
19942 {
19943   vat_main_t *vam = &vat_main;
19944   vat_json_node_t node;
19945   struct in_addr collector_address;
19946   struct in_addr src_address;
19947
19948   vat_json_init_object (&node);
19949   clib_memcpy (&collector_address, &mp->collector_address,
19950                sizeof (collector_address));
19951   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19952   vat_json_object_add_uint (&node, "collector_port",
19953                             ntohs (mp->collector_port));
19954   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19955   vat_json_object_add_ip4 (&node, "src_address", src_address);
19956   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19957   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19958   vat_json_object_add_uint (&node, "template_interval",
19959                             ntohl (mp->template_interval));
19960   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19961
19962   vat_json_print (vam->ofp, &node);
19963   vat_json_free (&node);
19964   vam->retval = 0;
19965   vam->result_ready = 1;
19966 }
19967
19968 int
19969 api_ipfix_exporter_dump (vat_main_t * vam)
19970 {
19971   vl_api_ipfix_exporter_dump_t *mp;
19972   int ret;
19973
19974   /* Construct the API message */
19975   M (IPFIX_EXPORTER_DUMP, mp);
19976   mp->context = 0;
19977
19978   S (mp);
19979   W (ret);
19980   return ret;
19981 }
19982
19983 static int
19984 api_ipfix_classify_stream_dump (vat_main_t * vam)
19985 {
19986   vl_api_ipfix_classify_stream_dump_t *mp;
19987   int ret;
19988
19989   /* Construct the API message */
19990   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19991   mp->context = 0;
19992
19993   S (mp);
19994   W (ret);
19995   return ret;
19996   /* NOTREACHED */
19997   return 0;
19998 }
19999
20000 static void
20001   vl_api_ipfix_classify_stream_details_t_handler
20002   (vl_api_ipfix_classify_stream_details_t * mp)
20003 {
20004   vat_main_t *vam = &vat_main;
20005   print (vam->ofp, "domain_id %d, src_port %d",
20006          ntohl (mp->domain_id), ntohs (mp->src_port));
20007   vam->retval = 0;
20008   vam->result_ready = 1;
20009 }
20010
20011 static void
20012   vl_api_ipfix_classify_stream_details_t_handler_json
20013   (vl_api_ipfix_classify_stream_details_t * mp)
20014 {
20015   vat_main_t *vam = &vat_main;
20016   vat_json_node_t node;
20017
20018   vat_json_init_object (&node);
20019   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20020   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20021
20022   vat_json_print (vam->ofp, &node);
20023   vat_json_free (&node);
20024   vam->retval = 0;
20025   vam->result_ready = 1;
20026 }
20027
20028 static int
20029 api_ipfix_classify_table_dump (vat_main_t * vam)
20030 {
20031   vl_api_ipfix_classify_table_dump_t *mp;
20032   vl_api_control_ping_t *mp_ping;
20033   int ret;
20034
20035   if (!vam->json_output)
20036     {
20037       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20038              "transport_protocol");
20039     }
20040
20041   /* Construct the API message */
20042   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20043
20044   /* send it... */
20045   S (mp);
20046
20047   /* Use a control ping for synchronization */
20048   MPING (CONTROL_PING, mp_ping);
20049   S (mp_ping);
20050
20051   W (ret);
20052   return ret;
20053 }
20054
20055 static void
20056   vl_api_ipfix_classify_table_details_t_handler
20057   (vl_api_ipfix_classify_table_details_t * mp)
20058 {
20059   vat_main_t *vam = &vat_main;
20060   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20061          mp->transport_protocol);
20062 }
20063
20064 static void
20065   vl_api_ipfix_classify_table_details_t_handler_json
20066   (vl_api_ipfix_classify_table_details_t * mp)
20067 {
20068   vat_json_node_t *node = NULL;
20069   vat_main_t *vam = &vat_main;
20070
20071   if (VAT_JSON_ARRAY != vam->json_tree.type)
20072     {
20073       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20074       vat_json_init_array (&vam->json_tree);
20075     }
20076
20077   node = vat_json_array_add (&vam->json_tree);
20078   vat_json_init_object (node);
20079
20080   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20081   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20082   vat_json_object_add_uint (node, "transport_protocol",
20083                             mp->transport_protocol);
20084 }
20085
20086 static int
20087 api_sw_interface_span_enable_disable (vat_main_t * vam)
20088 {
20089   unformat_input_t *i = vam->input;
20090   vl_api_sw_interface_span_enable_disable_t *mp;
20091   u32 src_sw_if_index = ~0;
20092   u32 dst_sw_if_index = ~0;
20093   u8 state = 3;
20094   int ret;
20095   u8 is_l2 = 0;
20096
20097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20098     {
20099       if (unformat
20100           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20101         ;
20102       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20103         ;
20104       else
20105         if (unformat
20106             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20107         ;
20108       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20109         ;
20110       else if (unformat (i, "disable"))
20111         state = 0;
20112       else if (unformat (i, "rx"))
20113         state = 1;
20114       else if (unformat (i, "tx"))
20115         state = 2;
20116       else if (unformat (i, "both"))
20117         state = 3;
20118       else if (unformat (i, "l2"))
20119         is_l2 = 1;
20120       else
20121         break;
20122     }
20123
20124   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20125
20126   mp->sw_if_index_from = htonl (src_sw_if_index);
20127   mp->sw_if_index_to = htonl (dst_sw_if_index);
20128   mp->state = state;
20129   mp->is_l2 = is_l2;
20130
20131   S (mp);
20132   W (ret);
20133   return ret;
20134 }
20135
20136 static void
20137 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20138                                             * mp)
20139 {
20140   vat_main_t *vam = &vat_main;
20141   u8 *sw_if_from_name = 0;
20142   u8 *sw_if_to_name = 0;
20143   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20144   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20145   char *states[] = { "none", "rx", "tx", "both" };
20146   hash_pair_t *p;
20147
20148   /* *INDENT-OFF* */
20149   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20150   ({
20151     if ((u32) p->value[0] == sw_if_index_from)
20152       {
20153         sw_if_from_name = (u8 *)(p->key);
20154         if (sw_if_to_name)
20155           break;
20156       }
20157     if ((u32) p->value[0] == sw_if_index_to)
20158       {
20159         sw_if_to_name = (u8 *)(p->key);
20160         if (sw_if_from_name)
20161           break;
20162       }
20163   }));
20164   /* *INDENT-ON* */
20165   print (vam->ofp, "%20s => %20s (%s)",
20166          sw_if_from_name, sw_if_to_name, states[mp->state]);
20167 }
20168
20169 static void
20170   vl_api_sw_interface_span_details_t_handler_json
20171   (vl_api_sw_interface_span_details_t * mp)
20172 {
20173   vat_main_t *vam = &vat_main;
20174   vat_json_node_t *node = NULL;
20175   u8 *sw_if_from_name = 0;
20176   u8 *sw_if_to_name = 0;
20177   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20178   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20179   hash_pair_t *p;
20180
20181   /* *INDENT-OFF* */
20182   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20183   ({
20184     if ((u32) p->value[0] == sw_if_index_from)
20185       {
20186         sw_if_from_name = (u8 *)(p->key);
20187         if (sw_if_to_name)
20188           break;
20189       }
20190     if ((u32) p->value[0] == sw_if_index_to)
20191       {
20192         sw_if_to_name = (u8 *)(p->key);
20193         if (sw_if_from_name)
20194           break;
20195       }
20196   }));
20197   /* *INDENT-ON* */
20198
20199   if (VAT_JSON_ARRAY != vam->json_tree.type)
20200     {
20201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20202       vat_json_init_array (&vam->json_tree);
20203     }
20204   node = vat_json_array_add (&vam->json_tree);
20205
20206   vat_json_init_object (node);
20207   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20208   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20209   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20210   if (0 != sw_if_to_name)
20211     {
20212       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20213     }
20214   vat_json_object_add_uint (node, "state", mp->state);
20215 }
20216
20217 static int
20218 api_sw_interface_span_dump (vat_main_t * vam)
20219 {
20220   unformat_input_t *input = vam->input;
20221   vl_api_sw_interface_span_dump_t *mp;
20222   vl_api_control_ping_t *mp_ping;
20223   u8 is_l2 = 0;
20224   int ret;
20225
20226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20227     {
20228       if (unformat (input, "l2"))
20229         is_l2 = 1;
20230       else
20231         break;
20232     }
20233
20234   M (SW_INTERFACE_SPAN_DUMP, mp);
20235   mp->is_l2 = is_l2;
20236   S (mp);
20237
20238   /* Use a control ping for synchronization */
20239   MPING (CONTROL_PING, mp_ping);
20240   S (mp_ping);
20241
20242   W (ret);
20243   return ret;
20244 }
20245
20246 int
20247 api_pg_create_interface (vat_main_t * vam)
20248 {
20249   unformat_input_t *input = vam->input;
20250   vl_api_pg_create_interface_t *mp;
20251
20252   u32 if_id = ~0;
20253   int ret;
20254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20255     {
20256       if (unformat (input, "if_id %d", &if_id))
20257         ;
20258       else
20259         break;
20260     }
20261   if (if_id == ~0)
20262     {
20263       errmsg ("missing pg interface index");
20264       return -99;
20265     }
20266
20267   /* Construct the API message */
20268   M (PG_CREATE_INTERFACE, mp);
20269   mp->context = 0;
20270   mp->interface_id = ntohl (if_id);
20271
20272   S (mp);
20273   W (ret);
20274   return ret;
20275 }
20276
20277 int
20278 api_pg_capture (vat_main_t * vam)
20279 {
20280   unformat_input_t *input = vam->input;
20281   vl_api_pg_capture_t *mp;
20282
20283   u32 if_id = ~0;
20284   u8 enable = 1;
20285   u32 count = 1;
20286   u8 pcap_file_set = 0;
20287   u8 *pcap_file = 0;
20288   int ret;
20289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20290     {
20291       if (unformat (input, "if_id %d", &if_id))
20292         ;
20293       else if (unformat (input, "pcap %s", &pcap_file))
20294         pcap_file_set = 1;
20295       else if (unformat (input, "count %d", &count))
20296         ;
20297       else if (unformat (input, "disable"))
20298         enable = 0;
20299       else
20300         break;
20301     }
20302   if (if_id == ~0)
20303     {
20304       errmsg ("missing pg interface index");
20305       return -99;
20306     }
20307   if (pcap_file_set > 0)
20308     {
20309       if (vec_len (pcap_file) > 255)
20310         {
20311           errmsg ("pcap file name is too long");
20312           return -99;
20313         }
20314     }
20315
20316   u32 name_len = vec_len (pcap_file);
20317   /* Construct the API message */
20318   M (PG_CAPTURE, mp);
20319   mp->context = 0;
20320   mp->interface_id = ntohl (if_id);
20321   mp->is_enabled = enable;
20322   mp->count = ntohl (count);
20323   mp->pcap_name_length = ntohl (name_len);
20324   if (pcap_file_set != 0)
20325     {
20326       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20327     }
20328   vec_free (pcap_file);
20329
20330   S (mp);
20331   W (ret);
20332   return ret;
20333 }
20334
20335 int
20336 api_pg_enable_disable (vat_main_t * vam)
20337 {
20338   unformat_input_t *input = vam->input;
20339   vl_api_pg_enable_disable_t *mp;
20340
20341   u8 enable = 1;
20342   u8 stream_name_set = 0;
20343   u8 *stream_name = 0;
20344   int ret;
20345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20346     {
20347       if (unformat (input, "stream %s", &stream_name))
20348         stream_name_set = 1;
20349       else if (unformat (input, "disable"))
20350         enable = 0;
20351       else
20352         break;
20353     }
20354
20355   if (stream_name_set > 0)
20356     {
20357       if (vec_len (stream_name) > 255)
20358         {
20359           errmsg ("stream name too long");
20360           return -99;
20361         }
20362     }
20363
20364   u32 name_len = vec_len (stream_name);
20365   /* Construct the API message */
20366   M (PG_ENABLE_DISABLE, mp);
20367   mp->context = 0;
20368   mp->is_enabled = enable;
20369   if (stream_name_set != 0)
20370     {
20371       mp->stream_name_length = ntohl (name_len);
20372       clib_memcpy (mp->stream_name, stream_name, name_len);
20373     }
20374   vec_free (stream_name);
20375
20376   S (mp);
20377   W (ret);
20378   return ret;
20379 }
20380
20381 int
20382 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20383 {
20384   unformat_input_t *input = vam->input;
20385   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20386
20387   u16 *low_ports = 0;
20388   u16 *high_ports = 0;
20389   u16 this_low;
20390   u16 this_hi;
20391   ip4_address_t ip4_addr;
20392   ip6_address_t ip6_addr;
20393   u32 length;
20394   u32 tmp, tmp2;
20395   u8 prefix_set = 0;
20396   u32 vrf_id = ~0;
20397   u8 is_add = 1;
20398   u8 is_ipv6 = 0;
20399   int ret;
20400
20401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20402     {
20403       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20404         {
20405           prefix_set = 1;
20406         }
20407       else
20408         if (unformat
20409             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20410         {
20411           prefix_set = 1;
20412           is_ipv6 = 1;
20413         }
20414       else if (unformat (input, "vrf %d", &vrf_id))
20415         ;
20416       else if (unformat (input, "del"))
20417         is_add = 0;
20418       else if (unformat (input, "port %d", &tmp))
20419         {
20420           if (tmp == 0 || tmp > 65535)
20421             {
20422               errmsg ("port %d out of range", tmp);
20423               return -99;
20424             }
20425           this_low = tmp;
20426           this_hi = this_low + 1;
20427           vec_add1 (low_ports, this_low);
20428           vec_add1 (high_ports, this_hi);
20429         }
20430       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20431         {
20432           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20433             {
20434               errmsg ("incorrect range parameters");
20435               return -99;
20436             }
20437           this_low = tmp;
20438           /* Note: in debug CLI +1 is added to high before
20439              passing to real fn that does "the work"
20440              (ip_source_and_port_range_check_add_del).
20441              This fn is a wrapper around the binary API fn a
20442              control plane will call, which expects this increment
20443              to have occurred. Hence letting the binary API control
20444              plane fn do the increment for consistency between VAT
20445              and other control planes.
20446            */
20447           this_hi = tmp2;
20448           vec_add1 (low_ports, this_low);
20449           vec_add1 (high_ports, this_hi);
20450         }
20451       else
20452         break;
20453     }
20454
20455   if (prefix_set == 0)
20456     {
20457       errmsg ("<address>/<mask> not specified");
20458       return -99;
20459     }
20460
20461   if (vrf_id == ~0)
20462     {
20463       errmsg ("VRF ID required, not specified");
20464       return -99;
20465     }
20466
20467   if (vrf_id == 0)
20468     {
20469       errmsg
20470         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20471       return -99;
20472     }
20473
20474   if (vec_len (low_ports) == 0)
20475     {
20476       errmsg ("At least one port or port range required");
20477       return -99;
20478     }
20479
20480   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20481
20482   mp->is_add = is_add;
20483
20484   if (is_ipv6)
20485     {
20486       mp->is_ipv6 = 1;
20487       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20488     }
20489   else
20490     {
20491       mp->is_ipv6 = 0;
20492       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20493     }
20494
20495   mp->mask_length = length;
20496   mp->number_of_ranges = vec_len (low_ports);
20497
20498   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20499   vec_free (low_ports);
20500
20501   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20502   vec_free (high_ports);
20503
20504   mp->vrf_id = ntohl (vrf_id);
20505
20506   S (mp);
20507   W (ret);
20508   return ret;
20509 }
20510
20511 int
20512 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20513 {
20514   unformat_input_t *input = vam->input;
20515   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20516   u32 sw_if_index = ~0;
20517   int vrf_set = 0;
20518   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20519   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20520   u8 is_add = 1;
20521   int ret;
20522
20523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20524     {
20525       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20526         ;
20527       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20528         ;
20529       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20530         vrf_set = 1;
20531       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20532         vrf_set = 1;
20533       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20534         vrf_set = 1;
20535       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20536         vrf_set = 1;
20537       else if (unformat (input, "del"))
20538         is_add = 0;
20539       else
20540         break;
20541     }
20542
20543   if (sw_if_index == ~0)
20544     {
20545       errmsg ("Interface required but not specified");
20546       return -99;
20547     }
20548
20549   if (vrf_set == 0)
20550     {
20551       errmsg ("VRF ID required but not specified");
20552       return -99;
20553     }
20554
20555   if (tcp_out_vrf_id == 0
20556       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20557     {
20558       errmsg
20559         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20560       return -99;
20561     }
20562
20563   /* Construct the API message */
20564   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20565
20566   mp->sw_if_index = ntohl (sw_if_index);
20567   mp->is_add = is_add;
20568   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20569   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20570   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20571   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20572
20573   /* send it... */
20574   S (mp);
20575
20576   /* Wait for a reply... */
20577   W (ret);
20578   return ret;
20579 }
20580
20581 static int
20582 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20583 {
20584   unformat_input_t *i = vam->input;
20585   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20586   u32 local_sa_id = 0;
20587   u32 remote_sa_id = 0;
20588   ip4_address_t src_address;
20589   ip4_address_t dst_address;
20590   u8 is_add = 1;
20591   int ret;
20592
20593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20594     {
20595       if (unformat (i, "local_sa %d", &local_sa_id))
20596         ;
20597       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20598         ;
20599       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20600         ;
20601       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20602         ;
20603       else if (unformat (i, "del"))
20604         is_add = 0;
20605       else
20606         {
20607           clib_warning ("parse error '%U'", format_unformat_error, i);
20608           return -99;
20609         }
20610     }
20611
20612   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20613
20614   mp->local_sa_id = ntohl (local_sa_id);
20615   mp->remote_sa_id = ntohl (remote_sa_id);
20616   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20617   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20618   mp->is_add = is_add;
20619
20620   S (mp);
20621   W (ret);
20622   return ret;
20623 }
20624
20625 static int
20626 api_punt (vat_main_t * vam)
20627 {
20628   unformat_input_t *i = vam->input;
20629   vl_api_punt_t *mp;
20630   u32 ipv = ~0;
20631   u32 protocol = ~0;
20632   u32 port = ~0;
20633   int is_add = 1;
20634   int ret;
20635
20636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20637     {
20638       if (unformat (i, "ip %d", &ipv))
20639         ;
20640       else if (unformat (i, "protocol %d", &protocol))
20641         ;
20642       else if (unformat (i, "port %d", &port))
20643         ;
20644       else if (unformat (i, "del"))
20645         is_add = 0;
20646       else
20647         {
20648           clib_warning ("parse error '%U'", format_unformat_error, i);
20649           return -99;
20650         }
20651     }
20652
20653   M (PUNT, mp);
20654
20655   mp->is_add = (u8) is_add;
20656   mp->ipv = (u8) ipv;
20657   mp->l4_protocol = (u8) protocol;
20658   mp->l4_port = htons ((u16) port);
20659
20660   S (mp);
20661   W (ret);
20662   return ret;
20663 }
20664
20665 static void vl_api_ipsec_gre_tunnel_details_t_handler
20666   (vl_api_ipsec_gre_tunnel_details_t * mp)
20667 {
20668   vat_main_t *vam = &vat_main;
20669
20670   print (vam->ofp, "%11d%15U%15U%14d%14d",
20671          ntohl (mp->sw_if_index),
20672          format_ip4_address, &mp->src_address,
20673          format_ip4_address, &mp->dst_address,
20674          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20675 }
20676
20677 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20678   (vl_api_ipsec_gre_tunnel_details_t * mp)
20679 {
20680   vat_main_t *vam = &vat_main;
20681   vat_json_node_t *node = NULL;
20682   struct in_addr ip4;
20683
20684   if (VAT_JSON_ARRAY != vam->json_tree.type)
20685     {
20686       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20687       vat_json_init_array (&vam->json_tree);
20688     }
20689   node = vat_json_array_add (&vam->json_tree);
20690
20691   vat_json_init_object (node);
20692   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20693   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20694   vat_json_object_add_ip4 (node, "src_address", ip4);
20695   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20696   vat_json_object_add_ip4 (node, "dst_address", ip4);
20697   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20698   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20699 }
20700
20701 static int
20702 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20703 {
20704   unformat_input_t *i = vam->input;
20705   vl_api_ipsec_gre_tunnel_dump_t *mp;
20706   vl_api_control_ping_t *mp_ping;
20707   u32 sw_if_index;
20708   u8 sw_if_index_set = 0;
20709   int ret;
20710
20711   /* Parse args required to build the message */
20712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20713     {
20714       if (unformat (i, "sw_if_index %d", &sw_if_index))
20715         sw_if_index_set = 1;
20716       else
20717         break;
20718     }
20719
20720   if (sw_if_index_set == 0)
20721     {
20722       sw_if_index = ~0;
20723     }
20724
20725   if (!vam->json_output)
20726     {
20727       print (vam->ofp, "%11s%15s%15s%14s%14s",
20728              "sw_if_index", "src_address", "dst_address",
20729              "local_sa_id", "remote_sa_id");
20730     }
20731
20732   /* Get list of gre-tunnel interfaces */
20733   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20734
20735   mp->sw_if_index = htonl (sw_if_index);
20736
20737   S (mp);
20738
20739   /* Use a control ping for synchronization */
20740   MPING (CONTROL_PING, mp_ping);
20741   S (mp_ping);
20742
20743   W (ret);
20744   return ret;
20745 }
20746
20747 static int
20748 api_delete_subif (vat_main_t * vam)
20749 {
20750   unformat_input_t *i = vam->input;
20751   vl_api_delete_subif_t *mp;
20752   u32 sw_if_index = ~0;
20753   int ret;
20754
20755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20756     {
20757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20758         ;
20759       if (unformat (i, "sw_if_index %d", &sw_if_index))
20760         ;
20761       else
20762         break;
20763     }
20764
20765   if (sw_if_index == ~0)
20766     {
20767       errmsg ("missing sw_if_index");
20768       return -99;
20769     }
20770
20771   /* Construct the API message */
20772   M (DELETE_SUBIF, mp);
20773   mp->sw_if_index = ntohl (sw_if_index);
20774
20775   S (mp);
20776   W (ret);
20777   return ret;
20778 }
20779
20780 #define foreach_pbb_vtr_op      \
20781 _("disable",  L2_VTR_DISABLED)  \
20782 _("pop",  L2_VTR_POP_2)         \
20783 _("push",  L2_VTR_PUSH_2)
20784
20785 static int
20786 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20787 {
20788   unformat_input_t *i = vam->input;
20789   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20790   u32 sw_if_index = ~0, vtr_op = ~0;
20791   u16 outer_tag = ~0;
20792   u8 dmac[6], smac[6];
20793   u8 dmac_set = 0, smac_set = 0;
20794   u16 vlanid = 0;
20795   u32 sid = ~0;
20796   u32 tmp;
20797   int ret;
20798
20799   /* Shut up coverity */
20800   memset (dmac, 0, sizeof (dmac));
20801   memset (smac, 0, sizeof (smac));
20802
20803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20804     {
20805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20806         ;
20807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20808         ;
20809       else if (unformat (i, "vtr_op %d", &vtr_op))
20810         ;
20811 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20812       foreach_pbb_vtr_op
20813 #undef _
20814         else if (unformat (i, "translate_pbb_stag"))
20815         {
20816           if (unformat (i, "%d", &tmp))
20817             {
20818               vtr_op = L2_VTR_TRANSLATE_2_1;
20819               outer_tag = tmp;
20820             }
20821           else
20822             {
20823               errmsg
20824                 ("translate_pbb_stag operation requires outer tag definition");
20825               return -99;
20826             }
20827         }
20828       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20829         dmac_set++;
20830       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20831         smac_set++;
20832       else if (unformat (i, "sid %d", &sid))
20833         ;
20834       else if (unformat (i, "vlanid %d", &tmp))
20835         vlanid = tmp;
20836       else
20837         {
20838           clib_warning ("parse error '%U'", format_unformat_error, i);
20839           return -99;
20840         }
20841     }
20842
20843   if ((sw_if_index == ~0) || (vtr_op == ~0))
20844     {
20845       errmsg ("missing sw_if_index or vtr operation");
20846       return -99;
20847     }
20848   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20849       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20850     {
20851       errmsg
20852         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20853       return -99;
20854     }
20855
20856   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20857   mp->sw_if_index = ntohl (sw_if_index);
20858   mp->vtr_op = ntohl (vtr_op);
20859   mp->outer_tag = ntohs (outer_tag);
20860   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20861   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20862   mp->b_vlanid = ntohs (vlanid);
20863   mp->i_sid = ntohl (sid);
20864
20865   S (mp);
20866   W (ret);
20867   return ret;
20868 }
20869
20870 static int
20871 api_flow_classify_set_interface (vat_main_t * vam)
20872 {
20873   unformat_input_t *i = vam->input;
20874   vl_api_flow_classify_set_interface_t *mp;
20875   u32 sw_if_index;
20876   int sw_if_index_set;
20877   u32 ip4_table_index = ~0;
20878   u32 ip6_table_index = ~0;
20879   u8 is_add = 1;
20880   int ret;
20881
20882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20883     {
20884       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20885         sw_if_index_set = 1;
20886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20887         sw_if_index_set = 1;
20888       else if (unformat (i, "del"))
20889         is_add = 0;
20890       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20891         ;
20892       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20893         ;
20894       else
20895         {
20896           clib_warning ("parse error '%U'", format_unformat_error, i);
20897           return -99;
20898         }
20899     }
20900
20901   if (sw_if_index_set == 0)
20902     {
20903       errmsg ("missing interface name or sw_if_index");
20904       return -99;
20905     }
20906
20907   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20908
20909   mp->sw_if_index = ntohl (sw_if_index);
20910   mp->ip4_table_index = ntohl (ip4_table_index);
20911   mp->ip6_table_index = ntohl (ip6_table_index);
20912   mp->is_add = is_add;
20913
20914   S (mp);
20915   W (ret);
20916   return ret;
20917 }
20918
20919 static int
20920 api_flow_classify_dump (vat_main_t * vam)
20921 {
20922   unformat_input_t *i = vam->input;
20923   vl_api_flow_classify_dump_t *mp;
20924   vl_api_control_ping_t *mp_ping;
20925   u8 type = FLOW_CLASSIFY_N_TABLES;
20926   int ret;
20927
20928   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20929     ;
20930   else
20931     {
20932       errmsg ("classify table type must be specified");
20933       return -99;
20934     }
20935
20936   if (!vam->json_output)
20937     {
20938       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20939     }
20940
20941   M (FLOW_CLASSIFY_DUMP, mp);
20942   mp->type = type;
20943   /* send it... */
20944   S (mp);
20945
20946   /* Use a control ping for synchronization */
20947   MPING (CONTROL_PING, mp_ping);
20948   S (mp_ping);
20949
20950   /* Wait for a reply... */
20951   W (ret);
20952   return ret;
20953 }
20954
20955 static int
20956 api_feature_enable_disable (vat_main_t * vam)
20957 {
20958   unformat_input_t *i = vam->input;
20959   vl_api_feature_enable_disable_t *mp;
20960   u8 *arc_name = 0;
20961   u8 *feature_name = 0;
20962   u32 sw_if_index = ~0;
20963   u8 enable = 1;
20964   int ret;
20965
20966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20967     {
20968       if (unformat (i, "arc_name %s", &arc_name))
20969         ;
20970       else if (unformat (i, "feature_name %s", &feature_name))
20971         ;
20972       else
20973         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20974         ;
20975       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20976         ;
20977       else if (unformat (i, "disable"))
20978         enable = 0;
20979       else
20980         break;
20981     }
20982
20983   if (arc_name == 0)
20984     {
20985       errmsg ("missing arc name");
20986       return -99;
20987     }
20988   if (vec_len (arc_name) > 63)
20989     {
20990       errmsg ("arc name too long");
20991     }
20992
20993   if (feature_name == 0)
20994     {
20995       errmsg ("missing feature name");
20996       return -99;
20997     }
20998   if (vec_len (feature_name) > 63)
20999     {
21000       errmsg ("feature name too long");
21001     }
21002
21003   if (sw_if_index == ~0)
21004     {
21005       errmsg ("missing interface name or sw_if_index");
21006       return -99;
21007     }
21008
21009   /* Construct the API message */
21010   M (FEATURE_ENABLE_DISABLE, mp);
21011   mp->sw_if_index = ntohl (sw_if_index);
21012   mp->enable = enable;
21013   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21014   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21015   vec_free (arc_name);
21016   vec_free (feature_name);
21017
21018   S (mp);
21019   W (ret);
21020   return ret;
21021 }
21022
21023 static int
21024 api_sw_interface_tag_add_del (vat_main_t * vam)
21025 {
21026   unformat_input_t *i = vam->input;
21027   vl_api_sw_interface_tag_add_del_t *mp;
21028   u32 sw_if_index = ~0;
21029   u8 *tag = 0;
21030   u8 enable = 1;
21031   int ret;
21032
21033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21034     {
21035       if (unformat (i, "tag %s", &tag))
21036         ;
21037       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21038         ;
21039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21040         ;
21041       else if (unformat (i, "del"))
21042         enable = 0;
21043       else
21044         break;
21045     }
21046
21047   if (sw_if_index == ~0)
21048     {
21049       errmsg ("missing interface name or sw_if_index");
21050       return -99;
21051     }
21052
21053   if (enable && (tag == 0))
21054     {
21055       errmsg ("no tag specified");
21056       return -99;
21057     }
21058
21059   /* Construct the API message */
21060   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21061   mp->sw_if_index = ntohl (sw_if_index);
21062   mp->is_add = enable;
21063   if (enable)
21064     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21065   vec_free (tag);
21066
21067   S (mp);
21068   W (ret);
21069   return ret;
21070 }
21071
21072 static void vl_api_l2_xconnect_details_t_handler
21073   (vl_api_l2_xconnect_details_t * mp)
21074 {
21075   vat_main_t *vam = &vat_main;
21076
21077   print (vam->ofp, "%15d%15d",
21078          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21079 }
21080
21081 static void vl_api_l2_xconnect_details_t_handler_json
21082   (vl_api_l2_xconnect_details_t * mp)
21083 {
21084   vat_main_t *vam = &vat_main;
21085   vat_json_node_t *node = NULL;
21086
21087   if (VAT_JSON_ARRAY != vam->json_tree.type)
21088     {
21089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21090       vat_json_init_array (&vam->json_tree);
21091     }
21092   node = vat_json_array_add (&vam->json_tree);
21093
21094   vat_json_init_object (node);
21095   vat_json_object_add_uint (node, "rx_sw_if_index",
21096                             ntohl (mp->rx_sw_if_index));
21097   vat_json_object_add_uint (node, "tx_sw_if_index",
21098                             ntohl (mp->tx_sw_if_index));
21099 }
21100
21101 static int
21102 api_l2_xconnect_dump (vat_main_t * vam)
21103 {
21104   vl_api_l2_xconnect_dump_t *mp;
21105   vl_api_control_ping_t *mp_ping;
21106   int ret;
21107
21108   if (!vam->json_output)
21109     {
21110       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21111     }
21112
21113   M (L2_XCONNECT_DUMP, mp);
21114
21115   S (mp);
21116
21117   /* Use a control ping for synchronization */
21118   MPING (CONTROL_PING, mp_ping);
21119   S (mp_ping);
21120
21121   W (ret);
21122   return ret;
21123 }
21124
21125 static int
21126 api_sw_interface_set_mtu (vat_main_t * vam)
21127 {
21128   unformat_input_t *i = vam->input;
21129   vl_api_sw_interface_set_mtu_t *mp;
21130   u32 sw_if_index = ~0;
21131   u32 mtu = 0;
21132   int ret;
21133
21134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21135     {
21136       if (unformat (i, "mtu %d", &mtu))
21137         ;
21138       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21139         ;
21140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21141         ;
21142       else
21143         break;
21144     }
21145
21146   if (sw_if_index == ~0)
21147     {
21148       errmsg ("missing interface name or sw_if_index");
21149       return -99;
21150     }
21151
21152   if (mtu == 0)
21153     {
21154       errmsg ("no mtu specified");
21155       return -99;
21156     }
21157
21158   /* Construct the API message */
21159   M (SW_INTERFACE_SET_MTU, mp);
21160   mp->sw_if_index = ntohl (sw_if_index);
21161   mp->mtu = ntohs ((u16) mtu);
21162
21163   S (mp);
21164   W (ret);
21165   return ret;
21166 }
21167
21168 static int
21169 api_p2p_ethernet_add (vat_main_t * vam)
21170 {
21171   unformat_input_t *i = vam->input;
21172   vl_api_p2p_ethernet_add_t *mp;
21173   u32 parent_if_index = ~0;
21174   u32 sub_id = ~0;
21175   u8 remote_mac[6];
21176   u8 mac_set = 0;
21177   int ret;
21178
21179   memset (remote_mac, 0, sizeof (remote_mac));
21180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21181     {
21182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21183         ;
21184       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21185         ;
21186       else
21187         if (unformat
21188             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21189         mac_set++;
21190       else if (unformat (i, "sub_id %d", &sub_id))
21191         ;
21192       else
21193         {
21194           clib_warning ("parse error '%U'", format_unformat_error, i);
21195           return -99;
21196         }
21197     }
21198
21199   if (parent_if_index == ~0)
21200     {
21201       errmsg ("missing interface name or sw_if_index");
21202       return -99;
21203     }
21204   if (mac_set == 0)
21205     {
21206       errmsg ("missing remote mac address");
21207       return -99;
21208     }
21209   if (sub_id == ~0)
21210     {
21211       errmsg ("missing sub-interface id");
21212       return -99;
21213     }
21214
21215   M (P2P_ETHERNET_ADD, mp);
21216   mp->parent_if_index = ntohl (parent_if_index);
21217   mp->subif_id = ntohl (sub_id);
21218   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21219
21220   S (mp);
21221   W (ret);
21222   return ret;
21223 }
21224
21225 static int
21226 api_p2p_ethernet_del (vat_main_t * vam)
21227 {
21228   unformat_input_t *i = vam->input;
21229   vl_api_p2p_ethernet_del_t *mp;
21230   u32 parent_if_index = ~0;
21231   u8 remote_mac[6];
21232   u8 mac_set = 0;
21233   int ret;
21234
21235   memset (remote_mac, 0, sizeof (remote_mac));
21236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21237     {
21238       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21239         ;
21240       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21241         ;
21242       else
21243         if (unformat
21244             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21245         mac_set++;
21246       else
21247         {
21248           clib_warning ("parse error '%U'", format_unformat_error, i);
21249           return -99;
21250         }
21251     }
21252
21253   if (parent_if_index == ~0)
21254     {
21255       errmsg ("missing interface name or sw_if_index");
21256       return -99;
21257     }
21258   if (mac_set == 0)
21259     {
21260       errmsg ("missing remote mac address");
21261       return -99;
21262     }
21263
21264   M (P2P_ETHERNET_DEL, mp);
21265   mp->parent_if_index = ntohl (parent_if_index);
21266   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21267
21268   S (mp);
21269   W (ret);
21270   return ret;
21271 }
21272
21273 static int
21274 api_lldp_config (vat_main_t * vam)
21275 {
21276   unformat_input_t *i = vam->input;
21277   vl_api_lldp_config_t *mp;
21278   int tx_hold = 0;
21279   int tx_interval = 0;
21280   u8 *sys_name = NULL;
21281   int ret;
21282
21283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21284     {
21285       if (unformat (i, "system-name %s", &sys_name))
21286         ;
21287       else if (unformat (i, "tx-hold %d", &tx_hold))
21288         ;
21289       else if (unformat (i, "tx-interval %d", &tx_interval))
21290         ;
21291       else
21292         {
21293           clib_warning ("parse error '%U'", format_unformat_error, i);
21294           return -99;
21295         }
21296     }
21297
21298   vec_add1 (sys_name, 0);
21299
21300   M (LLDP_CONFIG, mp);
21301   mp->tx_hold = htonl (tx_hold);
21302   mp->tx_interval = htonl (tx_interval);
21303   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21304   vec_free (sys_name);
21305
21306   S (mp);
21307   W (ret);
21308   return ret;
21309 }
21310
21311 static int
21312 api_sw_interface_set_lldp (vat_main_t * vam)
21313 {
21314   unformat_input_t *i = vam->input;
21315   vl_api_sw_interface_set_lldp_t *mp;
21316   u32 sw_if_index = ~0;
21317   u32 enable = 1;
21318   u8 *port_desc = NULL, *mgmt_oid = NULL;
21319   ip4_address_t ip4_addr;
21320   ip6_address_t ip6_addr;
21321   int ret;
21322
21323   memset (&ip4_addr, 0, sizeof (ip4_addr));
21324   memset (&ip6_addr, 0, sizeof (ip6_addr));
21325
21326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21327     {
21328       if (unformat (i, "disable"))
21329         enable = 0;
21330       else
21331         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21332         ;
21333       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21334         ;
21335       else if (unformat (i, "port-desc %s", &port_desc))
21336         ;
21337       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21338         ;
21339       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21340         ;
21341       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21342         ;
21343       else
21344         break;
21345     }
21346
21347   if (sw_if_index == ~0)
21348     {
21349       errmsg ("missing interface name or sw_if_index");
21350       return -99;
21351     }
21352
21353   /* Construct the API message */
21354   vec_add1 (port_desc, 0);
21355   vec_add1 (mgmt_oid, 0);
21356   M (SW_INTERFACE_SET_LLDP, mp);
21357   mp->sw_if_index = ntohl (sw_if_index);
21358   mp->enable = enable;
21359   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21360   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21361   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21362   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21363   vec_free (port_desc);
21364   vec_free (mgmt_oid);
21365
21366   S (mp);
21367   W (ret);
21368   return ret;
21369 }
21370
21371 static int
21372 api_tcp_configure_src_addresses (vat_main_t * vam)
21373 {
21374   vl_api_tcp_configure_src_addresses_t *mp;
21375   unformat_input_t *i = vam->input;
21376   ip4_address_t v4first, v4last;
21377   ip6_address_t v6first, v6last;
21378   u8 range_set = 0;
21379   u32 vrf_id = 0;
21380   int ret;
21381
21382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21383     {
21384       if (unformat (i, "%U - %U",
21385                     unformat_ip4_address, &v4first,
21386                     unformat_ip4_address, &v4last))
21387         {
21388           if (range_set)
21389             {
21390               errmsg ("one range per message (range already set)");
21391               return -99;
21392             }
21393           range_set = 1;
21394         }
21395       else if (unformat (i, "%U - %U",
21396                          unformat_ip6_address, &v6first,
21397                          unformat_ip6_address, &v6last))
21398         {
21399           if (range_set)
21400             {
21401               errmsg ("one range per message (range already set)");
21402               return -99;
21403             }
21404           range_set = 2;
21405         }
21406       else if (unformat (i, "vrf %d", &vrf_id))
21407         ;
21408       else
21409         break;
21410     }
21411
21412   if (range_set == 0)
21413     {
21414       errmsg ("address range not set");
21415       return -99;
21416     }
21417
21418   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21419   mp->vrf_id = ntohl (vrf_id);
21420   /* ipv6? */
21421   if (range_set == 2)
21422     {
21423       mp->is_ipv6 = 1;
21424       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21425       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21426     }
21427   else
21428     {
21429       mp->is_ipv6 = 0;
21430       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21431       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21432     }
21433   S (mp);
21434   W (ret);
21435   return ret;
21436 }
21437
21438 static void vl_api_app_namespace_add_del_reply_t_handler
21439   (vl_api_app_namespace_add_del_reply_t * mp)
21440 {
21441   vat_main_t *vam = &vat_main;
21442   i32 retval = ntohl (mp->retval);
21443   if (vam->async_mode)
21444     {
21445       vam->async_errors += (retval < 0);
21446     }
21447   else
21448     {
21449       vam->retval = retval;
21450       if (retval == 0)
21451         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21452       vam->result_ready = 1;
21453     }
21454 }
21455
21456 static void vl_api_app_namespace_add_del_reply_t_handler_json
21457   (vl_api_app_namespace_add_del_reply_t * mp)
21458 {
21459   vat_main_t *vam = &vat_main;
21460   vat_json_node_t node;
21461
21462   vat_json_init_object (&node);
21463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21464   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21465
21466   vat_json_print (vam->ofp, &node);
21467   vat_json_free (&node);
21468
21469   vam->retval = ntohl (mp->retval);
21470   vam->result_ready = 1;
21471 }
21472
21473 static int
21474 api_app_namespace_add_del (vat_main_t * vam)
21475 {
21476   vl_api_app_namespace_add_del_t *mp;
21477   unformat_input_t *i = vam->input;
21478   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21479   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21480   u64 secret;
21481   int ret;
21482
21483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21484     {
21485       if (unformat (i, "id %_%v%_", &ns_id))
21486         ;
21487       else if (unformat (i, "secret %lu", &secret))
21488         secret_set = 1;
21489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21490         sw_if_index_set = 1;
21491       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21492         ;
21493       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21494         ;
21495       else
21496         break;
21497     }
21498   if (!ns_id || !secret_set || !sw_if_index_set)
21499     {
21500       errmsg ("namespace id, secret and sw_if_index must be set");
21501       return -99;
21502     }
21503   if (vec_len (ns_id) > 64)
21504     {
21505       errmsg ("namespace id too long");
21506       return -99;
21507     }
21508   M (APP_NAMESPACE_ADD_DEL, mp);
21509
21510   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21511   mp->namespace_id_len = vec_len (ns_id);
21512   mp->secret = clib_host_to_net_u64 (secret);
21513   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21514   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21515   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21516   vec_free (ns_id);
21517   S (mp);
21518   W (ret);
21519   return ret;
21520 }
21521
21522 static int
21523 api_memfd_segment_create (vat_main_t * vam)
21524 {
21525 #if VPP_API_TEST_BUILTIN == 0
21526   unformat_input_t *i = vam->input;
21527   vl_api_memfd_segment_create_t *mp;
21528   u64 size = 64 << 20;
21529   int ret;
21530
21531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21532     {
21533       if (unformat (i, "size %U", unformat_memory_size, &size))
21534         ;
21535       else
21536         break;
21537     }
21538
21539   M (MEMFD_SEGMENT_CREATE, mp);
21540   mp->requested_size = size;
21541   S (mp);
21542   W (ret);
21543   return ret;
21544
21545 #else
21546   errmsg ("memfd_segment_create (builtin) not supported");
21547   return -99;
21548 #endif
21549 }
21550
21551 static int
21552 api_dns_enable_disable (vat_main_t * vam)
21553 {
21554   unformat_input_t *line_input = vam->input;
21555   vl_api_dns_enable_disable_t *mp;
21556   u8 enable_disable = 1;
21557   int ret;
21558
21559   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21560     {
21561       if (unformat (line_input, "disable"))
21562         enable_disable = 0;
21563       if (unformat (line_input, "enable"))
21564         enable_disable = 1;
21565       else
21566         break;
21567     }
21568
21569   /* Construct the API message */
21570   M (DNS_ENABLE_DISABLE, mp);
21571   mp->enable = enable_disable;
21572
21573   /* send it... */
21574   S (mp);
21575   /* Wait for the reply */
21576   W (ret);
21577   return ret;
21578 }
21579
21580 static int
21581 api_dns_resolve_name (vat_main_t * vam)
21582 {
21583   unformat_input_t *line_input = vam->input;
21584   vl_api_dns_resolve_name_t *mp;
21585   u8 *name = 0;
21586   int ret;
21587
21588   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21589     {
21590       if (unformat (line_input, "%s", &name))
21591         ;
21592       else
21593         break;
21594     }
21595
21596   if (vec_len (name) > 127)
21597     {
21598       errmsg ("name too long");
21599       return -99;
21600     }
21601
21602   /* Construct the API message */
21603   M (DNS_RESOLVE_NAME, mp);
21604   memcpy (mp->name, name, vec_len (name));
21605   vec_free (name);
21606
21607   /* send it... */
21608   S (mp);
21609   /* Wait for the reply */
21610   W (ret);
21611   return ret;
21612 }
21613
21614 static int
21615 api_dns_resolve_ip (vat_main_t * vam)
21616 {
21617   unformat_input_t *line_input = vam->input;
21618   vl_api_dns_resolve_ip_t *mp;
21619   int is_ip6 = -1;
21620   ip4_address_t addr4;
21621   ip6_address_t addr6;
21622   int ret;
21623
21624   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21625     {
21626       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21627         is_ip6 = 1;
21628       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21629         is_ip6 = 0;
21630       else
21631         break;
21632     }
21633
21634   if (is_ip6 == -1)
21635     {
21636       errmsg ("missing address");
21637       return -99;
21638     }
21639
21640   /* Construct the API message */
21641   M (DNS_RESOLVE_IP, mp);
21642   mp->is_ip6 = is_ip6;
21643   if (is_ip6)
21644     memcpy (mp->address, &addr6, sizeof (addr6));
21645   else
21646     memcpy (mp->address, &addr4, sizeof (addr4));
21647
21648   /* send it... */
21649   S (mp);
21650   /* Wait for the reply */
21651   W (ret);
21652   return ret;
21653 }
21654
21655 static int
21656 api_dns_name_server_add_del (vat_main_t * vam)
21657 {
21658   unformat_input_t *i = vam->input;
21659   vl_api_dns_name_server_add_del_t *mp;
21660   u8 is_add = 1;
21661   ip6_address_t ip6_server;
21662   ip4_address_t ip4_server;
21663   int ip6_set = 0;
21664   int ip4_set = 0;
21665   int ret = 0;
21666
21667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21668     {
21669       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21670         ip6_set = 1;
21671       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21672         ip4_set = 1;
21673       else if (unformat (i, "del"))
21674         is_add = 0;
21675       else
21676         {
21677           clib_warning ("parse error '%U'", format_unformat_error, i);
21678           return -99;
21679         }
21680     }
21681
21682   if (ip4_set && ip6_set)
21683     {
21684       errmsg ("Only one server address allowed per message");
21685       return -99;
21686     }
21687   if ((ip4_set + ip6_set) == 0)
21688     {
21689       errmsg ("Server address required");
21690       return -99;
21691     }
21692
21693   /* Construct the API message */
21694   M (DNS_NAME_SERVER_ADD_DEL, mp);
21695
21696   if (ip6_set)
21697     {
21698       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21699       mp->is_ip6 = 1;
21700     }
21701   else
21702     {
21703       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21704       mp->is_ip6 = 0;
21705     }
21706
21707   mp->is_add = is_add;
21708
21709   /* send it... */
21710   S (mp);
21711
21712   /* Wait for a reply, return good/bad news  */
21713   W (ret);
21714   return ret;
21715 }
21716
21717 static void
21718 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21719 {
21720   vat_main_t *vam = &vat_main;
21721
21722   if (mp->is_ip4)
21723     {
21724       print (vam->ofp,
21725              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21726              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21727              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21728              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21729              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21730              clib_net_to_host_u32 (mp->action_index), mp->tag);
21731     }
21732   else
21733     {
21734       print (vam->ofp,
21735              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21736              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21737              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21738              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21739              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21740              clib_net_to_host_u32 (mp->action_index), mp->tag);
21741     }
21742 }
21743
21744 static void
21745 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21746                                              mp)
21747 {
21748   vat_main_t *vam = &vat_main;
21749   vat_json_node_t *node = NULL;
21750   struct in6_addr ip6;
21751   struct in_addr ip4;
21752
21753   if (VAT_JSON_ARRAY != vam->json_tree.type)
21754     {
21755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21756       vat_json_init_array (&vam->json_tree);
21757     }
21758   node = vat_json_array_add (&vam->json_tree);
21759   vat_json_init_object (node);
21760
21761   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21762   vat_json_object_add_uint (node, "appns_index",
21763                             clib_net_to_host_u32 (mp->appns_index));
21764   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21765   vat_json_object_add_uint (node, "scope", mp->scope);
21766   vat_json_object_add_uint (node, "action_index",
21767                             clib_net_to_host_u32 (mp->action_index));
21768   vat_json_object_add_uint (node, "lcl_port",
21769                             clib_net_to_host_u16 (mp->lcl_port));
21770   vat_json_object_add_uint (node, "rmt_port",
21771                             clib_net_to_host_u16 (mp->rmt_port));
21772   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21773   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21774   vat_json_object_add_string_copy (node, "tag", mp->tag);
21775   if (mp->is_ip4)
21776     {
21777       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21778       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21779       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21780       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21781     }
21782   else
21783     {
21784       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21785       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21786       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21787       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21788     }
21789 }
21790
21791 static int
21792 api_session_rule_add_del (vat_main_t * vam)
21793 {
21794   vl_api_session_rule_add_del_t *mp;
21795   unformat_input_t *i = vam->input;
21796   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21797   u32 appns_index = 0, scope = 0;
21798   ip4_address_t lcl_ip4, rmt_ip4;
21799   ip6_address_t lcl_ip6, rmt_ip6;
21800   u8 is_ip4 = 1, conn_set = 0;
21801   u8 is_add = 1, *tag = 0;
21802   int ret;
21803
21804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21805     {
21806       if (unformat (i, "del"))
21807         is_add = 0;
21808       else if (unformat (i, "add"))
21809         ;
21810       else if (unformat (i, "proto tcp"))
21811         proto = 0;
21812       else if (unformat (i, "proto udp"))
21813         proto = 1;
21814       else if (unformat (i, "appns %d", &appns_index))
21815         ;
21816       else if (unformat (i, "scope %d", &scope))
21817         ;
21818       else if (unformat (i, "tag %_%v%_", &tag))
21819         ;
21820       else
21821         if (unformat
21822             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21823              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21824              &rmt_port))
21825         {
21826           is_ip4 = 1;
21827           conn_set = 1;
21828         }
21829       else
21830         if (unformat
21831             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21832              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21833              &rmt_port))
21834         {
21835           is_ip4 = 0;
21836           conn_set = 1;
21837         }
21838       else if (unformat (i, "action %d", &action))
21839         ;
21840       else
21841         break;
21842     }
21843   if (proto == ~0 || !conn_set || action == ~0)
21844     {
21845       errmsg ("transport proto, connection and action must be set");
21846       return -99;
21847     }
21848
21849   if (scope > 3)
21850     {
21851       errmsg ("scope should be 0-3");
21852       return -99;
21853     }
21854
21855   M (SESSION_RULE_ADD_DEL, mp);
21856
21857   mp->is_ip4 = is_ip4;
21858   mp->transport_proto = proto;
21859   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21860   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21861   mp->lcl_plen = lcl_plen;
21862   mp->rmt_plen = rmt_plen;
21863   mp->action_index = clib_host_to_net_u32 (action);
21864   mp->appns_index = clib_host_to_net_u32 (appns_index);
21865   mp->scope = scope;
21866   mp->is_add = is_add;
21867   if (is_ip4)
21868     {
21869       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21870       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21871     }
21872   else
21873     {
21874       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21875       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21876     }
21877   if (tag)
21878     {
21879       clib_memcpy (mp->tag, tag, vec_len (tag));
21880       vec_free (tag);
21881     }
21882
21883   S (mp);
21884   W (ret);
21885   return ret;
21886 }
21887
21888 static int
21889 api_session_rules_dump (vat_main_t * vam)
21890 {
21891   vl_api_session_rules_dump_t *mp;
21892   vl_api_control_ping_t *mp_ping;
21893   int ret;
21894
21895   if (!vam->json_output)
21896     {
21897       print (vam->ofp, "%=20s", "Session Rules");
21898     }
21899
21900   M (SESSION_RULES_DUMP, mp);
21901   /* send it... */
21902   S (mp);
21903
21904   /* Use a control ping for synchronization */
21905   MPING (CONTROL_PING, mp_ping);
21906   S (mp_ping);
21907
21908   /* Wait for a reply... */
21909   W (ret);
21910   return ret;
21911 }
21912
21913 static int
21914 api_ip_container_proxy_add_del (vat_main_t * vam)
21915 {
21916   vl_api_ip_container_proxy_add_del_t *mp;
21917   unformat_input_t *i = vam->input;
21918   u32 plen = ~0, sw_if_index = ~0;
21919   ip4_address_t ip4;
21920   ip6_address_t ip6;
21921   u8 is_ip4 = 1;
21922   u8 is_add = 1;
21923   int ret;
21924
21925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21926     {
21927       if (unformat (i, "del"))
21928         is_add = 0;
21929       else if (unformat (i, "add"))
21930         ;
21931       if (unformat (i, "%U", unformat_ip4_address, &ip4))
21932         {
21933           is_ip4 = 1;
21934           plen = 32;
21935         }
21936       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
21937         {
21938           is_ip4 = 0;
21939           plen = 128;
21940         }
21941       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21942         ;
21943       else
21944         break;
21945     }
21946   if (sw_if_index == ~0 || plen == ~0)
21947     {
21948       errmsg ("address and sw_if_index must be set");
21949       return -99;
21950     }
21951
21952   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21953
21954   mp->is_ip4 = is_ip4;
21955   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21956   mp->plen = plen;
21957   mp->is_add = is_add;
21958   if (is_ip4)
21959     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
21960   else
21961     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
21962
21963   S (mp);
21964   W (ret);
21965   return ret;
21966 }
21967
21968 static int
21969 q_or_quit (vat_main_t * vam)
21970 {
21971 #if VPP_API_TEST_BUILTIN == 0
21972   longjmp (vam->jump_buf, 1);
21973 #endif
21974   return 0;                     /* not so much */
21975 }
21976
21977 static int
21978 q (vat_main_t * vam)
21979 {
21980   return q_or_quit (vam);
21981 }
21982
21983 static int
21984 quit (vat_main_t * vam)
21985 {
21986   return q_or_quit (vam);
21987 }
21988
21989 static int
21990 comment (vat_main_t * vam)
21991 {
21992   return 0;
21993 }
21994
21995 static int
21996 cmd_cmp (void *a1, void *a2)
21997 {
21998   u8 **c1 = a1;
21999   u8 **c2 = a2;
22000
22001   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22002 }
22003
22004 static int
22005 help (vat_main_t * vam)
22006 {
22007   u8 **cmds = 0;
22008   u8 *name = 0;
22009   hash_pair_t *p;
22010   unformat_input_t *i = vam->input;
22011   int j;
22012
22013   if (unformat (i, "%s", &name))
22014     {
22015       uword *hs;
22016
22017       vec_add1 (name, 0);
22018
22019       hs = hash_get_mem (vam->help_by_name, name);
22020       if (hs)
22021         print (vam->ofp, "usage: %s %s", name, hs[0]);
22022       else
22023         print (vam->ofp, "No such msg / command '%s'", name);
22024       vec_free (name);
22025       return 0;
22026     }
22027
22028   print (vam->ofp, "Help is available for the following:");
22029
22030     /* *INDENT-OFF* */
22031     hash_foreach_pair (p, vam->function_by_name,
22032     ({
22033       vec_add1 (cmds, (u8 *)(p->key));
22034     }));
22035     /* *INDENT-ON* */
22036
22037   vec_sort_with_function (cmds, cmd_cmp);
22038
22039   for (j = 0; j < vec_len (cmds); j++)
22040     print (vam->ofp, "%s", cmds[j]);
22041
22042   vec_free (cmds);
22043   return 0;
22044 }
22045
22046 static int
22047 set (vat_main_t * vam)
22048 {
22049   u8 *name = 0, *value = 0;
22050   unformat_input_t *i = vam->input;
22051
22052   if (unformat (i, "%s", &name))
22053     {
22054       /* The input buffer is a vector, not a string. */
22055       value = vec_dup (i->buffer);
22056       vec_delete (value, i->index, 0);
22057       /* Almost certainly has a trailing newline */
22058       if (value[vec_len (value) - 1] == '\n')
22059         value[vec_len (value) - 1] = 0;
22060       /* Make sure it's a proper string, one way or the other */
22061       vec_add1 (value, 0);
22062       (void) clib_macro_set_value (&vam->macro_main,
22063                                    (char *) name, (char *) value);
22064     }
22065   else
22066     errmsg ("usage: set <name> <value>");
22067
22068   vec_free (name);
22069   vec_free (value);
22070   return 0;
22071 }
22072
22073 static int
22074 unset (vat_main_t * vam)
22075 {
22076   u8 *name = 0;
22077
22078   if (unformat (vam->input, "%s", &name))
22079     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22080       errmsg ("unset: %s wasn't set", name);
22081   vec_free (name);
22082   return 0;
22083 }
22084
22085 typedef struct
22086 {
22087   u8 *name;
22088   u8 *value;
22089 } macro_sort_t;
22090
22091
22092 static int
22093 macro_sort_cmp (void *a1, void *a2)
22094 {
22095   macro_sort_t *s1 = a1;
22096   macro_sort_t *s2 = a2;
22097
22098   return strcmp ((char *) (s1->name), (char *) (s2->name));
22099 }
22100
22101 static int
22102 dump_macro_table (vat_main_t * vam)
22103 {
22104   macro_sort_t *sort_me = 0, *sm;
22105   int i;
22106   hash_pair_t *p;
22107
22108     /* *INDENT-OFF* */
22109     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22110     ({
22111       vec_add2 (sort_me, sm, 1);
22112       sm->name = (u8 *)(p->key);
22113       sm->value = (u8 *) (p->value[0]);
22114     }));
22115     /* *INDENT-ON* */
22116
22117   vec_sort_with_function (sort_me, macro_sort_cmp);
22118
22119   if (vec_len (sort_me))
22120     print (vam->ofp, "%-15s%s", "Name", "Value");
22121   else
22122     print (vam->ofp, "The macro table is empty...");
22123
22124   for (i = 0; i < vec_len (sort_me); i++)
22125     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22126   return 0;
22127 }
22128
22129 static int
22130 dump_node_table (vat_main_t * vam)
22131 {
22132   int i, j;
22133   vlib_node_t *node, *next_node;
22134
22135   if (vec_len (vam->graph_nodes) == 0)
22136     {
22137       print (vam->ofp, "Node table empty, issue get_node_graph...");
22138       return 0;
22139     }
22140
22141   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22142     {
22143       node = vam->graph_nodes[i];
22144       print (vam->ofp, "[%d] %s", i, node->name);
22145       for (j = 0; j < vec_len (node->next_nodes); j++)
22146         {
22147           if (node->next_nodes[j] != ~0)
22148             {
22149               next_node = vam->graph_nodes[node->next_nodes[j]];
22150               print (vam->ofp, "  [%d] %s", j, next_node->name);
22151             }
22152         }
22153     }
22154   return 0;
22155 }
22156
22157 static int
22158 value_sort_cmp (void *a1, void *a2)
22159 {
22160   name_sort_t *n1 = a1;
22161   name_sort_t *n2 = a2;
22162
22163   if (n1->value < n2->value)
22164     return -1;
22165   if (n1->value > n2->value)
22166     return 1;
22167   return 0;
22168 }
22169
22170
22171 static int
22172 dump_msg_api_table (vat_main_t * vam)
22173 {
22174   api_main_t *am = &api_main;
22175   name_sort_t *nses = 0, *ns;
22176   hash_pair_t *hp;
22177   int i;
22178
22179   /* *INDENT-OFF* */
22180   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22181   ({
22182     vec_add2 (nses, ns, 1);
22183     ns->name = (u8 *)(hp->key);
22184     ns->value = (u32) hp->value[0];
22185   }));
22186   /* *INDENT-ON* */
22187
22188   vec_sort_with_function (nses, value_sort_cmp);
22189
22190   for (i = 0; i < vec_len (nses); i++)
22191     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22192   vec_free (nses);
22193   return 0;
22194 }
22195
22196 static int
22197 get_msg_id (vat_main_t * vam)
22198 {
22199   u8 *name_and_crc;
22200   u32 message_index;
22201
22202   if (unformat (vam->input, "%s", &name_and_crc))
22203     {
22204       message_index = vl_api_get_msg_index (name_and_crc);
22205       if (message_index == ~0)
22206         {
22207           print (vam->ofp, " '%s' not found", name_and_crc);
22208           return 0;
22209         }
22210       print (vam->ofp, " '%s' has message index %d",
22211              name_and_crc, message_index);
22212       return 0;
22213     }
22214   errmsg ("name_and_crc required...");
22215   return 0;
22216 }
22217
22218 static int
22219 search_node_table (vat_main_t * vam)
22220 {
22221   unformat_input_t *line_input = vam->input;
22222   u8 *node_to_find;
22223   int j;
22224   vlib_node_t *node, *next_node;
22225   uword *p;
22226
22227   if (vam->graph_node_index_by_name == 0)
22228     {
22229       print (vam->ofp, "Node table empty, issue get_node_graph...");
22230       return 0;
22231     }
22232
22233   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22234     {
22235       if (unformat (line_input, "%s", &node_to_find))
22236         {
22237           vec_add1 (node_to_find, 0);
22238           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22239           if (p == 0)
22240             {
22241               print (vam->ofp, "%s not found...", node_to_find);
22242               goto out;
22243             }
22244           node = vam->graph_nodes[p[0]];
22245           print (vam->ofp, "[%d] %s", p[0], node->name);
22246           for (j = 0; j < vec_len (node->next_nodes); j++)
22247             {
22248               if (node->next_nodes[j] != ~0)
22249                 {
22250                   next_node = vam->graph_nodes[node->next_nodes[j]];
22251                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22252                 }
22253             }
22254         }
22255
22256       else
22257         {
22258           clib_warning ("parse error '%U'", format_unformat_error,
22259                         line_input);
22260           return -99;
22261         }
22262
22263     out:
22264       vec_free (node_to_find);
22265
22266     }
22267
22268   return 0;
22269 }
22270
22271
22272 static int
22273 script (vat_main_t * vam)
22274 {
22275 #if (VPP_API_TEST_BUILTIN==0)
22276   u8 *s = 0;
22277   char *save_current_file;
22278   unformat_input_t save_input;
22279   jmp_buf save_jump_buf;
22280   u32 save_line_number;
22281
22282   FILE *new_fp, *save_ifp;
22283
22284   if (unformat (vam->input, "%s", &s))
22285     {
22286       new_fp = fopen ((char *) s, "r");
22287       if (new_fp == 0)
22288         {
22289           errmsg ("Couldn't open script file %s", s);
22290           vec_free (s);
22291           return -99;
22292         }
22293     }
22294   else
22295     {
22296       errmsg ("Missing script name");
22297       return -99;
22298     }
22299
22300   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22301   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22302   save_ifp = vam->ifp;
22303   save_line_number = vam->input_line_number;
22304   save_current_file = (char *) vam->current_file;
22305
22306   vam->input_line_number = 0;
22307   vam->ifp = new_fp;
22308   vam->current_file = s;
22309   do_one_file (vam);
22310
22311   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22312   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22313   vam->ifp = save_ifp;
22314   vam->input_line_number = save_line_number;
22315   vam->current_file = (u8 *) save_current_file;
22316   vec_free (s);
22317
22318   return 0;
22319 #else
22320   clib_warning ("use the exec command...");
22321   return -99;
22322 #endif
22323 }
22324
22325 static int
22326 echo (vat_main_t * vam)
22327 {
22328   print (vam->ofp, "%v", vam->input->buffer);
22329   return 0;
22330 }
22331
22332 /* List of API message constructors, CLI names map to api_xxx */
22333 #define foreach_vpe_api_msg                                             \
22334 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22335 _(sw_interface_dump,"")                                                 \
22336 _(sw_interface_set_flags,                                               \
22337   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22338 _(sw_interface_add_del_address,                                         \
22339   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22340 _(sw_interface_set_rx_mode,                                             \
22341   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22342 _(sw_interface_set_table,                                               \
22343   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22344 _(sw_interface_set_mpls_enable,                                         \
22345   "<intfc> | sw_if_index [disable | dis]")                              \
22346 _(sw_interface_set_vpath,                                               \
22347   "<intfc> | sw_if_index <id> enable | disable")                        \
22348 _(sw_interface_set_vxlan_bypass,                                        \
22349   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22350 _(sw_interface_set_geneve_bypass,                                       \
22351   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22352 _(sw_interface_set_l2_xconnect,                                         \
22353   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22354   "enable | disable")                                                   \
22355 _(sw_interface_set_l2_bridge,                                           \
22356   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22357   "[shg <split-horizon-group>] [bvi]\n"                                 \
22358   "enable | disable")                                                   \
22359 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22360 _(bridge_domain_add_del,                                                \
22361   "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") \
22362 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22363 _(l2fib_add_del,                                                        \
22364   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22365 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22366 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22367 _(l2_flags,                                                             \
22368   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22369 _(bridge_flags,                                                         \
22370   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22371 _(tap_connect,                                                          \
22372   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22373 _(tap_modify,                                                           \
22374   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22375 _(tap_delete,                                                           \
22376   "<vpp-if-name> | sw_if_index <id>")                                   \
22377 _(sw_interface_tap_dump, "")                                            \
22378 _(ip_table_add_del,                                                     \
22379   "table-id <n> [ipv6]\n")                                              \
22380 _(ip_add_del_route,                                                     \
22381   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22382   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22383   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22384   "[multipath] [count <n>]")                                            \
22385 _(ip_mroute_add_del,                                                    \
22386   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22387   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22388 _(mpls_table_add_del,                                                   \
22389   "table-id <n>\n")                                                     \
22390 _(mpls_route_add_del,                                                   \
22391   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22392   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22393   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22394   "[multipath] [count <n>]")                                            \
22395 _(mpls_ip_bind_unbind,                                                  \
22396   "<label> <addr/len>")                                                 \
22397 _(mpls_tunnel_add_del,                                                  \
22398   " via <addr> [table-id <n>]\n"                                        \
22399   "sw_if_index <id>] [l2]  [del]")                                      \
22400 _(bier_table_add_del,                                                   \
22401   "<label> <sub-domain> <set> <bsl> [del]")                             \
22402 _(bier_route_add_del,                                                   \
22403   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22404   "[<intfc> | sw_if_index <id>]"                                        \
22405   "[weight <n>] [del] [multipath]")                                     \
22406 _(proxy_arp_add_del,                                                    \
22407   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22408 _(proxy_arp_intfc_enable_disable,                                       \
22409   "<intfc> | sw_if_index <id> enable | disable")                        \
22410 _(sw_interface_set_unnumbered,                                          \
22411   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22412 _(ip_neighbor_add_del,                                                  \
22413   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22414   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22415 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22416 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22417   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22418   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22419   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22420 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22421 _(reset_fib, "vrf <n> [ipv6]")                                          \
22422 _(dhcp_proxy_config,                                                    \
22423   "svr <v46-address> src <v46-address>\n"                               \
22424    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22425 _(dhcp_proxy_set_vss,                                                   \
22426   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22427 _(dhcp_proxy_dump, "ip6")                                               \
22428 _(dhcp_client_config,                                                   \
22429   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22430 _(set_ip_flow_hash,                                                     \
22431   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22432 _(sw_interface_ip6_enable_disable,                                      \
22433   "<intfc> | sw_if_index <id> enable | disable")                        \
22434 _(sw_interface_ip6_set_link_local_address,                              \
22435   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22436 _(ip6nd_proxy_add_del,                                                  \
22437   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22438 _(ip6nd_proxy_dump, "")                                                 \
22439 _(sw_interface_ip6nd_ra_prefix,                                         \
22440   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22441   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22442   "[nolink] [isno]")                                                    \
22443 _(sw_interface_ip6nd_ra_config,                                         \
22444   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22445   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22446   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22447 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22448 _(l2_patch_add_del,                                                     \
22449   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22450   "enable | disable")                                                   \
22451 _(sr_localsid_add_del,                                                  \
22452   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22453   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22454 _(classify_add_del_table,                                               \
22455   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22456   " [del] [del-chain] mask <mask-value>\n"                              \
22457   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22458   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22459 _(classify_add_del_session,                                             \
22460   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22461   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22462   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22463   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22464 _(classify_set_interface_ip_table,                                      \
22465   "<intfc> | sw_if_index <nn> table <nn>")                              \
22466 _(classify_set_interface_l2_tables,                                     \
22467   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22468   "  [other-table <nn>]")                                               \
22469 _(get_node_index, "node <node-name")                                    \
22470 _(add_node_next, "node <node-name> next <next-node-name>")              \
22471 _(l2tpv3_create_tunnel,                                                 \
22472   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22473   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22474   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22475 _(l2tpv3_set_tunnel_cookies,                                            \
22476   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22477   "[new_remote_cookie <nn>]\n")                                         \
22478 _(l2tpv3_interface_enable_disable,                                      \
22479   "<intfc> | sw_if_index <nn> enable | disable")                        \
22480 _(l2tpv3_set_lookup_key,                                                \
22481   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22482 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22483 _(vxlan_add_del_tunnel,                                                 \
22484   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22485   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22486   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22487 _(geneve_add_del_tunnel,                                                \
22488   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22489   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22490   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22491 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22492 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22493 _(gre_add_del_tunnel,                                                   \
22494   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22495 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22496 _(l2_fib_clear_table, "")                                               \
22497 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22498 _(l2_interface_vlan_tag_rewrite,                                        \
22499   "<intfc> | sw_if_index <nn> \n"                                       \
22500   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22501   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22502 _(create_vhost_user_if,                                                 \
22503         "socket <filename> [server] [renumber <dev_instance>] "         \
22504         "[mac <mac_address>]")                                          \
22505 _(modify_vhost_user_if,                                                 \
22506         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22507         "[server] [renumber <dev_instance>]")                           \
22508 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22509 _(sw_interface_vhost_user_dump, "")                                     \
22510 _(show_version, "")                                                     \
22511 _(vxlan_gpe_add_del_tunnel,                                             \
22512   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22513   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22514   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22515   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22516 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22517 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22518 _(interface_name_renumber,                                              \
22519   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22520 _(input_acl_set_interface,                                              \
22521   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22522   "  [l2-table <nn>] [del]")                                            \
22523 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22524 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22525 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22526 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22527 _(ip_dump, "ipv4 | ipv6")                                               \
22528 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22529 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22530   "  spid_id <n> ")                                                     \
22531 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22532   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22533   "  integ_alg <alg> integ_key <hex>")                                  \
22534 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22535   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22536   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22537   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22538 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22539 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22540   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22541   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22542   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22543 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22544 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22545   "  <alg> <hex>\n")                                                    \
22546 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22547 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22548 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22549   "(auth_data 0x<data> | auth_data <data>)")                            \
22550 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22551   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22552 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22553   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22554   "(local|remote)")                                                     \
22555 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22556 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22557 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22558 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22559 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22560 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22561 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22562 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22563 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22564 _(delete_loopback,"sw_if_index <nn>")                                   \
22565 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22566 _(map_add_domain,                                                       \
22567   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22568   "ip6-src <ip6addr> "                                                  \
22569   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22570 _(map_del_domain, "index <n>")                                          \
22571 _(map_add_del_rule,                                                     \
22572   "index <n> psid <n> dst <ip6addr> [del]")                             \
22573 _(map_domain_dump, "")                                                  \
22574 _(map_rule_dump, "index <map-domain>")                                  \
22575 _(want_interface_events,  "enable|disable")                             \
22576 _(want_stats,"enable|disable")                                          \
22577 _(get_first_msg_id, "client <name>")                                    \
22578 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22579 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22580   "fib-id <nn> [ip4][ip6][default]")                                    \
22581 _(get_node_graph, " ")                                                  \
22582 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22583 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22584 _(ioam_disable, "")                                                     \
22585 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22586                             " sw_if_index <sw_if_index> p <priority> "  \
22587                             "w <weight>] [del]")                        \
22588 _(one_add_del_locator, "locator-set <locator_name> "                    \
22589                         "iface <intf> | sw_if_index <sw_if_index> "     \
22590                         "p <priority> w <weight> [del]")                \
22591 _(one_add_del_local_eid,"vni <vni> eid "                                \
22592                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22593                          "locator-set <locator_name> [del]"             \
22594                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22595 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22596 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22597 _(one_enable_disable, "enable|disable")                                 \
22598 _(one_map_register_enable_disable, "enable|disable")                    \
22599 _(one_map_register_fallback_threshold, "<value>")                       \
22600 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22601 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22602                                "[seid <seid>] "                         \
22603                                "rloc <locator> p <prio> "               \
22604                                "w <weight> [rloc <loc> ... ] "          \
22605                                "action <action> [del-all]")             \
22606 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22607                           "<local-eid>")                                \
22608 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22609 _(one_use_petr, "ip-address> | disable")                                \
22610 _(one_map_request_mode, "src-dst|dst-only")                             \
22611 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22612 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22613 _(one_locator_set_dump, "[local | remote]")                             \
22614 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22615 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22616                        "[local] | [remote]")                            \
22617 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22618 _(one_ndp_bd_get, "")                                                   \
22619 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22620 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22621 _(one_l2_arp_bd_get, "")                                                \
22622 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22623 _(one_stats_enable_disable, "enable|disalbe")                           \
22624 _(show_one_stats_enable_disable, "")                                    \
22625 _(one_eid_table_vni_dump, "")                                           \
22626 _(one_eid_table_map_dump, "l2|l3")                                      \
22627 _(one_map_resolver_dump, "")                                            \
22628 _(one_map_server_dump, "")                                              \
22629 _(one_adjacencies_get, "vni <vni>")                                     \
22630 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22631 _(show_one_rloc_probe_state, "")                                        \
22632 _(show_one_map_register_state, "")                                      \
22633 _(show_one_status, "")                                                  \
22634 _(one_stats_dump, "")                                                   \
22635 _(one_stats_flush, "")                                                  \
22636 _(one_get_map_request_itr_rlocs, "")                                    \
22637 _(one_map_register_set_ttl, "<ttl>")                                    \
22638 _(one_set_transport_protocol, "udp|api")                                \
22639 _(one_get_transport_protocol, "")                                       \
22640 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22641 _(one_show_xtr_mode, "")                                                \
22642 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22643 _(one_show_pitr_mode, "")                                               \
22644 _(one_enable_disable_petr_mode, "enable|disable")                       \
22645 _(one_show_petr_mode, "")                                               \
22646 _(show_one_nsh_mapping, "")                                             \
22647 _(show_one_pitr, "")                                                    \
22648 _(show_one_use_petr, "")                                                \
22649 _(show_one_map_request_mode, "")                                        \
22650 _(show_one_map_register_ttl, "")                                        \
22651 _(show_one_map_register_fallback_threshold, "")                         \
22652 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22653                             " sw_if_index <sw_if_index> p <priority> "  \
22654                             "w <weight>] [del]")                        \
22655 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22656                         "iface <intf> | sw_if_index <sw_if_index> "     \
22657                         "p <priority> w <weight> [del]")                \
22658 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22659                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22660                          "locator-set <locator_name> [del]"             \
22661                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22662 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22663 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22664 _(lisp_enable_disable, "enable|disable")                                \
22665 _(lisp_map_register_enable_disable, "enable|disable")                   \
22666 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22667 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22668                                "[seid <seid>] "                         \
22669                                "rloc <locator> p <prio> "               \
22670                                "w <weight> [rloc <loc> ... ] "          \
22671                                "action <action> [del-all]")             \
22672 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22673                           "<local-eid>")                                \
22674 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22675 _(lisp_use_petr, "<ip-address> | disable")                              \
22676 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22677 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22678 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22679 _(lisp_locator_set_dump, "[local | remote]")                            \
22680 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22681 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22682                        "[local] | [remote]")                            \
22683 _(lisp_eid_table_vni_dump, "")                                          \
22684 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22685 _(lisp_map_resolver_dump, "")                                           \
22686 _(lisp_map_server_dump, "")                                             \
22687 _(lisp_adjacencies_get, "vni <vni>")                                    \
22688 _(gpe_fwd_entry_vnis_get, "")                                           \
22689 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22690 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22691                                 "[table <table-id>]")                   \
22692 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22693 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22694 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22695 _(gpe_get_encap_mode, "")                                               \
22696 _(lisp_gpe_add_del_iface, "up|down")                                    \
22697 _(lisp_gpe_enable_disable, "enable|disable")                            \
22698 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22699   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22700 _(show_lisp_rloc_probe_state, "")                                       \
22701 _(show_lisp_map_register_state, "")                                     \
22702 _(show_lisp_status, "")                                                 \
22703 _(lisp_get_map_request_itr_rlocs, "")                                   \
22704 _(show_lisp_pitr, "")                                                   \
22705 _(show_lisp_use_petr, "")                                               \
22706 _(show_lisp_map_request_mode, "")                                       \
22707 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22708 _(af_packet_delete, "name <host interface name>")                       \
22709 _(policer_add_del, "name <policer name> <params> [del]")                \
22710 _(policer_dump, "[name <policer name>]")                                \
22711 _(policer_classify_set_interface,                                       \
22712   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22713   "  [l2-table <nn>] [del]")                                            \
22714 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22715 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22716     "[master|slave]")                                                   \
22717 _(netmap_delete, "name <interface name>")                               \
22718 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22719 _(mpls_fib_dump, "")                                                    \
22720 _(classify_table_ids, "")                                               \
22721 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22722 _(classify_table_info, "table_id <nn>")                                 \
22723 _(classify_session_dump, "table_id <nn>")                               \
22724 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22725     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22726     "[template_interval <nn>] [udp_checksum]")                          \
22727 _(ipfix_exporter_dump, "")                                              \
22728 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22729 _(ipfix_classify_stream_dump, "")                                       \
22730 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22731 _(ipfix_classify_table_dump, "")                                        \
22732 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22733 _(sw_interface_span_dump, "[l2]")                                           \
22734 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22735 _(pg_create_interface, "if_id <nn>")                                    \
22736 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22737 _(pg_enable_disable, "[stream <id>] disable")                           \
22738 _(ip_source_and_port_range_check_add_del,                               \
22739   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22740 _(ip_source_and_port_range_check_interface_add_del,                     \
22741   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22742   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22743 _(ipsec_gre_add_del_tunnel,                                             \
22744   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22745 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22746 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22747 _(l2_interface_pbb_tag_rewrite,                                         \
22748   "<intfc> | sw_if_index <nn> \n"                                       \
22749   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22750   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22751 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22752 _(flow_classify_set_interface,                                          \
22753   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22754 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22755 _(ip_fib_dump, "")                                                      \
22756 _(ip_mfib_dump, "")                                                     \
22757 _(ip6_fib_dump, "")                                                     \
22758 _(ip6_mfib_dump, "")                                                    \
22759 _(feature_enable_disable, "arc_name <arc_name> "                        \
22760   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22761 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22762 "[disable]")                                                            \
22763 _(l2_xconnect_dump, "")                                                 \
22764 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22765 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22766 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22767 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22768 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22769 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22770 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22771   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22772 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22773 _(memfd_segment_create,"size <nnn>")                                    \
22774 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22775 _(dns_enable_disable, "[enable][disable]")                              \
22776 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22777 _(dns_resolve_name, "<hostname>")                                       \
22778 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22779 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22780 _(dns_resolve_name, "<hostname>")                                       \
22781 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22782   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22783 _(session_rules_dump, "")                                               \
22784 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22785
22786 /* List of command functions, CLI names map directly to functions */
22787 #define foreach_cli_function                                    \
22788 _(comment, "usage: comment <ignore-rest-of-line>")              \
22789 _(dump_interface_table, "usage: dump_interface_table")          \
22790 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22791 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22792 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22793 _(dump_stats_table, "usage: dump_stats_table")                  \
22794 _(dump_macro_table, "usage: dump_macro_table ")                 \
22795 _(dump_node_table, "usage: dump_node_table")                    \
22796 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22797 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22798 _(echo, "usage: echo <message>")                                \
22799 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22800 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22801 _(help, "usage: help")                                          \
22802 _(q, "usage: quit")                                             \
22803 _(quit, "usage: quit")                                          \
22804 _(search_node_table, "usage: search_node_table <name>...")      \
22805 _(set, "usage: set <variable-name> <value>")                    \
22806 _(script, "usage: script <file-name>")                          \
22807 _(unset, "usage: unset <variable-name>")
22808 #define _(N,n)                                  \
22809     static void vl_api_##n##_t_handler_uni      \
22810     (vl_api_##n##_t * mp)                       \
22811     {                                           \
22812         vat_main_t * vam = &vat_main;           \
22813         if (vam->json_output) {                 \
22814             vl_api_##n##_t_handler_json(mp);    \
22815         } else {                                \
22816             vl_api_##n##_t_handler(mp);         \
22817         }                                       \
22818     }
22819 foreach_vpe_api_reply_msg;
22820 #if VPP_API_TEST_BUILTIN == 0
22821 foreach_standalone_reply_msg;
22822 #endif
22823 #undef _
22824
22825 void
22826 vat_api_hookup (vat_main_t * vam)
22827 {
22828 #define _(N,n)                                                  \
22829     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22830                            vl_api_##n##_t_handler_uni,          \
22831                            vl_noop_handler,                     \
22832                            vl_api_##n##_t_endian,               \
22833                            vl_api_##n##_t_print,                \
22834                            sizeof(vl_api_##n##_t), 1);
22835   foreach_vpe_api_reply_msg;
22836 #if VPP_API_TEST_BUILTIN == 0
22837   foreach_standalone_reply_msg;
22838 #endif
22839 #undef _
22840
22841 #if (VPP_API_TEST_BUILTIN==0)
22842   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22843
22844   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22845
22846   vam->function_by_name = hash_create_string (0, sizeof (uword));
22847
22848   vam->help_by_name = hash_create_string (0, sizeof (uword));
22849 #endif
22850
22851   /* API messages we can send */
22852 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22853   foreach_vpe_api_msg;
22854 #undef _
22855
22856   /* Help strings */
22857 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22858   foreach_vpe_api_msg;
22859 #undef _
22860
22861   /* CLI functions */
22862 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22863   foreach_cli_function;
22864 #undef _
22865
22866   /* Help strings */
22867 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22868   foreach_cli_function;
22869 #undef _
22870 }
22871
22872 #if VPP_API_TEST_BUILTIN
22873 static clib_error_t *
22874 vat_api_hookup_shim (vlib_main_t * vm)
22875 {
22876   vat_api_hookup (&vat_main);
22877   return 0;
22878 }
22879
22880 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22881 #endif
22882
22883 /*
22884  * fd.io coding-style-patch-verification: ON
22885  *
22886  * Local Variables:
22887  * eval: (c-set-style "gnu")
22888  * End:
22889  */