VPP-1338: fix ipsec api coverity warnings
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/ip/ip_neighbor.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/in_out_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/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
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   vam->socket_client_main = &socket_client_main;
92   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
93                                    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 int
103 vl_socket_client_read (int wait)
104 {
105   return -1;
106 };
107
108 int
109 vl_socket_client_write ()
110 {
111   return -1;
112 };
113
114 void *
115 vl_socket_client_msg_alloc (int nbytes)
116 {
117   return 0;
118 }
119 #endif
120
121
122 f64
123 vat_time_now (vat_main_t * vam)
124 {
125 #if VPP_API_TEST_BUILTIN
126   return vlib_time_now (vam->vlib_main);
127 #else
128   return clib_time_now (&vam->clib_time);
129 #endif
130 }
131
132 void
133 errmsg (char *fmt, ...)
134 {
135   vat_main_t *vam = &vat_main;
136   va_list va;
137   u8 *s;
138
139   va_start (va, fmt);
140   s = va_format (0, fmt, &va);
141   va_end (va);
142
143   vec_add1 (s, 0);
144
145 #if VPP_API_TEST_BUILTIN
146   vlib_cli_output (vam->vlib_main, (char *) s);
147 #else
148   {
149     if (vam->ifp != stdin)
150       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
151                vam->input_line_number);
152     fformat (vam->ofp, (char *) s);
153     fflush (vam->ofp);
154   }
155 #endif
156
157   vec_free (s);
158 }
159
160 #if VPP_API_TEST_BUILTIN == 0
161 static uword
162 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
163 {
164   vat_main_t *vam = va_arg (*args, vat_main_t *);
165   u32 *result = va_arg (*args, u32 *);
166   u8 *if_name;
167   uword *p;
168
169   if (!unformat (input, "%s", &if_name))
170     return 0;
171
172   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
173   if (p == 0)
174     return 0;
175   *result = p[0];
176   return 1;
177 }
178
179 static uword
180 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
181 {
182   return 0;
183 }
184
185 /* Parse an IP4 address %d.%d.%d.%d. */
186 uword
187 unformat_ip4_address (unformat_input_t * input, va_list * args)
188 {
189   u8 *result = va_arg (*args, u8 *);
190   unsigned a[4];
191
192   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
193     return 0;
194
195   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
196     return 0;
197
198   result[0] = a[0];
199   result[1] = a[1];
200   result[2] = a[2];
201   result[3] = a[3];
202
203   return 1;
204 }
205
206 uword
207 unformat_ethernet_address (unformat_input_t * input, va_list * args)
208 {
209   u8 *result = va_arg (*args, u8 *);
210   u32 i, a[6];
211
212   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
213                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
214     return 0;
215
216   /* Check range. */
217   for (i = 0; i < 6; i++)
218     if (a[i] >= (1 << 8))
219       return 0;
220
221   for (i = 0; i < 6; i++)
222     result[i] = a[i];
223
224   return 1;
225 }
226
227 /* Returns ethernet type as an int in host byte order. */
228 uword
229 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
230                                         va_list * args)
231 {
232   u16 *result = va_arg (*args, u16 *);
233   int type;
234
235   /* Numeric type. */
236   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
237     {
238       if (type >= (1 << 16))
239         return 0;
240       *result = type;
241       return 1;
242     }
243   return 0;
244 }
245
246 /* Parse an IP6 address. */
247 uword
248 unformat_ip6_address (unformat_input_t * input, va_list * args)
249 {
250   ip6_address_t *result = va_arg (*args, ip6_address_t *);
251   u16 hex_quads[8];
252   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
253   uword c, n_colon, double_colon_index;
254
255   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
256   double_colon_index = ARRAY_LEN (hex_quads);
257   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
258     {
259       hex_digit = 16;
260       if (c >= '0' && c <= '9')
261         hex_digit = c - '0';
262       else if (c >= 'a' && c <= 'f')
263         hex_digit = c + 10 - 'a';
264       else if (c >= 'A' && c <= 'F')
265         hex_digit = c + 10 - 'A';
266       else if (c == ':' && n_colon < 2)
267         n_colon++;
268       else
269         {
270           unformat_put_input (input);
271           break;
272         }
273
274       /* Too many hex quads. */
275       if (n_hex_quads >= ARRAY_LEN (hex_quads))
276         return 0;
277
278       if (hex_digit < 16)
279         {
280           hex_quad = (hex_quad << 4) | hex_digit;
281
282           /* Hex quad must fit in 16 bits. */
283           if (n_hex_digits >= 4)
284             return 0;
285
286           n_colon = 0;
287           n_hex_digits++;
288         }
289
290       /* Save position of :: */
291       if (n_colon == 2)
292         {
293           /* More than one :: ? */
294           if (double_colon_index < ARRAY_LEN (hex_quads))
295             return 0;
296           double_colon_index = n_hex_quads;
297         }
298
299       if (n_colon > 0 && n_hex_digits > 0)
300         {
301           hex_quads[n_hex_quads++] = hex_quad;
302           hex_quad = 0;
303           n_hex_digits = 0;
304         }
305     }
306
307   if (n_hex_digits > 0)
308     hex_quads[n_hex_quads++] = hex_quad;
309
310   {
311     word i;
312
313     /* Expand :: to appropriate number of zero hex quads. */
314     if (double_colon_index < ARRAY_LEN (hex_quads))
315       {
316         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
317
318         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
319           hex_quads[n_zero + i] = hex_quads[i];
320
321         for (i = 0; i < n_zero; i++)
322           hex_quads[double_colon_index + i] = 0;
323
324         n_hex_quads = ARRAY_LEN (hex_quads);
325       }
326
327     /* Too few hex quads given. */
328     if (n_hex_quads < ARRAY_LEN (hex_quads))
329       return 0;
330
331     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
332       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
333
334     return 1;
335   }
336 }
337
338 uword
339 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
340 {
341   u32 *r = va_arg (*args, u32 *);
342
343   if (0);
344 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
345   foreach_ipsec_policy_action
346 #undef _
347     else
348     return 0;
349   return 1;
350 }
351
352 uword
353 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
354 {
355   u32 *r = va_arg (*args, u32 *);
356
357   if (0);
358 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
359   foreach_ipsec_crypto_alg
360 #undef _
361     else
362     return 0;
363   return 1;
364 }
365
366 u8 *
367 format_ipsec_crypto_alg (u8 * s, va_list * args)
368 {
369   u32 i = va_arg (*args, u32);
370   u8 *t = 0;
371
372   switch (i)
373     {
374 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
375       foreach_ipsec_crypto_alg
376 #undef _
377     default:
378       return format (s, "unknown");
379     }
380   return format (s, "%s", t);
381 }
382
383 uword
384 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
385 {
386   u32 *r = va_arg (*args, u32 *);
387
388   if (0);
389 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
390   foreach_ipsec_integ_alg
391 #undef _
392     else
393     return 0;
394   return 1;
395 }
396
397 u8 *
398 format_ipsec_integ_alg (u8 * s, va_list * args)
399 {
400   u32 i = va_arg (*args, u32);
401   u8 *t = 0;
402
403   switch (i)
404     {
405 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
406       foreach_ipsec_integ_alg
407 #undef _
408     default:
409       return format (s, "unknown");
410     }
411   return format (s, "%s", t);
412 }
413
414 uword
415 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
416 {
417   u32 *r = va_arg (*args, u32 *);
418
419   if (0);
420 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
421   foreach_ikev2_auth_method
422 #undef _
423     else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
430 {
431   u32 *r = va_arg (*args, u32 *);
432
433   if (0);
434 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
435   foreach_ikev2_id_type
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441 #else /* VPP_API_TEST_BUILTIN == 1 */
442 static uword
443 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
444 {
445   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
446   vnet_main_t *vnm = vnet_get_main ();
447   u32 *result = va_arg (*args, u32 *);
448
449   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
450 }
451
452 static uword
453 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
454 {
455   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
456   vnet_main_t *vnm = vnet_get_main ();
457   u32 *result = va_arg (*args, u32 *);
458
459   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
460 }
461
462 #endif /* VPP_API_TEST_BUILTIN */
463
464 static uword
465 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
466 {
467   u8 *r = va_arg (*args, u8 *);
468
469   if (unformat (input, "kbps"))
470     *r = SSE2_QOS_RATE_KBPS;
471   else if (unformat (input, "pps"))
472     *r = SSE2_QOS_RATE_PPS;
473   else
474     return 0;
475   return 1;
476 }
477
478 static uword
479 unformat_policer_round_type (unformat_input_t * input, va_list * args)
480 {
481   u8 *r = va_arg (*args, u8 *);
482
483   if (unformat (input, "closest"))
484     *r = SSE2_QOS_ROUND_TO_CLOSEST;
485   else if (unformat (input, "up"))
486     *r = SSE2_QOS_ROUND_TO_UP;
487   else if (unformat (input, "down"))
488     *r = SSE2_QOS_ROUND_TO_DOWN;
489   else
490     return 0;
491   return 1;
492 }
493
494 static uword
495 unformat_policer_type (unformat_input_t * input, va_list * args)
496 {
497   u8 *r = va_arg (*args, u8 *);
498
499   if (unformat (input, "1r2c"))
500     *r = SSE2_QOS_POLICER_TYPE_1R2C;
501   else if (unformat (input, "1r3c"))
502     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
503   else if (unformat (input, "2r3c-2698"))
504     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
505   else if (unformat (input, "2r3c-4115"))
506     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
507   else if (unformat (input, "2r3c-mef5cf1"))
508     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
509   else
510     return 0;
511   return 1;
512 }
513
514 static uword
515 unformat_dscp (unformat_input_t * input, va_list * va)
516 {
517   u8 *r = va_arg (*va, u8 *);
518
519   if (0);
520 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
521   foreach_vnet_dscp
522 #undef _
523     else
524     return 0;
525   return 1;
526 }
527
528 static uword
529 unformat_policer_action_type (unformat_input_t * input, va_list * va)
530 {
531   sse2_qos_pol_action_params_st *a
532     = va_arg (*va, sse2_qos_pol_action_params_st *);
533
534   if (unformat (input, "drop"))
535     a->action_type = SSE2_QOS_ACTION_DROP;
536   else if (unformat (input, "transmit"))
537     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
538   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
539     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
540   else
541     return 0;
542   return 1;
543 }
544
545 static uword
546 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
547 {
548   u32 *r = va_arg (*va, u32 *);
549   u32 tid;
550
551   if (unformat (input, "ip4"))
552     tid = POLICER_CLASSIFY_TABLE_IP4;
553   else if (unformat (input, "ip6"))
554     tid = POLICER_CLASSIFY_TABLE_IP6;
555   else if (unformat (input, "l2"))
556     tid = POLICER_CLASSIFY_TABLE_L2;
557   else
558     return 0;
559
560   *r = tid;
561   return 1;
562 }
563
564 static uword
565 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
566 {
567   u32 *r = va_arg (*va, u32 *);
568   u32 tid;
569
570   if (unformat (input, "ip4"))
571     tid = FLOW_CLASSIFY_TABLE_IP4;
572   else if (unformat (input, "ip6"))
573     tid = FLOW_CLASSIFY_TABLE_IP6;
574   else
575     return 0;
576
577   *r = tid;
578   return 1;
579 }
580
581 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
582 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
583 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
584 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
585
586 #if (VPP_API_TEST_BUILTIN==0)
587 uword
588 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
589 {
590   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
591   mfib_itf_attribute_t attr;
592
593   old = *iflags;
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_long_names[attr]))
597       *iflags |= (1 << attr);
598   }
599   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
600   {
601     if (unformat (input, mfib_itf_flag_names[attr]))
602       *iflags |= (1 << attr);
603   }
604
605   return (old == *iflags ? 0 : 1);
606 }
607
608 uword
609 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
610 {
611   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
612   mfib_entry_attribute_t attr;
613
614   old = *eflags;
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_long_names[attr]))
618       *eflags |= (1 << attr);
619   }
620   FOR_EACH_MFIB_ATTRIBUTE (attr)
621   {
622     if (unformat (input, mfib_flag_names[attr]))
623       *eflags |= (1 << attr);
624   }
625
626   return (old == *eflags ? 0 : 1);
627 }
628
629 u8 *
630 format_ip4_address (u8 * s, va_list * args)
631 {
632   u8 *a = va_arg (*args, u8 *);
633   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
634 }
635
636 u8 *
637 format_ip6_address (u8 * s, va_list * args)
638 {
639   ip6_address_t *a = va_arg (*args, ip6_address_t *);
640   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
641
642   i_max_n_zero = ARRAY_LEN (a->as_u16);
643   max_n_zeros = 0;
644   i_first_zero = i_max_n_zero;
645   n_zeros = 0;
646   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
647     {
648       u32 is_zero = a->as_u16[i] == 0;
649       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
650         {
651           i_first_zero = i;
652           n_zeros = 0;
653         }
654       n_zeros += is_zero;
655       if ((!is_zero && n_zeros > max_n_zeros)
656           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
657         {
658           i_max_n_zero = i_first_zero;
659           max_n_zeros = n_zeros;
660           i_first_zero = ARRAY_LEN (a->as_u16);
661           n_zeros = 0;
662         }
663     }
664
665   last_double_colon = 0;
666   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
667     {
668       if (i == i_max_n_zero && max_n_zeros > 1)
669         {
670           s = format (s, "::");
671           i += max_n_zeros - 1;
672           last_double_colon = 1;
673         }
674       else
675         {
676           s = format (s, "%s%x",
677                       (last_double_colon || i == 0) ? "" : ":",
678                       clib_net_to_host_u16 (a->as_u16[i]));
679           last_double_colon = 0;
680         }
681     }
682
683   return s;
684 }
685
686 /* Format an IP46 address. */
687 u8 *
688 format_ip46_address (u8 * s, va_list * args)
689 {
690   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
691   ip46_type_t type = va_arg (*args, ip46_type_t);
692   int is_ip4 = 1;
693
694   switch (type)
695     {
696     case IP46_TYPE_ANY:
697       is_ip4 = ip46_address_is_ip4 (ip46);
698       break;
699     case IP46_TYPE_IP4:
700       is_ip4 = 1;
701       break;
702     case IP46_TYPE_IP6:
703       is_ip4 = 0;
704       break;
705     }
706
707   return is_ip4 ?
708     format (s, "%U", format_ip4_address, &ip46->ip4) :
709     format (s, "%U", format_ip6_address, &ip46->ip6);
710 }
711
712 u8 *
713 format_ethernet_address (u8 * s, va_list * args)
714 {
715   u8 *a = va_arg (*args, u8 *);
716
717   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
718                  a[0], a[1], a[2], a[3], a[4], a[5]);
719 }
720 #endif
721
722 static void
723 increment_v4_address (ip4_address_t * a)
724 {
725   u32 v;
726
727   v = ntohl (a->as_u32) + 1;
728   a->as_u32 = ntohl (v);
729 }
730
731 static void
732 increment_v6_address (ip6_address_t * a)
733 {
734   u64 v0, v1;
735
736   v0 = clib_net_to_host_u64 (a->as_u64[0]);
737   v1 = clib_net_to_host_u64 (a->as_u64[1]);
738
739   v1 += 1;
740   if (v1 == 0)
741     v0 += 1;
742   a->as_u64[0] = clib_net_to_host_u64 (v0);
743   a->as_u64[1] = clib_net_to_host_u64 (v1);
744 }
745
746 static void
747 increment_mac_address (u8 * mac)
748 {
749   u64 tmp = *((u64 *) mac);
750   tmp = clib_net_to_host_u64 (tmp);
751   tmp += 1 << 16;               /* skip unused (least significant) octets */
752   tmp = clib_host_to_net_u64 (tmp);
753
754   clib_memcpy (mac, &tmp, 6);
755 }
756
757 static void vl_api_create_loopback_reply_t_handler
758   (vl_api_create_loopback_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   i32 retval = ntohl (mp->retval);
762
763   vam->retval = retval;
764   vam->regenerate_interface_table = 1;
765   vam->sw_if_index = ntohl (mp->sw_if_index);
766   vam->result_ready = 1;
767 }
768
769 static void vl_api_create_loopback_reply_t_handler_json
770   (vl_api_create_loopback_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   vat_json_node_t node;
774
775   vat_json_init_object (&node);
776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
777   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
778
779   vat_json_print (vam->ofp, &node);
780   vat_json_free (&node);
781   vam->retval = ntohl (mp->retval);
782   vam->result_ready = 1;
783 }
784
785 static void vl_api_create_loopback_instance_reply_t_handler
786   (vl_api_create_loopback_instance_reply_t * mp)
787 {
788   vat_main_t *vam = &vat_main;
789   i32 retval = ntohl (mp->retval);
790
791   vam->retval = retval;
792   vam->regenerate_interface_table = 1;
793   vam->sw_if_index = ntohl (mp->sw_if_index);
794   vam->result_ready = 1;
795 }
796
797 static void vl_api_create_loopback_instance_reply_t_handler_json
798   (vl_api_create_loopback_instance_reply_t * mp)
799 {
800   vat_main_t *vam = &vat_main;
801   vat_json_node_t node;
802
803   vat_json_init_object (&node);
804   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
805   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
806
807   vat_json_print (vam->ofp, &node);
808   vat_json_free (&node);
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_af_packet_create_reply_t_handler
814   (vl_api_af_packet_create_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_af_packet_create_reply_t_handler_json
826   (vl_api_af_packet_create_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_vlan_subif_reply_t_handler
843   (vl_api_create_vlan_subif_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->sw_if_index = ntohl (mp->sw_if_index);
851   vam->result_ready = 1;
852 }
853
854 static void vl_api_create_vlan_subif_reply_t_handler_json
855   (vl_api_create_vlan_subif_reply_t * mp)
856 {
857   vat_main_t *vam = &vat_main;
858   vat_json_node_t node;
859
860   vat_json_init_object (&node);
861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
863
864   vat_json_print (vam->ofp, &node);
865   vat_json_free (&node);
866
867   vam->retval = ntohl (mp->retval);
868   vam->result_ready = 1;
869 }
870
871 static void vl_api_create_subif_reply_t_handler
872   (vl_api_create_subif_reply_t * mp)
873 {
874   vat_main_t *vam = &vat_main;
875   i32 retval = ntohl (mp->retval);
876
877   vam->retval = retval;
878   vam->regenerate_interface_table = 1;
879   vam->sw_if_index = ntohl (mp->sw_if_index);
880   vam->result_ready = 1;
881 }
882
883 static void vl_api_create_subif_reply_t_handler_json
884   (vl_api_create_subif_reply_t * mp)
885 {
886   vat_main_t *vam = &vat_main;
887   vat_json_node_t node;
888
889   vat_json_init_object (&node);
890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
892
893   vat_json_print (vam->ofp, &node);
894   vat_json_free (&node);
895
896   vam->retval = ntohl (mp->retval);
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_interface_name_renumber_reply_t_handler
901   (vl_api_interface_name_renumber_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   i32 retval = ntohl (mp->retval);
905
906   vam->retval = retval;
907   vam->regenerate_interface_table = 1;
908   vam->result_ready = 1;
909 }
910
911 static void vl_api_interface_name_renumber_reply_t_handler_json
912   (vl_api_interface_name_renumber_reply_t * mp)
913 {
914   vat_main_t *vam = &vat_main;
915   vat_json_node_t node;
916
917   vat_json_init_object (&node);
918   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
919
920   vat_json_print (vam->ofp, &node);
921   vat_json_free (&node);
922
923   vam->retval = ntohl (mp->retval);
924   vam->result_ready = 1;
925 }
926
927 /*
928  * Special-case: build the interface table, maintain
929  * the next loopback sw_if_index vbl.
930  */
931 static void vl_api_sw_interface_details_t_handler
932   (vl_api_sw_interface_details_t * mp)
933 {
934   vat_main_t *vam = &vat_main;
935   u8 *s = format (0, "%s%c", mp->interface_name, 0);
936
937   hash_set_mem (vam->sw_if_index_by_interface_name, s,
938                 ntohl (mp->sw_if_index));
939
940   /* In sub interface case, fill the sub interface table entry */
941   if (mp->sw_if_index != mp->sup_sw_if_index)
942     {
943       sw_interface_subif_t *sub = NULL;
944
945       vec_add2 (vam->sw_if_subif_table, sub, 1);
946
947       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
948       strncpy ((char *) sub->interface_name, (char *) s,
949                vec_len (sub->interface_name));
950       sub->sw_if_index = ntohl (mp->sw_if_index);
951       sub->sub_id = ntohl (mp->sub_id);
952
953       sub->sub_dot1ad = mp->sub_dot1ad;
954       sub->sub_number_of_tags = mp->sub_number_of_tags;
955       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
956       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
957       sub->sub_exact_match = mp->sub_exact_match;
958       sub->sub_default = mp->sub_default;
959       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
960       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
961
962       /* vlan tag rewrite */
963       sub->vtr_op = ntohl (mp->vtr_op);
964       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
965       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
966       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
967     }
968 }
969
970 static void vl_api_sw_interface_details_t_handler_json
971   (vl_api_sw_interface_details_t * mp)
972 {
973   vat_main_t *vam = &vat_main;
974   vat_json_node_t *node = NULL;
975
976   if (VAT_JSON_ARRAY != vam->json_tree.type)
977     {
978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
979       vat_json_init_array (&vam->json_tree);
980     }
981   node = vat_json_array_add (&vam->json_tree);
982
983   vat_json_init_object (node);
984   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
985   vat_json_object_add_uint (node, "sup_sw_if_index",
986                             ntohl (mp->sup_sw_if_index));
987   vat_json_object_add_uint (node, "l2_address_length",
988                             ntohl (mp->l2_address_length));
989   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
990                              sizeof (mp->l2_address));
991   vat_json_object_add_string_copy (node, "interface_name",
992                                    mp->interface_name);
993   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
994   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
995   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
996   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
997   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
998   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
999   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1000   vat_json_object_add_uint (node, "sub_number_of_tags",
1001                             mp->sub_number_of_tags);
1002   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1003                             ntohs (mp->sub_outer_vlan_id));
1004   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1005                             ntohs (mp->sub_inner_vlan_id));
1006   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1007   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1008   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1009                             mp->sub_outer_vlan_id_any);
1010   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1011                             mp->sub_inner_vlan_id_any);
1012   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1013   vat_json_object_add_uint (node, "vtr_push_dot1q",
1014                             ntohl (mp->vtr_push_dot1q));
1015   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1016   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1017   if (mp->sub_dot1ah)
1018     {
1019       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1020                                        format (0, "%U",
1021                                                format_ethernet_address,
1022                                                &mp->b_dmac));
1023       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1024                                        format (0, "%U",
1025                                                format_ethernet_address,
1026                                                &mp->b_smac));
1027       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1028       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1029     }
1030 }
1031
1032 #if VPP_API_TEST_BUILTIN == 0
1033 static void vl_api_sw_interface_event_t_handler
1034   (vl_api_sw_interface_event_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   if (vam->interface_event_display)
1038     errmsg ("interface flags: sw_if_index %d %s %s",
1039             ntohl (mp->sw_if_index),
1040             mp->admin_up_down ? "admin-up" : "admin-down",
1041             mp->link_up_down ? "link-up" : "link-down");
1042 }
1043 #endif
1044
1045 static void vl_api_sw_interface_event_t_handler_json
1046   (vl_api_sw_interface_event_t * mp)
1047 {
1048   /* JSON output not supported */
1049 }
1050
1051 static void
1052 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1053 {
1054   vat_main_t *vam = &vat_main;
1055   i32 retval = ntohl (mp->retval);
1056
1057   vam->retval = retval;
1058   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void
1063 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   vat_json_node_t node;
1067   api_main_t *am = &api_main;
1068   void *oldheap;
1069   u8 *reply;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "reply_in_shmem",
1074                             ntohl (mp->reply_in_shmem));
1075   /* Toss the shared-memory original... */
1076   pthread_mutex_lock (&am->vlib_rp->mutex);
1077   oldheap = svm_push_data_heap (am->vlib_rp);
1078
1079   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1080   vec_free (reply);
1081
1082   svm_pop_heap (oldheap);
1083   pthread_mutex_unlock (&am->vlib_rp->mutex);
1084
1085   vat_json_print (vam->ofp, &node);
1086   vat_json_free (&node);
1087
1088   vam->retval = ntohl (mp->retval);
1089   vam->result_ready = 1;
1090 }
1091
1092 static void
1093 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1094 {
1095   vat_main_t *vam = &vat_main;
1096   i32 retval = ntohl (mp->retval);
1097   u32 length = ntohl (mp->length);
1098
1099   vec_reset_length (vam->cmd_reply);
1100
1101   vam->retval = retval;
1102   if (retval == 0)
1103     {
1104       vec_validate (vam->cmd_reply, length);
1105       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1106       vam->cmd_reply[length] = 0;
1107     }
1108   vam->result_ready = 1;
1109 }
1110
1111 static void
1112 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   vat_json_node_t node;
1116
1117   vec_reset_length (vam->cmd_reply);
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1122
1123   vat_json_print (vam->ofp, &node);
1124   vat_json_free (&node);
1125
1126   vam->retval = ntohl (mp->retval);
1127   vam->result_ready = 1;
1128 }
1129
1130 static void vl_api_classify_add_del_table_reply_t_handler
1131   (vl_api_classify_add_del_table_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   i32 retval = ntohl (mp->retval);
1135   if (vam->async_mode)
1136     {
1137       vam->async_errors += (retval < 0);
1138     }
1139   else
1140     {
1141       vam->retval = retval;
1142       if (retval == 0 &&
1143           ((mp->new_table_index != 0xFFFFFFFF) ||
1144            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1145            (mp->match_n_vectors != 0xFFFFFFFF)))
1146         /*
1147          * Note: this is just barely thread-safe, depends on
1148          * the main thread spinning waiting for an answer...
1149          */
1150         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1151                 ntohl (mp->new_table_index),
1152                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1153       vam->result_ready = 1;
1154     }
1155 }
1156
1157 static void vl_api_classify_add_del_table_reply_t_handler_json
1158   (vl_api_classify_add_del_table_reply_t * mp)
1159 {
1160   vat_main_t *vam = &vat_main;
1161   vat_json_node_t node;
1162
1163   vat_json_init_object (&node);
1164   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1165   vat_json_object_add_uint (&node, "new_table_index",
1166                             ntohl (mp->new_table_index));
1167   vat_json_object_add_uint (&node, "skip_n_vectors",
1168                             ntohl (mp->skip_n_vectors));
1169   vat_json_object_add_uint (&node, "match_n_vectors",
1170                             ntohl (mp->match_n_vectors));
1171
1172   vat_json_print (vam->ofp, &node);
1173   vat_json_free (&node);
1174
1175   vam->retval = ntohl (mp->retval);
1176   vam->result_ready = 1;
1177 }
1178
1179 static void vl_api_get_node_index_reply_t_handler
1180   (vl_api_get_node_index_reply_t * mp)
1181 {
1182   vat_main_t *vam = &vat_main;
1183   i32 retval = ntohl (mp->retval);
1184   if (vam->async_mode)
1185     {
1186       vam->async_errors += (retval < 0);
1187     }
1188   else
1189     {
1190       vam->retval = retval;
1191       if (retval == 0)
1192         errmsg ("node index %d", ntohl (mp->node_index));
1193       vam->result_ready = 1;
1194     }
1195 }
1196
1197 static void vl_api_get_node_index_reply_t_handler_json
1198   (vl_api_get_node_index_reply_t * mp)
1199 {
1200   vat_main_t *vam = &vat_main;
1201   vat_json_node_t node;
1202
1203   vat_json_init_object (&node);
1204   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1205   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_next_index_reply_t_handler
1215   (vl_api_get_next_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("next node index %d", ntohl (mp->next_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_next_index_reply_t_handler_json
1233   (vl_api_get_next_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_add_node_next_reply_t_handler
1250   (vl_api_add_node_next_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_add_node_next_reply_t_handler_json
1268   (vl_api_add_node_next_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_show_version_reply_t_handler
1285   (vl_api_show_version_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289
1290   if (retval >= 0)
1291     {
1292       errmsg ("        program: %s", mp->program);
1293       errmsg ("        version: %s", mp->version);
1294       errmsg ("     build date: %s", mp->build_date);
1295       errmsg ("build directory: %s", mp->build_directory);
1296     }
1297   vam->retval = retval;
1298   vam->result_ready = 1;
1299 }
1300
1301 static void vl_api_show_version_reply_t_handler_json
1302   (vl_api_show_version_reply_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t node;
1306
1307   vat_json_init_object (&node);
1308   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1309   vat_json_object_add_string_copy (&node, "program", mp->program);
1310   vat_json_object_add_string_copy (&node, "version", mp->version);
1311   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1312   vat_json_object_add_string_copy (&node, "build_directory",
1313                                    mp->build_directory);
1314
1315   vat_json_print (vam->ofp, &node);
1316   vat_json_free (&node);
1317
1318   vam->retval = ntohl (mp->retval);
1319   vam->result_ready = 1;
1320 }
1321
1322 static void
1323 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1324 {
1325   u32 sw_if_index = ntohl (mp->sw_if_index);
1326   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1327           mp->mac_ip ? "mac/ip binding" : "address resolution",
1328           ntohl (mp->pid), format_ip4_address, &mp->address,
1329           format_ethernet_address, mp->new_mac, sw_if_index);
1330 }
1331
1332 static void
1333 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1334 {
1335   /* JSON output not supported */
1336 }
1337
1338 static void
1339 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1340 {
1341   u32 sw_if_index = ntohl (mp->sw_if_index);
1342   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1343           mp->mac_ip ? "mac/ip binding" : "address resolution",
1344           ntohl (mp->pid), format_ip6_address, mp->address,
1345           format_ethernet_address, mp->new_mac, sw_if_index);
1346 }
1347
1348 static void
1349 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1350 {
1351   /* JSON output not supported */
1352 }
1353
1354 static void
1355 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1356 {
1357   u32 n_macs = ntohl (mp->n_macs);
1358   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1359           ntohl (mp->pid), mp->client_index, n_macs);
1360   int i;
1361   for (i = 0; i < n_macs; i++)
1362     {
1363       vl_api_mac_entry_t *mac = &mp->mac[i];
1364       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1365               i + 1, ntohl (mac->sw_if_index),
1366               format_ethernet_address, mac->mac_addr, mac->action);
1367       if (i == 1000)
1368         break;
1369     }
1370 }
1371
1372 static void
1373 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1374 {
1375   /* JSON output not supported */
1376 }
1377
1378 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1379 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1380
1381 /*
1382  * Special-case: build the bridge domain table, maintain
1383  * the next bd id vbl.
1384  */
1385 static void vl_api_bridge_domain_details_t_handler
1386   (vl_api_bridge_domain_details_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1390   int i;
1391
1392   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1393          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1394
1395   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1396          ntohl (mp->bd_id), mp->learn, mp->forward,
1397          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1398
1399   if (n_sw_ifs)
1400     {
1401       vl_api_bridge_domain_sw_if_t *sw_ifs;
1402       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1403              "Interface Name");
1404
1405       sw_ifs = mp->sw_if_details;
1406       for (i = 0; i < n_sw_ifs; i++)
1407         {
1408           u8 *sw_if_name = 0;
1409           u32 sw_if_index;
1410           hash_pair_t *p;
1411
1412           sw_if_index = ntohl (sw_ifs->sw_if_index);
1413
1414           /* *INDENT-OFF* */
1415           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1416                              ({
1417                                if ((u32) p->value[0] == sw_if_index)
1418                                  {
1419                                    sw_if_name = (u8 *)(p->key);
1420                                    break;
1421                                  }
1422                              }));
1423           /* *INDENT-ON* */
1424           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1425                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1426                  "sw_if_index not found!");
1427
1428           sw_ifs++;
1429         }
1430     }
1431 }
1432
1433 static void vl_api_bridge_domain_details_t_handler_json
1434   (vl_api_bridge_domain_details_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   vat_json_node_t *node, *array = NULL;
1438   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1439
1440   if (VAT_JSON_ARRAY != vam->json_tree.type)
1441     {
1442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1443       vat_json_init_array (&vam->json_tree);
1444     }
1445   node = vat_json_array_add (&vam->json_tree);
1446
1447   vat_json_init_object (node);
1448   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1449   vat_json_object_add_uint (node, "flood", mp->flood);
1450   vat_json_object_add_uint (node, "forward", mp->forward);
1451   vat_json_object_add_uint (node, "learn", mp->learn);
1452   vat_json_object_add_uint (node, "bvi_sw_if_index",
1453                             ntohl (mp->bvi_sw_if_index));
1454   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1455   array = vat_json_object_add (node, "sw_if");
1456   vat_json_init_array (array);
1457
1458
1459
1460   if (n_sw_ifs)
1461     {
1462       vl_api_bridge_domain_sw_if_t *sw_ifs;
1463       int i;
1464
1465       sw_ifs = mp->sw_if_details;
1466       for (i = 0; i < n_sw_ifs; i++)
1467         {
1468           node = vat_json_array_add (array);
1469           vat_json_init_object (node);
1470           vat_json_object_add_uint (node, "sw_if_index",
1471                                     ntohl (sw_ifs->sw_if_index));
1472           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1473           sw_ifs++;
1474         }
1475     }
1476 }
1477
1478 static void vl_api_control_ping_reply_t_handler
1479   (vl_api_control_ping_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   i32 retval = ntohl (mp->retval);
1483   if (vam->async_mode)
1484     {
1485       vam->async_errors += (retval < 0);
1486     }
1487   else
1488     {
1489       vam->retval = retval;
1490       vam->result_ready = 1;
1491     }
1492   if (vam->socket_client_main)
1493     vam->socket_client_main->control_pings_outstanding--;
1494 }
1495
1496 static void vl_api_control_ping_reply_t_handler_json
1497   (vl_api_control_ping_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   i32 retval = ntohl (mp->retval);
1501
1502   if (VAT_JSON_NONE != vam->json_tree.type)
1503     {
1504       vat_json_print (vam->ofp, &vam->json_tree);
1505       vat_json_free (&vam->json_tree);
1506       vam->json_tree.type = VAT_JSON_NONE;
1507     }
1508   else
1509     {
1510       /* just print [] */
1511       vat_json_init_array (&vam->json_tree);
1512       vat_json_print (vam->ofp, &vam->json_tree);
1513       vam->json_tree.type = VAT_JSON_NONE;
1514     }
1515
1516   vam->retval = retval;
1517   vam->result_ready = 1;
1518 }
1519
1520 static void
1521   vl_api_bridge_domain_set_mac_age_reply_t_handler
1522   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1523 {
1524   vat_main_t *vam = &vat_main;
1525   i32 retval = ntohl (mp->retval);
1526   if (vam->async_mode)
1527     {
1528       vam->async_errors += (retval < 0);
1529     }
1530   else
1531     {
1532       vam->retval = retval;
1533       vam->result_ready = 1;
1534     }
1535 }
1536
1537 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1538   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1539 {
1540   vat_main_t *vam = &vat_main;
1541   vat_json_node_t node;
1542
1543   vat_json_init_object (&node);
1544   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1545
1546   vat_json_print (vam->ofp, &node);
1547   vat_json_free (&node);
1548
1549   vam->retval = ntohl (mp->retval);
1550   vam->result_ready = 1;
1551 }
1552
1553 static void
1554 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1555 {
1556   vat_main_t *vam = &vat_main;
1557   i32 retval = ntohl (mp->retval);
1558   if (vam->async_mode)
1559     {
1560       vam->async_errors += (retval < 0);
1561     }
1562   else
1563     {
1564       vam->retval = retval;
1565       vam->result_ready = 1;
1566     }
1567 }
1568
1569 static void vl_api_l2_flags_reply_t_handler_json
1570   (vl_api_l2_flags_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1578                             ntohl (mp->resulting_feature_bitmap));
1579
1580   vat_json_print (vam->ofp, &node);
1581   vat_json_free (&node);
1582
1583   vam->retval = ntohl (mp->retval);
1584   vam->result_ready = 1;
1585 }
1586
1587 static void vl_api_bridge_flags_reply_t_handler
1588   (vl_api_bridge_flags_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->result_ready = 1;
1600     }
1601 }
1602
1603 static void vl_api_bridge_flags_reply_t_handler_json
1604   (vl_api_bridge_flags_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   vat_json_node_t node;
1608
1609   vat_json_init_object (&node);
1610   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1611   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1612                             ntohl (mp->resulting_feature_bitmap));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void vl_api_tap_connect_reply_t_handler
1622   (vl_api_tap_connect_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->sw_if_index = ntohl (mp->sw_if_index);
1634       vam->result_ready = 1;
1635     }
1636
1637 }
1638
1639 static void vl_api_tap_connect_reply_t_handler_json
1640   (vl_api_tap_connect_reply_t * mp)
1641 {
1642   vat_main_t *vam = &vat_main;
1643   vat_json_node_t node;
1644
1645   vat_json_init_object (&node);
1646   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1647   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1648
1649   vat_json_print (vam->ofp, &node);
1650   vat_json_free (&node);
1651
1652   vam->retval = ntohl (mp->retval);
1653   vam->result_ready = 1;
1654
1655 }
1656
1657 static void
1658 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1659 {
1660   vat_main_t *vam = &vat_main;
1661   i32 retval = ntohl (mp->retval);
1662   if (vam->async_mode)
1663     {
1664       vam->async_errors += (retval < 0);
1665     }
1666   else
1667     {
1668       vam->retval = retval;
1669       vam->sw_if_index = ntohl (mp->sw_if_index);
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_tap_modify_reply_t_handler_json
1675   (vl_api_tap_modify_reply_t * mp)
1676 {
1677   vat_main_t *vam = &vat_main;
1678   vat_json_node_t node;
1679
1680   vat_json_init_object (&node);
1681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1682   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1683
1684   vat_json_print (vam->ofp, &node);
1685   vat_json_free (&node);
1686
1687   vam->retval = ntohl (mp->retval);
1688   vam->result_ready = 1;
1689 }
1690
1691 static void
1692 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1693 {
1694   vat_main_t *vam = &vat_main;
1695   i32 retval = ntohl (mp->retval);
1696   if (vam->async_mode)
1697     {
1698       vam->async_errors += (retval < 0);
1699     }
1700   else
1701     {
1702       vam->retval = retval;
1703       vam->result_ready = 1;
1704     }
1705 }
1706
1707 static void vl_api_tap_delete_reply_t_handler_json
1708   (vl_api_tap_delete_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   vat_json_node_t node;
1712
1713   vat_json_init_object (&node);
1714   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1715
1716   vat_json_print (vam->ofp, &node);
1717   vat_json_free (&node);
1718
1719   vam->retval = ntohl (mp->retval);
1720   vam->result_ready = 1;
1721 }
1722
1723 static void
1724 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1725 {
1726   vat_main_t *vam = &vat_main;
1727   i32 retval = ntohl (mp->retval);
1728   if (vam->async_mode)
1729     {
1730       vam->async_errors += (retval < 0);
1731     }
1732   else
1733     {
1734       vam->retval = retval;
1735       vam->sw_if_index = ntohl (mp->sw_if_index);
1736       vam->result_ready = 1;
1737     }
1738
1739 }
1740
1741 static void vl_api_tap_create_v2_reply_t_handler_json
1742   (vl_api_tap_create_v2_reply_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745   vat_json_node_t node;
1746
1747   vat_json_init_object (&node);
1748   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1749   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1750
1751   vat_json_print (vam->ofp, &node);
1752   vat_json_free (&node);
1753
1754   vam->retval = ntohl (mp->retval);
1755   vam->result_ready = 1;
1756
1757 }
1758
1759 static void
1760 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763   i32 retval = ntohl (mp->retval);
1764   if (vam->async_mode)
1765     {
1766       vam->async_errors += (retval < 0);
1767     }
1768   else
1769     {
1770       vam->retval = retval;
1771       vam->result_ready = 1;
1772     }
1773 }
1774
1775 static void vl_api_tap_delete_v2_reply_t_handler_json
1776   (vl_api_tap_delete_v2_reply_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779   vat_json_node_t node;
1780
1781   vat_json_init_object (&node);
1782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1783
1784   vat_json_print (vam->ofp, &node);
1785   vat_json_free (&node);
1786
1787   vam->retval = ntohl (mp->retval);
1788   vam->result_ready = 1;
1789 }
1790
1791 static void
1792 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   i32 retval = ntohl (mp->retval);
1796
1797   if (vam->async_mode)
1798     {
1799       vam->async_errors += (retval < 0);
1800     }
1801   else
1802     {
1803       vam->retval = retval;
1804       vam->sw_if_index = ntohl (mp->sw_if_index);
1805       vam->result_ready = 1;
1806     }
1807 }
1808
1809 static void vl_api_bond_create_reply_t_handler_json
1810   (vl_api_bond_create_reply_t * mp)
1811 {
1812   vat_main_t *vam = &vat_main;
1813   vat_json_node_t node;
1814
1815   vat_json_init_object (&node);
1816   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1817   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1818
1819   vat_json_print (vam->ofp, &node);
1820   vat_json_free (&node);
1821
1822   vam->retval = ntohl (mp->retval);
1823   vam->result_ready = 1;
1824 }
1825
1826 static void
1827 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   i32 retval = ntohl (mp->retval);
1831
1832   if (vam->async_mode)
1833     {
1834       vam->async_errors += (retval < 0);
1835     }
1836   else
1837     {
1838       vam->retval = retval;
1839       vam->result_ready = 1;
1840     }
1841 }
1842
1843 static void vl_api_bond_delete_reply_t_handler_json
1844   (vl_api_bond_delete_reply_t * mp)
1845 {
1846   vat_main_t *vam = &vat_main;
1847   vat_json_node_t node;
1848
1849   vat_json_init_object (&node);
1850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1851
1852   vat_json_print (vam->ofp, &node);
1853   vat_json_free (&node);
1854
1855   vam->retval = ntohl (mp->retval);
1856   vam->result_ready = 1;
1857 }
1858
1859 static void
1860 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1861 {
1862   vat_main_t *vam = &vat_main;
1863   i32 retval = ntohl (mp->retval);
1864
1865   if (vam->async_mode)
1866     {
1867       vam->async_errors += (retval < 0);
1868     }
1869   else
1870     {
1871       vam->retval = retval;
1872       vam->result_ready = 1;
1873     }
1874 }
1875
1876 static void vl_api_bond_enslave_reply_t_handler_json
1877   (vl_api_bond_enslave_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   vat_json_node_t node;
1881
1882   vat_json_init_object (&node);
1883   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1884
1885   vat_json_print (vam->ofp, &node);
1886   vat_json_free (&node);
1887
1888   vam->retval = ntohl (mp->retval);
1889   vam->result_ready = 1;
1890 }
1891
1892 static void
1893 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1894                                           mp)
1895 {
1896   vat_main_t *vam = &vat_main;
1897   i32 retval = ntohl (mp->retval);
1898
1899   if (vam->async_mode)
1900     {
1901       vam->async_errors += (retval < 0);
1902     }
1903   else
1904     {
1905       vam->retval = retval;
1906       vam->result_ready = 1;
1907     }
1908 }
1909
1910 static void vl_api_bond_detach_slave_reply_t_handler_json
1911   (vl_api_bond_detach_slave_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   vat_json_node_t node;
1915
1916   vat_json_init_object (&node);
1917   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1918
1919   vat_json_print (vam->ofp, &node);
1920   vat_json_free (&node);
1921
1922   vam->retval = ntohl (mp->retval);
1923   vam->result_ready = 1;
1924 }
1925
1926 static void vl_api_sw_interface_bond_details_t_handler
1927   (vl_api_sw_interface_bond_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   print (vam->ofp,
1932          "%-16s %-12d %-12U %-13U %-14u %-14u",
1933          mp->interface_name, ntohl (mp->sw_if_index),
1934          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1935          ntohl (mp->active_slaves), ntohl (mp->slaves));
1936 }
1937
1938 static void vl_api_sw_interface_bond_details_t_handler_json
1939   (vl_api_sw_interface_bond_details_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   vat_json_node_t *node = NULL;
1943
1944   if (VAT_JSON_ARRAY != vam->json_tree.type)
1945     {
1946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1947       vat_json_init_array (&vam->json_tree);
1948     }
1949   node = vat_json_array_add (&vam->json_tree);
1950
1951   vat_json_init_object (node);
1952   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1953   vat_json_object_add_string_copy (node, "interface_name",
1954                                    mp->interface_name);
1955   vat_json_object_add_uint (node, "mode", mp->mode);
1956   vat_json_object_add_uint (node, "load_balance", mp->lb);
1957   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1958   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1959 }
1960
1961 static int
1962 api_sw_interface_bond_dump (vat_main_t * vam)
1963 {
1964   vl_api_sw_interface_bond_dump_t *mp;
1965   vl_api_control_ping_t *mp_ping;
1966   int ret;
1967
1968   print (vam->ofp,
1969          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1970          "interface name", "sw_if_index", "mode", "load balance",
1971          "active slaves", "slaves");
1972
1973   /* Get list of bond interfaces */
1974   M (SW_INTERFACE_BOND_DUMP, mp);
1975   S (mp);
1976
1977   /* Use a control ping for synchronization */
1978   MPING (CONTROL_PING, mp_ping);
1979   S (mp_ping);
1980
1981   W (ret);
1982   return ret;
1983 }
1984
1985 static void vl_api_sw_interface_slave_details_t_handler
1986   (vl_api_sw_interface_slave_details_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989
1990   print (vam->ofp,
1991          "%-25s %-12d %-12d %d", mp->interface_name,
1992          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1993 }
1994
1995 static void vl_api_sw_interface_slave_details_t_handler_json
1996   (vl_api_sw_interface_slave_details_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t *node = NULL;
2000
2001   if (VAT_JSON_ARRAY != vam->json_tree.type)
2002     {
2003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2004       vat_json_init_array (&vam->json_tree);
2005     }
2006   node = vat_json_array_add (&vam->json_tree);
2007
2008   vat_json_init_object (node);
2009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2010   vat_json_object_add_string_copy (node, "interface_name",
2011                                    mp->interface_name);
2012   vat_json_object_add_uint (node, "passive", mp->is_passive);
2013   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2014 }
2015
2016 static int
2017 api_sw_interface_slave_dump (vat_main_t * vam)
2018 {
2019   unformat_input_t *i = vam->input;
2020   vl_api_sw_interface_slave_dump_t *mp;
2021   vl_api_control_ping_t *mp_ping;
2022   u32 sw_if_index = ~0;
2023   u8 sw_if_index_set = 0;
2024   int ret;
2025
2026   /* Parse args required to build the message */
2027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2028     {
2029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2030         sw_if_index_set = 1;
2031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2032         sw_if_index_set = 1;
2033       else
2034         break;
2035     }
2036
2037   if (sw_if_index_set == 0)
2038     {
2039       errmsg ("missing vpp interface name. ");
2040       return -99;
2041     }
2042
2043   print (vam->ofp,
2044          "\n%-25s %-12s %-12s %s",
2045          "slave interface name", "sw_if_index", "passive", "long_timeout");
2046
2047   /* Get list of bond interfaces */
2048   M (SW_INTERFACE_SLAVE_DUMP, mp);
2049   mp->sw_if_index = ntohl (sw_if_index);
2050   S (mp);
2051
2052   /* Use a control ping for synchronization */
2053   MPING (CONTROL_PING, mp_ping);
2054   S (mp_ping);
2055
2056   W (ret);
2057   return ret;
2058 }
2059
2060 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2061   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->result_ready = 1;
2073     }
2074 }
2075
2076 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2077   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   vat_json_node_t node;
2081
2082   vat_json_init_object (&node);
2083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2084   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2085                             ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2095   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2112   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2129   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   i32 retval = ntohl (mp->retval);
2133   if (vam->async_mode)
2134     {
2135       vam->async_errors += (retval < 0);
2136     }
2137   else
2138     {
2139       vam->retval = retval;
2140       vam->result_ready = 1;
2141     }
2142 }
2143
2144 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2145   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   vat_json_node_t node;
2149
2150   vat_json_init_object (&node);
2151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2152   vat_json_object_add_uint (&node, "fwd_entry_index",
2153                             clib_net_to_host_u32 (mp->fwd_entry_index));
2154
2155   vat_json_print (vam->ofp, &node);
2156   vat_json_free (&node);
2157
2158   vam->retval = ntohl (mp->retval);
2159   vam->result_ready = 1;
2160 }
2161
2162 u8 *
2163 format_lisp_transport_protocol (u8 * s, va_list * args)
2164 {
2165   u32 proto = va_arg (*args, u32);
2166
2167   switch (proto)
2168     {
2169     case 1:
2170       return format (s, "udp");
2171     case 2:
2172       return format (s, "api");
2173     default:
2174       return 0;
2175     }
2176   return 0;
2177 }
2178
2179 static void vl_api_one_get_transport_protocol_reply_t_handler
2180   (vl_api_one_get_transport_protocol_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       u32 proto = mp->protocol;
2191       print (vam->ofp, "Transport protocol: %U",
2192              format_lisp_transport_protocol, proto);
2193       vam->retval = retval;
2194       vam->result_ready = 1;
2195     }
2196 }
2197
2198 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2199   (vl_api_one_get_transport_protocol_reply_t * mp)
2200 {
2201   vat_main_t *vam = &vat_main;
2202   vat_json_node_t node;
2203   u8 *s;
2204
2205   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2206   vec_add1 (s, 0);
2207
2208   vat_json_init_object (&node);
2209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2210   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2211
2212   vec_free (s);
2213   vat_json_print (vam->ofp, &node);
2214   vat_json_free (&node);
2215
2216   vam->retval = ntohl (mp->retval);
2217   vam->result_ready = 1;
2218 }
2219
2220 static void vl_api_one_add_del_locator_set_reply_t_handler
2221   (vl_api_one_add_del_locator_set_reply_t * mp)
2222 {
2223   vat_main_t *vam = &vat_main;
2224   i32 retval = ntohl (mp->retval);
2225   if (vam->async_mode)
2226     {
2227       vam->async_errors += (retval < 0);
2228     }
2229   else
2230     {
2231       vam->retval = retval;
2232       vam->result_ready = 1;
2233     }
2234 }
2235
2236 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2237   (vl_api_one_add_del_locator_set_reply_t * mp)
2238 {
2239   vat_main_t *vam = &vat_main;
2240   vat_json_node_t node;
2241
2242   vat_json_init_object (&node);
2243   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2244   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2245
2246   vat_json_print (vam->ofp, &node);
2247   vat_json_free (&node);
2248
2249   vam->retval = ntohl (mp->retval);
2250   vam->result_ready = 1;
2251 }
2252
2253 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2254   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   i32 retval = ntohl (mp->retval);
2258   if (vam->async_mode)
2259     {
2260       vam->async_errors += (retval < 0);
2261     }
2262   else
2263     {
2264       vam->retval = retval;
2265       vam->sw_if_index = ntohl (mp->sw_if_index);
2266       vam->result_ready = 1;
2267     }
2268   vam->regenerate_interface_table = 1;
2269 }
2270
2271 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2272   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t node;
2276
2277   vat_json_init_object (&node);
2278   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2279   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2280
2281   vat_json_print (vam->ofp, &node);
2282   vat_json_free (&node);
2283
2284   vam->retval = ntohl (mp->retval);
2285   vam->result_ready = 1;
2286 }
2287
2288 static void vl_api_vxlan_offload_rx_reply_t_handler
2289   (vl_api_vxlan_offload_rx_reply_t * mp)
2290 {
2291   vat_main_t *vam = &vat_main;
2292   i32 retval = ntohl (mp->retval);
2293   if (vam->async_mode)
2294     {
2295       vam->async_errors += (retval < 0);
2296     }
2297   else
2298     {
2299       vam->retval = retval;
2300       vam->result_ready = 1;
2301     }
2302 }
2303
2304 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2305   (vl_api_vxlan_offload_rx_reply_t * mp)
2306 {
2307   vat_main_t *vam = &vat_main;
2308   vat_json_node_t node;
2309
2310   vat_json_init_object (&node);
2311   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2312
2313   vat_json_print (vam->ofp, &node);
2314   vat_json_free (&node);
2315
2316   vam->retval = ntohl (mp->retval);
2317   vam->result_ready = 1;
2318 }
2319
2320 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2321   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   i32 retval = ntohl (mp->retval);
2325   if (vam->async_mode)
2326     {
2327       vam->async_errors += (retval < 0);
2328     }
2329   else
2330     {
2331       vam->retval = retval;
2332       vam->sw_if_index = ntohl (mp->sw_if_index);
2333       vam->result_ready = 1;
2334     }
2335 }
2336
2337 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2338   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2339 {
2340   vat_main_t *vam = &vat_main;
2341   vat_json_node_t node;
2342
2343   vat_json_init_object (&node);
2344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2345   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2346
2347   vat_json_print (vam->ofp, &node);
2348   vat_json_free (&node);
2349
2350   vam->retval = ntohl (mp->retval);
2351   vam->result_ready = 1;
2352 }
2353
2354 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2355   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2356 {
2357   vat_main_t *vam = &vat_main;
2358   i32 retval = ntohl (mp->retval);
2359   if (vam->async_mode)
2360     {
2361       vam->async_errors += (retval < 0);
2362     }
2363   else
2364     {
2365       vam->retval = retval;
2366       vam->sw_if_index = ntohl (mp->sw_if_index);
2367       vam->result_ready = 1;
2368     }
2369   vam->regenerate_interface_table = 1;
2370 }
2371
2372 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2373   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   vat_json_node_t node;
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2381
2382   vat_json_print (vam->ofp, &node);
2383   vat_json_free (&node);
2384
2385   vam->retval = ntohl (mp->retval);
2386   vam->result_ready = 1;
2387 }
2388
2389 static void vl_api_gre_add_del_tunnel_reply_t_handler
2390   (vl_api_gre_add_del_tunnel_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   i32 retval = ntohl (mp->retval);
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->sw_if_index = ntohl (mp->sw_if_index);
2402       vam->result_ready = 1;
2403     }
2404 }
2405
2406 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2407   (vl_api_gre_add_del_tunnel_reply_t * mp)
2408 {
2409   vat_main_t *vam = &vat_main;
2410   vat_json_node_t node;
2411
2412   vat_json_init_object (&node);
2413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2415
2416   vat_json_print (vam->ofp, &node);
2417   vat_json_free (&node);
2418
2419   vam->retval = ntohl (mp->retval);
2420   vam->result_ready = 1;
2421 }
2422
2423 static void vl_api_create_vhost_user_if_reply_t_handler
2424   (vl_api_create_vhost_user_if_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   i32 retval = ntohl (mp->retval);
2428   if (vam->async_mode)
2429     {
2430       vam->async_errors += (retval < 0);
2431     }
2432   else
2433     {
2434       vam->retval = retval;
2435       vam->sw_if_index = ntohl (mp->sw_if_index);
2436       vam->result_ready = 1;
2437     }
2438   vam->regenerate_interface_table = 1;
2439 }
2440
2441 static void vl_api_create_vhost_user_if_reply_t_handler_json
2442   (vl_api_create_vhost_user_if_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t node;
2446
2447   vat_json_init_object (&node);
2448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2450
2451   vat_json_print (vam->ofp, &node);
2452   vat_json_free (&node);
2453
2454   vam->retval = ntohl (mp->retval);
2455   vam->result_ready = 1;
2456 }
2457
2458 static void vl_api_dns_resolve_name_reply_t_handler
2459   (vl_api_dns_resolve_name_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   i32 retval = ntohl (mp->retval);
2463   if (vam->async_mode)
2464     {
2465       vam->async_errors += (retval < 0);
2466     }
2467   else
2468     {
2469       vam->retval = retval;
2470       vam->result_ready = 1;
2471
2472       if (retval == 0)
2473         {
2474           if (mp->ip4_set)
2475             clib_warning ("ip4 address %U", format_ip4_address,
2476                           (ip4_address_t *) mp->ip4_address);
2477           if (mp->ip6_set)
2478             clib_warning ("ip6 address %U", format_ip6_address,
2479                           (ip6_address_t *) mp->ip6_address);
2480         }
2481       else
2482         clib_warning ("retval %d", retval);
2483     }
2484 }
2485
2486 static void vl_api_dns_resolve_name_reply_t_handler_json
2487   (vl_api_dns_resolve_name_reply_t * mp)
2488 {
2489   clib_warning ("not implemented");
2490 }
2491
2492 static void vl_api_dns_resolve_ip_reply_t_handler
2493   (vl_api_dns_resolve_ip_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   i32 retval = ntohl (mp->retval);
2497   if (vam->async_mode)
2498     {
2499       vam->async_errors += (retval < 0);
2500     }
2501   else
2502     {
2503       vam->retval = retval;
2504       vam->result_ready = 1;
2505
2506       if (retval == 0)
2507         {
2508           clib_warning ("canonical name %s", mp->name);
2509         }
2510       else
2511         clib_warning ("retval %d", retval);
2512     }
2513 }
2514
2515 static void vl_api_dns_resolve_ip_reply_t_handler_json
2516   (vl_api_dns_resolve_ip_reply_t * mp)
2517 {
2518   clib_warning ("not implemented");
2519 }
2520
2521
2522 static void vl_api_ip_address_details_t_handler
2523   (vl_api_ip_address_details_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   static ip_address_details_t empty_ip_address_details = { {0} };
2527   ip_address_details_t *address = NULL;
2528   ip_details_t *current_ip_details = NULL;
2529   ip_details_t *details = NULL;
2530
2531   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2532
2533   if (!details || vam->current_sw_if_index >= vec_len (details)
2534       || !details[vam->current_sw_if_index].present)
2535     {
2536       errmsg ("ip address details arrived but not stored");
2537       errmsg ("ip_dump should be called first");
2538       return;
2539     }
2540
2541   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2542
2543 #define addresses (current_ip_details->addr)
2544
2545   vec_validate_init_empty (addresses, vec_len (addresses),
2546                            empty_ip_address_details);
2547
2548   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2549
2550   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2551   address->prefix_length = mp->prefix_length;
2552 #undef addresses
2553 }
2554
2555 static void vl_api_ip_address_details_t_handler_json
2556   (vl_api_ip_address_details_t * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   vat_json_node_t *node = NULL;
2560   struct in6_addr ip6;
2561   struct in_addr ip4;
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   if (vam->is_ipv6)
2572     {
2573       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2574       vat_json_object_add_ip6 (node, "ip", ip6);
2575     }
2576   else
2577     {
2578       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2579       vat_json_object_add_ip4 (node, "ip", ip4);
2580     }
2581   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2582 }
2583
2584 static void
2585 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   static ip_details_t empty_ip_details = { 0 };
2589   ip_details_t *ip = NULL;
2590   u32 sw_if_index = ~0;
2591
2592   sw_if_index = ntohl (mp->sw_if_index);
2593
2594   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2595                            sw_if_index, empty_ip_details);
2596
2597   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2598                          sw_if_index);
2599
2600   ip->present = 1;
2601 }
2602
2603 static void
2604 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2605 {
2606   vat_main_t *vam = &vat_main;
2607
2608   if (VAT_JSON_ARRAY != vam->json_tree.type)
2609     {
2610       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2611       vat_json_init_array (&vam->json_tree);
2612     }
2613   vat_json_array_add_uint (&vam->json_tree,
2614                            clib_net_to_host_u32 (mp->sw_if_index));
2615 }
2616
2617 static void
2618 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2619 {
2620   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2621           "router_addr %U host_mac %U",
2622           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2623           mp->lease.hostname,
2624           format_ip4_address, &mp->lease.host_address,
2625           format_ip4_address, &mp->lease.router_address,
2626           format_ethernet_address, mp->lease.host_mac);
2627 }
2628
2629 static void vl_api_dhcp_compl_event_t_handler_json
2630   (vl_api_dhcp_compl_event_t * mp)
2631 {
2632   /* JSON output not supported */
2633 }
2634
2635 static void
2636 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2637                               u32 counter)
2638 {
2639   vat_main_t *vam = &vat_main;
2640   static u64 default_counter = 0;
2641
2642   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2643                            NULL);
2644   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2645                            sw_if_index, default_counter);
2646   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2647 }
2648
2649 static void
2650 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2651                                 interface_counter_t counter)
2652 {
2653   vat_main_t *vam = &vat_main;
2654   static interface_counter_t default_counter = { 0, };
2655
2656   vec_validate_init_empty (vam->combined_interface_counters,
2657                            vnet_counter_type, NULL);
2658   vec_validate_init_empty (vam->combined_interface_counters
2659                            [vnet_counter_type], sw_if_index, default_counter);
2660   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2661 }
2662
2663 static void vl_api_vnet_interface_simple_counters_t_handler
2664   (vl_api_vnet_interface_simple_counters_t * mp)
2665 {
2666   /* not supported */
2667 }
2668
2669 static void vl_api_vnet_interface_combined_counters_t_handler
2670   (vl_api_vnet_interface_combined_counters_t * mp)
2671 {
2672   /* not supported */
2673 }
2674
2675 static void vl_api_vnet_interface_simple_counters_t_handler_json
2676   (vl_api_vnet_interface_simple_counters_t * mp)
2677 {
2678   u64 *v_packets;
2679   u64 packets;
2680   u32 count;
2681   u32 first_sw_if_index;
2682   int i;
2683
2684   count = ntohl (mp->count);
2685   first_sw_if_index = ntohl (mp->first_sw_if_index);
2686
2687   v_packets = (u64 *) & mp->data;
2688   for (i = 0; i < count; i++)
2689     {
2690       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2691       set_simple_interface_counter (mp->vnet_counter_type,
2692                                     first_sw_if_index + i, packets);
2693       v_packets++;
2694     }
2695 }
2696
2697 static void vl_api_vnet_interface_combined_counters_t_handler_json
2698   (vl_api_vnet_interface_combined_counters_t * mp)
2699 {
2700   interface_counter_t counter;
2701   vlib_counter_t *v;
2702   u32 first_sw_if_index;
2703   int i;
2704   u32 count;
2705
2706   count = ntohl (mp->count);
2707   first_sw_if_index = ntohl (mp->first_sw_if_index);
2708
2709   v = (vlib_counter_t *) & mp->data;
2710   for (i = 0; i < count; i++)
2711     {
2712       counter.packets =
2713         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2714       counter.bytes =
2715         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2716       set_combined_interface_counter (mp->vnet_counter_type,
2717                                       first_sw_if_index + i, counter);
2718       v++;
2719     }
2720 }
2721
2722 static u32
2723 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2724 {
2725   vat_main_t *vam = &vat_main;
2726   u32 i;
2727
2728   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2729     {
2730       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2731         {
2732           return i;
2733         }
2734     }
2735   return ~0;
2736 }
2737
2738 static u32
2739 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2740 {
2741   vat_main_t *vam = &vat_main;
2742   u32 i;
2743
2744   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2745     {
2746       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2747         {
2748           return i;
2749         }
2750     }
2751   return ~0;
2752 }
2753
2754 static void vl_api_vnet_ip4_fib_counters_t_handler
2755   (vl_api_vnet_ip4_fib_counters_t * mp)
2756 {
2757   /* not supported */
2758 }
2759
2760 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2761   (vl_api_vnet_ip4_fib_counters_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   vl_api_ip4_fib_counter_t *v;
2765   ip4_fib_counter_t *counter;
2766   struct in_addr ip4;
2767   u32 vrf_id;
2768   u32 vrf_index;
2769   u32 count;
2770   int i;
2771
2772   vrf_id = ntohl (mp->vrf_id);
2773   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2774   if (~0 == vrf_index)
2775     {
2776       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2777       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2778       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2779       vec_validate (vam->ip4_fib_counters, vrf_index);
2780       vam->ip4_fib_counters[vrf_index] = NULL;
2781     }
2782
2783   vec_free (vam->ip4_fib_counters[vrf_index]);
2784   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2785   count = ntohl (mp->count);
2786   for (i = 0; i < count; i++)
2787     {
2788       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2789       counter = &vam->ip4_fib_counters[vrf_index][i];
2790       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2791       counter->address = ip4;
2792       counter->address_length = v->address_length;
2793       counter->packets = clib_net_to_host_u64 (v->packets);
2794       counter->bytes = clib_net_to_host_u64 (v->bytes);
2795       v++;
2796     }
2797 }
2798
2799 static void vl_api_vnet_ip4_nbr_counters_t_handler
2800   (vl_api_vnet_ip4_nbr_counters_t * mp)
2801 {
2802   /* not supported */
2803 }
2804
2805 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2806   (vl_api_vnet_ip4_nbr_counters_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   vl_api_ip4_nbr_counter_t *v;
2810   ip4_nbr_counter_t *counter;
2811   u32 sw_if_index;
2812   u32 count;
2813   int i;
2814
2815   sw_if_index = ntohl (mp->sw_if_index);
2816   count = ntohl (mp->count);
2817   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2818
2819   if (mp->begin)
2820     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2821
2822   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2823   for (i = 0; i < count; i++)
2824     {
2825       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2826       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2827       counter->address.s_addr = v->address;
2828       counter->packets = clib_net_to_host_u64 (v->packets);
2829       counter->bytes = clib_net_to_host_u64 (v->bytes);
2830       counter->linkt = v->link_type;
2831       v++;
2832     }
2833 }
2834
2835 static void vl_api_vnet_ip6_fib_counters_t_handler
2836   (vl_api_vnet_ip6_fib_counters_t * mp)
2837 {
2838   /* not supported */
2839 }
2840
2841 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2842   (vl_api_vnet_ip6_fib_counters_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   vl_api_ip6_fib_counter_t *v;
2846   ip6_fib_counter_t *counter;
2847   struct in6_addr ip6;
2848   u32 vrf_id;
2849   u32 vrf_index;
2850   u32 count;
2851   int i;
2852
2853   vrf_id = ntohl (mp->vrf_id);
2854   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2855   if (~0 == vrf_index)
2856     {
2857       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2858       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2859       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2860       vec_validate (vam->ip6_fib_counters, vrf_index);
2861       vam->ip6_fib_counters[vrf_index] = NULL;
2862     }
2863
2864   vec_free (vam->ip6_fib_counters[vrf_index]);
2865   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2866   count = ntohl (mp->count);
2867   for (i = 0; i < count; i++)
2868     {
2869       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2870       counter = &vam->ip6_fib_counters[vrf_index][i];
2871       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2872       counter->address = ip6;
2873       counter->address_length = v->address_length;
2874       counter->packets = clib_net_to_host_u64 (v->packets);
2875       counter->bytes = clib_net_to_host_u64 (v->bytes);
2876       v++;
2877     }
2878 }
2879
2880 static void vl_api_vnet_ip6_nbr_counters_t_handler
2881   (vl_api_vnet_ip6_nbr_counters_t * mp)
2882 {
2883   /* not supported */
2884 }
2885
2886 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2887   (vl_api_vnet_ip6_nbr_counters_t * mp)
2888 {
2889   vat_main_t *vam = &vat_main;
2890   vl_api_ip6_nbr_counter_t *v;
2891   ip6_nbr_counter_t *counter;
2892   struct in6_addr ip6;
2893   u32 sw_if_index;
2894   u32 count;
2895   int i;
2896
2897   sw_if_index = ntohl (mp->sw_if_index);
2898   count = ntohl (mp->count);
2899   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2900
2901   if (mp->begin)
2902     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2903
2904   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2905   for (i = 0; i < count; i++)
2906     {
2907       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2908       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2909       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2910       counter->address = ip6;
2911       counter->packets = clib_net_to_host_u64 (v->packets);
2912       counter->bytes = clib_net_to_host_u64 (v->bytes);
2913       v++;
2914     }
2915 }
2916
2917 static void vl_api_get_first_msg_id_reply_t_handler
2918   (vl_api_get_first_msg_id_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   i32 retval = ntohl (mp->retval);
2922
2923   if (vam->async_mode)
2924     {
2925       vam->async_errors += (retval < 0);
2926     }
2927   else
2928     {
2929       vam->retval = retval;
2930       vam->result_ready = 1;
2931     }
2932   if (retval >= 0)
2933     {
2934       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2935     }
2936 }
2937
2938 static void vl_api_get_first_msg_id_reply_t_handler_json
2939   (vl_api_get_first_msg_id_reply_t * mp)
2940 {
2941   vat_main_t *vam = &vat_main;
2942   vat_json_node_t node;
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2946   vat_json_object_add_uint (&node, "first_msg_id",
2947                             (uint) ntohs (mp->first_msg_id));
2948
2949   vat_json_print (vam->ofp, &node);
2950   vat_json_free (&node);
2951
2952   vam->retval = ntohl (mp->retval);
2953   vam->result_ready = 1;
2954 }
2955
2956 static void vl_api_get_node_graph_reply_t_handler
2957   (vl_api_get_node_graph_reply_t * mp)
2958 {
2959   vat_main_t *vam = &vat_main;
2960   api_main_t *am = &api_main;
2961   i32 retval = ntohl (mp->retval);
2962   u8 *pvt_copy, *reply;
2963   void *oldheap;
2964   vlib_node_t *node;
2965   int i;
2966
2967   if (vam->async_mode)
2968     {
2969       vam->async_errors += (retval < 0);
2970     }
2971   else
2972     {
2973       vam->retval = retval;
2974       vam->result_ready = 1;
2975     }
2976
2977   /* "Should never happen..." */
2978   if (retval != 0)
2979     return;
2980
2981   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2982   pvt_copy = vec_dup (reply);
2983
2984   /* Toss the shared-memory original... */
2985   pthread_mutex_lock (&am->vlib_rp->mutex);
2986   oldheap = svm_push_data_heap (am->vlib_rp);
2987
2988   vec_free (reply);
2989
2990   svm_pop_heap (oldheap);
2991   pthread_mutex_unlock (&am->vlib_rp->mutex);
2992
2993   if (vam->graph_nodes)
2994     {
2995       hash_free (vam->graph_node_index_by_name);
2996
2997       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2998         {
2999           node = vam->graph_nodes[0][i];
3000           vec_free (node->name);
3001           vec_free (node->next_nodes);
3002           vec_free (node);
3003         }
3004       vec_free (vam->graph_nodes[0]);
3005       vec_free (vam->graph_nodes);
3006     }
3007
3008   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3009   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3010   vec_free (pvt_copy);
3011
3012   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3013     {
3014       node = vam->graph_nodes[0][i];
3015       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3016     }
3017 }
3018
3019 static void vl_api_get_node_graph_reply_t_handler_json
3020   (vl_api_get_node_graph_reply_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   api_main_t *am = &api_main;
3024   void *oldheap;
3025   vat_json_node_t node;
3026   u8 *reply;
3027
3028   /* $$$$ make this real? */
3029   vat_json_init_object (&node);
3030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3031   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3032
3033   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3034
3035   /* Toss the shared-memory original... */
3036   pthread_mutex_lock (&am->vlib_rp->mutex);
3037   oldheap = svm_push_data_heap (am->vlib_rp);
3038
3039   vec_free (reply);
3040
3041   svm_pop_heap (oldheap);
3042   pthread_mutex_unlock (&am->vlib_rp->mutex);
3043
3044   vat_json_print (vam->ofp, &node);
3045   vat_json_free (&node);
3046
3047   vam->retval = ntohl (mp->retval);
3048   vam->result_ready = 1;
3049 }
3050
3051 static void
3052 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3053 {
3054   vat_main_t *vam = &vat_main;
3055   u8 *s = 0;
3056
3057   if (mp->local)
3058     {
3059       s = format (s, "%=16d%=16d%=16d",
3060                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3061     }
3062   else
3063     {
3064       s = format (s, "%=16U%=16d%=16d",
3065                   mp->is_ipv6 ? format_ip6_address :
3066                   format_ip4_address,
3067                   mp->ip_address, mp->priority, mp->weight);
3068     }
3069
3070   print (vam->ofp, "%v", s);
3071   vec_free (s);
3072 }
3073
3074 static void
3075 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3076 {
3077   vat_main_t *vam = &vat_main;
3078   vat_json_node_t *node = NULL;
3079   struct in6_addr ip6;
3080   struct in_addr ip4;
3081
3082   if (VAT_JSON_ARRAY != vam->json_tree.type)
3083     {
3084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3085       vat_json_init_array (&vam->json_tree);
3086     }
3087   node = vat_json_array_add (&vam->json_tree);
3088   vat_json_init_object (node);
3089
3090   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3091   vat_json_object_add_uint (node, "priority", mp->priority);
3092   vat_json_object_add_uint (node, "weight", mp->weight);
3093
3094   if (mp->local)
3095     vat_json_object_add_uint (node, "sw_if_index",
3096                               clib_net_to_host_u32 (mp->sw_if_index));
3097   else
3098     {
3099       if (mp->is_ipv6)
3100         {
3101           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3102           vat_json_object_add_ip6 (node, "address", ip6);
3103         }
3104       else
3105         {
3106           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3107           vat_json_object_add_ip4 (node, "address", ip4);
3108         }
3109     }
3110 }
3111
3112 static void
3113 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3114                                           mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   u8 *ls_name = 0;
3118
3119   ls_name = format (0, "%s", mp->ls_name);
3120
3121   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3122          ls_name);
3123   vec_free (ls_name);
3124 }
3125
3126 static void
3127   vl_api_one_locator_set_details_t_handler_json
3128   (vl_api_one_locator_set_details_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   vat_json_node_t *node = 0;
3132   u8 *ls_name = 0;
3133
3134   ls_name = format (0, "%s", mp->ls_name);
3135   vec_add1 (ls_name, 0);
3136
3137   if (VAT_JSON_ARRAY != vam->json_tree.type)
3138     {
3139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3140       vat_json_init_array (&vam->json_tree);
3141     }
3142   node = vat_json_array_add (&vam->json_tree);
3143
3144   vat_json_init_object (node);
3145   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3146   vat_json_object_add_uint (node, "ls_index",
3147                             clib_net_to_host_u32 (mp->ls_index));
3148   vec_free (ls_name);
3149 }
3150
3151 typedef struct
3152 {
3153   u32 spi;
3154   u8 si;
3155 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3156
3157 uword
3158 unformat_nsh_address (unformat_input_t * input, va_list * args)
3159 {
3160   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3161   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3162 }
3163
3164 u8 *
3165 format_nsh_address_vat (u8 * s, va_list * args)
3166 {
3167   nsh_t *a = va_arg (*args, nsh_t *);
3168   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3169 }
3170
3171 static u8 *
3172 format_lisp_flat_eid (u8 * s, va_list * args)
3173 {
3174   u32 type = va_arg (*args, u32);
3175   u8 *eid = va_arg (*args, u8 *);
3176   u32 eid_len = va_arg (*args, u32);
3177
3178   switch (type)
3179     {
3180     case 0:
3181       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3182     case 1:
3183       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3184     case 2:
3185       return format (s, "%U", format_ethernet_address, eid);
3186     case 3:
3187       return format (s, "%U", format_nsh_address_vat, eid);
3188     }
3189   return 0;
3190 }
3191
3192 static u8 *
3193 format_lisp_eid_vat (u8 * s, va_list * args)
3194 {
3195   u32 type = va_arg (*args, u32);
3196   u8 *eid = va_arg (*args, u8 *);
3197   u32 eid_len = va_arg (*args, u32);
3198   u8 *seid = va_arg (*args, u8 *);
3199   u32 seid_len = va_arg (*args, u32);
3200   u32 is_src_dst = va_arg (*args, u32);
3201
3202   if (is_src_dst)
3203     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3204
3205   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3206
3207   return s;
3208 }
3209
3210 static void
3211 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   u8 *s = 0, *eid = 0;
3215
3216   if (~0 == mp->locator_set_index)
3217     s = format (0, "action: %d", mp->action);
3218   else
3219     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3220
3221   eid = format (0, "%U", format_lisp_eid_vat,
3222                 mp->eid_type,
3223                 mp->eid,
3224                 mp->eid_prefix_len,
3225                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3226   vec_add1 (eid, 0);
3227
3228   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3229          clib_net_to_host_u32 (mp->vni),
3230          eid,
3231          mp->is_local ? "local" : "remote",
3232          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3233          clib_net_to_host_u16 (mp->key_id), mp->key);
3234
3235   vec_free (s);
3236   vec_free (eid);
3237 }
3238
3239 static void
3240 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3241                                              * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t *node = 0;
3245   u8 *eid = 0;
3246
3247   if (VAT_JSON_ARRAY != vam->json_tree.type)
3248     {
3249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3250       vat_json_init_array (&vam->json_tree);
3251     }
3252   node = vat_json_array_add (&vam->json_tree);
3253
3254   vat_json_init_object (node);
3255   if (~0 == mp->locator_set_index)
3256     vat_json_object_add_uint (node, "action", mp->action);
3257   else
3258     vat_json_object_add_uint (node, "locator_set_index",
3259                               clib_net_to_host_u32 (mp->locator_set_index));
3260
3261   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3262   if (mp->eid_type == 3)
3263     {
3264       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3265       vat_json_init_object (nsh_json);
3266       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3267       vat_json_object_add_uint (nsh_json, "spi",
3268                                 clib_net_to_host_u32 (nsh->spi));
3269       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3270     }
3271   else
3272     {
3273       eid = format (0, "%U", format_lisp_eid_vat,
3274                     mp->eid_type,
3275                     mp->eid,
3276                     mp->eid_prefix_len,
3277                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3278       vec_add1 (eid, 0);
3279       vat_json_object_add_string_copy (node, "eid", eid);
3280       vec_free (eid);
3281     }
3282   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3283   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3284   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3285
3286   if (mp->key_id)
3287     {
3288       vat_json_object_add_uint (node, "key_id",
3289                                 clib_net_to_host_u16 (mp->key_id));
3290       vat_json_object_add_string_copy (node, "key", mp->key);
3291     }
3292 }
3293
3294 static void
3295 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   u8 *seid = 0, *deid = 0;
3299   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3300
3301   deid = format (0, "%U", format_lisp_eid_vat,
3302                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3303
3304   seid = format (0, "%U", format_lisp_eid_vat,
3305                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3306
3307   vec_add1 (deid, 0);
3308   vec_add1 (seid, 0);
3309
3310   if (mp->is_ip4)
3311     format_ip_address_fcn = format_ip4_address;
3312   else
3313     format_ip_address_fcn = format_ip6_address;
3314
3315
3316   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3317          clib_net_to_host_u32 (mp->vni),
3318          seid, deid,
3319          format_ip_address_fcn, mp->lloc,
3320          format_ip_address_fcn, mp->rloc,
3321          clib_net_to_host_u32 (mp->pkt_count),
3322          clib_net_to_host_u32 (mp->bytes));
3323
3324   vec_free (deid);
3325   vec_free (seid);
3326 }
3327
3328 static void
3329 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3330 {
3331   struct in6_addr ip6;
3332   struct in_addr ip4;
3333   vat_main_t *vam = &vat_main;
3334   vat_json_node_t *node = 0;
3335   u8 *deid = 0, *seid = 0;
3336
3337   if (VAT_JSON_ARRAY != vam->json_tree.type)
3338     {
3339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3340       vat_json_init_array (&vam->json_tree);
3341     }
3342   node = vat_json_array_add (&vam->json_tree);
3343
3344   vat_json_init_object (node);
3345   deid = format (0, "%U", format_lisp_eid_vat,
3346                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3347
3348   seid = format (0, "%U", format_lisp_eid_vat,
3349                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3350
3351   vec_add1 (deid, 0);
3352   vec_add1 (seid, 0);
3353
3354   vat_json_object_add_string_copy (node, "seid", seid);
3355   vat_json_object_add_string_copy (node, "deid", deid);
3356   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3357
3358   if (mp->is_ip4)
3359     {
3360       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3361       vat_json_object_add_ip4 (node, "lloc", ip4);
3362       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3363       vat_json_object_add_ip4 (node, "rloc", ip4);
3364     }
3365   else
3366     {
3367       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3368       vat_json_object_add_ip6 (node, "lloc", ip6);
3369       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3370       vat_json_object_add_ip6 (node, "rloc", ip6);
3371     }
3372   vat_json_object_add_uint (node, "pkt_count",
3373                             clib_net_to_host_u32 (mp->pkt_count));
3374   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3375
3376   vec_free (deid);
3377   vec_free (seid);
3378 }
3379
3380 static void
3381   vl_api_one_eid_table_map_details_t_handler
3382   (vl_api_one_eid_table_map_details_t * mp)
3383 {
3384   vat_main_t *vam = &vat_main;
3385
3386   u8 *line = format (0, "%=10d%=10d",
3387                      clib_net_to_host_u32 (mp->vni),
3388                      clib_net_to_host_u32 (mp->dp_table));
3389   print (vam->ofp, "%v", line);
3390   vec_free (line);
3391 }
3392
3393 static void
3394   vl_api_one_eid_table_map_details_t_handler_json
3395   (vl_api_one_eid_table_map_details_t * mp)
3396 {
3397   vat_main_t *vam = &vat_main;
3398   vat_json_node_t *node = NULL;
3399
3400   if (VAT_JSON_ARRAY != vam->json_tree.type)
3401     {
3402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3403       vat_json_init_array (&vam->json_tree);
3404     }
3405   node = vat_json_array_add (&vam->json_tree);
3406   vat_json_init_object (node);
3407   vat_json_object_add_uint (node, "dp_table",
3408                             clib_net_to_host_u32 (mp->dp_table));
3409   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3410 }
3411
3412 static void
3413   vl_api_one_eid_table_vni_details_t_handler
3414   (vl_api_one_eid_table_vni_details_t * mp)
3415 {
3416   vat_main_t *vam = &vat_main;
3417
3418   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3419   print (vam->ofp, "%v", line);
3420   vec_free (line);
3421 }
3422
3423 static void
3424   vl_api_one_eid_table_vni_details_t_handler_json
3425   (vl_api_one_eid_table_vni_details_t * mp)
3426 {
3427   vat_main_t *vam = &vat_main;
3428   vat_json_node_t *node = NULL;
3429
3430   if (VAT_JSON_ARRAY != vam->json_tree.type)
3431     {
3432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3433       vat_json_init_array (&vam->json_tree);
3434     }
3435   node = vat_json_array_add (&vam->json_tree);
3436   vat_json_init_object (node);
3437   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3438 }
3439
3440 static void
3441   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3442   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   int retval = clib_net_to_host_u32 (mp->retval);
3446
3447   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3448   print (vam->ofp, "fallback threshold value: %d", mp->value);
3449
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3456   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t _node, *node = &_node;
3460   int retval = clib_net_to_host_u32 (mp->retval);
3461
3462   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3463   vat_json_init_object (node);
3464   vat_json_object_add_uint (node, "value", mp->value);
3465
3466   vat_json_print (vam->ofp, node);
3467   vat_json_free (node);
3468
3469   vam->retval = retval;
3470   vam->result_ready = 1;
3471 }
3472
3473 static void
3474   vl_api_show_one_map_register_state_reply_t_handler
3475   (vl_api_show_one_map_register_state_reply_t * mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478   int retval = clib_net_to_host_u32 (mp->retval);
3479
3480   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3481
3482   vam->retval = retval;
3483   vam->result_ready = 1;
3484 }
3485
3486 static void
3487   vl_api_show_one_map_register_state_reply_t_handler_json
3488   (vl_api_show_one_map_register_state_reply_t * mp)
3489 {
3490   vat_main_t *vam = &vat_main;
3491   vat_json_node_t _node, *node = &_node;
3492   int retval = clib_net_to_host_u32 (mp->retval);
3493
3494   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3495
3496   vat_json_init_object (node);
3497   vat_json_object_add_string_copy (node, "state", s);
3498
3499   vat_json_print (vam->ofp, node);
3500   vat_json_free (node);
3501
3502   vam->retval = retval;
3503   vam->result_ready = 1;
3504   vec_free (s);
3505 }
3506
3507 static void
3508   vl_api_show_one_rloc_probe_state_reply_t_handler
3509   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3510 {
3511   vat_main_t *vam = &vat_main;
3512   int retval = clib_net_to_host_u32 (mp->retval);
3513
3514   if (retval)
3515     goto end;
3516
3517   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3518 end:
3519   vam->retval = retval;
3520   vam->result_ready = 1;
3521 }
3522
3523 static void
3524   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3525   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3526 {
3527   vat_main_t *vam = &vat_main;
3528   vat_json_node_t _node, *node = &_node;
3529   int retval = clib_net_to_host_u32 (mp->retval);
3530
3531   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3532   vat_json_init_object (node);
3533   vat_json_object_add_string_copy (node, "state", s);
3534
3535   vat_json_print (vam->ofp, node);
3536   vat_json_free (node);
3537
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540   vec_free (s);
3541 }
3542
3543 static void
3544   vl_api_show_one_stats_enable_disable_reply_t_handler
3545   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   int retval = clib_net_to_host_u32 (mp->retval);
3549
3550   if (retval)
3551     goto end;
3552
3553   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3561   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t _node, *node = &_node;
3565   int retval = clib_net_to_host_u32 (mp->retval);
3566
3567   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3568   vat_json_init_object (node);
3569   vat_json_object_add_string_copy (node, "state", s);
3570
3571   vat_json_print (vam->ofp, node);
3572   vat_json_free (node);
3573
3574   vam->retval = retval;
3575   vam->result_ready = 1;
3576   vec_free (s);
3577 }
3578
3579 static void
3580 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3581 {
3582   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3583   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3584   e->vni = clib_net_to_host_u32 (e->vni);
3585 }
3586
3587 static void
3588   gpe_fwd_entries_get_reply_t_net_to_host
3589   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3590 {
3591   u32 i;
3592
3593   mp->count = clib_net_to_host_u32 (mp->count);
3594   for (i = 0; i < mp->count; i++)
3595     {
3596       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3597     }
3598 }
3599
3600 static u8 *
3601 format_gpe_encap_mode (u8 * s, va_list * args)
3602 {
3603   u32 mode = va_arg (*args, u32);
3604
3605   switch (mode)
3606     {
3607     case 0:
3608       return format (s, "lisp");
3609     case 1:
3610       return format (s, "vxlan");
3611     }
3612   return 0;
3613 }
3614
3615 static void
3616   vl_api_gpe_get_encap_mode_reply_t_handler
3617   (vl_api_gpe_get_encap_mode_reply_t * mp)
3618 {
3619   vat_main_t *vam = &vat_main;
3620
3621   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3622   vam->retval = ntohl (mp->retval);
3623   vam->result_ready = 1;
3624 }
3625
3626 static void
3627   vl_api_gpe_get_encap_mode_reply_t_handler_json
3628   (vl_api_gpe_get_encap_mode_reply_t * mp)
3629 {
3630   vat_main_t *vam = &vat_main;
3631   vat_json_node_t node;
3632
3633   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3634   vec_add1 (encap_mode, 0);
3635
3636   vat_json_init_object (&node);
3637   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3638
3639   vec_free (encap_mode);
3640   vat_json_print (vam->ofp, &node);
3641   vat_json_free (&node);
3642
3643   vam->retval = ntohl (mp->retval);
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_gpe_fwd_entry_path_details_t_handler
3649   (vl_api_gpe_fwd_entry_path_details_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3653
3654   if (mp->lcl_loc.is_ip4)
3655     format_ip_address_fcn = format_ip4_address;
3656   else
3657     format_ip_address_fcn = format_ip6_address;
3658
3659   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3660          format_ip_address_fcn, &mp->lcl_loc,
3661          format_ip_address_fcn, &mp->rmt_loc);
3662 }
3663
3664 static void
3665 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3666 {
3667   struct in6_addr ip6;
3668   struct in_addr ip4;
3669
3670   if (loc->is_ip4)
3671     {
3672       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3673       vat_json_object_add_ip4 (n, "address", ip4);
3674     }
3675   else
3676     {
3677       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3678       vat_json_object_add_ip6 (n, "address", ip6);
3679     }
3680   vat_json_object_add_uint (n, "weight", loc->weight);
3681 }
3682
3683 static void
3684   vl_api_gpe_fwd_entry_path_details_t_handler_json
3685   (vl_api_gpe_fwd_entry_path_details_t * mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688   vat_json_node_t *node = NULL;
3689   vat_json_node_t *loc_node;
3690
3691   if (VAT_JSON_ARRAY != vam->json_tree.type)
3692     {
3693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694       vat_json_init_array (&vam->json_tree);
3695     }
3696   node = vat_json_array_add (&vam->json_tree);
3697   vat_json_init_object (node);
3698
3699   loc_node = vat_json_object_add (node, "local_locator");
3700   vat_json_init_object (loc_node);
3701   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3702
3703   loc_node = vat_json_object_add (node, "remote_locator");
3704   vat_json_init_object (loc_node);
3705   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3706 }
3707
3708 static void
3709   vl_api_gpe_fwd_entries_get_reply_t_handler
3710   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   u32 i;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715   vl_api_gpe_fwd_entry_t *e;
3716
3717   if (retval)
3718     goto end;
3719
3720   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3721
3722   for (i = 0; i < mp->count; i++)
3723     {
3724       e = &mp->entries[i];
3725       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3726              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3727              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3728     }
3729
3730 end:
3731   vam->retval = retval;
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3737   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3738 {
3739   u8 *s = 0;
3740   vat_main_t *vam = &vat_main;
3741   vat_json_node_t *e = 0, root;
3742   u32 i;
3743   int retval = clib_net_to_host_u32 (mp->retval);
3744   vl_api_gpe_fwd_entry_t *fwd;
3745
3746   if (retval)
3747     goto end;
3748
3749   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3750   vat_json_init_array (&root);
3751
3752   for (i = 0; i < mp->count; i++)
3753     {
3754       e = vat_json_array_add (&root);
3755       fwd = &mp->entries[i];
3756
3757       vat_json_init_object (e);
3758       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3759       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3760       vat_json_object_add_int (e, "vni", fwd->vni);
3761       vat_json_object_add_int (e, "action", fwd->action);
3762
3763       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3764                   fwd->leid_prefix_len);
3765       vec_add1 (s, 0);
3766       vat_json_object_add_string_copy (e, "leid", s);
3767       vec_free (s);
3768
3769       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3770                   fwd->reid_prefix_len);
3771       vec_add1 (s, 0);
3772       vat_json_object_add_string_copy (e, "reid", s);
3773       vec_free (s);
3774     }
3775
3776   vat_json_print (vam->ofp, &root);
3777   vat_json_free (&root);
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3786   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   u32 i, n;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791   vl_api_gpe_native_fwd_rpath_t *r;
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     {
3800       r = &mp->entries[i];
3801       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3802              clib_net_to_host_u32 (r->fib_index),
3803              clib_net_to_host_u32 (r->nh_sw_if_index),
3804              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3805     }
3806
3807 end:
3808   vam->retval = retval;
3809   vam->result_ready = 1;
3810 }
3811
3812 static void
3813   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3814   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3815 {
3816   vat_main_t *vam = &vat_main;
3817   vat_json_node_t root, *e;
3818   u32 i, n;
3819   int retval = clib_net_to_host_u32 (mp->retval);
3820   vl_api_gpe_native_fwd_rpath_t *r;
3821   u8 *s;
3822
3823   if (retval)
3824     goto end;
3825
3826   n = clib_net_to_host_u32 (mp->count);
3827   vat_json_init_array (&root);
3828
3829   for (i = 0; i < n; i++)
3830     {
3831       e = vat_json_array_add (&root);
3832       vat_json_init_object (e);
3833       r = &mp->entries[i];
3834       s =
3835         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3836                 r->nh_addr);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip4", s);
3839       vec_free (s);
3840
3841       vat_json_object_add_uint (e, "fib_index",
3842                                 clib_net_to_host_u32 (r->fib_index));
3843       vat_json_object_add_uint (e, "nh_sw_if_index",
3844                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3845     }
3846
3847   vat_json_print (vam->ofp, &root);
3848   vat_json_free (&root);
3849
3850 end:
3851   vam->retval = retval;
3852   vam->result_ready = 1;
3853 }
3854
3855 static void
3856   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3857   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3858 {
3859   vat_main_t *vam = &vat_main;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867
3868   for (i = 0; i < n; i++)
3869     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3870
3871 end:
3872   vam->retval = retval;
3873   vam->result_ready = 1;
3874 }
3875
3876 static void
3877   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3878   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   vat_json_node_t root;
3882   u32 i, n;
3883   int retval = clib_net_to_host_u32 (mp->retval);
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3893
3894   vat_json_print (vam->ofp, &root);
3895   vat_json_free (&root);
3896
3897 end:
3898   vam->retval = retval;
3899   vam->result_ready = 1;
3900 }
3901
3902 static void
3903   vl_api_one_ndp_entries_get_reply_t_handler
3904   (vl_api_one_ndp_entries_get_reply_t * mp)
3905 {
3906   vat_main_t *vam = &vat_main;
3907   u32 i, n;
3908   int retval = clib_net_to_host_u32 (mp->retval);
3909
3910   if (retval)
3911     goto end;
3912
3913   n = clib_net_to_host_u32 (mp->count);
3914
3915   for (i = 0; i < n; i++)
3916     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3917            format_ethernet_address, mp->entries[i].mac);
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_one_ndp_entries_get_reply_t_handler_json
3926   (vl_api_one_ndp_entries_get_reply_t * mp)
3927 {
3928   u8 *s = 0;
3929   vat_main_t *vam = &vat_main;
3930   vat_json_node_t *e = 0, root;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933   vl_api_one_ndp_entry_t *arp_entry;
3934
3935   if (retval)
3936     goto end;
3937
3938   n = clib_net_to_host_u32 (mp->count);
3939   vat_json_init_array (&root);
3940
3941   for (i = 0; i < n; i++)
3942     {
3943       e = vat_json_array_add (&root);
3944       arp_entry = &mp->entries[i];
3945
3946       vat_json_init_object (e);
3947       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3948       vec_add1 (s, 0);
3949
3950       vat_json_object_add_string_copy (e, "mac", s);
3951       vec_free (s);
3952
3953       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3954       vec_add1 (s, 0);
3955       vat_json_object_add_string_copy (e, "ip6", s);
3956       vec_free (s);
3957     }
3958
3959   vat_json_print (vam->ofp, &root);
3960   vat_json_free (&root);
3961
3962 end:
3963   vam->retval = retval;
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968   vl_api_one_l2_arp_entries_get_reply_t_handler
3969   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972   u32 i, n;
3973   int retval = clib_net_to_host_u32 (mp->retval);
3974
3975   if (retval)
3976     goto end;
3977
3978   n = clib_net_to_host_u32 (mp->count);
3979
3980   for (i = 0; i < n; i++)
3981     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3982            format_ethernet_address, mp->entries[i].mac);
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3992 {
3993   u8 *s = 0;
3994   vat_main_t *vam = &vat_main;
3995   vat_json_node_t *e = 0, root;
3996   u32 i, n;
3997   int retval = clib_net_to_host_u32 (mp->retval);
3998   vl_api_one_l2_arp_entry_t *arp_entry;
3999
4000   if (retval)
4001     goto end;
4002
4003   n = clib_net_to_host_u32 (mp->count);
4004   vat_json_init_array (&root);
4005
4006   for (i = 0; i < n; i++)
4007     {
4008       e = vat_json_array_add (&root);
4009       arp_entry = &mp->entries[i];
4010
4011       vat_json_init_object (e);
4012       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4013       vec_add1 (s, 0);
4014
4015       vat_json_object_add_string_copy (e, "mac", s);
4016       vec_free (s);
4017
4018       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4019       vec_add1 (s, 0);
4020       vat_json_object_add_string_copy (e, "ip4", s);
4021       vec_free (s);
4022     }
4023
4024   vat_json_print (vam->ofp, &root);
4025   vat_json_free (&root);
4026
4027 end:
4028   vam->retval = retval;
4029   vam->result_ready = 1;
4030 }
4031
4032 static void
4033 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   u32 i, n;
4037   int retval = clib_net_to_host_u32 (mp->retval);
4038
4039   if (retval)
4040     goto end;
4041
4042   n = clib_net_to_host_u32 (mp->count);
4043
4044   for (i = 0; i < n; i++)
4045     {
4046       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4047     }
4048
4049 end:
4050   vam->retval = retval;
4051   vam->result_ready = 1;
4052 }
4053
4054 static void
4055   vl_api_one_ndp_bd_get_reply_t_handler_json
4056   (vl_api_one_ndp_bd_get_reply_t * mp)
4057 {
4058   vat_main_t *vam = &vat_main;
4059   vat_json_node_t root;
4060   u32 i, n;
4061   int retval = clib_net_to_host_u32 (mp->retval);
4062
4063   if (retval)
4064     goto end;
4065
4066   n = clib_net_to_host_u32 (mp->count);
4067   vat_json_init_array (&root);
4068
4069   for (i = 0; i < n; i++)
4070     {
4071       vat_json_array_add_uint (&root,
4072                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4073     }
4074
4075   vat_json_print (vam->ofp, &root);
4076   vat_json_free (&root);
4077
4078 end:
4079   vam->retval = retval;
4080   vam->result_ready = 1;
4081 }
4082
4083 static void
4084   vl_api_one_l2_arp_bd_get_reply_t_handler
4085   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4086 {
4087   vat_main_t *vam = &vat_main;
4088   u32 i, n;
4089   int retval = clib_net_to_host_u32 (mp->retval);
4090
4091   if (retval)
4092     goto end;
4093
4094   n = clib_net_to_host_u32 (mp->count);
4095
4096   for (i = 0; i < n; i++)
4097     {
4098       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4099     }
4100
4101 end:
4102   vam->retval = retval;
4103   vam->result_ready = 1;
4104 }
4105
4106 static void
4107   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4108   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4109 {
4110   vat_main_t *vam = &vat_main;
4111   vat_json_node_t root;
4112   u32 i, n;
4113   int retval = clib_net_to_host_u32 (mp->retval);
4114
4115   if (retval)
4116     goto end;
4117
4118   n = clib_net_to_host_u32 (mp->count);
4119   vat_json_init_array (&root);
4120
4121   for (i = 0; i < n; i++)
4122     {
4123       vat_json_array_add_uint (&root,
4124                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4125     }
4126
4127   vat_json_print (vam->ofp, &root);
4128   vat_json_free (&root);
4129
4130 end:
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_one_adjacencies_get_reply_t_handler
4137   (vl_api_one_adjacencies_get_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   u32 i, n;
4141   int retval = clib_net_to_host_u32 (mp->retval);
4142   vl_api_one_adjacency_t *a;
4143
4144   if (retval)
4145     goto end;
4146
4147   n = clib_net_to_host_u32 (mp->count);
4148
4149   for (i = 0; i < n; i++)
4150     {
4151       a = &mp->adjacencies[i];
4152       print (vam->ofp, "%U %40U",
4153              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4154              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4155     }
4156
4157 end:
4158   vam->retval = retval;
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_adjacencies_get_reply_t_handler_json
4164   (vl_api_one_adjacencies_get_reply_t * mp)
4165 {
4166   u8 *s = 0;
4167   vat_main_t *vam = &vat_main;
4168   vat_json_node_t *e = 0, root;
4169   u32 i, n;
4170   int retval = clib_net_to_host_u32 (mp->retval);
4171   vl_api_one_adjacency_t *a;
4172
4173   if (retval)
4174     goto end;
4175
4176   n = clib_net_to_host_u32 (mp->count);
4177   vat_json_init_array (&root);
4178
4179   for (i = 0; i < n; i++)
4180     {
4181       e = vat_json_array_add (&root);
4182       a = &mp->adjacencies[i];
4183
4184       vat_json_init_object (e);
4185       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4186                   a->leid_prefix_len);
4187       vec_add1 (s, 0);
4188       vat_json_object_add_string_copy (e, "leid", s);
4189       vec_free (s);
4190
4191       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4192                   a->reid_prefix_len);
4193       vec_add1 (s, 0);
4194       vat_json_object_add_string_copy (e, "reid", s);
4195       vec_free (s);
4196     }
4197
4198   vat_json_print (vam->ofp, &root);
4199   vat_json_free (&root);
4200
4201 end:
4202   vam->retval = retval;
4203   vam->result_ready = 1;
4204 }
4205
4206 static void
4207 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4208 {
4209   vat_main_t *vam = &vat_main;
4210
4211   print (vam->ofp, "%=20U",
4212          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4213          mp->ip_address);
4214 }
4215
4216 static void
4217   vl_api_one_map_server_details_t_handler_json
4218   (vl_api_one_map_server_details_t * mp)
4219 {
4220   vat_main_t *vam = &vat_main;
4221   vat_json_node_t *node = NULL;
4222   struct in6_addr ip6;
4223   struct in_addr ip4;
4224
4225   if (VAT_JSON_ARRAY != vam->json_tree.type)
4226     {
4227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4228       vat_json_init_array (&vam->json_tree);
4229     }
4230   node = vat_json_array_add (&vam->json_tree);
4231
4232   vat_json_init_object (node);
4233   if (mp->is_ipv6)
4234     {
4235       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4236       vat_json_object_add_ip6 (node, "map-server", ip6);
4237     }
4238   else
4239     {
4240       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4241       vat_json_object_add_ip4 (node, "map-server", ip4);
4242     }
4243 }
4244
4245 static void
4246 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4247                                            * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250
4251   print (vam->ofp, "%=20U",
4252          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4253          mp->ip_address);
4254 }
4255
4256 static void
4257   vl_api_one_map_resolver_details_t_handler_json
4258   (vl_api_one_map_resolver_details_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   vat_json_node_t *node = NULL;
4262   struct in6_addr ip6;
4263   struct in_addr ip4;
4264
4265   if (VAT_JSON_ARRAY != vam->json_tree.type)
4266     {
4267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4268       vat_json_init_array (&vam->json_tree);
4269     }
4270   node = vat_json_array_add (&vam->json_tree);
4271
4272   vat_json_init_object (node);
4273   if (mp->is_ipv6)
4274     {
4275       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4276       vat_json_object_add_ip6 (node, "map resolver", ip6);
4277     }
4278   else
4279     {
4280       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4281       vat_json_object_add_ip4 (node, "map resolver", ip4);
4282     }
4283 }
4284
4285 static void
4286 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       print (vam->ofp, "feature: %s\ngpe: %s",
4294              mp->feature_status ? "enabled" : "disabled",
4295              mp->gpe_status ? "enabled" : "disabled");
4296     }
4297
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_show_one_status_reply_t_handler_json
4304   (vl_api_show_one_status_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *gpe_status = NULL;
4309   u8 *feature_status = NULL;
4310
4311   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4312   feature_status = format (0, "%s",
4313                            mp->feature_status ? "enabled" : "disabled");
4314   vec_add1 (gpe_status, 0);
4315   vec_add1 (feature_status, 0);
4316
4317   vat_json_init_object (&node);
4318   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4319   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4320
4321   vec_free (gpe_status);
4322   vec_free (feature_status);
4323
4324   vat_json_print (vam->ofp, &node);
4325   vat_json_free (&node);
4326
4327   vam->retval = ntohl (mp->retval);
4328   vam->result_ready = 1;
4329 }
4330
4331 static void
4332   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4333   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4334 {
4335   vat_main_t *vam = &vat_main;
4336   i32 retval = ntohl (mp->retval);
4337
4338   if (retval >= 0)
4339     {
4340       print (vam->ofp, "%=20s", mp->locator_set_name);
4341     }
4342
4343   vam->retval = retval;
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4349   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   vat_json_node_t *node = NULL;
4353
4354   if (VAT_JSON_ARRAY != vam->json_tree.type)
4355     {
4356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4357       vat_json_init_array (&vam->json_tree);
4358     }
4359   node = vat_json_array_add (&vam->json_tree);
4360
4361   vat_json_init_object (node);
4362   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4363
4364   vat_json_print (vam->ofp, node);
4365   vat_json_free (node);
4366
4367   vam->retval = ntohl (mp->retval);
4368   vam->result_ready = 1;
4369 }
4370
4371 static u8 *
4372 format_lisp_map_request_mode (u8 * s, va_list * args)
4373 {
4374   u32 mode = va_arg (*args, u32);
4375
4376   switch (mode)
4377     {
4378     case 0:
4379       return format (0, "dst-only");
4380     case 1:
4381       return format (0, "src-dst");
4382     }
4383   return 0;
4384 }
4385
4386 static void
4387   vl_api_show_one_map_request_mode_reply_t_handler
4388   (vl_api_show_one_map_request_mode_reply_t * mp)
4389 {
4390   vat_main_t *vam = &vat_main;
4391   i32 retval = ntohl (mp->retval);
4392
4393   if (0 <= retval)
4394     {
4395       u32 mode = mp->mode;
4396       print (vam->ofp, "map_request_mode: %U",
4397              format_lisp_map_request_mode, mode);
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_show_one_map_request_mode_reply_t_handler_json
4406   (vl_api_show_one_map_request_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *s = 0;
4411   u32 mode;
4412
4413   mode = mp->mode;
4414   s = format (0, "%U", format_lisp_map_request_mode, mode);
4415   vec_add1 (s, 0);
4416
4417   vat_json_init_object (&node);
4418   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4419   vat_json_print (vam->ofp, &node);
4420   vat_json_free (&node);
4421
4422   vec_free (s);
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_one_show_xtr_mode_reply_t_handler
4429   (vl_api_one_show_xtr_mode_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4437     }
4438
4439   vam->retval = retval;
4440   vam->result_ready = 1;
4441 }
4442
4443 static void
4444   vl_api_one_show_xtr_mode_reply_t_handler_json
4445   (vl_api_one_show_xtr_mode_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   vat_json_node_t node;
4449   u8 *status = 0;
4450
4451   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4452   vec_add1 (status, 0);
4453
4454   vat_json_init_object (&node);
4455   vat_json_object_add_string_copy (&node, "status", status);
4456
4457   vec_free (status);
4458
4459   vat_json_print (vam->ofp, &node);
4460   vat_json_free (&node);
4461
4462   vam->retval = ntohl (mp->retval);
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467   vl_api_one_show_pitr_mode_reply_t_handler
4468   (vl_api_one_show_pitr_mode_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   i32 retval = ntohl (mp->retval);
4472
4473   if (0 <= retval)
4474     {
4475       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483   vl_api_one_show_pitr_mode_reply_t_handler_json
4484   (vl_api_one_show_pitr_mode_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488   u8 *status = 0;
4489
4490   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4491   vec_add1 (status, 0);
4492
4493   vat_json_init_object (&node);
4494   vat_json_object_add_string_copy (&node, "status", status);
4495
4496   vec_free (status);
4497
4498   vat_json_print (vam->ofp, &node);
4499   vat_json_free (&node);
4500
4501   vam->retval = ntohl (mp->retval);
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_one_show_petr_mode_reply_t_handler
4507   (vl_api_one_show_petr_mode_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   i32 retval = ntohl (mp->retval);
4511
4512   if (0 <= retval)
4513     {
4514       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4515     }
4516
4517   vam->retval = retval;
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522   vl_api_one_show_petr_mode_reply_t_handler_json
4523   (vl_api_one_show_petr_mode_reply_t * mp)
4524 {
4525   vat_main_t *vam = &vat_main;
4526   vat_json_node_t node;
4527   u8 *status = 0;
4528
4529   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4530   vec_add1 (status, 0);
4531
4532   vat_json_init_object (&node);
4533   vat_json_object_add_string_copy (&node, "status", status);
4534
4535   vec_free (status);
4536
4537   vat_json_print (vam->ofp, &node);
4538   vat_json_free (&node);
4539
4540   vam->retval = ntohl (mp->retval);
4541   vam->result_ready = 1;
4542 }
4543
4544 static void
4545   vl_api_show_one_use_petr_reply_t_handler
4546   (vl_api_show_one_use_petr_reply_t * mp)
4547 {
4548   vat_main_t *vam = &vat_main;
4549   i32 retval = ntohl (mp->retval);
4550
4551   if (0 <= retval)
4552     {
4553       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4554       if (mp->status)
4555         {
4556           print (vam->ofp, "Proxy-ETR address; %U",
4557                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4558                  mp->address);
4559         }
4560     }
4561
4562   vam->retval = retval;
4563   vam->result_ready = 1;
4564 }
4565
4566 static void
4567   vl_api_show_one_use_petr_reply_t_handler_json
4568   (vl_api_show_one_use_petr_reply_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t node;
4572   u8 *status = 0;
4573   struct in_addr ip4;
4574   struct in6_addr ip6;
4575
4576   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4577   vec_add1 (status, 0);
4578
4579   vat_json_init_object (&node);
4580   vat_json_object_add_string_copy (&node, "status", status);
4581   if (mp->status)
4582     {
4583       if (mp->is_ip4)
4584         {
4585           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4586           vat_json_object_add_ip6 (&node, "address", ip6);
4587         }
4588       else
4589         {
4590           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4591           vat_json_object_add_ip4 (&node, "address", ip4);
4592         }
4593     }
4594
4595   vec_free (status);
4596
4597   vat_json_print (vam->ofp, &node);
4598   vat_json_free (&node);
4599
4600   vam->retval = ntohl (mp->retval);
4601   vam->result_ready = 1;
4602 }
4603
4604 static void
4605   vl_api_show_one_nsh_mapping_reply_t_handler
4606   (vl_api_show_one_nsh_mapping_reply_t * mp)
4607 {
4608   vat_main_t *vam = &vat_main;
4609   i32 retval = ntohl (mp->retval);
4610
4611   if (0 <= retval)
4612     {
4613       print (vam->ofp, "%-20s%-16s",
4614              mp->is_set ? "set" : "not-set",
4615              mp->is_set ? (char *) mp->locator_set_name : "");
4616     }
4617
4618   vam->retval = retval;
4619   vam->result_ready = 1;
4620 }
4621
4622 static void
4623   vl_api_show_one_nsh_mapping_reply_t_handler_json
4624   (vl_api_show_one_nsh_mapping_reply_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   vat_json_node_t node;
4628   u8 *status = 0;
4629
4630   status = format (0, "%s", mp->is_set ? "yes" : "no");
4631   vec_add1 (status, 0);
4632
4633   vat_json_init_object (&node);
4634   vat_json_object_add_string_copy (&node, "is_set", status);
4635   if (mp->is_set)
4636     {
4637       vat_json_object_add_string_copy (&node, "locator_set",
4638                                        mp->locator_set_name);
4639     }
4640
4641   vec_free (status);
4642
4643   vat_json_print (vam->ofp, &node);
4644   vat_json_free (&node);
4645
4646   vam->retval = ntohl (mp->retval);
4647   vam->result_ready = 1;
4648 }
4649
4650 static void
4651   vl_api_show_one_map_register_ttl_reply_t_handler
4652   (vl_api_show_one_map_register_ttl_reply_t * mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   i32 retval = ntohl (mp->retval);
4656
4657   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4658
4659   if (0 <= retval)
4660     {
4661       print (vam->ofp, "ttl: %u", mp->ttl);
4662     }
4663
4664   vam->retval = retval;
4665   vam->result_ready = 1;
4666 }
4667
4668 static void
4669   vl_api_show_one_map_register_ttl_reply_t_handler_json
4670   (vl_api_show_one_map_register_ttl_reply_t * mp)
4671 {
4672   vat_main_t *vam = &vat_main;
4673   vat_json_node_t node;
4674
4675   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4676   vat_json_init_object (&node);
4677   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4678
4679   vat_json_print (vam->ofp, &node);
4680   vat_json_free (&node);
4681
4682   vam->retval = ntohl (mp->retval);
4683   vam->result_ready = 1;
4684 }
4685
4686 static void
4687 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4688 {
4689   vat_main_t *vam = &vat_main;
4690   i32 retval = ntohl (mp->retval);
4691
4692   if (0 <= retval)
4693     {
4694       print (vam->ofp, "%-20s%-16s",
4695              mp->status ? "enabled" : "disabled",
4696              mp->status ? (char *) mp->locator_set_name : "");
4697     }
4698
4699   vam->retval = retval;
4700   vam->result_ready = 1;
4701 }
4702
4703 static void
4704 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   vat_json_node_t node;
4708   u8 *status = 0;
4709
4710   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4711   vec_add1 (status, 0);
4712
4713   vat_json_init_object (&node);
4714   vat_json_object_add_string_copy (&node, "status", status);
4715   if (mp->status)
4716     {
4717       vat_json_object_add_string_copy (&node, "locator_set",
4718                                        mp->locator_set_name);
4719     }
4720
4721   vec_free (status);
4722
4723   vat_json_print (vam->ofp, &node);
4724   vat_json_free (&node);
4725
4726   vam->retval = ntohl (mp->retval);
4727   vam->result_ready = 1;
4728 }
4729
4730 static u8 *
4731 format_policer_type (u8 * s, va_list * va)
4732 {
4733   u32 i = va_arg (*va, u32);
4734
4735   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4736     s = format (s, "1r2c");
4737   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4738     s = format (s, "1r3c");
4739   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4740     s = format (s, "2r3c-2698");
4741   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4742     s = format (s, "2r3c-4115");
4743   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4744     s = format (s, "2r3c-mef5cf1");
4745   else
4746     s = format (s, "ILLEGAL");
4747   return s;
4748 }
4749
4750 static u8 *
4751 format_policer_rate_type (u8 * s, va_list * va)
4752 {
4753   u32 i = va_arg (*va, u32);
4754
4755   if (i == SSE2_QOS_RATE_KBPS)
4756     s = format (s, "kbps");
4757   else if (i == SSE2_QOS_RATE_PPS)
4758     s = format (s, "pps");
4759   else
4760     s = format (s, "ILLEGAL");
4761   return s;
4762 }
4763
4764 static u8 *
4765 format_policer_round_type (u8 * s, va_list * va)
4766 {
4767   u32 i = va_arg (*va, u32);
4768
4769   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4770     s = format (s, "closest");
4771   else if (i == SSE2_QOS_ROUND_TO_UP)
4772     s = format (s, "up");
4773   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4774     s = format (s, "down");
4775   else
4776     s = format (s, "ILLEGAL");
4777   return s;
4778 }
4779
4780 static u8 *
4781 format_policer_action_type (u8 * s, va_list * va)
4782 {
4783   u32 i = va_arg (*va, u32);
4784
4785   if (i == SSE2_QOS_ACTION_DROP)
4786     s = format (s, "drop");
4787   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4788     s = format (s, "transmit");
4789   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4790     s = format (s, "mark-and-transmit");
4791   else
4792     s = format (s, "ILLEGAL");
4793   return s;
4794 }
4795
4796 static u8 *
4797 format_dscp (u8 * s, va_list * va)
4798 {
4799   u32 i = va_arg (*va, u32);
4800   char *t = 0;
4801
4802   switch (i)
4803     {
4804 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4805       foreach_vnet_dscp
4806 #undef _
4807     default:
4808       return format (s, "ILLEGAL");
4809     }
4810   s = format (s, "%s", t);
4811   return s;
4812 }
4813
4814 static void
4815 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4816 {
4817   vat_main_t *vam = &vat_main;
4818   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4819
4820   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4821     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4822   else
4823     conform_dscp_str = format (0, "");
4824
4825   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4826     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4827   else
4828     exceed_dscp_str = format (0, "");
4829
4830   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4831     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4832   else
4833     violate_dscp_str = format (0, "");
4834
4835   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4836          "rate type %U, round type %U, %s rate, %s color-aware, "
4837          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4838          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4839          "conform action %U%s, exceed action %U%s, violate action %U%s",
4840          mp->name,
4841          format_policer_type, mp->type,
4842          ntohl (mp->cir),
4843          ntohl (mp->eir),
4844          clib_net_to_host_u64 (mp->cb),
4845          clib_net_to_host_u64 (mp->eb),
4846          format_policer_rate_type, mp->rate_type,
4847          format_policer_round_type, mp->round_type,
4848          mp->single_rate ? "single" : "dual",
4849          mp->color_aware ? "is" : "not",
4850          ntohl (mp->cir_tokens_per_period),
4851          ntohl (mp->pir_tokens_per_period),
4852          ntohl (mp->scale),
4853          ntohl (mp->current_limit),
4854          ntohl (mp->current_bucket),
4855          ntohl (mp->extended_limit),
4856          ntohl (mp->extended_bucket),
4857          clib_net_to_host_u64 (mp->last_update_time),
4858          format_policer_action_type, mp->conform_action_type,
4859          conform_dscp_str,
4860          format_policer_action_type, mp->exceed_action_type,
4861          exceed_dscp_str,
4862          format_policer_action_type, mp->violate_action_type,
4863          violate_dscp_str);
4864
4865   vec_free (conform_dscp_str);
4866   vec_free (exceed_dscp_str);
4867   vec_free (violate_dscp_str);
4868 }
4869
4870 static void vl_api_policer_details_t_handler_json
4871   (vl_api_policer_details_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   vat_json_node_t *node;
4875   u8 *rate_type_str, *round_type_str, *type_str;
4876   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4877
4878   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4879   round_type_str =
4880     format (0, "%U", format_policer_round_type, mp->round_type);
4881   type_str = format (0, "%U", format_policer_type, mp->type);
4882   conform_action_str = format (0, "%U", format_policer_action_type,
4883                                mp->conform_action_type);
4884   exceed_action_str = format (0, "%U", format_policer_action_type,
4885                               mp->exceed_action_type);
4886   violate_action_str = format (0, "%U", format_policer_action_type,
4887                                mp->violate_action_type);
4888
4889   if (VAT_JSON_ARRAY != vam->json_tree.type)
4890     {
4891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4892       vat_json_init_array (&vam->json_tree);
4893     }
4894   node = vat_json_array_add (&vam->json_tree);
4895
4896   vat_json_init_object (node);
4897   vat_json_object_add_string_copy (node, "name", mp->name);
4898   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4899   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4900   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4901   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4902   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4903   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4904   vat_json_object_add_string_copy (node, "type", type_str);
4905   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4906   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4907   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4908   vat_json_object_add_uint (node, "cir_tokens_per_period",
4909                             ntohl (mp->cir_tokens_per_period));
4910   vat_json_object_add_uint (node, "eir_tokens_per_period",
4911                             ntohl (mp->pir_tokens_per_period));
4912   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4913   vat_json_object_add_uint (node, "current_bucket",
4914                             ntohl (mp->current_bucket));
4915   vat_json_object_add_uint (node, "extended_limit",
4916                             ntohl (mp->extended_limit));
4917   vat_json_object_add_uint (node, "extended_bucket",
4918                             ntohl (mp->extended_bucket));
4919   vat_json_object_add_uint (node, "last_update_time",
4920                             ntohl (mp->last_update_time));
4921   vat_json_object_add_string_copy (node, "conform_action",
4922                                    conform_action_str);
4923   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4924     {
4925       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4926       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4927       vec_free (dscp_str);
4928     }
4929   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4930   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4931     {
4932       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4933       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4934       vec_free (dscp_str);
4935     }
4936   vat_json_object_add_string_copy (node, "violate_action",
4937                                    violate_action_str);
4938   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4939     {
4940       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4941       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4942       vec_free (dscp_str);
4943     }
4944
4945   vec_free (rate_type_str);
4946   vec_free (round_type_str);
4947   vec_free (type_str);
4948   vec_free (conform_action_str);
4949   vec_free (exceed_action_str);
4950   vec_free (violate_action_str);
4951 }
4952
4953 static void
4954 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4955                                            mp)
4956 {
4957   vat_main_t *vam = &vat_main;
4958   int i, count = ntohl (mp->count);
4959
4960   if (count > 0)
4961     print (vam->ofp, "classify table ids (%d) : ", count);
4962   for (i = 0; i < count; i++)
4963     {
4964       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4965       print (vam->ofp, (i < count - 1) ? "," : "");
4966     }
4967   vam->retval = ntohl (mp->retval);
4968   vam->result_ready = 1;
4969 }
4970
4971 static void
4972   vl_api_classify_table_ids_reply_t_handler_json
4973   (vl_api_classify_table_ids_reply_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976   int i, count = ntohl (mp->count);
4977
4978   if (count > 0)
4979     {
4980       vat_json_node_t node;
4981
4982       vat_json_init_object (&node);
4983       for (i = 0; i < count; i++)
4984         {
4985           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4986         }
4987       vat_json_print (vam->ofp, &node);
4988       vat_json_free (&node);
4989     }
4990   vam->retval = ntohl (mp->retval);
4991   vam->result_ready = 1;
4992 }
4993
4994 static void
4995   vl_api_classify_table_by_interface_reply_t_handler
4996   (vl_api_classify_table_by_interface_reply_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999   u32 table_id;
5000
5001   table_id = ntohl (mp->l2_table_id);
5002   if (table_id != ~0)
5003     print (vam->ofp, "l2 table id : %d", table_id);
5004   else
5005     print (vam->ofp, "l2 table id : No input ACL tables configured");
5006   table_id = ntohl (mp->ip4_table_id);
5007   if (table_id != ~0)
5008     print (vam->ofp, "ip4 table id : %d", table_id);
5009   else
5010     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5011   table_id = ntohl (mp->ip6_table_id);
5012   if (table_id != ~0)
5013     print (vam->ofp, "ip6 table id : %d", table_id);
5014   else
5015     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5016   vam->retval = ntohl (mp->retval);
5017   vam->result_ready = 1;
5018 }
5019
5020 static void
5021   vl_api_classify_table_by_interface_reply_t_handler_json
5022   (vl_api_classify_table_by_interface_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   vat_json_node_t node;
5026
5027   vat_json_init_object (&node);
5028
5029   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5030   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5031   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5032
5033   vat_json_print (vam->ofp, &node);
5034   vat_json_free (&node);
5035
5036   vam->retval = ntohl (mp->retval);
5037   vam->result_ready = 1;
5038 }
5039
5040 static void vl_api_policer_add_del_reply_t_handler
5041   (vl_api_policer_add_del_reply_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   i32 retval = ntohl (mp->retval);
5045   if (vam->async_mode)
5046     {
5047       vam->async_errors += (retval < 0);
5048     }
5049   else
5050     {
5051       vam->retval = retval;
5052       vam->result_ready = 1;
5053       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5054         /*
5055          * Note: this is just barely thread-safe, depends on
5056          * the main thread spinning waiting for an answer...
5057          */
5058         errmsg ("policer index %d", ntohl (mp->policer_index));
5059     }
5060 }
5061
5062 static void vl_api_policer_add_del_reply_t_handler_json
5063   (vl_api_policer_add_del_reply_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066   vat_json_node_t node;
5067
5068   vat_json_init_object (&node);
5069   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5070   vat_json_object_add_uint (&node, "policer_index",
5071                             ntohl (mp->policer_index));
5072
5073   vat_json_print (vam->ofp, &node);
5074   vat_json_free (&node);
5075
5076   vam->retval = ntohl (mp->retval);
5077   vam->result_ready = 1;
5078 }
5079
5080 /* Format hex dump. */
5081 u8 *
5082 format_hex_bytes (u8 * s, va_list * va)
5083 {
5084   u8 *bytes = va_arg (*va, u8 *);
5085   int n_bytes = va_arg (*va, int);
5086   uword i;
5087
5088   /* Print short or long form depending on byte count. */
5089   uword short_form = n_bytes <= 32;
5090   u32 indent = format_get_indent (s);
5091
5092   if (n_bytes == 0)
5093     return s;
5094
5095   for (i = 0; i < n_bytes; i++)
5096     {
5097       if (!short_form && (i % 32) == 0)
5098         s = format (s, "%08x: ", i);
5099       s = format (s, "%02x", bytes[i]);
5100       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5101         s = format (s, "\n%U", format_white_space, indent);
5102     }
5103
5104   return s;
5105 }
5106
5107 static void
5108 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5109                                             * mp)
5110 {
5111   vat_main_t *vam = &vat_main;
5112   i32 retval = ntohl (mp->retval);
5113   if (retval == 0)
5114     {
5115       print (vam->ofp, "classify table info :");
5116       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5117              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5118              ntohl (mp->miss_next_index));
5119       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5120              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5121              ntohl (mp->match_n_vectors));
5122       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5123              ntohl (mp->mask_length));
5124     }
5125   vam->retval = retval;
5126   vam->result_ready = 1;
5127 }
5128
5129 static void
5130   vl_api_classify_table_info_reply_t_handler_json
5131   (vl_api_classify_table_info_reply_t * mp)
5132 {
5133   vat_main_t *vam = &vat_main;
5134   vat_json_node_t node;
5135
5136   i32 retval = ntohl (mp->retval);
5137   if (retval == 0)
5138     {
5139       vat_json_init_object (&node);
5140
5141       vat_json_object_add_int (&node, "sessions",
5142                                ntohl (mp->active_sessions));
5143       vat_json_object_add_int (&node, "nexttbl",
5144                                ntohl (mp->next_table_index));
5145       vat_json_object_add_int (&node, "nextnode",
5146                                ntohl (mp->miss_next_index));
5147       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5148       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5149       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5150       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5151                       ntohl (mp->mask_length), 0);
5152       vat_json_object_add_string_copy (&node, "mask", s);
5153
5154       vat_json_print (vam->ofp, &node);
5155       vat_json_free (&node);
5156     }
5157   vam->retval = ntohl (mp->retval);
5158   vam->result_ready = 1;
5159 }
5160
5161 static void
5162 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5163                                            mp)
5164 {
5165   vat_main_t *vam = &vat_main;
5166
5167   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5168          ntohl (mp->hit_next_index), ntohl (mp->advance),
5169          ntohl (mp->opaque_index));
5170   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5171          ntohl (mp->match_length));
5172 }
5173
5174 static void
5175   vl_api_classify_session_details_t_handler_json
5176   (vl_api_classify_session_details_t * mp)
5177 {
5178   vat_main_t *vam = &vat_main;
5179   vat_json_node_t *node = NULL;
5180
5181   if (VAT_JSON_ARRAY != vam->json_tree.type)
5182     {
5183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5184       vat_json_init_array (&vam->json_tree);
5185     }
5186   node = vat_json_array_add (&vam->json_tree);
5187
5188   vat_json_init_object (node);
5189   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5190   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5191   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5192   u8 *s =
5193     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5194             0);
5195   vat_json_object_add_string_copy (node, "match", s);
5196 }
5197
5198 static void vl_api_pg_create_interface_reply_t_handler
5199   (vl_api_pg_create_interface_reply_t * mp)
5200 {
5201   vat_main_t *vam = &vat_main;
5202
5203   vam->retval = ntohl (mp->retval);
5204   vam->result_ready = 1;
5205 }
5206
5207 static void vl_api_pg_create_interface_reply_t_handler_json
5208   (vl_api_pg_create_interface_reply_t * mp)
5209 {
5210   vat_main_t *vam = &vat_main;
5211   vat_json_node_t node;
5212
5213   i32 retval = ntohl (mp->retval);
5214   if (retval == 0)
5215     {
5216       vat_json_init_object (&node);
5217
5218       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5219
5220       vat_json_print (vam->ofp, &node);
5221       vat_json_free (&node);
5222     }
5223   vam->retval = ntohl (mp->retval);
5224   vam->result_ready = 1;
5225 }
5226
5227 static void vl_api_policer_classify_details_t_handler
5228   (vl_api_policer_classify_details_t * mp)
5229 {
5230   vat_main_t *vam = &vat_main;
5231
5232   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5233          ntohl (mp->table_index));
5234 }
5235
5236 static void vl_api_policer_classify_details_t_handler_json
5237   (vl_api_policer_classify_details_t * mp)
5238 {
5239   vat_main_t *vam = &vat_main;
5240   vat_json_node_t *node;
5241
5242   if (VAT_JSON_ARRAY != vam->json_tree.type)
5243     {
5244       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5245       vat_json_init_array (&vam->json_tree);
5246     }
5247   node = vat_json_array_add (&vam->json_tree);
5248
5249   vat_json_init_object (node);
5250   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5251   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5252 }
5253
5254 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5255   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5256 {
5257   vat_main_t *vam = &vat_main;
5258   i32 retval = ntohl (mp->retval);
5259   if (vam->async_mode)
5260     {
5261       vam->async_errors += (retval < 0);
5262     }
5263   else
5264     {
5265       vam->retval = retval;
5266       vam->sw_if_index = ntohl (mp->sw_if_index);
5267       vam->result_ready = 1;
5268     }
5269   vam->regenerate_interface_table = 1;
5270 }
5271
5272 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5273   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5274 {
5275   vat_main_t *vam = &vat_main;
5276   vat_json_node_t node;
5277
5278   vat_json_init_object (&node);
5279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5280   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5281
5282   vat_json_print (vam->ofp, &node);
5283   vat_json_free (&node);
5284
5285   vam->retval = ntohl (mp->retval);
5286   vam->result_ready = 1;
5287 }
5288
5289 static void vl_api_flow_classify_details_t_handler
5290   (vl_api_flow_classify_details_t * mp)
5291 {
5292   vat_main_t *vam = &vat_main;
5293
5294   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5295          ntohl (mp->table_index));
5296 }
5297
5298 static void vl_api_flow_classify_details_t_handler_json
5299   (vl_api_flow_classify_details_t * mp)
5300 {
5301   vat_main_t *vam = &vat_main;
5302   vat_json_node_t *node;
5303
5304   if (VAT_JSON_ARRAY != vam->json_tree.type)
5305     {
5306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5307       vat_json_init_array (&vam->json_tree);
5308     }
5309   node = vat_json_array_add (&vam->json_tree);
5310
5311   vat_json_init_object (node);
5312   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5313   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5314 }
5315
5316 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5317 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5318 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5319 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5320 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5321 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5322 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5323 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5324 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5325 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5326 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5327 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5328 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5329 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5330 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5331 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5332 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5333 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5334 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5335 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5336 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5337 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5338
5339 /*
5340  * Generate boilerplate reply handlers, which
5341  * dig the return value out of the xxx_reply_t API message,
5342  * stick it into vam->retval, and set vam->result_ready
5343  *
5344  * Could also do this by pointing N message decode slots at
5345  * a single function, but that could break in subtle ways.
5346  */
5347
5348 #define foreach_standard_reply_retval_handler           \
5349 _(sw_interface_set_flags_reply)                         \
5350 _(sw_interface_add_del_address_reply)                   \
5351 _(sw_interface_set_rx_mode_reply)                       \
5352 _(sw_interface_set_table_reply)                         \
5353 _(sw_interface_set_mpls_enable_reply)                   \
5354 _(sw_interface_set_vpath_reply)                         \
5355 _(sw_interface_set_vxlan_bypass_reply)                  \
5356 _(sw_interface_set_geneve_bypass_reply)                 \
5357 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5358 _(sw_interface_set_l2_bridge_reply)                     \
5359 _(bridge_domain_add_del_reply)                          \
5360 _(sw_interface_set_l2_xconnect_reply)                   \
5361 _(l2fib_add_del_reply)                                  \
5362 _(l2fib_flush_int_reply)                                \
5363 _(l2fib_flush_bd_reply)                                 \
5364 _(ip_add_del_route_reply)                               \
5365 _(ip_table_add_del_reply)                               \
5366 _(ip_mroute_add_del_reply)                              \
5367 _(mpls_route_add_del_reply)                             \
5368 _(mpls_table_add_del_reply)                             \
5369 _(mpls_ip_bind_unbind_reply)                            \
5370 _(bier_route_add_del_reply)                             \
5371 _(bier_table_add_del_reply)                             \
5372 _(proxy_arp_add_del_reply)                              \
5373 _(proxy_arp_intfc_enable_disable_reply)                 \
5374 _(sw_interface_set_unnumbered_reply)                    \
5375 _(ip_neighbor_add_del_reply)                            \
5376 _(oam_add_del_reply)                                    \
5377 _(reset_fib_reply)                                      \
5378 _(dhcp_proxy_config_reply)                              \
5379 _(dhcp_proxy_set_vss_reply)                             \
5380 _(dhcp_client_config_reply)                             \
5381 _(set_ip_flow_hash_reply)                               \
5382 _(sw_interface_ip6_enable_disable_reply)                \
5383 _(sw_interface_ip6_set_link_local_address_reply)        \
5384 _(ip6nd_proxy_add_del_reply)                            \
5385 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5386 _(sw_interface_ip6nd_ra_config_reply)                   \
5387 _(set_arp_neighbor_limit_reply)                         \
5388 _(l2_patch_add_del_reply)                               \
5389 _(sr_policy_add_reply)                                  \
5390 _(sr_policy_mod_reply)                                  \
5391 _(sr_policy_del_reply)                                  \
5392 _(sr_localsid_add_del_reply)                            \
5393 _(sr_steering_add_del_reply)                            \
5394 _(classify_add_del_session_reply)                       \
5395 _(classify_set_interface_ip_table_reply)                \
5396 _(classify_set_interface_l2_tables_reply)               \
5397 _(l2tpv3_set_tunnel_cookies_reply)                      \
5398 _(l2tpv3_interface_enable_disable_reply)                \
5399 _(l2tpv3_set_lookup_key_reply)                          \
5400 _(l2_fib_clear_table_reply)                             \
5401 _(l2_interface_efp_filter_reply)                        \
5402 _(l2_interface_vlan_tag_rewrite_reply)                  \
5403 _(modify_vhost_user_if_reply)                           \
5404 _(delete_vhost_user_if_reply)                           \
5405 _(ip_probe_neighbor_reply)                              \
5406 _(ip_scan_neighbor_enable_disable_reply)                \
5407 _(want_ip4_arp_events_reply)                            \
5408 _(want_ip6_nd_events_reply)                             \
5409 _(want_l2_macs_events_reply)                            \
5410 _(input_acl_set_interface_reply)                        \
5411 _(ipsec_spd_add_del_reply)                              \
5412 _(ipsec_interface_add_del_spd_reply)                    \
5413 _(ipsec_spd_add_del_entry_reply)                        \
5414 _(ipsec_sad_add_del_entry_reply)                        \
5415 _(ipsec_sa_set_key_reply)                               \
5416 _(ipsec_tunnel_if_add_del_reply)                        \
5417 _(ipsec_tunnel_if_set_key_reply)                        \
5418 _(ipsec_tunnel_if_set_sa_reply)                         \
5419 _(ikev2_profile_add_del_reply)                          \
5420 _(ikev2_profile_set_auth_reply)                         \
5421 _(ikev2_profile_set_id_reply)                           \
5422 _(ikev2_profile_set_ts_reply)                           \
5423 _(ikev2_set_local_key_reply)                            \
5424 _(ikev2_set_responder_reply)                            \
5425 _(ikev2_set_ike_transforms_reply)                       \
5426 _(ikev2_set_esp_transforms_reply)                       \
5427 _(ikev2_set_sa_lifetime_reply)                          \
5428 _(ikev2_initiate_sa_init_reply)                         \
5429 _(ikev2_initiate_del_ike_sa_reply)                      \
5430 _(ikev2_initiate_del_child_sa_reply)                    \
5431 _(ikev2_initiate_rekey_child_sa_reply)                  \
5432 _(delete_loopback_reply)                                \
5433 _(bd_ip_mac_add_del_reply)                              \
5434 _(want_interface_events_reply)                          \
5435 _(want_stats_reply)                                     \
5436 _(cop_interface_enable_disable_reply)                   \
5437 _(cop_whitelist_enable_disable_reply)                   \
5438 _(sw_interface_clear_stats_reply)                       \
5439 _(ioam_enable_reply)                                    \
5440 _(ioam_disable_reply)                                   \
5441 _(one_add_del_locator_reply)                            \
5442 _(one_add_del_local_eid_reply)                          \
5443 _(one_add_del_remote_mapping_reply)                     \
5444 _(one_add_del_adjacency_reply)                          \
5445 _(one_add_del_map_resolver_reply)                       \
5446 _(one_add_del_map_server_reply)                         \
5447 _(one_enable_disable_reply)                             \
5448 _(one_rloc_probe_enable_disable_reply)                  \
5449 _(one_map_register_enable_disable_reply)                \
5450 _(one_map_register_set_ttl_reply)                       \
5451 _(one_set_transport_protocol_reply)                     \
5452 _(one_map_register_fallback_threshold_reply)            \
5453 _(one_pitr_set_locator_set_reply)                       \
5454 _(one_map_request_mode_reply)                           \
5455 _(one_add_del_map_request_itr_rlocs_reply)              \
5456 _(one_eid_table_add_del_map_reply)                      \
5457 _(one_use_petr_reply)                                   \
5458 _(one_stats_enable_disable_reply)                       \
5459 _(one_add_del_l2_arp_entry_reply)                       \
5460 _(one_add_del_ndp_entry_reply)                          \
5461 _(one_stats_flush_reply)                                \
5462 _(one_enable_disable_xtr_mode_reply)                    \
5463 _(one_enable_disable_pitr_mode_reply)                   \
5464 _(one_enable_disable_petr_mode_reply)                   \
5465 _(gpe_enable_disable_reply)                             \
5466 _(gpe_set_encap_mode_reply)                             \
5467 _(gpe_add_del_iface_reply)                              \
5468 _(gpe_add_del_native_fwd_rpath_reply)                   \
5469 _(af_packet_delete_reply)                               \
5470 _(policer_classify_set_interface_reply)                 \
5471 _(netmap_create_reply)                                  \
5472 _(netmap_delete_reply)                                  \
5473 _(set_ipfix_exporter_reply)                             \
5474 _(set_ipfix_classify_stream_reply)                      \
5475 _(ipfix_classify_table_add_del_reply)                   \
5476 _(flow_classify_set_interface_reply)                    \
5477 _(sw_interface_span_enable_disable_reply)               \
5478 _(pg_capture_reply)                                     \
5479 _(pg_enable_disable_reply)                              \
5480 _(ip_source_and_port_range_check_add_del_reply)         \
5481 _(ip_source_and_port_range_check_interface_add_del_reply)\
5482 _(delete_subif_reply)                                   \
5483 _(l2_interface_pbb_tag_rewrite_reply)                   \
5484 _(punt_reply)                                           \
5485 _(feature_enable_disable_reply)                         \
5486 _(sw_interface_tag_add_del_reply)                       \
5487 _(hw_interface_set_mtu_reply)                           \
5488 _(p2p_ethernet_add_reply)                               \
5489 _(p2p_ethernet_del_reply)                               \
5490 _(lldp_config_reply)                                    \
5491 _(sw_interface_set_lldp_reply)                          \
5492 _(tcp_configure_src_addresses_reply)                    \
5493 _(dns_enable_disable_reply)                             \
5494 _(dns_name_server_add_del_reply)                        \
5495 _(session_rule_add_del_reply)                           \
5496 _(ip_container_proxy_add_del_reply)                     \
5497 _(output_acl_set_interface_reply)                       \
5498 _(qos_record_enable_disable_reply)
5499
5500 #define _(n)                                    \
5501     static void vl_api_##n##_t_handler          \
5502     (vl_api_##n##_t * mp)                       \
5503     {                                           \
5504         vat_main_t * vam = &vat_main;           \
5505         i32 retval = ntohl(mp->retval);         \
5506         if (vam->async_mode) {                  \
5507             vam->async_errors += (retval < 0);  \
5508         } else {                                \
5509             vam->retval = retval;               \
5510             vam->result_ready = 1;              \
5511         }                                       \
5512     }
5513 foreach_standard_reply_retval_handler;
5514 #undef _
5515
5516 #define _(n)                                    \
5517     static void vl_api_##n##_t_handler_json     \
5518     (vl_api_##n##_t * mp)                       \
5519     {                                           \
5520         vat_main_t * vam = &vat_main;           \
5521         vat_json_node_t node;                   \
5522         vat_json_init_object(&node);            \
5523         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5524         vat_json_print(vam->ofp, &node);        \
5525         vam->retval = ntohl(mp->retval);        \
5526         vam->result_ready = 1;                  \
5527     }
5528 foreach_standard_reply_retval_handler;
5529 #undef _
5530
5531 /*
5532  * Table of message reply handlers, must include boilerplate handlers
5533  * we just generated
5534  */
5535
5536 #define foreach_vpe_api_reply_msg                                       \
5537 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5538 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5539 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5540 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5541 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5542 _(CLI_REPLY, cli_reply)                                                 \
5543 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5544 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5545   sw_interface_add_del_address_reply)                                   \
5546 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5547 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5548 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5549 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5550 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5551 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5552 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5553 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5554   sw_interface_set_l2_xconnect_reply)                                   \
5555 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5556   sw_interface_set_l2_bridge_reply)                                     \
5557 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5558 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5559 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5560 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5561 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5562 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5563 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5564 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5565 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5566 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5567 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5568 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5569 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5570 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5571 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5572 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5573 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5574 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5575 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5576 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5577 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5578 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5579 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5580 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5581 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5582 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5583 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5584 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5585 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5586 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5587 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5588   proxy_arp_intfc_enable_disable_reply)                                 \
5589 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5590 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5591   sw_interface_set_unnumbered_reply)                                    \
5592 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5593 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5594 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5595 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5596 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5597 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5598 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5599 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5600 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5601 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5602 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5603   sw_interface_ip6_enable_disable_reply)                                \
5604 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5605   sw_interface_ip6_set_link_local_address_reply)                        \
5606 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5607 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5608 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5609   sw_interface_ip6nd_ra_prefix_reply)                                   \
5610 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5611   sw_interface_ip6nd_ra_config_reply)                                   \
5612 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5613 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5614 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5615 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5616 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5617 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5618 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5619 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5620 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5621 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5622 classify_set_interface_ip_table_reply)                                  \
5623 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5624   classify_set_interface_l2_tables_reply)                               \
5625 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5626 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5627 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5628 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5629 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5630   l2tpv3_interface_enable_disable_reply)                                \
5631 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5632 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5633 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5634 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5635 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5636 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5637 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5638 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5639 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5640 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5641 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5642 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5643 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5644 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5645 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5646 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5647 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5648 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5649 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5650 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5651 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5652 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5653 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5654 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5655 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5656 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5657 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5658 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5659 _(L2_MACS_EVENT, l2_macs_event)                                         \
5660 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5661 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5662 _(IP_DETAILS, ip_details)                                               \
5663 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5664 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5665 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5666 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5667 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5668 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5669 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5670 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5671 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5672 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5673 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5674 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5675 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5676 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5677 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5678 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5679 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5680 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5681 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5682 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5683 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5684 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5685 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5686 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5687 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5688 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5689 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5690 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5691 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5692 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5693 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5694 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5695 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5696 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5697 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5698 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5699 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5700 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5701 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5702 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5703 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5704 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5705 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5706   one_map_register_enable_disable_reply)                                \
5707 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5708 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5709 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5710 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5711   one_map_register_fallback_threshold_reply)                            \
5712 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5713   one_rloc_probe_enable_disable_reply)                                  \
5714 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5715 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5716 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5717 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5718 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5719 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5720 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5721 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5722 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5723 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5724 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5725 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5726 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5727 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5728 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5729 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5730   show_one_stats_enable_disable_reply)                                  \
5731 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5732 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5733 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5734 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5735 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5736 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5737 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5738 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5739   one_enable_disable_pitr_mode_reply)                                   \
5740 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5741   one_enable_disable_petr_mode_reply)                                   \
5742 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5743 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5744 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5745 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5746 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5747 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5748 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5749 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5750 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5751 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5752 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5753 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5754   gpe_add_del_native_fwd_rpath_reply)                                   \
5755 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5756   gpe_fwd_entry_path_details)                                           \
5757 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5758 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5759   one_add_del_map_request_itr_rlocs_reply)                              \
5760 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5761   one_get_map_request_itr_rlocs_reply)                                  \
5762 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5763 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5764 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5765 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5766 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5767 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5768   show_one_map_register_state_reply)                                    \
5769 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5770 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5771   show_one_map_register_fallback_threshold_reply)                       \
5772 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5773 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5774 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5775 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5776 _(POLICER_DETAILS, policer_details)                                     \
5777 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5778 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5779 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5780 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5781 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5782 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5783 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5784 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5785 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5786 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5787 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5788 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5789 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5790 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5791 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5792 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5793 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5794 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5795 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5796 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5797 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5798 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5799 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5800 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5801 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5802  ip_source_and_port_range_check_add_del_reply)                          \
5803 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5804  ip_source_and_port_range_check_interface_add_del_reply)                \
5805 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5806 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5807 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5808 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5809 _(PUNT_REPLY, punt_reply)                                               \
5810 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5811 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5812 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5813 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5814 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5815 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5816 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5817 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5818 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5819 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5820 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5821 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5822 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5823 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5824 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5825 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5826 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5827 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5828 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5829 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5830 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5831 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5832 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5833
5834 #define foreach_standalone_reply_msg                                    \
5835 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5836 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5837 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5838 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5839 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5840 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5841 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5842
5843 typedef struct
5844 {
5845   u8 *name;
5846   u32 value;
5847 } name_sort_t;
5848
5849 #define STR_VTR_OP_CASE(op)     \
5850     case L2_VTR_ ## op:         \
5851         return "" # op;
5852
5853 static const char *
5854 str_vtr_op (u32 vtr_op)
5855 {
5856   switch (vtr_op)
5857     {
5858       STR_VTR_OP_CASE (DISABLED);
5859       STR_VTR_OP_CASE (PUSH_1);
5860       STR_VTR_OP_CASE (PUSH_2);
5861       STR_VTR_OP_CASE (POP_1);
5862       STR_VTR_OP_CASE (POP_2);
5863       STR_VTR_OP_CASE (TRANSLATE_1_1);
5864       STR_VTR_OP_CASE (TRANSLATE_1_2);
5865       STR_VTR_OP_CASE (TRANSLATE_2_1);
5866       STR_VTR_OP_CASE (TRANSLATE_2_2);
5867     }
5868
5869   return "UNKNOWN";
5870 }
5871
5872 static int
5873 dump_sub_interface_table (vat_main_t * vam)
5874 {
5875   const sw_interface_subif_t *sub = NULL;
5876
5877   if (vam->json_output)
5878     {
5879       clib_warning
5880         ("JSON output supported only for VPE API calls and dump_stats_table");
5881       return -99;
5882     }
5883
5884   print (vam->ofp,
5885          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5886          "Interface", "sw_if_index",
5887          "sub id", "dot1ad", "tags", "outer id",
5888          "inner id", "exact", "default", "outer any", "inner any");
5889
5890   vec_foreach (sub, vam->sw_if_subif_table)
5891   {
5892     print (vam->ofp,
5893            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5894            sub->interface_name,
5895            sub->sw_if_index,
5896            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5897            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5898            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5899            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5900     if (sub->vtr_op != L2_VTR_DISABLED)
5901       {
5902         print (vam->ofp,
5903                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5904                "tag1: %d tag2: %d ]",
5905                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5906                sub->vtr_tag1, sub->vtr_tag2);
5907       }
5908   }
5909
5910   return 0;
5911 }
5912
5913 static int
5914 name_sort_cmp (void *a1, void *a2)
5915 {
5916   name_sort_t *n1 = a1;
5917   name_sort_t *n2 = a2;
5918
5919   return strcmp ((char *) n1->name, (char *) n2->name);
5920 }
5921
5922 static int
5923 dump_interface_table (vat_main_t * vam)
5924 {
5925   hash_pair_t *p;
5926   name_sort_t *nses = 0, *ns;
5927
5928   if (vam->json_output)
5929     {
5930       clib_warning
5931         ("JSON output supported only for VPE API calls and dump_stats_table");
5932       return -99;
5933     }
5934
5935   /* *INDENT-OFF* */
5936   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5937   ({
5938     vec_add2 (nses, ns, 1);
5939     ns->name = (u8 *)(p->key);
5940     ns->value = (u32) p->value[0];
5941   }));
5942   /* *INDENT-ON* */
5943
5944   vec_sort_with_function (nses, name_sort_cmp);
5945
5946   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5947   vec_foreach (ns, nses)
5948   {
5949     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5950   }
5951   vec_free (nses);
5952   return 0;
5953 }
5954
5955 static int
5956 dump_ip_table (vat_main_t * vam, int is_ipv6)
5957 {
5958   const ip_details_t *det = NULL;
5959   const ip_address_details_t *address = NULL;
5960   u32 i = ~0;
5961
5962   print (vam->ofp, "%-12s", "sw_if_index");
5963
5964   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5965   {
5966     i++;
5967     if (!det->present)
5968       {
5969         continue;
5970       }
5971     print (vam->ofp, "%-12d", i);
5972     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5973     if (!det->addr)
5974       {
5975         continue;
5976       }
5977     vec_foreach (address, det->addr)
5978     {
5979       print (vam->ofp,
5980              "            %-30U%-13d",
5981              is_ipv6 ? format_ip6_address : format_ip4_address,
5982              address->ip, address->prefix_length);
5983     }
5984   }
5985
5986   return 0;
5987 }
5988
5989 static int
5990 dump_ipv4_table (vat_main_t * vam)
5991 {
5992   if (vam->json_output)
5993     {
5994       clib_warning
5995         ("JSON output supported only for VPE API calls and dump_stats_table");
5996       return -99;
5997     }
5998
5999   return dump_ip_table (vam, 0);
6000 }
6001
6002 static int
6003 dump_ipv6_table (vat_main_t * vam)
6004 {
6005   if (vam->json_output)
6006     {
6007       clib_warning
6008         ("JSON output supported only for VPE API calls and dump_stats_table");
6009       return -99;
6010     }
6011
6012   return dump_ip_table (vam, 1);
6013 }
6014
6015 static char *
6016 counter_type_to_str (u8 counter_type, u8 is_combined)
6017 {
6018   if (!is_combined)
6019     {
6020       switch (counter_type)
6021         {
6022         case VNET_INTERFACE_COUNTER_DROP:
6023           return "drop";
6024         case VNET_INTERFACE_COUNTER_PUNT:
6025           return "punt";
6026         case VNET_INTERFACE_COUNTER_IP4:
6027           return "ip4";
6028         case VNET_INTERFACE_COUNTER_IP6:
6029           return "ip6";
6030         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6031           return "rx-no-buf";
6032         case VNET_INTERFACE_COUNTER_RX_MISS:
6033           return "rx-miss";
6034         case VNET_INTERFACE_COUNTER_RX_ERROR:
6035           return "rx-error";
6036         case VNET_INTERFACE_COUNTER_TX_ERROR:
6037           return "tx-error";
6038         default:
6039           return "INVALID-COUNTER-TYPE";
6040         }
6041     }
6042   else
6043     {
6044       switch (counter_type)
6045         {
6046         case VNET_INTERFACE_COUNTER_RX:
6047           return "rx";
6048         case VNET_INTERFACE_COUNTER_TX:
6049           return "tx";
6050         default:
6051           return "INVALID-COUNTER-TYPE";
6052         }
6053     }
6054 }
6055
6056 static int
6057 dump_stats_table (vat_main_t * vam)
6058 {
6059   vat_json_node_t node;
6060   vat_json_node_t *msg_array;
6061   vat_json_node_t *msg;
6062   vat_json_node_t *counter_array;
6063   vat_json_node_t *counter;
6064   interface_counter_t c;
6065   u64 packets;
6066   ip4_fib_counter_t *c4;
6067   ip6_fib_counter_t *c6;
6068   ip4_nbr_counter_t *n4;
6069   ip6_nbr_counter_t *n6;
6070   int i, j;
6071
6072   if (!vam->json_output)
6073     {
6074       clib_warning ("dump_stats_table supported only in JSON format");
6075       return -99;
6076     }
6077
6078   vat_json_init_object (&node);
6079
6080   /* interface counters */
6081   msg_array = vat_json_object_add (&node, "interface_counters");
6082   vat_json_init_array (msg_array);
6083   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6084     {
6085       msg = vat_json_array_add (msg_array);
6086       vat_json_init_object (msg);
6087       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6088                                        (u8 *) counter_type_to_str (i, 0));
6089       vat_json_object_add_int (msg, "is_combined", 0);
6090       counter_array = vat_json_object_add (msg, "data");
6091       vat_json_init_array (counter_array);
6092       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6093         {
6094           packets = vam->simple_interface_counters[i][j];
6095           vat_json_array_add_uint (counter_array, packets);
6096         }
6097     }
6098   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6099     {
6100       msg = vat_json_array_add (msg_array);
6101       vat_json_init_object (msg);
6102       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6103                                        (u8 *) counter_type_to_str (i, 1));
6104       vat_json_object_add_int (msg, "is_combined", 1);
6105       counter_array = vat_json_object_add (msg, "data");
6106       vat_json_init_array (counter_array);
6107       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6108         {
6109           c = vam->combined_interface_counters[i][j];
6110           counter = vat_json_array_add (counter_array);
6111           vat_json_init_object (counter);
6112           vat_json_object_add_uint (counter, "packets", c.packets);
6113           vat_json_object_add_uint (counter, "bytes", c.bytes);
6114         }
6115     }
6116
6117   /* ip4 fib counters */
6118   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6119   vat_json_init_array (msg_array);
6120   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6121     {
6122       msg = vat_json_array_add (msg_array);
6123       vat_json_init_object (msg);
6124       vat_json_object_add_uint (msg, "vrf_id",
6125                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6126       counter_array = vat_json_object_add (msg, "c");
6127       vat_json_init_array (counter_array);
6128       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6129         {
6130           counter = vat_json_array_add (counter_array);
6131           vat_json_init_object (counter);
6132           c4 = &vam->ip4_fib_counters[i][j];
6133           vat_json_object_add_ip4 (counter, "address", c4->address);
6134           vat_json_object_add_uint (counter, "address_length",
6135                                     c4->address_length);
6136           vat_json_object_add_uint (counter, "packets", c4->packets);
6137           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6138         }
6139     }
6140
6141   /* ip6 fib counters */
6142   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6143   vat_json_init_array (msg_array);
6144   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6145     {
6146       msg = vat_json_array_add (msg_array);
6147       vat_json_init_object (msg);
6148       vat_json_object_add_uint (msg, "vrf_id",
6149                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6150       counter_array = vat_json_object_add (msg, "c");
6151       vat_json_init_array (counter_array);
6152       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6153         {
6154           counter = vat_json_array_add (counter_array);
6155           vat_json_init_object (counter);
6156           c6 = &vam->ip6_fib_counters[i][j];
6157           vat_json_object_add_ip6 (counter, "address", c6->address);
6158           vat_json_object_add_uint (counter, "address_length",
6159                                     c6->address_length);
6160           vat_json_object_add_uint (counter, "packets", c6->packets);
6161           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6162         }
6163     }
6164
6165   /* ip4 nbr counters */
6166   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6167   vat_json_init_array (msg_array);
6168   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6169     {
6170       msg = vat_json_array_add (msg_array);
6171       vat_json_init_object (msg);
6172       vat_json_object_add_uint (msg, "sw_if_index", i);
6173       counter_array = vat_json_object_add (msg, "c");
6174       vat_json_init_array (counter_array);
6175       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6176         {
6177           counter = vat_json_array_add (counter_array);
6178           vat_json_init_object (counter);
6179           n4 = &vam->ip4_nbr_counters[i][j];
6180           vat_json_object_add_ip4 (counter, "address", n4->address);
6181           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6182           vat_json_object_add_uint (counter, "packets", n4->packets);
6183           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6184         }
6185     }
6186
6187   /* ip6 nbr counters */
6188   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6189   vat_json_init_array (msg_array);
6190   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6191     {
6192       msg = vat_json_array_add (msg_array);
6193       vat_json_init_object (msg);
6194       vat_json_object_add_uint (msg, "sw_if_index", i);
6195       counter_array = vat_json_object_add (msg, "c");
6196       vat_json_init_array (counter_array);
6197       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6198         {
6199           counter = vat_json_array_add (counter_array);
6200           vat_json_init_object (counter);
6201           n6 = &vam->ip6_nbr_counters[i][j];
6202           vat_json_object_add_ip6 (counter, "address", n6->address);
6203           vat_json_object_add_uint (counter, "packets", n6->packets);
6204           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6205         }
6206     }
6207
6208   vat_json_print (vam->ofp, &node);
6209   vat_json_free (&node);
6210
6211   return 0;
6212 }
6213
6214 /*
6215  * Pass CLI buffers directly in the CLI_INBAND API message,
6216  * instead of an additional shared memory area.
6217  */
6218 static int
6219 exec_inband (vat_main_t * vam)
6220 {
6221   vl_api_cli_inband_t *mp;
6222   unformat_input_t *i = vam->input;
6223   int ret;
6224
6225   if (vec_len (i->buffer) == 0)
6226     return -1;
6227
6228   if (vam->exec_mode == 0 && unformat (i, "mode"))
6229     {
6230       vam->exec_mode = 1;
6231       return 0;
6232     }
6233   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6234     {
6235       vam->exec_mode = 0;
6236       return 0;
6237     }
6238
6239   /*
6240    * In order for the CLI command to work, it
6241    * must be a vector ending in \n, not a C-string ending
6242    * in \n\0.
6243    */
6244   u32 len = vec_len (vam->input->buffer);
6245   M2 (CLI_INBAND, mp, len);
6246   clib_memcpy (mp->cmd, vam->input->buffer, len);
6247   mp->length = htonl (len);
6248
6249   S (mp);
6250   W (ret);
6251   /* json responses may or may not include a useful reply... */
6252   if (vec_len (vam->cmd_reply))
6253     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6254   return ret;
6255 }
6256
6257 int
6258 exec (vat_main_t * vam)
6259 {
6260   return exec_inband (vam);
6261 }
6262
6263 static int
6264 api_create_loopback (vat_main_t * vam)
6265 {
6266   unformat_input_t *i = vam->input;
6267   vl_api_create_loopback_t *mp;
6268   vl_api_create_loopback_instance_t *mp_lbi;
6269   u8 mac_address[6];
6270   u8 mac_set = 0;
6271   u8 is_specified = 0;
6272   u32 user_instance = 0;
6273   int ret;
6274
6275   memset (mac_address, 0, sizeof (mac_address));
6276
6277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6278     {
6279       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6280         mac_set = 1;
6281       if (unformat (i, "instance %d", &user_instance))
6282         is_specified = 1;
6283       else
6284         break;
6285     }
6286
6287   if (is_specified)
6288     {
6289       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6290       mp_lbi->is_specified = is_specified;
6291       if (is_specified)
6292         mp_lbi->user_instance = htonl (user_instance);
6293       if (mac_set)
6294         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6295       S (mp_lbi);
6296     }
6297   else
6298     {
6299       /* Construct the API message */
6300       M (CREATE_LOOPBACK, mp);
6301       if (mac_set)
6302         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6303       S (mp);
6304     }
6305
6306   W (ret);
6307   return ret;
6308 }
6309
6310 static int
6311 api_delete_loopback (vat_main_t * vam)
6312 {
6313   unformat_input_t *i = vam->input;
6314   vl_api_delete_loopback_t *mp;
6315   u32 sw_if_index = ~0;
6316   int ret;
6317
6318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6319     {
6320       if (unformat (i, "sw_if_index %d", &sw_if_index))
6321         ;
6322       else
6323         break;
6324     }
6325
6326   if (sw_if_index == ~0)
6327     {
6328       errmsg ("missing sw_if_index");
6329       return -99;
6330     }
6331
6332   /* Construct the API message */
6333   M (DELETE_LOOPBACK, mp);
6334   mp->sw_if_index = ntohl (sw_if_index);
6335
6336   S (mp);
6337   W (ret);
6338   return ret;
6339 }
6340
6341 static int
6342 api_want_stats (vat_main_t * vam)
6343 {
6344   unformat_input_t *i = vam->input;
6345   vl_api_want_stats_t *mp;
6346   int enable = -1;
6347   int ret;
6348
6349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6350     {
6351       if (unformat (i, "enable"))
6352         enable = 1;
6353       else if (unformat (i, "disable"))
6354         enable = 0;
6355       else
6356         break;
6357     }
6358
6359   if (enable == -1)
6360     {
6361       errmsg ("missing enable|disable");
6362       return -99;
6363     }
6364
6365   M (WANT_STATS, mp);
6366   mp->enable_disable = enable;
6367
6368   S (mp);
6369   W (ret);
6370   return ret;
6371 }
6372
6373 static int
6374 api_want_interface_events (vat_main_t * vam)
6375 {
6376   unformat_input_t *i = vam->input;
6377   vl_api_want_interface_events_t *mp;
6378   int enable = -1;
6379   int ret;
6380
6381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6382     {
6383       if (unformat (i, "enable"))
6384         enable = 1;
6385       else if (unformat (i, "disable"))
6386         enable = 0;
6387       else
6388         break;
6389     }
6390
6391   if (enable == -1)
6392     {
6393       errmsg ("missing enable|disable");
6394       return -99;
6395     }
6396
6397   M (WANT_INTERFACE_EVENTS, mp);
6398   mp->enable_disable = enable;
6399
6400   vam->interface_event_display = enable;
6401
6402   S (mp);
6403   W (ret);
6404   return ret;
6405 }
6406
6407
6408 /* Note: non-static, called once to set up the initial intfc table */
6409 int
6410 api_sw_interface_dump (vat_main_t * vam)
6411 {
6412   vl_api_sw_interface_dump_t *mp;
6413   vl_api_control_ping_t *mp_ping;
6414   hash_pair_t *p;
6415   name_sort_t *nses = 0, *ns;
6416   sw_interface_subif_t *sub = NULL;
6417   int ret;
6418
6419   /* Toss the old name table */
6420   /* *INDENT-OFF* */
6421   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6422   ({
6423     vec_add2 (nses, ns, 1);
6424     ns->name = (u8 *)(p->key);
6425     ns->value = (u32) p->value[0];
6426   }));
6427   /* *INDENT-ON* */
6428
6429   hash_free (vam->sw_if_index_by_interface_name);
6430
6431   vec_foreach (ns, nses) vec_free (ns->name);
6432
6433   vec_free (nses);
6434
6435   vec_foreach (sub, vam->sw_if_subif_table)
6436   {
6437     vec_free (sub->interface_name);
6438   }
6439   vec_free (vam->sw_if_subif_table);
6440
6441   /* recreate the interface name hash table */
6442   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6443
6444   /*
6445    * Ask for all interface names. Otherwise, the epic catalog of
6446    * name filters becomes ridiculously long, and vat ends up needing
6447    * to be taught about new interface types.
6448    */
6449   M (SW_INTERFACE_DUMP, mp);
6450   S (mp);
6451
6452   /* Use a control ping for synchronization */
6453   MPING (CONTROL_PING, mp_ping);
6454   S (mp_ping);
6455
6456   W (ret);
6457   return ret;
6458 }
6459
6460 static int
6461 api_sw_interface_set_flags (vat_main_t * vam)
6462 {
6463   unformat_input_t *i = vam->input;
6464   vl_api_sw_interface_set_flags_t *mp;
6465   u32 sw_if_index;
6466   u8 sw_if_index_set = 0;
6467   u8 admin_up = 0;
6468   int ret;
6469
6470   /* Parse args required to build the message */
6471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6472     {
6473       if (unformat (i, "admin-up"))
6474         admin_up = 1;
6475       else if (unformat (i, "admin-down"))
6476         admin_up = 0;
6477       else
6478         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6479         sw_if_index_set = 1;
6480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6481         sw_if_index_set = 1;
6482       else
6483         break;
6484     }
6485
6486   if (sw_if_index_set == 0)
6487     {
6488       errmsg ("missing interface name or sw_if_index");
6489       return -99;
6490     }
6491
6492   /* Construct the API message */
6493   M (SW_INTERFACE_SET_FLAGS, mp);
6494   mp->sw_if_index = ntohl (sw_if_index);
6495   mp->admin_up_down = admin_up;
6496
6497   /* send it... */
6498   S (mp);
6499
6500   /* Wait for a reply, return the good/bad news... */
6501   W (ret);
6502   return ret;
6503 }
6504
6505 static int
6506 api_sw_interface_set_rx_mode (vat_main_t * vam)
6507 {
6508   unformat_input_t *i = vam->input;
6509   vl_api_sw_interface_set_rx_mode_t *mp;
6510   u32 sw_if_index;
6511   u8 sw_if_index_set = 0;
6512   int ret;
6513   u8 queue_id_valid = 0;
6514   u32 queue_id;
6515   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6516
6517   /* Parse args required to build the message */
6518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6519     {
6520       if (unformat (i, "queue %d", &queue_id))
6521         queue_id_valid = 1;
6522       else if (unformat (i, "polling"))
6523         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6524       else if (unformat (i, "interrupt"))
6525         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6526       else if (unformat (i, "adaptive"))
6527         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6528       else
6529         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6530         sw_if_index_set = 1;
6531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6532         sw_if_index_set = 1;
6533       else
6534         break;
6535     }
6536
6537   if (sw_if_index_set == 0)
6538     {
6539       errmsg ("missing interface name or sw_if_index");
6540       return -99;
6541     }
6542   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6543     {
6544       errmsg ("missing rx-mode");
6545       return -99;
6546     }
6547
6548   /* Construct the API message */
6549   M (SW_INTERFACE_SET_RX_MODE, mp);
6550   mp->sw_if_index = ntohl (sw_if_index);
6551   mp->mode = mode;
6552   mp->queue_id_valid = queue_id_valid;
6553   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6554
6555   /* send it... */
6556   S (mp);
6557
6558   /* Wait for a reply, return the good/bad news... */
6559   W (ret);
6560   return ret;
6561 }
6562
6563 static int
6564 api_sw_interface_clear_stats (vat_main_t * vam)
6565 {
6566   unformat_input_t *i = vam->input;
6567   vl_api_sw_interface_clear_stats_t *mp;
6568   u32 sw_if_index;
6569   u8 sw_if_index_set = 0;
6570   int ret;
6571
6572   /* Parse args required to build the message */
6573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6574     {
6575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6576         sw_if_index_set = 1;
6577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6578         sw_if_index_set = 1;
6579       else
6580         break;
6581     }
6582
6583   /* Construct the API message */
6584   M (SW_INTERFACE_CLEAR_STATS, mp);
6585
6586   if (sw_if_index_set == 1)
6587     mp->sw_if_index = ntohl (sw_if_index);
6588   else
6589     mp->sw_if_index = ~0;
6590
6591   /* send it... */
6592   S (mp);
6593
6594   /* Wait for a reply, return the good/bad news... */
6595   W (ret);
6596   return ret;
6597 }
6598
6599 static int
6600 api_sw_interface_add_del_address (vat_main_t * vam)
6601 {
6602   unformat_input_t *i = vam->input;
6603   vl_api_sw_interface_add_del_address_t *mp;
6604   u32 sw_if_index;
6605   u8 sw_if_index_set = 0;
6606   u8 is_add = 1, del_all = 0;
6607   u32 address_length = 0;
6608   u8 v4_address_set = 0;
6609   u8 v6_address_set = 0;
6610   ip4_address_t v4address;
6611   ip6_address_t v6address;
6612   int ret;
6613
6614   /* Parse args required to build the message */
6615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6616     {
6617       if (unformat (i, "del-all"))
6618         del_all = 1;
6619       else if (unformat (i, "del"))
6620         is_add = 0;
6621       else
6622         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6623         sw_if_index_set = 1;
6624       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6625         sw_if_index_set = 1;
6626       else if (unformat (i, "%U/%d",
6627                          unformat_ip4_address, &v4address, &address_length))
6628         v4_address_set = 1;
6629       else if (unformat (i, "%U/%d",
6630                          unformat_ip6_address, &v6address, &address_length))
6631         v6_address_set = 1;
6632       else
6633         break;
6634     }
6635
6636   if (sw_if_index_set == 0)
6637     {
6638       errmsg ("missing interface name or sw_if_index");
6639       return -99;
6640     }
6641   if (v4_address_set && v6_address_set)
6642     {
6643       errmsg ("both v4 and v6 addresses set");
6644       return -99;
6645     }
6646   if (!v4_address_set && !v6_address_set && !del_all)
6647     {
6648       errmsg ("no addresses set");
6649       return -99;
6650     }
6651
6652   /* Construct the API message */
6653   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6654
6655   mp->sw_if_index = ntohl (sw_if_index);
6656   mp->is_add = is_add;
6657   mp->del_all = del_all;
6658   if (v6_address_set)
6659     {
6660       mp->is_ipv6 = 1;
6661       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6662     }
6663   else
6664     {
6665       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6666     }
6667   mp->address_length = address_length;
6668
6669   /* send it... */
6670   S (mp);
6671
6672   /* Wait for a reply, return good/bad news  */
6673   W (ret);
6674   return ret;
6675 }
6676
6677 static int
6678 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6679 {
6680   unformat_input_t *i = vam->input;
6681   vl_api_sw_interface_set_mpls_enable_t *mp;
6682   u32 sw_if_index;
6683   u8 sw_if_index_set = 0;
6684   u8 enable = 1;
6685   int ret;
6686
6687   /* Parse args required to build the message */
6688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6689     {
6690       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6691         sw_if_index_set = 1;
6692       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6693         sw_if_index_set = 1;
6694       else if (unformat (i, "disable"))
6695         enable = 0;
6696       else if (unformat (i, "dis"))
6697         enable = 0;
6698       else
6699         break;
6700     }
6701
6702   if (sw_if_index_set == 0)
6703     {
6704       errmsg ("missing interface name or sw_if_index");
6705       return -99;
6706     }
6707
6708   /* Construct the API message */
6709   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6710
6711   mp->sw_if_index = ntohl (sw_if_index);
6712   mp->enable = enable;
6713
6714   /* send it... */
6715   S (mp);
6716
6717   /* Wait for a reply... */
6718   W (ret);
6719   return ret;
6720 }
6721
6722 static int
6723 api_sw_interface_set_table (vat_main_t * vam)
6724 {
6725   unformat_input_t *i = vam->input;
6726   vl_api_sw_interface_set_table_t *mp;
6727   u32 sw_if_index, vrf_id = 0;
6728   u8 sw_if_index_set = 0;
6729   u8 is_ipv6 = 0;
6730   int ret;
6731
6732   /* Parse args required to build the message */
6733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6734     {
6735       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6736         sw_if_index_set = 1;
6737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6738         sw_if_index_set = 1;
6739       else if (unformat (i, "vrf %d", &vrf_id))
6740         ;
6741       else if (unformat (i, "ipv6"))
6742         is_ipv6 = 1;
6743       else
6744         break;
6745     }
6746
6747   if (sw_if_index_set == 0)
6748     {
6749       errmsg ("missing interface name or sw_if_index");
6750       return -99;
6751     }
6752
6753   /* Construct the API message */
6754   M (SW_INTERFACE_SET_TABLE, mp);
6755
6756   mp->sw_if_index = ntohl (sw_if_index);
6757   mp->is_ipv6 = is_ipv6;
6758   mp->vrf_id = ntohl (vrf_id);
6759
6760   /* send it... */
6761   S (mp);
6762
6763   /* Wait for a reply... */
6764   W (ret);
6765   return ret;
6766 }
6767
6768 static void vl_api_sw_interface_get_table_reply_t_handler
6769   (vl_api_sw_interface_get_table_reply_t * mp)
6770 {
6771   vat_main_t *vam = &vat_main;
6772
6773   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6774
6775   vam->retval = ntohl (mp->retval);
6776   vam->result_ready = 1;
6777
6778 }
6779
6780 static void vl_api_sw_interface_get_table_reply_t_handler_json
6781   (vl_api_sw_interface_get_table_reply_t * mp)
6782 {
6783   vat_main_t *vam = &vat_main;
6784   vat_json_node_t node;
6785
6786   vat_json_init_object (&node);
6787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6788   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6789
6790   vat_json_print (vam->ofp, &node);
6791   vat_json_free (&node);
6792
6793   vam->retval = ntohl (mp->retval);
6794   vam->result_ready = 1;
6795 }
6796
6797 static int
6798 api_sw_interface_get_table (vat_main_t * vam)
6799 {
6800   unformat_input_t *i = vam->input;
6801   vl_api_sw_interface_get_table_t *mp;
6802   u32 sw_if_index;
6803   u8 sw_if_index_set = 0;
6804   u8 is_ipv6 = 0;
6805   int ret;
6806
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, "ipv6"))
6814         is_ipv6 = 1;
6815       else
6816         break;
6817     }
6818
6819   if (sw_if_index_set == 0)
6820     {
6821       errmsg ("missing interface name or sw_if_index");
6822       return -99;
6823     }
6824
6825   M (SW_INTERFACE_GET_TABLE, mp);
6826   mp->sw_if_index = htonl (sw_if_index);
6827   mp->is_ipv6 = is_ipv6;
6828
6829   S (mp);
6830   W (ret);
6831   return ret;
6832 }
6833
6834 static int
6835 api_sw_interface_set_vpath (vat_main_t * vam)
6836 {
6837   unformat_input_t *i = vam->input;
6838   vl_api_sw_interface_set_vpath_t *mp;
6839   u32 sw_if_index = 0;
6840   u8 sw_if_index_set = 0;
6841   u8 is_enable = 0;
6842   int ret;
6843
6844   /* Parse args required to build the message */
6845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6846     {
6847       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6848         sw_if_index_set = 1;
6849       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6850         sw_if_index_set = 1;
6851       else if (unformat (i, "enable"))
6852         is_enable = 1;
6853       else if (unformat (i, "disable"))
6854         is_enable = 0;
6855       else
6856         break;
6857     }
6858
6859   if (sw_if_index_set == 0)
6860     {
6861       errmsg ("missing interface name or sw_if_index");
6862       return -99;
6863     }
6864
6865   /* Construct the API message */
6866   M (SW_INTERFACE_SET_VPATH, mp);
6867
6868   mp->sw_if_index = ntohl (sw_if_index);
6869   mp->enable = is_enable;
6870
6871   /* send it... */
6872   S (mp);
6873
6874   /* Wait for a reply... */
6875   W (ret);
6876   return ret;
6877 }
6878
6879 static int
6880 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6881 {
6882   unformat_input_t *i = vam->input;
6883   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6884   u32 sw_if_index = 0;
6885   u8 sw_if_index_set = 0;
6886   u8 is_enable = 1;
6887   u8 is_ipv6 = 0;
6888   int ret;
6889
6890   /* Parse args required to build the message */
6891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6892     {
6893       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6894         sw_if_index_set = 1;
6895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6896         sw_if_index_set = 1;
6897       else if (unformat (i, "enable"))
6898         is_enable = 1;
6899       else if (unformat (i, "disable"))
6900         is_enable = 0;
6901       else if (unformat (i, "ip4"))
6902         is_ipv6 = 0;
6903       else if (unformat (i, "ip6"))
6904         is_ipv6 = 1;
6905       else
6906         break;
6907     }
6908
6909   if (sw_if_index_set == 0)
6910     {
6911       errmsg ("missing interface name or sw_if_index");
6912       return -99;
6913     }
6914
6915   /* Construct the API message */
6916   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6917
6918   mp->sw_if_index = ntohl (sw_if_index);
6919   mp->enable = is_enable;
6920   mp->is_ipv6 = is_ipv6;
6921
6922   /* send it... */
6923   S (mp);
6924
6925   /* Wait for a reply... */
6926   W (ret);
6927   return ret;
6928 }
6929
6930 static int
6931 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6932 {
6933   unformat_input_t *i = vam->input;
6934   vl_api_sw_interface_set_geneve_bypass_t *mp;
6935   u32 sw_if_index = 0;
6936   u8 sw_if_index_set = 0;
6937   u8 is_enable = 1;
6938   u8 is_ipv6 = 0;
6939   int ret;
6940
6941   /* Parse args required to build the message */
6942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6943     {
6944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6945         sw_if_index_set = 1;
6946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6947         sw_if_index_set = 1;
6948       else if (unformat (i, "enable"))
6949         is_enable = 1;
6950       else if (unformat (i, "disable"))
6951         is_enable = 0;
6952       else if (unformat (i, "ip4"))
6953         is_ipv6 = 0;
6954       else if (unformat (i, "ip6"))
6955         is_ipv6 = 1;
6956       else
6957         break;
6958     }
6959
6960   if (sw_if_index_set == 0)
6961     {
6962       errmsg ("missing interface name or sw_if_index");
6963       return -99;
6964     }
6965
6966   /* Construct the API message */
6967   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6968
6969   mp->sw_if_index = ntohl (sw_if_index);
6970   mp->enable = is_enable;
6971   mp->is_ipv6 = is_ipv6;
6972
6973   /* send it... */
6974   S (mp);
6975
6976   /* Wait for a reply... */
6977   W (ret);
6978   return ret;
6979 }
6980
6981 static int
6982 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6983 {
6984   unformat_input_t *i = vam->input;
6985   vl_api_sw_interface_set_l2_xconnect_t *mp;
6986   u32 rx_sw_if_index;
6987   u8 rx_sw_if_index_set = 0;
6988   u32 tx_sw_if_index;
6989   u8 tx_sw_if_index_set = 0;
6990   u8 enable = 1;
6991   int ret;
6992
6993   /* Parse args required to build the message */
6994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6995     {
6996       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6997         rx_sw_if_index_set = 1;
6998       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6999         tx_sw_if_index_set = 1;
7000       else if (unformat (i, "rx"))
7001         {
7002           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7003             {
7004               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7005                             &rx_sw_if_index))
7006                 rx_sw_if_index_set = 1;
7007             }
7008           else
7009             break;
7010         }
7011       else if (unformat (i, "tx"))
7012         {
7013           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7014             {
7015               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7016                             &tx_sw_if_index))
7017                 tx_sw_if_index_set = 1;
7018             }
7019           else
7020             break;
7021         }
7022       else if (unformat (i, "enable"))
7023         enable = 1;
7024       else if (unformat (i, "disable"))
7025         enable = 0;
7026       else
7027         break;
7028     }
7029
7030   if (rx_sw_if_index_set == 0)
7031     {
7032       errmsg ("missing rx interface name or rx_sw_if_index");
7033       return -99;
7034     }
7035
7036   if (enable && (tx_sw_if_index_set == 0))
7037     {
7038       errmsg ("missing tx interface name or tx_sw_if_index");
7039       return -99;
7040     }
7041
7042   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7043
7044   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7045   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7046   mp->enable = enable;
7047
7048   S (mp);
7049   W (ret);
7050   return ret;
7051 }
7052
7053 static int
7054 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7055 {
7056   unformat_input_t *i = vam->input;
7057   vl_api_sw_interface_set_l2_bridge_t *mp;
7058   u32 rx_sw_if_index;
7059   u8 rx_sw_if_index_set = 0;
7060   u32 bd_id;
7061   u8 bd_id_set = 0;
7062   u8 bvi = 0;
7063   u32 shg = 0;
7064   u8 enable = 1;
7065   int ret;
7066
7067   /* Parse args required to build the message */
7068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7069     {
7070       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7071         rx_sw_if_index_set = 1;
7072       else if (unformat (i, "bd_id %d", &bd_id))
7073         bd_id_set = 1;
7074       else
7075         if (unformat
7076             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7077         rx_sw_if_index_set = 1;
7078       else if (unformat (i, "shg %d", &shg))
7079         ;
7080       else if (unformat (i, "bvi"))
7081         bvi = 1;
7082       else if (unformat (i, "enable"))
7083         enable = 1;
7084       else if (unformat (i, "disable"))
7085         enable = 0;
7086       else
7087         break;
7088     }
7089
7090   if (rx_sw_if_index_set == 0)
7091     {
7092       errmsg ("missing rx interface name or sw_if_index");
7093       return -99;
7094     }
7095
7096   if (enable && (bd_id_set == 0))
7097     {
7098       errmsg ("missing bridge domain");
7099       return -99;
7100     }
7101
7102   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7103
7104   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7105   mp->bd_id = ntohl (bd_id);
7106   mp->shg = (u8) shg;
7107   mp->bvi = bvi;
7108   mp->enable = enable;
7109
7110   S (mp);
7111   W (ret);
7112   return ret;
7113 }
7114
7115 static int
7116 api_bridge_domain_dump (vat_main_t * vam)
7117 {
7118   unformat_input_t *i = vam->input;
7119   vl_api_bridge_domain_dump_t *mp;
7120   vl_api_control_ping_t *mp_ping;
7121   u32 bd_id = ~0;
7122   int ret;
7123
7124   /* Parse args required to build the message */
7125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7126     {
7127       if (unformat (i, "bd_id %d", &bd_id))
7128         ;
7129       else
7130         break;
7131     }
7132
7133   M (BRIDGE_DOMAIN_DUMP, mp);
7134   mp->bd_id = ntohl (bd_id);
7135   S (mp);
7136
7137   /* Use a control ping for synchronization */
7138   MPING (CONTROL_PING, mp_ping);
7139   S (mp_ping);
7140
7141   W (ret);
7142   return ret;
7143 }
7144
7145 static int
7146 api_bridge_domain_add_del (vat_main_t * vam)
7147 {
7148   unformat_input_t *i = vam->input;
7149   vl_api_bridge_domain_add_del_t *mp;
7150   u32 bd_id = ~0;
7151   u8 is_add = 1;
7152   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7153   u8 *bd_tag = NULL;
7154   u32 mac_age = 0;
7155   int ret;
7156
7157   /* Parse args required to build the message */
7158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7159     {
7160       if (unformat (i, "bd_id %d", &bd_id))
7161         ;
7162       else if (unformat (i, "flood %d", &flood))
7163         ;
7164       else if (unformat (i, "uu-flood %d", &uu_flood))
7165         ;
7166       else if (unformat (i, "forward %d", &forward))
7167         ;
7168       else if (unformat (i, "learn %d", &learn))
7169         ;
7170       else if (unformat (i, "arp-term %d", &arp_term))
7171         ;
7172       else if (unformat (i, "mac-age %d", &mac_age))
7173         ;
7174       else if (unformat (i, "bd-tag %s", &bd_tag))
7175         ;
7176       else if (unformat (i, "del"))
7177         {
7178           is_add = 0;
7179           flood = uu_flood = forward = learn = 0;
7180         }
7181       else
7182         break;
7183     }
7184
7185   if (bd_id == ~0)
7186     {
7187       errmsg ("missing bridge domain");
7188       ret = -99;
7189       goto done;
7190     }
7191
7192   if (mac_age > 255)
7193     {
7194       errmsg ("mac age must be less than 256 ");
7195       ret = -99;
7196       goto done;
7197     }
7198
7199   if ((bd_tag) && (vec_len (bd_tag) > 63))
7200     {
7201       errmsg ("bd-tag cannot be longer than 63");
7202       ret = -99;
7203       goto done;
7204     }
7205
7206   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7207
7208   mp->bd_id = ntohl (bd_id);
7209   mp->flood = flood;
7210   mp->uu_flood = uu_flood;
7211   mp->forward = forward;
7212   mp->learn = learn;
7213   mp->arp_term = arp_term;
7214   mp->is_add = is_add;
7215   mp->mac_age = (u8) mac_age;
7216   if (bd_tag)
7217     {
7218       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7219       mp->bd_tag[vec_len (bd_tag)] = 0;
7220     }
7221   S (mp);
7222   W (ret);
7223
7224 done:
7225   vec_free (bd_tag);
7226   return ret;
7227 }
7228
7229 static int
7230 api_l2fib_flush_bd (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_l2fib_flush_bd_t *mp;
7234   u32 bd_id = ~0;
7235   int ret;
7236
7237   /* Parse args required to build the message */
7238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7239     {
7240       if (unformat (i, "bd_id %d", &bd_id));
7241       else
7242         break;
7243     }
7244
7245   if (bd_id == ~0)
7246     {
7247       errmsg ("missing bridge domain");
7248       return -99;
7249     }
7250
7251   M (L2FIB_FLUSH_BD, mp);
7252
7253   mp->bd_id = htonl (bd_id);
7254
7255   S (mp);
7256   W (ret);
7257   return ret;
7258 }
7259
7260 static int
7261 api_l2fib_flush_int (vat_main_t * vam)
7262 {
7263   unformat_input_t *i = vam->input;
7264   vl_api_l2fib_flush_int_t *mp;
7265   u32 sw_if_index = ~0;
7266   int ret;
7267
7268   /* Parse args required to build the message */
7269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7270     {
7271       if (unformat (i, "sw_if_index %d", &sw_if_index));
7272       else
7273         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7274       else
7275         break;
7276     }
7277
7278   if (sw_if_index == ~0)
7279     {
7280       errmsg ("missing interface name or sw_if_index");
7281       return -99;
7282     }
7283
7284   M (L2FIB_FLUSH_INT, mp);
7285
7286   mp->sw_if_index = ntohl (sw_if_index);
7287
7288   S (mp);
7289   W (ret);
7290   return ret;
7291 }
7292
7293 static int
7294 api_l2fib_add_del (vat_main_t * vam)
7295 {
7296   unformat_input_t *i = vam->input;
7297   vl_api_l2fib_add_del_t *mp;
7298   f64 timeout;
7299   u8 mac[6] = { 0 };
7300   u8 mac_set = 0;
7301   u32 bd_id;
7302   u8 bd_id_set = 0;
7303   u32 sw_if_index = 0;
7304   u8 sw_if_index_set = 0;
7305   u8 is_add = 1;
7306   u8 static_mac = 0;
7307   u8 filter_mac = 0;
7308   u8 bvi_mac = 0;
7309   int count = 1;
7310   f64 before = 0;
7311   int j;
7312
7313   /* Parse args required to build the message */
7314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7315     {
7316       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7317         mac_set = 1;
7318       else if (unformat (i, "bd_id %d", &bd_id))
7319         bd_id_set = 1;
7320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7321         sw_if_index_set = 1;
7322       else if (unformat (i, "sw_if"))
7323         {
7324           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7325             {
7326               if (unformat
7327                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7328                 sw_if_index_set = 1;
7329             }
7330           else
7331             break;
7332         }
7333       else if (unformat (i, "static"))
7334         static_mac = 1;
7335       else if (unformat (i, "filter"))
7336         {
7337           filter_mac = 1;
7338           static_mac = 1;
7339         }
7340       else if (unformat (i, "bvi"))
7341         {
7342           bvi_mac = 1;
7343           static_mac = 1;
7344         }
7345       else if (unformat (i, "del"))
7346         is_add = 0;
7347       else if (unformat (i, "count %d", &count))
7348         ;
7349       else
7350         break;
7351     }
7352
7353   if (mac_set == 0)
7354     {
7355       errmsg ("missing mac address");
7356       return -99;
7357     }
7358
7359   if (bd_id_set == 0)
7360     {
7361       errmsg ("missing bridge domain");
7362       return -99;
7363     }
7364
7365   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7366     {
7367       errmsg ("missing interface name or sw_if_index");
7368       return -99;
7369     }
7370
7371   if (count > 1)
7372     {
7373       /* Turn on async mode */
7374       vam->async_mode = 1;
7375       vam->async_errors = 0;
7376       before = vat_time_now (vam);
7377     }
7378
7379   for (j = 0; j < count; j++)
7380     {
7381       M (L2FIB_ADD_DEL, mp);
7382
7383       clib_memcpy (mp->mac, mac, 6);
7384       mp->bd_id = ntohl (bd_id);
7385       mp->is_add = is_add;
7386       mp->sw_if_index = ntohl (sw_if_index);
7387
7388       if (is_add)
7389         {
7390           mp->static_mac = static_mac;
7391           mp->filter_mac = filter_mac;
7392           mp->bvi_mac = bvi_mac;
7393         }
7394       increment_mac_address (mac);
7395       /* send it... */
7396       S (mp);
7397     }
7398
7399   if (count > 1)
7400     {
7401       vl_api_control_ping_t *mp_ping;
7402       f64 after;
7403
7404       /* Shut off async mode */
7405       vam->async_mode = 0;
7406
7407       MPING (CONTROL_PING, mp_ping);
7408       S (mp_ping);
7409
7410       timeout = vat_time_now (vam) + 1.0;
7411       while (vat_time_now (vam) < timeout)
7412         if (vam->result_ready == 1)
7413           goto out;
7414       vam->retval = -99;
7415
7416     out:
7417       if (vam->retval == -99)
7418         errmsg ("timeout");
7419
7420       if (vam->async_errors > 0)
7421         {
7422           errmsg ("%d asynchronous errors", vam->async_errors);
7423           vam->retval = -98;
7424         }
7425       vam->async_errors = 0;
7426       after = vat_time_now (vam);
7427
7428       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7429              count, after - before, count / (after - before));
7430     }
7431   else
7432     {
7433       int ret;
7434
7435       /* Wait for a reply... */
7436       W (ret);
7437       return ret;
7438     }
7439   /* Return the good/bad news */
7440   return (vam->retval);
7441 }
7442
7443 static int
7444 api_bridge_domain_set_mac_age (vat_main_t * vam)
7445 {
7446   unformat_input_t *i = vam->input;
7447   vl_api_bridge_domain_set_mac_age_t *mp;
7448   u32 bd_id = ~0;
7449   u32 mac_age = 0;
7450   int ret;
7451
7452   /* Parse args required to build the message */
7453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7454     {
7455       if (unformat (i, "bd_id %d", &bd_id));
7456       else if (unformat (i, "mac-age %d", &mac_age));
7457       else
7458         break;
7459     }
7460
7461   if (bd_id == ~0)
7462     {
7463       errmsg ("missing bridge domain");
7464       return -99;
7465     }
7466
7467   if (mac_age > 255)
7468     {
7469       errmsg ("mac age must be less than 256 ");
7470       return -99;
7471     }
7472
7473   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7474
7475   mp->bd_id = htonl (bd_id);
7476   mp->mac_age = (u8) mac_age;
7477
7478   S (mp);
7479   W (ret);
7480   return ret;
7481 }
7482
7483 static int
7484 api_l2_flags (vat_main_t * vam)
7485 {
7486   unformat_input_t *i = vam->input;
7487   vl_api_l2_flags_t *mp;
7488   u32 sw_if_index;
7489   u32 flags = 0;
7490   u8 sw_if_index_set = 0;
7491   u8 is_set = 0;
7492   int ret;
7493
7494   /* Parse args required to build the message */
7495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7496     {
7497       if (unformat (i, "sw_if_index %d", &sw_if_index))
7498         sw_if_index_set = 1;
7499       else if (unformat (i, "sw_if"))
7500         {
7501           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7502             {
7503               if (unformat
7504                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7505                 sw_if_index_set = 1;
7506             }
7507           else
7508             break;
7509         }
7510       else if (unformat (i, "learn"))
7511         flags |= L2_LEARN;
7512       else if (unformat (i, "forward"))
7513         flags |= L2_FWD;
7514       else if (unformat (i, "flood"))
7515         flags |= L2_FLOOD;
7516       else if (unformat (i, "uu-flood"))
7517         flags |= L2_UU_FLOOD;
7518       else if (unformat (i, "arp-term"))
7519         flags |= L2_ARP_TERM;
7520       else if (unformat (i, "off"))
7521         is_set = 0;
7522       else if (unformat (i, "disable"))
7523         is_set = 0;
7524       else
7525         break;
7526     }
7527
7528   if (sw_if_index_set == 0)
7529     {
7530       errmsg ("missing interface name or sw_if_index");
7531       return -99;
7532     }
7533
7534   M (L2_FLAGS, mp);
7535
7536   mp->sw_if_index = ntohl (sw_if_index);
7537   mp->feature_bitmap = ntohl (flags);
7538   mp->is_set = is_set;
7539
7540   S (mp);
7541   W (ret);
7542   return ret;
7543 }
7544
7545 static int
7546 api_bridge_flags (vat_main_t * vam)
7547 {
7548   unformat_input_t *i = vam->input;
7549   vl_api_bridge_flags_t *mp;
7550   u32 bd_id;
7551   u8 bd_id_set = 0;
7552   u8 is_set = 1;
7553   u32 flags = 0;
7554   int ret;
7555
7556   /* Parse args required to build the message */
7557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7558     {
7559       if (unformat (i, "bd_id %d", &bd_id))
7560         bd_id_set = 1;
7561       else if (unformat (i, "learn"))
7562         flags |= L2_LEARN;
7563       else if (unformat (i, "forward"))
7564         flags |= L2_FWD;
7565       else if (unformat (i, "flood"))
7566         flags |= L2_FLOOD;
7567       else if (unformat (i, "uu-flood"))
7568         flags |= L2_UU_FLOOD;
7569       else if (unformat (i, "arp-term"))
7570         flags |= L2_ARP_TERM;
7571       else if (unformat (i, "off"))
7572         is_set = 0;
7573       else if (unformat (i, "disable"))
7574         is_set = 0;
7575       else
7576         break;
7577     }
7578
7579   if (bd_id_set == 0)
7580     {
7581       errmsg ("missing bridge domain");
7582       return -99;
7583     }
7584
7585   M (BRIDGE_FLAGS, mp);
7586
7587   mp->bd_id = ntohl (bd_id);
7588   mp->feature_bitmap = ntohl (flags);
7589   mp->is_set = is_set;
7590
7591   S (mp);
7592   W (ret);
7593   return ret;
7594 }
7595
7596 static int
7597 api_bd_ip_mac_add_del (vat_main_t * vam)
7598 {
7599   unformat_input_t *i = vam->input;
7600   vl_api_bd_ip_mac_add_del_t *mp;
7601   u32 bd_id;
7602   u8 is_ipv6 = 0;
7603   u8 is_add = 1;
7604   u8 bd_id_set = 0;
7605   u8 ip_set = 0;
7606   u8 mac_set = 0;
7607   ip4_address_t v4addr;
7608   ip6_address_t v6addr;
7609   u8 macaddr[6];
7610   int ret;
7611
7612
7613   /* Parse args required to build the message */
7614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7615     {
7616       if (unformat (i, "bd_id %d", &bd_id))
7617         {
7618           bd_id_set++;
7619         }
7620       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7621         {
7622           ip_set++;
7623         }
7624       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7625         {
7626           ip_set++;
7627           is_ipv6++;
7628         }
7629       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7630         {
7631           mac_set++;
7632         }
7633       else if (unformat (i, "del"))
7634         is_add = 0;
7635       else
7636         break;
7637     }
7638
7639   if (bd_id_set == 0)
7640     {
7641       errmsg ("missing bridge domain");
7642       return -99;
7643     }
7644   else if (ip_set == 0)
7645     {
7646       errmsg ("missing IP address");
7647       return -99;
7648     }
7649   else if (mac_set == 0)
7650     {
7651       errmsg ("missing MAC address");
7652       return -99;
7653     }
7654
7655   M (BD_IP_MAC_ADD_DEL, mp);
7656
7657   mp->bd_id = ntohl (bd_id);
7658   mp->is_ipv6 = is_ipv6;
7659   mp->is_add = is_add;
7660   if (is_ipv6)
7661     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7662   else
7663     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7664   clib_memcpy (mp->mac_address, macaddr, 6);
7665   S (mp);
7666   W (ret);
7667   return ret;
7668 }
7669
7670 static int
7671 api_tap_connect (vat_main_t * vam)
7672 {
7673   unformat_input_t *i = vam->input;
7674   vl_api_tap_connect_t *mp;
7675   u8 mac_address[6];
7676   u8 random_mac = 1;
7677   u8 name_set = 0;
7678   u8 *tap_name;
7679   u8 *tag = 0;
7680   ip4_address_t ip4_address;
7681   u32 ip4_mask_width;
7682   int ip4_address_set = 0;
7683   ip6_address_t ip6_address;
7684   u32 ip6_mask_width;
7685   int ip6_address_set = 0;
7686   int ret;
7687
7688   memset (mac_address, 0, sizeof (mac_address));
7689
7690   /* Parse args required to build the message */
7691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7692     {
7693       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7694         {
7695           random_mac = 0;
7696         }
7697       else if (unformat (i, "random-mac"))
7698         random_mac = 1;
7699       else if (unformat (i, "tapname %s", &tap_name))
7700         name_set = 1;
7701       else if (unformat (i, "tag %s", &tag))
7702         ;
7703       else if (unformat (i, "address %U/%d",
7704                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7705         ip4_address_set = 1;
7706       else if (unformat (i, "address %U/%d",
7707                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7708         ip6_address_set = 1;
7709       else
7710         break;
7711     }
7712
7713   if (name_set == 0)
7714     {
7715       errmsg ("missing tap name");
7716       return -99;
7717     }
7718   if (vec_len (tap_name) > 63)
7719     {
7720       errmsg ("tap name too long");
7721       return -99;
7722     }
7723   vec_add1 (tap_name, 0);
7724
7725   if (vec_len (tag) > 63)
7726     {
7727       errmsg ("tag too long");
7728       return -99;
7729     }
7730
7731   /* Construct the API message */
7732   M (TAP_CONNECT, mp);
7733
7734   mp->use_random_mac = random_mac;
7735   clib_memcpy (mp->mac_address, mac_address, 6);
7736   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7737   if (tag)
7738     clib_memcpy (mp->tag, tag, vec_len (tag));
7739
7740   if (ip4_address_set)
7741     {
7742       mp->ip4_address_set = 1;
7743       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7744       mp->ip4_mask_width = ip4_mask_width;
7745     }
7746   if (ip6_address_set)
7747     {
7748       mp->ip6_address_set = 1;
7749       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7750       mp->ip6_mask_width = ip6_mask_width;
7751     }
7752
7753   vec_free (tap_name);
7754   vec_free (tag);
7755
7756   /* send it... */
7757   S (mp);
7758
7759   /* Wait for a reply... */
7760   W (ret);
7761   return ret;
7762 }
7763
7764 static int
7765 api_tap_modify (vat_main_t * vam)
7766 {
7767   unformat_input_t *i = vam->input;
7768   vl_api_tap_modify_t *mp;
7769   u8 mac_address[6];
7770   u8 random_mac = 1;
7771   u8 name_set = 0;
7772   u8 *tap_name;
7773   u32 sw_if_index = ~0;
7774   u8 sw_if_index_set = 0;
7775   int ret;
7776
7777   memset (mac_address, 0, sizeof (mac_address));
7778
7779   /* Parse args required to build the message */
7780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7781     {
7782       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7783         sw_if_index_set = 1;
7784       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7785         sw_if_index_set = 1;
7786       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7787         {
7788           random_mac = 0;
7789         }
7790       else if (unformat (i, "random-mac"))
7791         random_mac = 1;
7792       else if (unformat (i, "tapname %s", &tap_name))
7793         name_set = 1;
7794       else
7795         break;
7796     }
7797
7798   if (sw_if_index_set == 0)
7799     {
7800       errmsg ("missing vpp interface name");
7801       return -99;
7802     }
7803   if (name_set == 0)
7804     {
7805       errmsg ("missing tap name");
7806       return -99;
7807     }
7808   if (vec_len (tap_name) > 63)
7809     {
7810       errmsg ("tap name too long");
7811     }
7812   vec_add1 (tap_name, 0);
7813
7814   /* Construct the API message */
7815   M (TAP_MODIFY, mp);
7816
7817   mp->use_random_mac = random_mac;
7818   mp->sw_if_index = ntohl (sw_if_index);
7819   clib_memcpy (mp->mac_address, mac_address, 6);
7820   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7821   vec_free (tap_name);
7822
7823   /* send it... */
7824   S (mp);
7825
7826   /* Wait for a reply... */
7827   W (ret);
7828   return ret;
7829 }
7830
7831 static int
7832 api_tap_delete (vat_main_t * vam)
7833 {
7834   unformat_input_t *i = vam->input;
7835   vl_api_tap_delete_t *mp;
7836   u32 sw_if_index = ~0;
7837   u8 sw_if_index_set = 0;
7838   int ret;
7839
7840   /* Parse args required to build the message */
7841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7842     {
7843       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7844         sw_if_index_set = 1;
7845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7846         sw_if_index_set = 1;
7847       else
7848         break;
7849     }
7850
7851   if (sw_if_index_set == 0)
7852     {
7853       errmsg ("missing vpp interface name");
7854       return -99;
7855     }
7856
7857   /* Construct the API message */
7858   M (TAP_DELETE, mp);
7859
7860   mp->sw_if_index = ntohl (sw_if_index);
7861
7862   /* send it... */
7863   S (mp);
7864
7865   /* Wait for a reply... */
7866   W (ret);
7867   return ret;
7868 }
7869
7870 static int
7871 api_tap_create_v2 (vat_main_t * vam)
7872 {
7873   unformat_input_t *i = vam->input;
7874   vl_api_tap_create_v2_t *mp;
7875   u8 mac_address[6];
7876   u8 random_mac = 1;
7877   u32 id = ~0;
7878   u8 *host_if_name = 0;
7879   u8 *host_ns = 0;
7880   u8 host_mac_addr[6];
7881   u8 host_mac_addr_set = 0;
7882   u8 *host_bridge = 0;
7883   ip4_address_t host_ip4_addr;
7884   ip4_address_t host_ip4_gw;
7885   u8 host_ip4_gw_set = 0;
7886   u32 host_ip4_prefix_len = 0;
7887   ip6_address_t host_ip6_addr;
7888   ip6_address_t host_ip6_gw;
7889   u8 host_ip6_gw_set = 0;
7890   u32 host_ip6_prefix_len = 0;
7891   int ret;
7892   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7893
7894   memset (mac_address, 0, sizeof (mac_address));
7895
7896   /* Parse args required to build the message */
7897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7898     {
7899       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7900         {
7901           random_mac = 0;
7902         }
7903       else if (unformat (i, "id %u", &id))
7904         ;
7905       else if (unformat (i, "host-if-name %s", &host_if_name))
7906         ;
7907       else if (unformat (i, "host-ns %s", &host_ns))
7908         ;
7909       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7910                          host_mac_addr))
7911         host_mac_addr_set = 1;
7912       else if (unformat (i, "host-bridge %s", &host_bridge))
7913         ;
7914       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7915                          &host_ip4_addr, &host_ip4_prefix_len))
7916         ;
7917       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7918                          &host_ip6_addr, &host_ip6_prefix_len))
7919         ;
7920       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7921                          &host_ip4_gw))
7922         host_ip4_gw_set = 1;
7923       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7924                          &host_ip6_gw))
7925         host_ip6_gw_set = 1;
7926       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7927         ;
7928       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7929         ;
7930       else
7931         break;
7932     }
7933
7934   if (vec_len (host_if_name) > 63)
7935     {
7936       errmsg ("tap name too long. ");
7937       return -99;
7938     }
7939   if (vec_len (host_ns) > 63)
7940     {
7941       errmsg ("host name space too long. ");
7942       return -99;
7943     }
7944   if (vec_len (host_bridge) > 63)
7945     {
7946       errmsg ("host bridge name too long. ");
7947       return -99;
7948     }
7949   if (host_ip4_prefix_len > 32)
7950     {
7951       errmsg ("host ip4 prefix length not valid. ");
7952       return -99;
7953     }
7954   if (host_ip6_prefix_len > 128)
7955     {
7956       errmsg ("host ip6 prefix length not valid. ");
7957       return -99;
7958     }
7959   if (!is_pow2 (rx_ring_sz))
7960     {
7961       errmsg ("rx ring size must be power of 2. ");
7962       return -99;
7963     }
7964   if (rx_ring_sz > 32768)
7965     {
7966       errmsg ("rx ring size must be 32768 or lower. ");
7967       return -99;
7968     }
7969   if (!is_pow2 (tx_ring_sz))
7970     {
7971       errmsg ("tx ring size must be power of 2. ");
7972       return -99;
7973     }
7974   if (tx_ring_sz > 32768)
7975     {
7976       errmsg ("tx ring size must be 32768 or lower. ");
7977       return -99;
7978     }
7979
7980   /* Construct the API message */
7981   M (TAP_CREATE_V2, mp);
7982
7983   mp->use_random_mac = random_mac;
7984
7985   mp->id = ntohl (id);
7986   mp->host_namespace_set = host_ns != 0;
7987   mp->host_bridge_set = host_bridge != 0;
7988   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7989   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7990   mp->rx_ring_sz = ntohs (rx_ring_sz);
7991   mp->tx_ring_sz = ntohs (tx_ring_sz);
7992
7993   if (random_mac == 0)
7994     clib_memcpy (mp->mac_address, mac_address, 6);
7995   if (host_mac_addr_set)
7996     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7997   if (host_if_name)
7998     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7999   if (host_ns)
8000     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8001   if (host_bridge)
8002     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8003   if (host_ip4_prefix_len)
8004     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8005   if (host_ip4_prefix_len)
8006     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8007   if (host_ip4_gw_set)
8008     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8009   if (host_ip6_gw_set)
8010     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8011
8012   vec_free (host_ns);
8013   vec_free (host_if_name);
8014   vec_free (host_bridge);
8015
8016   /* send it... */
8017   S (mp);
8018
8019   /* Wait for a reply... */
8020   W (ret);
8021   return ret;
8022 }
8023
8024 static int
8025 api_tap_delete_v2 (vat_main_t * vam)
8026 {
8027   unformat_input_t *i = vam->input;
8028   vl_api_tap_delete_v2_t *mp;
8029   u32 sw_if_index = ~0;
8030   u8 sw_if_index_set = 0;
8031   int ret;
8032
8033   /* Parse args required to build the message */
8034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8035     {
8036       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8037         sw_if_index_set = 1;
8038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8039         sw_if_index_set = 1;
8040       else
8041         break;
8042     }
8043
8044   if (sw_if_index_set == 0)
8045     {
8046       errmsg ("missing vpp interface name. ");
8047       return -99;
8048     }
8049
8050   /* Construct the API message */
8051   M (TAP_DELETE_V2, mp);
8052
8053   mp->sw_if_index = ntohl (sw_if_index);
8054
8055   /* send it... */
8056   S (mp);
8057
8058   /* Wait for a reply... */
8059   W (ret);
8060   return ret;
8061 }
8062
8063 static int
8064 api_bond_create (vat_main_t * vam)
8065 {
8066   unformat_input_t *i = vam->input;
8067   vl_api_bond_create_t *mp;
8068   u8 mac_address[6];
8069   u8 custom_mac = 0;
8070   int ret;
8071   u8 mode;
8072   u8 lb;
8073   u8 mode_is_set = 0;
8074
8075   memset (mac_address, 0, sizeof (mac_address));
8076   lb = BOND_LB_L2;
8077
8078   /* Parse args required to build the message */
8079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8080     {
8081       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8082         mode_is_set = 1;
8083       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8084                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8085         ;
8086       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8087                          mac_address))
8088         custom_mac = 1;
8089       else
8090         break;
8091     }
8092
8093   if (mode_is_set == 0)
8094     {
8095       errmsg ("Missing bond mode. ");
8096       return -99;
8097     }
8098
8099   /* Construct the API message */
8100   M (BOND_CREATE, mp);
8101
8102   mp->use_custom_mac = custom_mac;
8103
8104   mp->mode = mode;
8105   mp->lb = lb;
8106
8107   if (custom_mac)
8108     clib_memcpy (mp->mac_address, mac_address, 6);
8109
8110   /* send it... */
8111   S (mp);
8112
8113   /* Wait for a reply... */
8114   W (ret);
8115   return ret;
8116 }
8117
8118 static int
8119 api_bond_delete (vat_main_t * vam)
8120 {
8121   unformat_input_t *i = vam->input;
8122   vl_api_bond_delete_t *mp;
8123   u32 sw_if_index = ~0;
8124   u8 sw_if_index_set = 0;
8125   int ret;
8126
8127   /* Parse args required to build the message */
8128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8129     {
8130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8131         sw_if_index_set = 1;
8132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8133         sw_if_index_set = 1;
8134       else
8135         break;
8136     }
8137
8138   if (sw_if_index_set == 0)
8139     {
8140       errmsg ("missing vpp interface name. ");
8141       return -99;
8142     }
8143
8144   /* Construct the API message */
8145   M (BOND_DELETE, mp);
8146
8147   mp->sw_if_index = ntohl (sw_if_index);
8148
8149   /* send it... */
8150   S (mp);
8151
8152   /* Wait for a reply... */
8153   W (ret);
8154   return ret;
8155 }
8156
8157 static int
8158 api_bond_enslave (vat_main_t * vam)
8159 {
8160   unformat_input_t *i = vam->input;
8161   vl_api_bond_enslave_t *mp;
8162   u32 bond_sw_if_index;
8163   int ret;
8164   u8 is_passive;
8165   u8 is_long_timeout;
8166   u32 bond_sw_if_index_is_set = 0;
8167   u32 sw_if_index;
8168   u8 sw_if_index_is_set = 0;
8169
8170   /* Parse args required to build the message */
8171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8172     {
8173       if (unformat (i, "sw_if_index %d", &sw_if_index))
8174         sw_if_index_is_set = 1;
8175       else if (unformat (i, "bond %u", &bond_sw_if_index))
8176         bond_sw_if_index_is_set = 1;
8177       else if (unformat (i, "passive %d", &is_passive))
8178         ;
8179       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8180         ;
8181       else
8182         break;
8183     }
8184
8185   if (bond_sw_if_index_is_set == 0)
8186     {
8187       errmsg ("Missing bond sw_if_index. ");
8188       return -99;
8189     }
8190   if (sw_if_index_is_set == 0)
8191     {
8192       errmsg ("Missing slave sw_if_index. ");
8193       return -99;
8194     }
8195
8196   /* Construct the API message */
8197   M (BOND_ENSLAVE, mp);
8198
8199   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8200   mp->sw_if_index = ntohl (sw_if_index);
8201   mp->is_long_timeout = is_long_timeout;
8202   mp->is_passive = is_passive;
8203
8204   /* send it... */
8205   S (mp);
8206
8207   /* Wait for a reply... */
8208   W (ret);
8209   return ret;
8210 }
8211
8212 static int
8213 api_bond_detach_slave (vat_main_t * vam)
8214 {
8215   unformat_input_t *i = vam->input;
8216   vl_api_bond_detach_slave_t *mp;
8217   u32 sw_if_index = ~0;
8218   u8 sw_if_index_set = 0;
8219   int ret;
8220
8221   /* Parse args required to build the message */
8222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8223     {
8224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8225         sw_if_index_set = 1;
8226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8227         sw_if_index_set = 1;
8228       else
8229         break;
8230     }
8231
8232   if (sw_if_index_set == 0)
8233     {
8234       errmsg ("missing vpp interface name. ");
8235       return -99;
8236     }
8237
8238   /* Construct the API message */
8239   M (BOND_DETACH_SLAVE, mp);
8240
8241   mp->sw_if_index = ntohl (sw_if_index);
8242
8243   /* send it... */
8244   S (mp);
8245
8246   /* Wait for a reply... */
8247   W (ret);
8248   return ret;
8249 }
8250
8251 static int
8252 api_ip_table_add_del (vat_main_t * vam)
8253 {
8254   unformat_input_t *i = vam->input;
8255   vl_api_ip_table_add_del_t *mp;
8256   u32 table_id = ~0;
8257   u8 is_ipv6 = 0;
8258   u8 is_add = 1;
8259   int ret = 0;
8260
8261   /* Parse args required to build the message */
8262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8263     {
8264       if (unformat (i, "ipv6"))
8265         is_ipv6 = 1;
8266       else if (unformat (i, "del"))
8267         is_add = 0;
8268       else if (unformat (i, "add"))
8269         is_add = 1;
8270       else if (unformat (i, "table %d", &table_id))
8271         ;
8272       else
8273         {
8274           clib_warning ("parse error '%U'", format_unformat_error, i);
8275           return -99;
8276         }
8277     }
8278
8279   if (~0 == table_id)
8280     {
8281       errmsg ("missing table-ID");
8282       return -99;
8283     }
8284
8285   /* Construct the API message */
8286   M (IP_TABLE_ADD_DEL, mp);
8287
8288   mp->table_id = ntohl (table_id);
8289   mp->is_ipv6 = is_ipv6;
8290   mp->is_add = is_add;
8291
8292   /* send it... */
8293   S (mp);
8294
8295   /* Wait for a reply... */
8296   W (ret);
8297
8298   return ret;
8299 }
8300
8301 static int
8302 api_ip_add_del_route (vat_main_t * vam)
8303 {
8304   unformat_input_t *i = vam->input;
8305   vl_api_ip_add_del_route_t *mp;
8306   u32 sw_if_index = ~0, vrf_id = 0;
8307   u8 is_ipv6 = 0;
8308   u8 is_local = 0, is_drop = 0;
8309   u8 is_unreach = 0, is_prohibit = 0;
8310   u8 is_add = 1;
8311   u32 next_hop_weight = 1;
8312   u8 is_multipath = 0;
8313   u8 address_set = 0;
8314   u8 address_length_set = 0;
8315   u32 next_hop_table_id = 0;
8316   u32 resolve_attempts = 0;
8317   u32 dst_address_length = 0;
8318   u8 next_hop_set = 0;
8319   ip4_address_t v4_dst_address, v4_next_hop_address;
8320   ip6_address_t v6_dst_address, v6_next_hop_address;
8321   int count = 1;
8322   int j;
8323   f64 before = 0;
8324   u32 random_add_del = 0;
8325   u32 *random_vector = 0;
8326   uword *random_hash;
8327   u32 random_seed = 0xdeaddabe;
8328   u32 classify_table_index = ~0;
8329   u8 is_classify = 0;
8330   u8 resolve_host = 0, resolve_attached = 0;
8331   mpls_label_t *next_hop_out_label_stack = NULL;
8332   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8333   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8334
8335   /* Parse args required to build the message */
8336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8337     {
8338       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8339         ;
8340       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8341         ;
8342       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8343         {
8344           address_set = 1;
8345           is_ipv6 = 0;
8346         }
8347       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8348         {
8349           address_set = 1;
8350           is_ipv6 = 1;
8351         }
8352       else if (unformat (i, "/%d", &dst_address_length))
8353         {
8354           address_length_set = 1;
8355         }
8356
8357       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8358                                          &v4_next_hop_address))
8359         {
8360           next_hop_set = 1;
8361         }
8362       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8363                                          &v6_next_hop_address))
8364         {
8365           next_hop_set = 1;
8366         }
8367       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8368         ;
8369       else if (unformat (i, "weight %d", &next_hop_weight))
8370         ;
8371       else if (unformat (i, "drop"))
8372         {
8373           is_drop = 1;
8374         }
8375       else if (unformat (i, "null-send-unreach"))
8376         {
8377           is_unreach = 1;
8378         }
8379       else if (unformat (i, "null-send-prohibit"))
8380         {
8381           is_prohibit = 1;
8382         }
8383       else if (unformat (i, "local"))
8384         {
8385           is_local = 1;
8386         }
8387       else if (unformat (i, "classify %d", &classify_table_index))
8388         {
8389           is_classify = 1;
8390         }
8391       else if (unformat (i, "del"))
8392         is_add = 0;
8393       else if (unformat (i, "add"))
8394         is_add = 1;
8395       else if (unformat (i, "resolve-via-host"))
8396         resolve_host = 1;
8397       else if (unformat (i, "resolve-via-attached"))
8398         resolve_attached = 1;
8399       else if (unformat (i, "multipath"))
8400         is_multipath = 1;
8401       else if (unformat (i, "vrf %d", &vrf_id))
8402         ;
8403       else if (unformat (i, "count %d", &count))
8404         ;
8405       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8406         ;
8407       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8408         ;
8409       else if (unformat (i, "out-label %d", &next_hop_out_label))
8410         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8411       else if (unformat (i, "via-label %d", &next_hop_via_label))
8412         ;
8413       else if (unformat (i, "random"))
8414         random_add_del = 1;
8415       else if (unformat (i, "seed %d", &random_seed))
8416         ;
8417       else
8418         {
8419           clib_warning ("parse error '%U'", format_unformat_error, i);
8420           return -99;
8421         }
8422     }
8423
8424   if (!next_hop_set && !is_drop && !is_local &&
8425       !is_classify && !is_unreach && !is_prohibit &&
8426       MPLS_LABEL_INVALID == next_hop_via_label)
8427     {
8428       errmsg
8429         ("next hop / local / drop / unreach / prohibit / classify not set");
8430       return -99;
8431     }
8432
8433   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8434     {
8435       errmsg ("next hop and next-hop via label set");
8436       return -99;
8437     }
8438   if (address_set == 0)
8439     {
8440       errmsg ("missing addresses");
8441       return -99;
8442     }
8443
8444   if (address_length_set == 0)
8445     {
8446       errmsg ("missing address length");
8447       return -99;
8448     }
8449
8450   /* Generate a pile of unique, random routes */
8451   if (random_add_del)
8452     {
8453       u32 this_random_address;
8454       random_hash = hash_create (count, sizeof (uword));
8455
8456       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8457       for (j = 0; j <= count; j++)
8458         {
8459           do
8460             {
8461               this_random_address = random_u32 (&random_seed);
8462               this_random_address =
8463                 clib_host_to_net_u32 (this_random_address);
8464             }
8465           while (hash_get (random_hash, this_random_address));
8466           vec_add1 (random_vector, this_random_address);
8467           hash_set (random_hash, this_random_address, 1);
8468         }
8469       hash_free (random_hash);
8470       v4_dst_address.as_u32 = random_vector[0];
8471     }
8472
8473   if (count > 1)
8474     {
8475       /* Turn on async mode */
8476       vam->async_mode = 1;
8477       vam->async_errors = 0;
8478       before = vat_time_now (vam);
8479     }
8480
8481   for (j = 0; j < count; j++)
8482     {
8483       /* Construct the API message */
8484       M2 (IP_ADD_DEL_ROUTE, mp,
8485           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8486
8487       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8488       mp->table_id = ntohl (vrf_id);
8489
8490       mp->is_add = is_add;
8491       mp->is_drop = is_drop;
8492       mp->is_unreach = is_unreach;
8493       mp->is_prohibit = is_prohibit;
8494       mp->is_ipv6 = is_ipv6;
8495       mp->is_local = is_local;
8496       mp->is_classify = is_classify;
8497       mp->is_multipath = is_multipath;
8498       mp->is_resolve_host = resolve_host;
8499       mp->is_resolve_attached = resolve_attached;
8500       mp->next_hop_weight = next_hop_weight;
8501       mp->dst_address_length = dst_address_length;
8502       mp->next_hop_table_id = ntohl (next_hop_table_id);
8503       mp->classify_table_index = ntohl (classify_table_index);
8504       mp->next_hop_via_label = ntohl (next_hop_via_label);
8505       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8506       if (0 != mp->next_hop_n_out_labels)
8507         {
8508           memcpy (mp->next_hop_out_label_stack,
8509                   next_hop_out_label_stack,
8510                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8511           vec_free (next_hop_out_label_stack);
8512         }
8513
8514       if (is_ipv6)
8515         {
8516           clib_memcpy (mp->dst_address, &v6_dst_address,
8517                        sizeof (v6_dst_address));
8518           if (next_hop_set)
8519             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8520                          sizeof (v6_next_hop_address));
8521           increment_v6_address (&v6_dst_address);
8522         }
8523       else
8524         {
8525           clib_memcpy (mp->dst_address, &v4_dst_address,
8526                        sizeof (v4_dst_address));
8527           if (next_hop_set)
8528             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8529                          sizeof (v4_next_hop_address));
8530           if (random_add_del)
8531             v4_dst_address.as_u32 = random_vector[j + 1];
8532           else
8533             increment_v4_address (&v4_dst_address);
8534         }
8535       /* send it... */
8536       S (mp);
8537       /* If we receive SIGTERM, stop now... */
8538       if (vam->do_exit)
8539         break;
8540     }
8541
8542   /* When testing multiple add/del ops, use a control-ping to sync */
8543   if (count > 1)
8544     {
8545       vl_api_control_ping_t *mp_ping;
8546       f64 after;
8547       f64 timeout;
8548
8549       /* Shut off async mode */
8550       vam->async_mode = 0;
8551
8552       MPING (CONTROL_PING, mp_ping);
8553       S (mp_ping);
8554
8555       timeout = vat_time_now (vam) + 1.0;
8556       while (vat_time_now (vam) < timeout)
8557         if (vam->result_ready == 1)
8558           goto out;
8559       vam->retval = -99;
8560
8561     out:
8562       if (vam->retval == -99)
8563         errmsg ("timeout");
8564
8565       if (vam->async_errors > 0)
8566         {
8567           errmsg ("%d asynchronous errors", vam->async_errors);
8568           vam->retval = -98;
8569         }
8570       vam->async_errors = 0;
8571       after = vat_time_now (vam);
8572
8573       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8574       if (j > 0)
8575         count = j;
8576
8577       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8578              count, after - before, count / (after - before));
8579     }
8580   else
8581     {
8582       int ret;
8583
8584       /* Wait for a reply... */
8585       W (ret);
8586       return ret;
8587     }
8588
8589   /* Return the good/bad news */
8590   return (vam->retval);
8591 }
8592
8593 static int
8594 api_ip_mroute_add_del (vat_main_t * vam)
8595 {
8596   unformat_input_t *i = vam->input;
8597   vl_api_ip_mroute_add_del_t *mp;
8598   u32 sw_if_index = ~0, vrf_id = 0;
8599   u8 is_ipv6 = 0;
8600   u8 is_local = 0;
8601   u8 is_add = 1;
8602   u8 address_set = 0;
8603   u32 grp_address_length = 0;
8604   ip4_address_t v4_grp_address, v4_src_address;
8605   ip6_address_t v6_grp_address, v6_src_address;
8606   mfib_itf_flags_t iflags = 0;
8607   mfib_entry_flags_t eflags = 0;
8608   int ret;
8609
8610   /* Parse args required to build the message */
8611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8612     {
8613       if (unformat (i, "sw_if_index %d", &sw_if_index))
8614         ;
8615       else if (unformat (i, "%U %U",
8616                          unformat_ip4_address, &v4_src_address,
8617                          unformat_ip4_address, &v4_grp_address))
8618         {
8619           grp_address_length = 64;
8620           address_set = 1;
8621           is_ipv6 = 0;
8622         }
8623       else if (unformat (i, "%U %U",
8624                          unformat_ip6_address, &v6_src_address,
8625                          unformat_ip6_address, &v6_grp_address))
8626         {
8627           grp_address_length = 256;
8628           address_set = 1;
8629           is_ipv6 = 1;
8630         }
8631       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8632         {
8633           memset (&v4_src_address, 0, sizeof (v4_src_address));
8634           grp_address_length = 32;
8635           address_set = 1;
8636           is_ipv6 = 0;
8637         }
8638       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8639         {
8640           memset (&v6_src_address, 0, sizeof (v6_src_address));
8641           grp_address_length = 128;
8642           address_set = 1;
8643           is_ipv6 = 1;
8644         }
8645       else if (unformat (i, "/%d", &grp_address_length))
8646         ;
8647       else if (unformat (i, "local"))
8648         {
8649           is_local = 1;
8650         }
8651       else if (unformat (i, "del"))
8652         is_add = 0;
8653       else if (unformat (i, "add"))
8654         is_add = 1;
8655       else if (unformat (i, "vrf %d", &vrf_id))
8656         ;
8657       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8658         ;
8659       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8660         ;
8661       else
8662         {
8663           clib_warning ("parse error '%U'", format_unformat_error, i);
8664           return -99;
8665         }
8666     }
8667
8668   if (address_set == 0)
8669     {
8670       errmsg ("missing addresses\n");
8671       return -99;
8672     }
8673
8674   /* Construct the API message */
8675   M (IP_MROUTE_ADD_DEL, mp);
8676
8677   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8678   mp->table_id = ntohl (vrf_id);
8679
8680   mp->is_add = is_add;
8681   mp->is_ipv6 = is_ipv6;
8682   mp->is_local = is_local;
8683   mp->itf_flags = ntohl (iflags);
8684   mp->entry_flags = ntohl (eflags);
8685   mp->grp_address_length = grp_address_length;
8686   mp->grp_address_length = ntohs (mp->grp_address_length);
8687
8688   if (is_ipv6)
8689     {
8690       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8691       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8692     }
8693   else
8694     {
8695       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8696       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8697
8698     }
8699
8700   /* send it... */
8701   S (mp);
8702   /* Wait for a reply... */
8703   W (ret);
8704   return ret;
8705 }
8706
8707 static int
8708 api_mpls_table_add_del (vat_main_t * vam)
8709 {
8710   unformat_input_t *i = vam->input;
8711   vl_api_mpls_table_add_del_t *mp;
8712   u32 table_id = ~0;
8713   u8 is_add = 1;
8714   int ret = 0;
8715
8716   /* Parse args required to build the message */
8717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8718     {
8719       if (unformat (i, "table %d", &table_id))
8720         ;
8721       else if (unformat (i, "del"))
8722         is_add = 0;
8723       else if (unformat (i, "add"))
8724         is_add = 1;
8725       else
8726         {
8727           clib_warning ("parse error '%U'", format_unformat_error, i);
8728           return -99;
8729         }
8730     }
8731
8732   if (~0 == table_id)
8733     {
8734       errmsg ("missing table-ID");
8735       return -99;
8736     }
8737
8738   /* Construct the API message */
8739   M (MPLS_TABLE_ADD_DEL, mp);
8740
8741   mp->mt_table_id = ntohl (table_id);
8742   mp->mt_is_add = is_add;
8743
8744   /* send it... */
8745   S (mp);
8746
8747   /* Wait for a reply... */
8748   W (ret);
8749
8750   return ret;
8751 }
8752
8753 static int
8754 api_mpls_route_add_del (vat_main_t * vam)
8755 {
8756   unformat_input_t *i = vam->input;
8757   vl_api_mpls_route_add_del_t *mp;
8758   u32 sw_if_index = ~0, table_id = 0;
8759   u8 is_add = 1;
8760   u32 next_hop_weight = 1;
8761   u8 is_multipath = 0;
8762   u32 next_hop_table_id = 0;
8763   u8 next_hop_set = 0;
8764   ip4_address_t v4_next_hop_address = {
8765     .as_u32 = 0,
8766   };
8767   ip6_address_t v6_next_hop_address = { {0} };
8768   int count = 1;
8769   int j;
8770   f64 before = 0;
8771   u32 classify_table_index = ~0;
8772   u8 is_classify = 0;
8773   u8 resolve_host = 0, resolve_attached = 0;
8774   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8775   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8776   mpls_label_t *next_hop_out_label_stack = NULL;
8777   mpls_label_t local_label = MPLS_LABEL_INVALID;
8778   u8 is_eos = 0;
8779   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8780
8781   /* Parse args required to build the message */
8782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8783     {
8784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8785         ;
8786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8787         ;
8788       else if (unformat (i, "%d", &local_label))
8789         ;
8790       else if (unformat (i, "eos"))
8791         is_eos = 1;
8792       else if (unformat (i, "non-eos"))
8793         is_eos = 0;
8794       else if (unformat (i, "via %U", unformat_ip4_address,
8795                          &v4_next_hop_address))
8796         {
8797           next_hop_set = 1;
8798           next_hop_proto = DPO_PROTO_IP4;
8799         }
8800       else if (unformat (i, "via %U", unformat_ip6_address,
8801                          &v6_next_hop_address))
8802         {
8803           next_hop_set = 1;
8804           next_hop_proto = DPO_PROTO_IP6;
8805         }
8806       else if (unformat (i, "weight %d", &next_hop_weight))
8807         ;
8808       else if (unformat (i, "classify %d", &classify_table_index))
8809         {
8810           is_classify = 1;
8811         }
8812       else if (unformat (i, "del"))
8813         is_add = 0;
8814       else if (unformat (i, "add"))
8815         is_add = 1;
8816       else if (unformat (i, "resolve-via-host"))
8817         resolve_host = 1;
8818       else if (unformat (i, "resolve-via-attached"))
8819         resolve_attached = 1;
8820       else if (unformat (i, "multipath"))
8821         is_multipath = 1;
8822       else if (unformat (i, "count %d", &count))
8823         ;
8824       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8825         {
8826           next_hop_set = 1;
8827           next_hop_proto = DPO_PROTO_IP4;
8828         }
8829       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8830         {
8831           next_hop_set = 1;
8832           next_hop_proto = DPO_PROTO_IP6;
8833         }
8834       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8835         ;
8836       else if (unformat (i, "via-label %d", &next_hop_via_label))
8837         ;
8838       else if (unformat (i, "out-label %d", &next_hop_out_label))
8839         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8840       else
8841         {
8842           clib_warning ("parse error '%U'", format_unformat_error, i);
8843           return -99;
8844         }
8845     }
8846
8847   if (!next_hop_set && !is_classify)
8848     {
8849       errmsg ("next hop / classify not set");
8850       return -99;
8851     }
8852
8853   if (MPLS_LABEL_INVALID == local_label)
8854     {
8855       errmsg ("missing label");
8856       return -99;
8857     }
8858
8859   if (count > 1)
8860     {
8861       /* Turn on async mode */
8862       vam->async_mode = 1;
8863       vam->async_errors = 0;
8864       before = vat_time_now (vam);
8865     }
8866
8867   for (j = 0; j < count; j++)
8868     {
8869       /* Construct the API message */
8870       M2 (MPLS_ROUTE_ADD_DEL, mp,
8871           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8872
8873       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8874       mp->mr_table_id = ntohl (table_id);
8875
8876       mp->mr_is_add = is_add;
8877       mp->mr_next_hop_proto = next_hop_proto;
8878       mp->mr_is_classify = is_classify;
8879       mp->mr_is_multipath = is_multipath;
8880       mp->mr_is_resolve_host = resolve_host;
8881       mp->mr_is_resolve_attached = resolve_attached;
8882       mp->mr_next_hop_weight = next_hop_weight;
8883       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8884       mp->mr_classify_table_index = ntohl (classify_table_index);
8885       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8886       mp->mr_label = ntohl (local_label);
8887       mp->mr_eos = is_eos;
8888
8889       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8890       if (0 != mp->mr_next_hop_n_out_labels)
8891         {
8892           memcpy (mp->mr_next_hop_out_label_stack,
8893                   next_hop_out_label_stack,
8894                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8895           vec_free (next_hop_out_label_stack);
8896         }
8897
8898       if (next_hop_set)
8899         {
8900           if (DPO_PROTO_IP4 == next_hop_proto)
8901             {
8902               clib_memcpy (mp->mr_next_hop,
8903                            &v4_next_hop_address,
8904                            sizeof (v4_next_hop_address));
8905             }
8906           else if (DPO_PROTO_IP6 == next_hop_proto)
8907
8908             {
8909               clib_memcpy (mp->mr_next_hop,
8910                            &v6_next_hop_address,
8911                            sizeof (v6_next_hop_address));
8912             }
8913         }
8914       local_label++;
8915
8916       /* send it... */
8917       S (mp);
8918       /* If we receive SIGTERM, stop now... */
8919       if (vam->do_exit)
8920         break;
8921     }
8922
8923   /* When testing multiple add/del ops, use a control-ping to sync */
8924   if (count > 1)
8925     {
8926       vl_api_control_ping_t *mp_ping;
8927       f64 after;
8928       f64 timeout;
8929
8930       /* Shut off async mode */
8931       vam->async_mode = 0;
8932
8933       MPING (CONTROL_PING, mp_ping);
8934       S (mp_ping);
8935
8936       timeout = vat_time_now (vam) + 1.0;
8937       while (vat_time_now (vam) < timeout)
8938         if (vam->result_ready == 1)
8939           goto out;
8940       vam->retval = -99;
8941
8942     out:
8943       if (vam->retval == -99)
8944         errmsg ("timeout");
8945
8946       if (vam->async_errors > 0)
8947         {
8948           errmsg ("%d asynchronous errors", vam->async_errors);
8949           vam->retval = -98;
8950         }
8951       vam->async_errors = 0;
8952       after = vat_time_now (vam);
8953
8954       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8955       if (j > 0)
8956         count = j;
8957
8958       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8959              count, after - before, count / (after - before));
8960     }
8961   else
8962     {
8963       int ret;
8964
8965       /* Wait for a reply... */
8966       W (ret);
8967       return ret;
8968     }
8969
8970   /* Return the good/bad news */
8971   return (vam->retval);
8972 }
8973
8974 static int
8975 api_mpls_ip_bind_unbind (vat_main_t * vam)
8976 {
8977   unformat_input_t *i = vam->input;
8978   vl_api_mpls_ip_bind_unbind_t *mp;
8979   u32 ip_table_id = 0;
8980   u8 is_bind = 1;
8981   u8 is_ip4 = 1;
8982   ip4_address_t v4_address;
8983   ip6_address_t v6_address;
8984   u32 address_length;
8985   u8 address_set = 0;
8986   mpls_label_t local_label = MPLS_LABEL_INVALID;
8987   int ret;
8988
8989   /* Parse args required to build the message */
8990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8991     {
8992       if (unformat (i, "%U/%d", unformat_ip4_address,
8993                     &v4_address, &address_length))
8994         {
8995           is_ip4 = 1;
8996           address_set = 1;
8997         }
8998       else if (unformat (i, "%U/%d", unformat_ip6_address,
8999                          &v6_address, &address_length))
9000         {
9001           is_ip4 = 0;
9002           address_set = 1;
9003         }
9004       else if (unformat (i, "%d", &local_label))
9005         ;
9006       else if (unformat (i, "table-id %d", &ip_table_id))
9007         ;
9008       else if (unformat (i, "unbind"))
9009         is_bind = 0;
9010       else if (unformat (i, "bind"))
9011         is_bind = 1;
9012       else
9013         {
9014           clib_warning ("parse error '%U'", format_unformat_error, i);
9015           return -99;
9016         }
9017     }
9018
9019   if (!address_set)
9020     {
9021       errmsg ("IP addres not set");
9022       return -99;
9023     }
9024
9025   if (MPLS_LABEL_INVALID == local_label)
9026     {
9027       errmsg ("missing label");
9028       return -99;
9029     }
9030
9031   /* Construct the API message */
9032   M (MPLS_IP_BIND_UNBIND, mp);
9033
9034   mp->mb_is_bind = is_bind;
9035   mp->mb_is_ip4 = is_ip4;
9036   mp->mb_ip_table_id = ntohl (ip_table_id);
9037   mp->mb_mpls_table_id = 0;
9038   mp->mb_label = ntohl (local_label);
9039   mp->mb_address_length = address_length;
9040
9041   if (is_ip4)
9042     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9043   else
9044     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9045
9046   /* send it... */
9047   S (mp);
9048
9049   /* Wait for a reply... */
9050   W (ret);
9051   return ret;
9052 }
9053
9054 static int
9055 api_bier_table_add_del (vat_main_t * vam)
9056 {
9057   unformat_input_t *i = vam->input;
9058   vl_api_bier_table_add_del_t *mp;
9059   u8 is_add = 1;
9060   u32 set = 0, sub_domain = 0, hdr_len = 3;
9061   mpls_label_t local_label = MPLS_LABEL_INVALID;
9062   int ret;
9063
9064   /* Parse args required to build the message */
9065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9066     {
9067       if (unformat (i, "sub-domain %d", &sub_domain))
9068         ;
9069       else if (unformat (i, "set %d", &set))
9070         ;
9071       else if (unformat (i, "label %d", &local_label))
9072         ;
9073       else if (unformat (i, "hdr-len %d", &hdr_len))
9074         ;
9075       else if (unformat (i, "add"))
9076         is_add = 1;
9077       else if (unformat (i, "del"))
9078         is_add = 0;
9079       else
9080         {
9081           clib_warning ("parse error '%U'", format_unformat_error, i);
9082           return -99;
9083         }
9084     }
9085
9086   if (MPLS_LABEL_INVALID == local_label)
9087     {
9088       errmsg ("missing label\n");
9089       return -99;
9090     }
9091
9092   /* Construct the API message */
9093   M (BIER_TABLE_ADD_DEL, mp);
9094
9095   mp->bt_is_add = is_add;
9096   mp->bt_label = ntohl (local_label);
9097   mp->bt_tbl_id.bt_set = set;
9098   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9099   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9100
9101   /* send it... */
9102   S (mp);
9103
9104   /* Wait for a reply... */
9105   W (ret);
9106
9107   return (ret);
9108 }
9109
9110 static int
9111 api_bier_route_add_del (vat_main_t * vam)
9112 {
9113   unformat_input_t *i = vam->input;
9114   vl_api_bier_route_add_del_t *mp;
9115   u8 is_add = 1;
9116   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9117   ip4_address_t v4_next_hop_address;
9118   ip6_address_t v6_next_hop_address;
9119   u8 next_hop_set = 0;
9120   u8 next_hop_proto_is_ip4 = 1;
9121   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9122   int ret;
9123
9124   /* Parse args required to build the message */
9125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9126     {
9127       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9128         {
9129           next_hop_proto_is_ip4 = 1;
9130           next_hop_set = 1;
9131         }
9132       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9133         {
9134           next_hop_proto_is_ip4 = 0;
9135           next_hop_set = 1;
9136         }
9137       if (unformat (i, "sub-domain %d", &sub_domain))
9138         ;
9139       else if (unformat (i, "set %d", &set))
9140         ;
9141       else if (unformat (i, "hdr-len %d", &hdr_len))
9142         ;
9143       else if (unformat (i, "bp %d", &bp))
9144         ;
9145       else if (unformat (i, "add"))
9146         is_add = 1;
9147       else if (unformat (i, "del"))
9148         is_add = 0;
9149       else if (unformat (i, "out-label %d", &next_hop_out_label))
9150         ;
9151       else
9152         {
9153           clib_warning ("parse error '%U'", format_unformat_error, i);
9154           return -99;
9155         }
9156     }
9157
9158   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9159     {
9160       errmsg ("next hop / label set\n");
9161       return -99;
9162     }
9163   if (0 == bp)
9164     {
9165       errmsg ("bit=position not set\n");
9166       return -99;
9167     }
9168
9169   /* Construct the API message */
9170   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9171
9172   mp->br_is_add = is_add;
9173   mp->br_tbl_id.bt_set = set;
9174   mp->br_tbl_id.bt_sub_domain = sub_domain;
9175   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9176   mp->br_bp = ntohs (bp);
9177   mp->br_n_paths = 1;
9178   mp->br_paths[0].n_labels = 1;
9179   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9180   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9181
9182   if (next_hop_proto_is_ip4)
9183     {
9184       clib_memcpy (mp->br_paths[0].next_hop,
9185                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9186     }
9187   else
9188     {
9189       clib_memcpy (mp->br_paths[0].next_hop,
9190                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9191     }
9192
9193   /* send it... */
9194   S (mp);
9195
9196   /* Wait for a reply... */
9197   W (ret);
9198
9199   return (ret);
9200 }
9201
9202 static int
9203 api_proxy_arp_add_del (vat_main_t * vam)
9204 {
9205   unformat_input_t *i = vam->input;
9206   vl_api_proxy_arp_add_del_t *mp;
9207   u32 vrf_id = 0;
9208   u8 is_add = 1;
9209   ip4_address_t lo, hi;
9210   u8 range_set = 0;
9211   int ret;
9212
9213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9214     {
9215       if (unformat (i, "vrf %d", &vrf_id))
9216         ;
9217       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9218                          unformat_ip4_address, &hi))
9219         range_set = 1;
9220       else if (unformat (i, "del"))
9221         is_add = 0;
9222       else
9223         {
9224           clib_warning ("parse error '%U'", format_unformat_error, i);
9225           return -99;
9226         }
9227     }
9228
9229   if (range_set == 0)
9230     {
9231       errmsg ("address range not set");
9232       return -99;
9233     }
9234
9235   M (PROXY_ARP_ADD_DEL, mp);
9236
9237   mp->proxy.vrf_id = ntohl (vrf_id);
9238   mp->is_add = is_add;
9239   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9240   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9241
9242   S (mp);
9243   W (ret);
9244   return ret;
9245 }
9246
9247 static int
9248 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9249 {
9250   unformat_input_t *i = vam->input;
9251   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9252   u32 sw_if_index;
9253   u8 enable = 1;
9254   u8 sw_if_index_set = 0;
9255   int ret;
9256
9257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9258     {
9259       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9260         sw_if_index_set = 1;
9261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9262         sw_if_index_set = 1;
9263       else if (unformat (i, "enable"))
9264         enable = 1;
9265       else if (unformat (i, "disable"))
9266         enable = 0;
9267       else
9268         {
9269           clib_warning ("parse error '%U'", format_unformat_error, i);
9270           return -99;
9271         }
9272     }
9273
9274   if (sw_if_index_set == 0)
9275     {
9276       errmsg ("missing interface name or sw_if_index");
9277       return -99;
9278     }
9279
9280   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9281
9282   mp->sw_if_index = ntohl (sw_if_index);
9283   mp->enable_disable = enable;
9284
9285   S (mp);
9286   W (ret);
9287   return ret;
9288 }
9289
9290 static int
9291 api_mpls_tunnel_add_del (vat_main_t * vam)
9292 {
9293   unformat_input_t *i = vam->input;
9294   vl_api_mpls_tunnel_add_del_t *mp;
9295
9296   u8 is_add = 1;
9297   u8 l2_only = 0;
9298   u32 sw_if_index = ~0;
9299   u32 next_hop_sw_if_index = ~0;
9300   u32 next_hop_proto_is_ip4 = 1;
9301
9302   u32 next_hop_table_id = 0;
9303   ip4_address_t v4_next_hop_address = {
9304     .as_u32 = 0,
9305   };
9306   ip6_address_t v6_next_hop_address = { {0} };
9307   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9308   int ret;
9309
9310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9311     {
9312       if (unformat (i, "add"))
9313         is_add = 1;
9314       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9315         is_add = 0;
9316       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9317         ;
9318       else if (unformat (i, "via %U",
9319                          unformat_ip4_address, &v4_next_hop_address))
9320         {
9321           next_hop_proto_is_ip4 = 1;
9322         }
9323       else if (unformat (i, "via %U",
9324                          unformat_ip6_address, &v6_next_hop_address))
9325         {
9326           next_hop_proto_is_ip4 = 0;
9327         }
9328       else if (unformat (i, "l2-only"))
9329         l2_only = 1;
9330       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9331         ;
9332       else if (unformat (i, "out-label %d", &next_hop_out_label))
9333         vec_add1 (labels, ntohl (next_hop_out_label));
9334       else
9335         {
9336           clib_warning ("parse error '%U'", format_unformat_error, i);
9337           return -99;
9338         }
9339     }
9340
9341   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9342
9343   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9344   mp->mt_sw_if_index = ntohl (sw_if_index);
9345   mp->mt_is_add = is_add;
9346   mp->mt_l2_only = l2_only;
9347   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9348   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9349
9350   mp->mt_next_hop_n_out_labels = vec_len (labels);
9351
9352   if (0 != mp->mt_next_hop_n_out_labels)
9353     {
9354       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9355                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9356       vec_free (labels);
9357     }
9358
9359   if (next_hop_proto_is_ip4)
9360     {
9361       clib_memcpy (mp->mt_next_hop,
9362                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9363     }
9364   else
9365     {
9366       clib_memcpy (mp->mt_next_hop,
9367                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9368     }
9369
9370   S (mp);
9371   W (ret);
9372   return ret;
9373 }
9374
9375 static int
9376 api_sw_interface_set_unnumbered (vat_main_t * vam)
9377 {
9378   unformat_input_t *i = vam->input;
9379   vl_api_sw_interface_set_unnumbered_t *mp;
9380   u32 sw_if_index;
9381   u32 unnum_sw_index = ~0;
9382   u8 is_add = 1;
9383   u8 sw_if_index_set = 0;
9384   int ret;
9385
9386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9387     {
9388       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9389         sw_if_index_set = 1;
9390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9391         sw_if_index_set = 1;
9392       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9393         ;
9394       else if (unformat (i, "del"))
9395         is_add = 0;
9396       else
9397         {
9398           clib_warning ("parse error '%U'", format_unformat_error, i);
9399           return -99;
9400         }
9401     }
9402
9403   if (sw_if_index_set == 0)
9404     {
9405       errmsg ("missing interface name or sw_if_index");
9406       return -99;
9407     }
9408
9409   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9410
9411   mp->sw_if_index = ntohl (sw_if_index);
9412   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9413   mp->is_add = is_add;
9414
9415   S (mp);
9416   W (ret);
9417   return ret;
9418 }
9419
9420 static int
9421 api_ip_neighbor_add_del (vat_main_t * vam)
9422 {
9423   unformat_input_t *i = vam->input;
9424   vl_api_ip_neighbor_add_del_t *mp;
9425   u32 sw_if_index;
9426   u8 sw_if_index_set = 0;
9427   u8 is_add = 1;
9428   u8 is_static = 0;
9429   u8 is_no_fib_entry = 0;
9430   u8 mac_address[6];
9431   u8 mac_set = 0;
9432   u8 v4_address_set = 0;
9433   u8 v6_address_set = 0;
9434   ip4_address_t v4address;
9435   ip6_address_t v6address;
9436   int ret;
9437
9438   memset (mac_address, 0, sizeof (mac_address));
9439
9440   /* Parse args required to build the message */
9441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9442     {
9443       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9444         {
9445           mac_set = 1;
9446         }
9447       else if (unformat (i, "del"))
9448         is_add = 0;
9449       else
9450         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9451         sw_if_index_set = 1;
9452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9453         sw_if_index_set = 1;
9454       else if (unformat (i, "is_static"))
9455         is_static = 1;
9456       else if (unformat (i, "no-fib-entry"))
9457         is_no_fib_entry = 1;
9458       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9459         v4_address_set = 1;
9460       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9461         v6_address_set = 1;
9462       else
9463         {
9464           clib_warning ("parse error '%U'", format_unformat_error, i);
9465           return -99;
9466         }
9467     }
9468
9469   if (sw_if_index_set == 0)
9470     {
9471       errmsg ("missing interface name or sw_if_index");
9472       return -99;
9473     }
9474   if (v4_address_set && v6_address_set)
9475     {
9476       errmsg ("both v4 and v6 addresses set");
9477       return -99;
9478     }
9479   if (!v4_address_set && !v6_address_set)
9480     {
9481       errmsg ("no address set");
9482       return -99;
9483     }
9484
9485   /* Construct the API message */
9486   M (IP_NEIGHBOR_ADD_DEL, mp);
9487
9488   mp->sw_if_index = ntohl (sw_if_index);
9489   mp->is_add = is_add;
9490   mp->is_static = is_static;
9491   mp->is_no_adj_fib = is_no_fib_entry;
9492   if (mac_set)
9493     clib_memcpy (mp->mac_address, mac_address, 6);
9494   if (v6_address_set)
9495     {
9496       mp->is_ipv6 = 1;
9497       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9498     }
9499   else
9500     {
9501       /* mp->is_ipv6 = 0; via memset in M macro above */
9502       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9503     }
9504
9505   /* send it... */
9506   S (mp);
9507
9508   /* Wait for a reply, return good/bad news  */
9509   W (ret);
9510   return ret;
9511 }
9512
9513 static int
9514 api_create_vlan_subif (vat_main_t * vam)
9515 {
9516   unformat_input_t *i = vam->input;
9517   vl_api_create_vlan_subif_t *mp;
9518   u32 sw_if_index;
9519   u8 sw_if_index_set = 0;
9520   u32 vlan_id;
9521   u8 vlan_id_set = 0;
9522   int ret;
9523
9524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9525     {
9526       if (unformat (i, "sw_if_index %d", &sw_if_index))
9527         sw_if_index_set = 1;
9528       else
9529         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9530         sw_if_index_set = 1;
9531       else if (unformat (i, "vlan %d", &vlan_id))
9532         vlan_id_set = 1;
9533       else
9534         {
9535           clib_warning ("parse error '%U'", format_unformat_error, i);
9536           return -99;
9537         }
9538     }
9539
9540   if (sw_if_index_set == 0)
9541     {
9542       errmsg ("missing interface name or sw_if_index");
9543       return -99;
9544     }
9545
9546   if (vlan_id_set == 0)
9547     {
9548       errmsg ("missing vlan_id");
9549       return -99;
9550     }
9551   M (CREATE_VLAN_SUBIF, mp);
9552
9553   mp->sw_if_index = ntohl (sw_if_index);
9554   mp->vlan_id = ntohl (vlan_id);
9555
9556   S (mp);
9557   W (ret);
9558   return ret;
9559 }
9560
9561 #define foreach_create_subif_bit                \
9562 _(no_tags)                                      \
9563 _(one_tag)                                      \
9564 _(two_tags)                                     \
9565 _(dot1ad)                                       \
9566 _(exact_match)                                  \
9567 _(default_sub)                                  \
9568 _(outer_vlan_id_any)                            \
9569 _(inner_vlan_id_any)
9570
9571 static int
9572 api_create_subif (vat_main_t * vam)
9573 {
9574   unformat_input_t *i = vam->input;
9575   vl_api_create_subif_t *mp;
9576   u32 sw_if_index;
9577   u8 sw_if_index_set = 0;
9578   u32 sub_id;
9579   u8 sub_id_set = 0;
9580   u32 no_tags = 0;
9581   u32 one_tag = 0;
9582   u32 two_tags = 0;
9583   u32 dot1ad = 0;
9584   u32 exact_match = 0;
9585   u32 default_sub = 0;
9586   u32 outer_vlan_id_any = 0;
9587   u32 inner_vlan_id_any = 0;
9588   u32 tmp;
9589   u16 outer_vlan_id = 0;
9590   u16 inner_vlan_id = 0;
9591   int ret;
9592
9593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9594     {
9595       if (unformat (i, "sw_if_index %d", &sw_if_index))
9596         sw_if_index_set = 1;
9597       else
9598         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9599         sw_if_index_set = 1;
9600       else if (unformat (i, "sub_id %d", &sub_id))
9601         sub_id_set = 1;
9602       else if (unformat (i, "outer_vlan_id %d", &tmp))
9603         outer_vlan_id = tmp;
9604       else if (unformat (i, "inner_vlan_id %d", &tmp))
9605         inner_vlan_id = tmp;
9606
9607 #define _(a) else if (unformat (i, #a)) a = 1 ;
9608       foreach_create_subif_bit
9609 #undef _
9610         else
9611         {
9612           clib_warning ("parse error '%U'", format_unformat_error, i);
9613           return -99;
9614         }
9615     }
9616
9617   if (sw_if_index_set == 0)
9618     {
9619       errmsg ("missing interface name or sw_if_index");
9620       return -99;
9621     }
9622
9623   if (sub_id_set == 0)
9624     {
9625       errmsg ("missing sub_id");
9626       return -99;
9627     }
9628   M (CREATE_SUBIF, mp);
9629
9630   mp->sw_if_index = ntohl (sw_if_index);
9631   mp->sub_id = ntohl (sub_id);
9632
9633 #define _(a) mp->a = a;
9634   foreach_create_subif_bit;
9635 #undef _
9636
9637   mp->outer_vlan_id = ntohs (outer_vlan_id);
9638   mp->inner_vlan_id = ntohs (inner_vlan_id);
9639
9640   S (mp);
9641   W (ret);
9642   return ret;
9643 }
9644
9645 static int
9646 api_oam_add_del (vat_main_t * vam)
9647 {
9648   unformat_input_t *i = vam->input;
9649   vl_api_oam_add_del_t *mp;
9650   u32 vrf_id = 0;
9651   u8 is_add = 1;
9652   ip4_address_t src, dst;
9653   u8 src_set = 0;
9654   u8 dst_set = 0;
9655   int ret;
9656
9657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9658     {
9659       if (unformat (i, "vrf %d", &vrf_id))
9660         ;
9661       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9662         src_set = 1;
9663       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9664         dst_set = 1;
9665       else if (unformat (i, "del"))
9666         is_add = 0;
9667       else
9668         {
9669           clib_warning ("parse error '%U'", format_unformat_error, i);
9670           return -99;
9671         }
9672     }
9673
9674   if (src_set == 0)
9675     {
9676       errmsg ("missing src addr");
9677       return -99;
9678     }
9679
9680   if (dst_set == 0)
9681     {
9682       errmsg ("missing dst addr");
9683       return -99;
9684     }
9685
9686   M (OAM_ADD_DEL, mp);
9687
9688   mp->vrf_id = ntohl (vrf_id);
9689   mp->is_add = is_add;
9690   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9691   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9692
9693   S (mp);
9694   W (ret);
9695   return ret;
9696 }
9697
9698 static int
9699 api_reset_fib (vat_main_t * vam)
9700 {
9701   unformat_input_t *i = vam->input;
9702   vl_api_reset_fib_t *mp;
9703   u32 vrf_id = 0;
9704   u8 is_ipv6 = 0;
9705   u8 vrf_id_set = 0;
9706
9707   int ret;
9708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9709     {
9710       if (unformat (i, "vrf %d", &vrf_id))
9711         vrf_id_set = 1;
9712       else if (unformat (i, "ipv6"))
9713         is_ipv6 = 1;
9714       else
9715         {
9716           clib_warning ("parse error '%U'", format_unformat_error, i);
9717           return -99;
9718         }
9719     }
9720
9721   if (vrf_id_set == 0)
9722     {
9723       errmsg ("missing vrf id");
9724       return -99;
9725     }
9726
9727   M (RESET_FIB, mp);
9728
9729   mp->vrf_id = ntohl (vrf_id);
9730   mp->is_ipv6 = is_ipv6;
9731
9732   S (mp);
9733   W (ret);
9734   return ret;
9735 }
9736
9737 static int
9738 api_dhcp_proxy_config (vat_main_t * vam)
9739 {
9740   unformat_input_t *i = vam->input;
9741   vl_api_dhcp_proxy_config_t *mp;
9742   u32 rx_vrf_id = 0;
9743   u32 server_vrf_id = 0;
9744   u8 is_add = 1;
9745   u8 v4_address_set = 0;
9746   u8 v6_address_set = 0;
9747   ip4_address_t v4address;
9748   ip6_address_t v6address;
9749   u8 v4_src_address_set = 0;
9750   u8 v6_src_address_set = 0;
9751   ip4_address_t v4srcaddress;
9752   ip6_address_t v6srcaddress;
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, "del"))
9759         is_add = 0;
9760       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9761         ;
9762       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9763         ;
9764       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9765         v4_address_set = 1;
9766       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9767         v6_address_set = 1;
9768       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9769         v4_src_address_set = 1;
9770       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9771         v6_src_address_set = 1;
9772       else
9773         break;
9774     }
9775
9776   if (v4_address_set && v6_address_set)
9777     {
9778       errmsg ("both v4 and v6 server addresses set");
9779       return -99;
9780     }
9781   if (!v4_address_set && !v6_address_set)
9782     {
9783       errmsg ("no server addresses set");
9784       return -99;
9785     }
9786
9787   if (v4_src_address_set && v6_src_address_set)
9788     {
9789       errmsg ("both v4 and v6  src addresses set");
9790       return -99;
9791     }
9792   if (!v4_src_address_set && !v6_src_address_set)
9793     {
9794       errmsg ("no src addresses set");
9795       return -99;
9796     }
9797
9798   if (!(v4_src_address_set && v4_address_set) &&
9799       !(v6_src_address_set && v6_address_set))
9800     {
9801       errmsg ("no matching server and src addresses set");
9802       return -99;
9803     }
9804
9805   /* Construct the API message */
9806   M (DHCP_PROXY_CONFIG, mp);
9807
9808   mp->is_add = is_add;
9809   mp->rx_vrf_id = ntohl (rx_vrf_id);
9810   mp->server_vrf_id = ntohl (server_vrf_id);
9811   if (v6_address_set)
9812     {
9813       mp->is_ipv6 = 1;
9814       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9815       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9816     }
9817   else
9818     {
9819       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9820       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9821     }
9822
9823   /* send it... */
9824   S (mp);
9825
9826   /* Wait for a reply, return good/bad news  */
9827   W (ret);
9828   return ret;
9829 }
9830
9831 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9832 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9833
9834 static void
9835 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9836 {
9837   vat_main_t *vam = &vat_main;
9838   u32 i, count = mp->count;
9839   vl_api_dhcp_server_t *s;
9840
9841   if (mp->is_ipv6)
9842     print (vam->ofp,
9843            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9844            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9845            ntohl (mp->rx_vrf_id),
9846            format_ip6_address, mp->dhcp_src_address,
9847            mp->vss_type, mp->vss_vpn_ascii_id,
9848            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9849   else
9850     print (vam->ofp,
9851            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9852            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9853            ntohl (mp->rx_vrf_id),
9854            format_ip4_address, mp->dhcp_src_address,
9855            mp->vss_type, mp->vss_vpn_ascii_id,
9856            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9857
9858   for (i = 0; i < count; i++)
9859     {
9860       s = &mp->servers[i];
9861
9862       if (mp->is_ipv6)
9863         print (vam->ofp,
9864                " Server Table-ID %d, Server Address %U",
9865                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9866       else
9867         print (vam->ofp,
9868                " Server Table-ID %d, Server Address %U",
9869                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9870     }
9871 }
9872
9873 static void vl_api_dhcp_proxy_details_t_handler_json
9874   (vl_api_dhcp_proxy_details_t * mp)
9875 {
9876   vat_main_t *vam = &vat_main;
9877   vat_json_node_t *node = NULL;
9878   u32 i, count = mp->count;
9879   struct in_addr ip4;
9880   struct in6_addr ip6;
9881   vl_api_dhcp_server_t *s;
9882
9883   if (VAT_JSON_ARRAY != vam->json_tree.type)
9884     {
9885       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9886       vat_json_init_array (&vam->json_tree);
9887     }
9888   node = vat_json_array_add (&vam->json_tree);
9889
9890   vat_json_init_object (node);
9891   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9892   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9893                              sizeof (mp->vss_type));
9894   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9895                                    mp->vss_vpn_ascii_id);
9896   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9897   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9898
9899   if (mp->is_ipv6)
9900     {
9901       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9902       vat_json_object_add_ip6 (node, "src_address", ip6);
9903     }
9904   else
9905     {
9906       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9907       vat_json_object_add_ip4 (node, "src_address", ip4);
9908     }
9909
9910   for (i = 0; i < count; i++)
9911     {
9912       s = &mp->servers[i];
9913
9914       vat_json_object_add_uint (node, "server-table-id",
9915                                 ntohl (s->server_vrf_id));
9916
9917       if (mp->is_ipv6)
9918         {
9919           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9920           vat_json_object_add_ip4 (node, "src_address", ip4);
9921         }
9922       else
9923         {
9924           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9925           vat_json_object_add_ip6 (node, "server_address", ip6);
9926         }
9927     }
9928 }
9929
9930 static int
9931 api_dhcp_proxy_dump (vat_main_t * vam)
9932 {
9933   unformat_input_t *i = vam->input;
9934   vl_api_control_ping_t *mp_ping;
9935   vl_api_dhcp_proxy_dump_t *mp;
9936   u8 is_ipv6 = 0;
9937   int ret;
9938
9939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9940     {
9941       if (unformat (i, "ipv6"))
9942         is_ipv6 = 1;
9943       else
9944         {
9945           clib_warning ("parse error '%U'", format_unformat_error, i);
9946           return -99;
9947         }
9948     }
9949
9950   M (DHCP_PROXY_DUMP, mp);
9951
9952   mp->is_ip6 = is_ipv6;
9953   S (mp);
9954
9955   /* Use a control ping for synchronization */
9956   MPING (CONTROL_PING, mp_ping);
9957   S (mp_ping);
9958
9959   W (ret);
9960   return ret;
9961 }
9962
9963 static int
9964 api_dhcp_proxy_set_vss (vat_main_t * vam)
9965 {
9966   unformat_input_t *i = vam->input;
9967   vl_api_dhcp_proxy_set_vss_t *mp;
9968   u8 is_ipv6 = 0;
9969   u8 is_add = 1;
9970   u32 tbl_id = ~0;
9971   u8 vss_type = VSS_TYPE_DEFAULT;
9972   u8 *vpn_ascii_id = 0;
9973   u32 oui = 0;
9974   u32 fib_id = 0;
9975   int ret;
9976
9977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9978     {
9979       if (unformat (i, "tbl_id %d", &tbl_id))
9980         ;
9981       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9982         vss_type = VSS_TYPE_ASCII;
9983       else if (unformat (i, "fib_id %d", &fib_id))
9984         vss_type = VSS_TYPE_VPN_ID;
9985       else if (unformat (i, "oui %d", &oui))
9986         vss_type = VSS_TYPE_VPN_ID;
9987       else if (unformat (i, "ipv6"))
9988         is_ipv6 = 1;
9989       else if (unformat (i, "del"))
9990         is_add = 0;
9991       else
9992         break;
9993     }
9994
9995   if (tbl_id == ~0)
9996     {
9997       errmsg ("missing tbl_id ");
9998       vec_free (vpn_ascii_id);
9999       return -99;
10000     }
10001
10002   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10003     {
10004       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10005       vec_free (vpn_ascii_id);
10006       return -99;
10007     }
10008
10009   M (DHCP_PROXY_SET_VSS, mp);
10010   mp->tbl_id = ntohl (tbl_id);
10011   mp->vss_type = vss_type;
10012   if (vpn_ascii_id)
10013     {
10014       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10015       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10016     }
10017   mp->vpn_index = ntohl (fib_id);
10018   mp->oui = ntohl (oui);
10019   mp->is_ipv6 = is_ipv6;
10020   mp->is_add = is_add;
10021
10022   S (mp);
10023   W (ret);
10024
10025   vec_free (vpn_ascii_id);
10026   return ret;
10027 }
10028
10029 static int
10030 api_dhcp_client_config (vat_main_t * vam)
10031 {
10032   unformat_input_t *i = vam->input;
10033   vl_api_dhcp_client_config_t *mp;
10034   u32 sw_if_index;
10035   u8 sw_if_index_set = 0;
10036   u8 is_add = 1;
10037   u8 *hostname = 0;
10038   u8 disable_event = 0;
10039   int ret;
10040
10041   /* Parse args required to build the message */
10042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10043     {
10044       if (unformat (i, "del"))
10045         is_add = 0;
10046       else
10047         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10048         sw_if_index_set = 1;
10049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10050         sw_if_index_set = 1;
10051       else if (unformat (i, "hostname %s", &hostname))
10052         ;
10053       else if (unformat (i, "disable_event"))
10054         disable_event = 1;
10055       else
10056         break;
10057     }
10058
10059   if (sw_if_index_set == 0)
10060     {
10061       errmsg ("missing interface name or sw_if_index");
10062       return -99;
10063     }
10064
10065   if (vec_len (hostname) > 63)
10066     {
10067       errmsg ("hostname too long");
10068     }
10069   vec_add1 (hostname, 0);
10070
10071   /* Construct the API message */
10072   M (DHCP_CLIENT_CONFIG, mp);
10073
10074   mp->is_add = is_add;
10075   mp->client.sw_if_index = htonl (sw_if_index);
10076   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10077   vec_free (hostname);
10078   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10079   mp->client.pid = htonl (getpid ());
10080
10081   /* send it... */
10082   S (mp);
10083
10084   /* Wait for a reply, return good/bad news  */
10085   W (ret);
10086   return ret;
10087 }
10088
10089 static int
10090 api_set_ip_flow_hash (vat_main_t * vam)
10091 {
10092   unformat_input_t *i = vam->input;
10093   vl_api_set_ip_flow_hash_t *mp;
10094   u32 vrf_id = 0;
10095   u8 is_ipv6 = 0;
10096   u8 vrf_id_set = 0;
10097   u8 src = 0;
10098   u8 dst = 0;
10099   u8 sport = 0;
10100   u8 dport = 0;
10101   u8 proto = 0;
10102   u8 reverse = 0;
10103   int ret;
10104
10105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10106     {
10107       if (unformat (i, "vrf %d", &vrf_id))
10108         vrf_id_set = 1;
10109       else if (unformat (i, "ipv6"))
10110         is_ipv6 = 1;
10111       else if (unformat (i, "src"))
10112         src = 1;
10113       else if (unformat (i, "dst"))
10114         dst = 1;
10115       else if (unformat (i, "sport"))
10116         sport = 1;
10117       else if (unformat (i, "dport"))
10118         dport = 1;
10119       else if (unformat (i, "proto"))
10120         proto = 1;
10121       else if (unformat (i, "reverse"))
10122         reverse = 1;
10123
10124       else
10125         {
10126           clib_warning ("parse error '%U'", format_unformat_error, i);
10127           return -99;
10128         }
10129     }
10130
10131   if (vrf_id_set == 0)
10132     {
10133       errmsg ("missing vrf id");
10134       return -99;
10135     }
10136
10137   M (SET_IP_FLOW_HASH, mp);
10138   mp->src = src;
10139   mp->dst = dst;
10140   mp->sport = sport;
10141   mp->dport = dport;
10142   mp->proto = proto;
10143   mp->reverse = reverse;
10144   mp->vrf_id = ntohl (vrf_id);
10145   mp->is_ipv6 = is_ipv6;
10146
10147   S (mp);
10148   W (ret);
10149   return ret;
10150 }
10151
10152 static int
10153 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10154 {
10155   unformat_input_t *i = vam->input;
10156   vl_api_sw_interface_ip6_enable_disable_t *mp;
10157   u32 sw_if_index;
10158   u8 sw_if_index_set = 0;
10159   u8 enable = 0;
10160   int ret;
10161
10162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10163     {
10164       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10165         sw_if_index_set = 1;
10166       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10167         sw_if_index_set = 1;
10168       else if (unformat (i, "enable"))
10169         enable = 1;
10170       else if (unformat (i, "disable"))
10171         enable = 0;
10172       else
10173         {
10174           clib_warning ("parse error '%U'", format_unformat_error, i);
10175           return -99;
10176         }
10177     }
10178
10179   if (sw_if_index_set == 0)
10180     {
10181       errmsg ("missing interface name or sw_if_index");
10182       return -99;
10183     }
10184
10185   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10186
10187   mp->sw_if_index = ntohl (sw_if_index);
10188   mp->enable = enable;
10189
10190   S (mp);
10191   W (ret);
10192   return ret;
10193 }
10194
10195 static int
10196 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10197 {
10198   unformat_input_t *i = vam->input;
10199   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10200   u32 sw_if_index;
10201   u8 sw_if_index_set = 0;
10202   u8 v6_address_set = 0;
10203   ip6_address_t v6address;
10204   int ret;
10205
10206   /* Parse args required to build the message */
10207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10208     {
10209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10210         sw_if_index_set = 1;
10211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10212         sw_if_index_set = 1;
10213       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10214         v6_address_set = 1;
10215       else
10216         break;
10217     }
10218
10219   if (sw_if_index_set == 0)
10220     {
10221       errmsg ("missing interface name or sw_if_index");
10222       return -99;
10223     }
10224   if (!v6_address_set)
10225     {
10226       errmsg ("no address set");
10227       return -99;
10228     }
10229
10230   /* Construct the API message */
10231   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10232
10233   mp->sw_if_index = ntohl (sw_if_index);
10234   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10235
10236   /* send it... */
10237   S (mp);
10238
10239   /* Wait for a reply, return good/bad news  */
10240   W (ret);
10241   return ret;
10242 }
10243
10244 static int
10245 api_ip6nd_proxy_add_del (vat_main_t * vam)
10246 {
10247   unformat_input_t *i = vam->input;
10248   vl_api_ip6nd_proxy_add_del_t *mp;
10249   u32 sw_if_index = ~0;
10250   u8 v6_address_set = 0;
10251   ip6_address_t v6address;
10252   u8 is_del = 0;
10253   int ret;
10254
10255   /* Parse args required to build the message */
10256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10257     {
10258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10259         ;
10260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10261         ;
10262       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10263         v6_address_set = 1;
10264       if (unformat (i, "del"))
10265         is_del = 1;
10266       else
10267         {
10268           clib_warning ("parse error '%U'", format_unformat_error, i);
10269           return -99;
10270         }
10271     }
10272
10273   if (sw_if_index == ~0)
10274     {
10275       errmsg ("missing interface name or sw_if_index");
10276       return -99;
10277     }
10278   if (!v6_address_set)
10279     {
10280       errmsg ("no address set");
10281       return -99;
10282     }
10283
10284   /* Construct the API message */
10285   M (IP6ND_PROXY_ADD_DEL, mp);
10286
10287   mp->is_del = is_del;
10288   mp->sw_if_index = ntohl (sw_if_index);
10289   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10290
10291   /* send it... */
10292   S (mp);
10293
10294   /* Wait for a reply, return good/bad news  */
10295   W (ret);
10296   return ret;
10297 }
10298
10299 static int
10300 api_ip6nd_proxy_dump (vat_main_t * vam)
10301 {
10302   vl_api_ip6nd_proxy_dump_t *mp;
10303   vl_api_control_ping_t *mp_ping;
10304   int ret;
10305
10306   M (IP6ND_PROXY_DUMP, mp);
10307
10308   S (mp);
10309
10310   /* Use a control ping for synchronization */
10311   MPING (CONTROL_PING, mp_ping);
10312   S (mp_ping);
10313
10314   W (ret);
10315   return ret;
10316 }
10317
10318 static void vl_api_ip6nd_proxy_details_t_handler
10319   (vl_api_ip6nd_proxy_details_t * mp)
10320 {
10321   vat_main_t *vam = &vat_main;
10322
10323   print (vam->ofp, "host %U sw_if_index %d",
10324          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10325 }
10326
10327 static void vl_api_ip6nd_proxy_details_t_handler_json
10328   (vl_api_ip6nd_proxy_details_t * mp)
10329 {
10330   vat_main_t *vam = &vat_main;
10331   struct in6_addr ip6;
10332   vat_json_node_t *node = NULL;
10333
10334   if (VAT_JSON_ARRAY != vam->json_tree.type)
10335     {
10336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10337       vat_json_init_array (&vam->json_tree);
10338     }
10339   node = vat_json_array_add (&vam->json_tree);
10340
10341   vat_json_init_object (node);
10342   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10343
10344   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10345   vat_json_object_add_ip6 (node, "host", ip6);
10346 }
10347
10348 static int
10349 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10350 {
10351   unformat_input_t *i = vam->input;
10352   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10353   u32 sw_if_index;
10354   u8 sw_if_index_set = 0;
10355   u32 address_length = 0;
10356   u8 v6_address_set = 0;
10357   ip6_address_t v6address;
10358   u8 use_default = 0;
10359   u8 no_advertise = 0;
10360   u8 off_link = 0;
10361   u8 no_autoconfig = 0;
10362   u8 no_onlink = 0;
10363   u8 is_no = 0;
10364   u32 val_lifetime = 0;
10365   u32 pref_lifetime = 0;
10366   int ret;
10367
10368   /* Parse args required to build the message */
10369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10370     {
10371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10372         sw_if_index_set = 1;
10373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10374         sw_if_index_set = 1;
10375       else if (unformat (i, "%U/%d",
10376                          unformat_ip6_address, &v6address, &address_length))
10377         v6_address_set = 1;
10378       else if (unformat (i, "val_life %d", &val_lifetime))
10379         ;
10380       else if (unformat (i, "pref_life %d", &pref_lifetime))
10381         ;
10382       else if (unformat (i, "def"))
10383         use_default = 1;
10384       else if (unformat (i, "noadv"))
10385         no_advertise = 1;
10386       else if (unformat (i, "offl"))
10387         off_link = 1;
10388       else if (unformat (i, "noauto"))
10389         no_autoconfig = 1;
10390       else if (unformat (i, "nolink"))
10391         no_onlink = 1;
10392       else if (unformat (i, "isno"))
10393         is_no = 1;
10394       else
10395         {
10396           clib_warning ("parse error '%U'", format_unformat_error, i);
10397           return -99;
10398         }
10399     }
10400
10401   if (sw_if_index_set == 0)
10402     {
10403       errmsg ("missing interface name or sw_if_index");
10404       return -99;
10405     }
10406   if (!v6_address_set)
10407     {
10408       errmsg ("no address set");
10409       return -99;
10410     }
10411
10412   /* Construct the API message */
10413   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10414
10415   mp->sw_if_index = ntohl (sw_if_index);
10416   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10417   mp->address_length = address_length;
10418   mp->use_default = use_default;
10419   mp->no_advertise = no_advertise;
10420   mp->off_link = off_link;
10421   mp->no_autoconfig = no_autoconfig;
10422   mp->no_onlink = no_onlink;
10423   mp->is_no = is_no;
10424   mp->val_lifetime = ntohl (val_lifetime);
10425   mp->pref_lifetime = ntohl (pref_lifetime);
10426
10427   /* send it... */
10428   S (mp);
10429
10430   /* Wait for a reply, return good/bad news  */
10431   W (ret);
10432   return ret;
10433 }
10434
10435 static int
10436 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10437 {
10438   unformat_input_t *i = vam->input;
10439   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10440   u32 sw_if_index;
10441   u8 sw_if_index_set = 0;
10442   u8 suppress = 0;
10443   u8 managed = 0;
10444   u8 other = 0;
10445   u8 ll_option = 0;
10446   u8 send_unicast = 0;
10447   u8 cease = 0;
10448   u8 is_no = 0;
10449   u8 default_router = 0;
10450   u32 max_interval = 0;
10451   u32 min_interval = 0;
10452   u32 lifetime = 0;
10453   u32 initial_count = 0;
10454   u32 initial_interval = 0;
10455   int ret;
10456
10457
10458   /* Parse args required to build the message */
10459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10460     {
10461       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10462         sw_if_index_set = 1;
10463       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10464         sw_if_index_set = 1;
10465       else if (unformat (i, "maxint %d", &max_interval))
10466         ;
10467       else if (unformat (i, "minint %d", &min_interval))
10468         ;
10469       else if (unformat (i, "life %d", &lifetime))
10470         ;
10471       else if (unformat (i, "count %d", &initial_count))
10472         ;
10473       else if (unformat (i, "interval %d", &initial_interval))
10474         ;
10475       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10476         suppress = 1;
10477       else if (unformat (i, "managed"))
10478         managed = 1;
10479       else if (unformat (i, "other"))
10480         other = 1;
10481       else if (unformat (i, "ll"))
10482         ll_option = 1;
10483       else if (unformat (i, "send"))
10484         send_unicast = 1;
10485       else if (unformat (i, "cease"))
10486         cease = 1;
10487       else if (unformat (i, "isno"))
10488         is_no = 1;
10489       else if (unformat (i, "def"))
10490         default_router = 1;
10491       else
10492         {
10493           clib_warning ("parse error '%U'", format_unformat_error, i);
10494           return -99;
10495         }
10496     }
10497
10498   if (sw_if_index_set == 0)
10499     {
10500       errmsg ("missing interface name or sw_if_index");
10501       return -99;
10502     }
10503
10504   /* Construct the API message */
10505   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10506
10507   mp->sw_if_index = ntohl (sw_if_index);
10508   mp->max_interval = ntohl (max_interval);
10509   mp->min_interval = ntohl (min_interval);
10510   mp->lifetime = ntohl (lifetime);
10511   mp->initial_count = ntohl (initial_count);
10512   mp->initial_interval = ntohl (initial_interval);
10513   mp->suppress = suppress;
10514   mp->managed = managed;
10515   mp->other = other;
10516   mp->ll_option = ll_option;
10517   mp->send_unicast = send_unicast;
10518   mp->cease = cease;
10519   mp->is_no = is_no;
10520   mp->default_router = default_router;
10521
10522   /* send it... */
10523   S (mp);
10524
10525   /* Wait for a reply, return good/bad news  */
10526   W (ret);
10527   return ret;
10528 }
10529
10530 static int
10531 api_set_arp_neighbor_limit (vat_main_t * vam)
10532 {
10533   unformat_input_t *i = vam->input;
10534   vl_api_set_arp_neighbor_limit_t *mp;
10535   u32 arp_nbr_limit;
10536   u8 limit_set = 0;
10537   u8 is_ipv6 = 0;
10538   int ret;
10539
10540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10541     {
10542       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10543         limit_set = 1;
10544       else if (unformat (i, "ipv6"))
10545         is_ipv6 = 1;
10546       else
10547         {
10548           clib_warning ("parse error '%U'", format_unformat_error, i);
10549           return -99;
10550         }
10551     }
10552
10553   if (limit_set == 0)
10554     {
10555       errmsg ("missing limit value");
10556       return -99;
10557     }
10558
10559   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10560
10561   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10562   mp->is_ipv6 = is_ipv6;
10563
10564   S (mp);
10565   W (ret);
10566   return ret;
10567 }
10568
10569 static int
10570 api_l2_patch_add_del (vat_main_t * vam)
10571 {
10572   unformat_input_t *i = vam->input;
10573   vl_api_l2_patch_add_del_t *mp;
10574   u32 rx_sw_if_index;
10575   u8 rx_sw_if_index_set = 0;
10576   u32 tx_sw_if_index;
10577   u8 tx_sw_if_index_set = 0;
10578   u8 is_add = 1;
10579   int ret;
10580
10581   /* Parse args required to build the message */
10582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10583     {
10584       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10585         rx_sw_if_index_set = 1;
10586       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10587         tx_sw_if_index_set = 1;
10588       else if (unformat (i, "rx"))
10589         {
10590           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10591             {
10592               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10593                             &rx_sw_if_index))
10594                 rx_sw_if_index_set = 1;
10595             }
10596           else
10597             break;
10598         }
10599       else if (unformat (i, "tx"))
10600         {
10601           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10602             {
10603               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10604                             &tx_sw_if_index))
10605                 tx_sw_if_index_set = 1;
10606             }
10607           else
10608             break;
10609         }
10610       else if (unformat (i, "del"))
10611         is_add = 0;
10612       else
10613         break;
10614     }
10615
10616   if (rx_sw_if_index_set == 0)
10617     {
10618       errmsg ("missing rx interface name or rx_sw_if_index");
10619       return -99;
10620     }
10621
10622   if (tx_sw_if_index_set == 0)
10623     {
10624       errmsg ("missing tx interface name or tx_sw_if_index");
10625       return -99;
10626     }
10627
10628   M (L2_PATCH_ADD_DEL, mp);
10629
10630   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10631   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10632   mp->is_add = is_add;
10633
10634   S (mp);
10635   W (ret);
10636   return ret;
10637 }
10638
10639 u8 is_del;
10640 u8 localsid_addr[16];
10641 u8 end_psp;
10642 u8 behavior;
10643 u32 sw_if_index;
10644 u32 vlan_index;
10645 u32 fib_table;
10646 u8 nh_addr[16];
10647
10648 static int
10649 api_sr_localsid_add_del (vat_main_t * vam)
10650 {
10651   unformat_input_t *i = vam->input;
10652   vl_api_sr_localsid_add_del_t *mp;
10653
10654   u8 is_del;
10655   ip6_address_t localsid;
10656   u8 end_psp = 0;
10657   u8 behavior = ~0;
10658   u32 sw_if_index;
10659   u32 fib_table = ~(u32) 0;
10660   ip6_address_t nh_addr6;
10661   ip4_address_t nh_addr4;
10662   memset (&nh_addr6, 0, sizeof (ip6_address_t));
10663   memset (&nh_addr4, 0, sizeof (ip4_address_t));
10664
10665   bool nexthop_set = 0;
10666
10667   int ret;
10668
10669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10670     {
10671       if (unformat (i, "del"))
10672         is_del = 1;
10673       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10674       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10675         nexthop_set = 1;
10676       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10677         nexthop_set = 1;
10678       else if (unformat (i, "behavior %u", &behavior));
10679       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10680       else if (unformat (i, "fib-table %u", &fib_table));
10681       else if (unformat (i, "end.psp %u", &behavior));
10682       else
10683         break;
10684     }
10685
10686   M (SR_LOCALSID_ADD_DEL, mp);
10687
10688   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10689   if (nexthop_set)
10690     {
10691       clib_memcpy (mp->nh_addr6, &nh_addr4, sizeof (mp->nh_addr6));
10692       clib_memcpy (mp->nh_addr4, &nh_addr6, sizeof (mp->nh_addr4));
10693     }
10694   mp->behavior = behavior;
10695   mp->sw_if_index = ntohl (sw_if_index);
10696   mp->fib_table = ntohl (fib_table);
10697   mp->end_psp = end_psp;
10698   mp->is_del = is_del;
10699
10700   S (mp);
10701   W (ret);
10702   return ret;
10703 }
10704
10705 static int
10706 api_ioam_enable (vat_main_t * vam)
10707 {
10708   unformat_input_t *input = vam->input;
10709   vl_api_ioam_enable_t *mp;
10710   u32 id = 0;
10711   int has_trace_option = 0;
10712   int has_pot_option = 0;
10713   int has_seqno_option = 0;
10714   int has_analyse_option = 0;
10715   int ret;
10716
10717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10718     {
10719       if (unformat (input, "trace"))
10720         has_trace_option = 1;
10721       else if (unformat (input, "pot"))
10722         has_pot_option = 1;
10723       else if (unformat (input, "seqno"))
10724         has_seqno_option = 1;
10725       else if (unformat (input, "analyse"))
10726         has_analyse_option = 1;
10727       else
10728         break;
10729     }
10730   M (IOAM_ENABLE, mp);
10731   mp->id = htons (id);
10732   mp->seqno = has_seqno_option;
10733   mp->analyse = has_analyse_option;
10734   mp->pot_enable = has_pot_option;
10735   mp->trace_enable = has_trace_option;
10736
10737   S (mp);
10738   W (ret);
10739   return ret;
10740 }
10741
10742
10743 static int
10744 api_ioam_disable (vat_main_t * vam)
10745 {
10746   vl_api_ioam_disable_t *mp;
10747   int ret;
10748
10749   M (IOAM_DISABLE, mp);
10750   S (mp);
10751   W (ret);
10752   return ret;
10753 }
10754
10755 #define foreach_tcp_proto_field                 \
10756 _(src_port)                                     \
10757 _(dst_port)
10758
10759 #define foreach_udp_proto_field                 \
10760 _(src_port)                                     \
10761 _(dst_port)
10762
10763 #define foreach_ip4_proto_field                 \
10764 _(src_address)                                  \
10765 _(dst_address)                                  \
10766 _(tos)                                          \
10767 _(length)                                       \
10768 _(fragment_id)                                  \
10769 _(ttl)                                          \
10770 _(protocol)                                     \
10771 _(checksum)
10772
10773 typedef struct
10774 {
10775   u16 src_port, dst_port;
10776 } tcpudp_header_t;
10777
10778 #if VPP_API_TEST_BUILTIN == 0
10779 uword
10780 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10781 {
10782   u8 **maskp = va_arg (*args, u8 **);
10783   u8 *mask = 0;
10784   u8 found_something = 0;
10785   tcp_header_t *tcp;
10786
10787 #define _(a) u8 a=0;
10788   foreach_tcp_proto_field;
10789 #undef _
10790
10791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10792     {
10793       if (0);
10794 #define _(a) else if (unformat (input, #a)) a=1;
10795       foreach_tcp_proto_field
10796 #undef _
10797         else
10798         break;
10799     }
10800
10801 #define _(a) found_something += a;
10802   foreach_tcp_proto_field;
10803 #undef _
10804
10805   if (found_something == 0)
10806     return 0;
10807
10808   vec_validate (mask, sizeof (*tcp) - 1);
10809
10810   tcp = (tcp_header_t *) mask;
10811
10812 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10813   foreach_tcp_proto_field;
10814 #undef _
10815
10816   *maskp = mask;
10817   return 1;
10818 }
10819
10820 uword
10821 unformat_udp_mask (unformat_input_t * input, va_list * args)
10822 {
10823   u8 **maskp = va_arg (*args, u8 **);
10824   u8 *mask = 0;
10825   u8 found_something = 0;
10826   udp_header_t *udp;
10827
10828 #define _(a) u8 a=0;
10829   foreach_udp_proto_field;
10830 #undef _
10831
10832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10833     {
10834       if (0);
10835 #define _(a) else if (unformat (input, #a)) a=1;
10836       foreach_udp_proto_field
10837 #undef _
10838         else
10839         break;
10840     }
10841
10842 #define _(a) found_something += a;
10843   foreach_udp_proto_field;
10844 #undef _
10845
10846   if (found_something == 0)
10847     return 0;
10848
10849   vec_validate (mask, sizeof (*udp) - 1);
10850
10851   udp = (udp_header_t *) mask;
10852
10853 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10854   foreach_udp_proto_field;
10855 #undef _
10856
10857   *maskp = mask;
10858   return 1;
10859 }
10860
10861 uword
10862 unformat_l4_mask (unformat_input_t * input, va_list * args)
10863 {
10864   u8 **maskp = va_arg (*args, u8 **);
10865   u16 src_port = 0, dst_port = 0;
10866   tcpudp_header_t *tcpudp;
10867
10868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10869     {
10870       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10871         return 1;
10872       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10873         return 1;
10874       else if (unformat (input, "src_port"))
10875         src_port = 0xFFFF;
10876       else if (unformat (input, "dst_port"))
10877         dst_port = 0xFFFF;
10878       else
10879         return 0;
10880     }
10881
10882   if (!src_port && !dst_port)
10883     return 0;
10884
10885   u8 *mask = 0;
10886   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10887
10888   tcpudp = (tcpudp_header_t *) mask;
10889   tcpudp->src_port = src_port;
10890   tcpudp->dst_port = dst_port;
10891
10892   *maskp = mask;
10893
10894   return 1;
10895 }
10896
10897 uword
10898 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10899 {
10900   u8 **maskp = va_arg (*args, u8 **);
10901   u8 *mask = 0;
10902   u8 found_something = 0;
10903   ip4_header_t *ip;
10904
10905 #define _(a) u8 a=0;
10906   foreach_ip4_proto_field;
10907 #undef _
10908   u8 version = 0;
10909   u8 hdr_length = 0;
10910
10911
10912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10913     {
10914       if (unformat (input, "version"))
10915         version = 1;
10916       else if (unformat (input, "hdr_length"))
10917         hdr_length = 1;
10918       else if (unformat (input, "src"))
10919         src_address = 1;
10920       else if (unformat (input, "dst"))
10921         dst_address = 1;
10922       else if (unformat (input, "proto"))
10923         protocol = 1;
10924
10925 #define _(a) else if (unformat (input, #a)) a=1;
10926       foreach_ip4_proto_field
10927 #undef _
10928         else
10929         break;
10930     }
10931
10932 #define _(a) found_something += a;
10933   foreach_ip4_proto_field;
10934 #undef _
10935
10936   if (found_something == 0)
10937     return 0;
10938
10939   vec_validate (mask, sizeof (*ip) - 1);
10940
10941   ip = (ip4_header_t *) mask;
10942
10943 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10944   foreach_ip4_proto_field;
10945 #undef _
10946
10947   ip->ip_version_and_header_length = 0;
10948
10949   if (version)
10950     ip->ip_version_and_header_length |= 0xF0;
10951
10952   if (hdr_length)
10953     ip->ip_version_and_header_length |= 0x0F;
10954
10955   *maskp = mask;
10956   return 1;
10957 }
10958
10959 #define foreach_ip6_proto_field                 \
10960 _(src_address)                                  \
10961 _(dst_address)                                  \
10962 _(payload_length)                               \
10963 _(hop_limit)                                    \
10964 _(protocol)
10965
10966 uword
10967 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10968 {
10969   u8 **maskp = va_arg (*args, u8 **);
10970   u8 *mask = 0;
10971   u8 found_something = 0;
10972   ip6_header_t *ip;
10973   u32 ip_version_traffic_class_and_flow_label;
10974
10975 #define _(a) u8 a=0;
10976   foreach_ip6_proto_field;
10977 #undef _
10978   u8 version = 0;
10979   u8 traffic_class = 0;
10980   u8 flow_label = 0;
10981
10982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (input, "version"))
10985         version = 1;
10986       else if (unformat (input, "traffic-class"))
10987         traffic_class = 1;
10988       else if (unformat (input, "flow-label"))
10989         flow_label = 1;
10990       else if (unformat (input, "src"))
10991         src_address = 1;
10992       else if (unformat (input, "dst"))
10993         dst_address = 1;
10994       else if (unformat (input, "proto"))
10995         protocol = 1;
10996
10997 #define _(a) else if (unformat (input, #a)) a=1;
10998       foreach_ip6_proto_field
10999 #undef _
11000         else
11001         break;
11002     }
11003
11004 #define _(a) found_something += a;
11005   foreach_ip6_proto_field;
11006 #undef _
11007
11008   if (found_something == 0)
11009     return 0;
11010
11011   vec_validate (mask, sizeof (*ip) - 1);
11012
11013   ip = (ip6_header_t *) mask;
11014
11015 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11016   foreach_ip6_proto_field;
11017 #undef _
11018
11019   ip_version_traffic_class_and_flow_label = 0;
11020
11021   if (version)
11022     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11023
11024   if (traffic_class)
11025     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11026
11027   if (flow_label)
11028     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11029
11030   ip->ip_version_traffic_class_and_flow_label =
11031     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11032
11033   *maskp = mask;
11034   return 1;
11035 }
11036
11037 uword
11038 unformat_l3_mask (unformat_input_t * input, va_list * args)
11039 {
11040   u8 **maskp = va_arg (*args, u8 **);
11041
11042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11043     {
11044       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11045         return 1;
11046       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11047         return 1;
11048       else
11049         break;
11050     }
11051   return 0;
11052 }
11053
11054 uword
11055 unformat_l2_mask (unformat_input_t * input, va_list * args)
11056 {
11057   u8 **maskp = va_arg (*args, u8 **);
11058   u8 *mask = 0;
11059   u8 src = 0;
11060   u8 dst = 0;
11061   u8 proto = 0;
11062   u8 tag1 = 0;
11063   u8 tag2 = 0;
11064   u8 ignore_tag1 = 0;
11065   u8 ignore_tag2 = 0;
11066   u8 cos1 = 0;
11067   u8 cos2 = 0;
11068   u8 dot1q = 0;
11069   u8 dot1ad = 0;
11070   int len = 14;
11071
11072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11073     {
11074       if (unformat (input, "src"))
11075         src = 1;
11076       else if (unformat (input, "dst"))
11077         dst = 1;
11078       else if (unformat (input, "proto"))
11079         proto = 1;
11080       else if (unformat (input, "tag1"))
11081         tag1 = 1;
11082       else if (unformat (input, "tag2"))
11083         tag2 = 1;
11084       else if (unformat (input, "ignore-tag1"))
11085         ignore_tag1 = 1;
11086       else if (unformat (input, "ignore-tag2"))
11087         ignore_tag2 = 1;
11088       else if (unformat (input, "cos1"))
11089         cos1 = 1;
11090       else if (unformat (input, "cos2"))
11091         cos2 = 1;
11092       else if (unformat (input, "dot1q"))
11093         dot1q = 1;
11094       else if (unformat (input, "dot1ad"))
11095         dot1ad = 1;
11096       else
11097         break;
11098     }
11099   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11100        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11101     return 0;
11102
11103   if (tag1 || ignore_tag1 || cos1 || dot1q)
11104     len = 18;
11105   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11106     len = 22;
11107
11108   vec_validate (mask, len - 1);
11109
11110   if (dst)
11111     memset (mask, 0xff, 6);
11112
11113   if (src)
11114     memset (mask + 6, 0xff, 6);
11115
11116   if (tag2 || dot1ad)
11117     {
11118       /* inner vlan tag */
11119       if (tag2)
11120         {
11121           mask[19] = 0xff;
11122           mask[18] = 0x0f;
11123         }
11124       if (cos2)
11125         mask[18] |= 0xe0;
11126       if (proto)
11127         mask[21] = mask[20] = 0xff;
11128       if (tag1)
11129         {
11130           mask[15] = 0xff;
11131           mask[14] = 0x0f;
11132         }
11133       if (cos1)
11134         mask[14] |= 0xe0;
11135       *maskp = mask;
11136       return 1;
11137     }
11138   if (tag1 | dot1q)
11139     {
11140       if (tag1)
11141         {
11142           mask[15] = 0xff;
11143           mask[14] = 0x0f;
11144         }
11145       if (cos1)
11146         mask[14] |= 0xe0;
11147       if (proto)
11148         mask[16] = mask[17] = 0xff;
11149
11150       *maskp = mask;
11151       return 1;
11152     }
11153   if (cos2)
11154     mask[18] |= 0xe0;
11155   if (cos1)
11156     mask[14] |= 0xe0;
11157   if (proto)
11158     mask[12] = mask[13] = 0xff;
11159
11160   *maskp = mask;
11161   return 1;
11162 }
11163
11164 uword
11165 unformat_classify_mask (unformat_input_t * input, va_list * args)
11166 {
11167   u8 **maskp = va_arg (*args, u8 **);
11168   u32 *skipp = va_arg (*args, u32 *);
11169   u32 *matchp = va_arg (*args, u32 *);
11170   u32 match;
11171   u8 *mask = 0;
11172   u8 *l2 = 0;
11173   u8 *l3 = 0;
11174   u8 *l4 = 0;
11175   int i;
11176
11177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11178     {
11179       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11180         ;
11181       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11182         ;
11183       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11184         ;
11185       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11186         ;
11187       else
11188         break;
11189     }
11190
11191   if (l4 && !l3)
11192     {
11193       vec_free (mask);
11194       vec_free (l2);
11195       vec_free (l4);
11196       return 0;
11197     }
11198
11199   if (mask || l2 || l3 || l4)
11200     {
11201       if (l2 || l3 || l4)
11202         {
11203           /* "With a free Ethernet header in every package" */
11204           if (l2 == 0)
11205             vec_validate (l2, 13);
11206           mask = l2;
11207           if (vec_len (l3))
11208             {
11209               vec_append (mask, l3);
11210               vec_free (l3);
11211             }
11212           if (vec_len (l4))
11213             {
11214               vec_append (mask, l4);
11215               vec_free (l4);
11216             }
11217         }
11218
11219       /* Scan forward looking for the first significant mask octet */
11220       for (i = 0; i < vec_len (mask); i++)
11221         if (mask[i])
11222           break;
11223
11224       /* compute (skip, match) params */
11225       *skipp = i / sizeof (u32x4);
11226       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11227
11228       /* Pad mask to an even multiple of the vector size */
11229       while (vec_len (mask) % sizeof (u32x4))
11230         vec_add1 (mask, 0);
11231
11232       match = vec_len (mask) / sizeof (u32x4);
11233
11234       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11235         {
11236           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11237           if (*tmp || *(tmp + 1))
11238             break;
11239           match--;
11240         }
11241       if (match == 0)
11242         clib_warning ("BUG: match 0");
11243
11244       _vec_len (mask) = match * sizeof (u32x4);
11245
11246       *matchp = match;
11247       *maskp = mask;
11248
11249       return 1;
11250     }
11251
11252   return 0;
11253 }
11254 #endif /* VPP_API_TEST_BUILTIN */
11255
11256 #define foreach_l2_next                         \
11257 _(drop, DROP)                                   \
11258 _(ethernet, ETHERNET_INPUT)                     \
11259 _(ip4, IP4_INPUT)                               \
11260 _(ip6, IP6_INPUT)
11261
11262 uword
11263 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11264 {
11265   u32 *miss_next_indexp = va_arg (*args, u32 *);
11266   u32 next_index = 0;
11267   u32 tmp;
11268
11269 #define _(n,N) \
11270   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11271   foreach_l2_next;
11272 #undef _
11273
11274   if (unformat (input, "%d", &tmp))
11275     {
11276       next_index = tmp;
11277       goto out;
11278     }
11279
11280   return 0;
11281
11282 out:
11283   *miss_next_indexp = next_index;
11284   return 1;
11285 }
11286
11287 #define foreach_ip_next                         \
11288 _(drop, DROP)                                   \
11289 _(local, LOCAL)                                 \
11290 _(rewrite, REWRITE)
11291
11292 uword
11293 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11294 {
11295   u32 *miss_next_indexp = va_arg (*args, u32 *);
11296   u32 next_index = 0;
11297   u32 tmp;
11298
11299 #define _(n,N) \
11300   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11301   foreach_ip_next;
11302 #undef _
11303
11304   if (unformat (input, "%d", &tmp))
11305     {
11306       next_index = tmp;
11307       goto out;
11308     }
11309
11310   return 0;
11311
11312 out:
11313   *miss_next_indexp = next_index;
11314   return 1;
11315 }
11316
11317 #define foreach_acl_next                        \
11318 _(deny, DENY)
11319
11320 uword
11321 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11322 {
11323   u32 *miss_next_indexp = va_arg (*args, u32 *);
11324   u32 next_index = 0;
11325   u32 tmp;
11326
11327 #define _(n,N) \
11328   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11329   foreach_acl_next;
11330 #undef _
11331
11332   if (unformat (input, "permit"))
11333     {
11334       next_index = ~0;
11335       goto out;
11336     }
11337   else if (unformat (input, "%d", &tmp))
11338     {
11339       next_index = tmp;
11340       goto out;
11341     }
11342
11343   return 0;
11344
11345 out:
11346   *miss_next_indexp = next_index;
11347   return 1;
11348 }
11349
11350 uword
11351 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11352 {
11353   u32 *r = va_arg (*args, u32 *);
11354
11355   if (unformat (input, "conform-color"))
11356     *r = POLICE_CONFORM;
11357   else if (unformat (input, "exceed-color"))
11358     *r = POLICE_EXCEED;
11359   else
11360     return 0;
11361
11362   return 1;
11363 }
11364
11365 static int
11366 api_classify_add_del_table (vat_main_t * vam)
11367 {
11368   unformat_input_t *i = vam->input;
11369   vl_api_classify_add_del_table_t *mp;
11370
11371   u32 nbuckets = 2;
11372   u32 skip = ~0;
11373   u32 match = ~0;
11374   int is_add = 1;
11375   int del_chain = 0;
11376   u32 table_index = ~0;
11377   u32 next_table_index = ~0;
11378   u32 miss_next_index = ~0;
11379   u32 memory_size = 32 << 20;
11380   u8 *mask = 0;
11381   u32 current_data_flag = 0;
11382   int current_data_offset = 0;
11383   int ret;
11384
11385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11386     {
11387       if (unformat (i, "del"))
11388         is_add = 0;
11389       else if (unformat (i, "del-chain"))
11390         {
11391           is_add = 0;
11392           del_chain = 1;
11393         }
11394       else if (unformat (i, "buckets %d", &nbuckets))
11395         ;
11396       else if (unformat (i, "memory_size %d", &memory_size))
11397         ;
11398       else if (unformat (i, "skip %d", &skip))
11399         ;
11400       else if (unformat (i, "match %d", &match))
11401         ;
11402       else if (unformat (i, "table %d", &table_index))
11403         ;
11404       else if (unformat (i, "mask %U", unformat_classify_mask,
11405                          &mask, &skip, &match))
11406         ;
11407       else if (unformat (i, "next-table %d", &next_table_index))
11408         ;
11409       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11410                          &miss_next_index))
11411         ;
11412       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11413                          &miss_next_index))
11414         ;
11415       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11416                          &miss_next_index))
11417         ;
11418       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11419         ;
11420       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11421         ;
11422       else
11423         break;
11424     }
11425
11426   if (is_add && mask == 0)
11427     {
11428       errmsg ("Mask required");
11429       return -99;
11430     }
11431
11432   if (is_add && skip == ~0)
11433     {
11434       errmsg ("skip count required");
11435       return -99;
11436     }
11437
11438   if (is_add && match == ~0)
11439     {
11440       errmsg ("match count required");
11441       return -99;
11442     }
11443
11444   if (!is_add && table_index == ~0)
11445     {
11446       errmsg ("table index required for delete");
11447       return -99;
11448     }
11449
11450   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11451
11452   mp->is_add = is_add;
11453   mp->del_chain = del_chain;
11454   mp->table_index = ntohl (table_index);
11455   mp->nbuckets = ntohl (nbuckets);
11456   mp->memory_size = ntohl (memory_size);
11457   mp->skip_n_vectors = ntohl (skip);
11458   mp->match_n_vectors = ntohl (match);
11459   mp->next_table_index = ntohl (next_table_index);
11460   mp->miss_next_index = ntohl (miss_next_index);
11461   mp->current_data_flag = ntohl (current_data_flag);
11462   mp->current_data_offset = ntohl (current_data_offset);
11463   clib_memcpy (mp->mask, mask, vec_len (mask));
11464
11465   vec_free (mask);
11466
11467   S (mp);
11468   W (ret);
11469   return ret;
11470 }
11471
11472 #if VPP_API_TEST_BUILTIN == 0
11473 uword
11474 unformat_l4_match (unformat_input_t * input, va_list * args)
11475 {
11476   u8 **matchp = va_arg (*args, u8 **);
11477
11478   u8 *proto_header = 0;
11479   int src_port = 0;
11480   int dst_port = 0;
11481
11482   tcpudp_header_t h;
11483
11484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11485     {
11486       if (unformat (input, "src_port %d", &src_port))
11487         ;
11488       else if (unformat (input, "dst_port %d", &dst_port))
11489         ;
11490       else
11491         return 0;
11492     }
11493
11494   h.src_port = clib_host_to_net_u16 (src_port);
11495   h.dst_port = clib_host_to_net_u16 (dst_port);
11496   vec_validate (proto_header, sizeof (h) - 1);
11497   memcpy (proto_header, &h, sizeof (h));
11498
11499   *matchp = proto_header;
11500
11501   return 1;
11502 }
11503
11504 uword
11505 unformat_ip4_match (unformat_input_t * input, va_list * args)
11506 {
11507   u8 **matchp = va_arg (*args, u8 **);
11508   u8 *match = 0;
11509   ip4_header_t *ip;
11510   int version = 0;
11511   u32 version_val;
11512   int hdr_length = 0;
11513   u32 hdr_length_val;
11514   int src = 0, dst = 0;
11515   ip4_address_t src_val, dst_val;
11516   int proto = 0;
11517   u32 proto_val;
11518   int tos = 0;
11519   u32 tos_val;
11520   int length = 0;
11521   u32 length_val;
11522   int fragment_id = 0;
11523   u32 fragment_id_val;
11524   int ttl = 0;
11525   int ttl_val;
11526   int checksum = 0;
11527   u32 checksum_val;
11528
11529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11530     {
11531       if (unformat (input, "version %d", &version_val))
11532         version = 1;
11533       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11534         hdr_length = 1;
11535       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11536         src = 1;
11537       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11538         dst = 1;
11539       else if (unformat (input, "proto %d", &proto_val))
11540         proto = 1;
11541       else if (unformat (input, "tos %d", &tos_val))
11542         tos = 1;
11543       else if (unformat (input, "length %d", &length_val))
11544         length = 1;
11545       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11546         fragment_id = 1;
11547       else if (unformat (input, "ttl %d", &ttl_val))
11548         ttl = 1;
11549       else if (unformat (input, "checksum %d", &checksum_val))
11550         checksum = 1;
11551       else
11552         break;
11553     }
11554
11555   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11556       + ttl + checksum == 0)
11557     return 0;
11558
11559   /*
11560    * Aligned because we use the real comparison functions
11561    */
11562   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11563
11564   ip = (ip4_header_t *) match;
11565
11566   /* These are realistically matched in practice */
11567   if (src)
11568     ip->src_address.as_u32 = src_val.as_u32;
11569
11570   if (dst)
11571     ip->dst_address.as_u32 = dst_val.as_u32;
11572
11573   if (proto)
11574     ip->protocol = proto_val;
11575
11576
11577   /* These are not, but they're included for completeness */
11578   if (version)
11579     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11580
11581   if (hdr_length)
11582     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11583
11584   if (tos)
11585     ip->tos = tos_val;
11586
11587   if (length)
11588     ip->length = clib_host_to_net_u16 (length_val);
11589
11590   if (ttl)
11591     ip->ttl = ttl_val;
11592
11593   if (checksum)
11594     ip->checksum = clib_host_to_net_u16 (checksum_val);
11595
11596   *matchp = match;
11597   return 1;
11598 }
11599
11600 uword
11601 unformat_ip6_match (unformat_input_t * input, va_list * args)
11602 {
11603   u8 **matchp = va_arg (*args, u8 **);
11604   u8 *match = 0;
11605   ip6_header_t *ip;
11606   int version = 0;
11607   u32 version_val;
11608   u8 traffic_class = 0;
11609   u32 traffic_class_val = 0;
11610   u8 flow_label = 0;
11611   u8 flow_label_val;
11612   int src = 0, dst = 0;
11613   ip6_address_t src_val, dst_val;
11614   int proto = 0;
11615   u32 proto_val;
11616   int payload_length = 0;
11617   u32 payload_length_val;
11618   int hop_limit = 0;
11619   int hop_limit_val;
11620   u32 ip_version_traffic_class_and_flow_label;
11621
11622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11623     {
11624       if (unformat (input, "version %d", &version_val))
11625         version = 1;
11626       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11627         traffic_class = 1;
11628       else if (unformat (input, "flow_label %d", &flow_label_val))
11629         flow_label = 1;
11630       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11631         src = 1;
11632       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11633         dst = 1;
11634       else if (unformat (input, "proto %d", &proto_val))
11635         proto = 1;
11636       else if (unformat (input, "payload_length %d", &payload_length_val))
11637         payload_length = 1;
11638       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11639         hop_limit = 1;
11640       else
11641         break;
11642     }
11643
11644   if (version + traffic_class + flow_label + src + dst + proto +
11645       payload_length + hop_limit == 0)
11646     return 0;
11647
11648   /*
11649    * Aligned because we use the real comparison functions
11650    */
11651   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11652
11653   ip = (ip6_header_t *) match;
11654
11655   if (src)
11656     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11657
11658   if (dst)
11659     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11660
11661   if (proto)
11662     ip->protocol = proto_val;
11663
11664   ip_version_traffic_class_and_flow_label = 0;
11665
11666   if (version)
11667     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11668
11669   if (traffic_class)
11670     ip_version_traffic_class_and_flow_label |=
11671       (traffic_class_val & 0xFF) << 20;
11672
11673   if (flow_label)
11674     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11675
11676   ip->ip_version_traffic_class_and_flow_label =
11677     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11678
11679   if (payload_length)
11680     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11681
11682   if (hop_limit)
11683     ip->hop_limit = hop_limit_val;
11684
11685   *matchp = match;
11686   return 1;
11687 }
11688
11689 uword
11690 unformat_l3_match (unformat_input_t * input, va_list * args)
11691 {
11692   u8 **matchp = va_arg (*args, u8 **);
11693
11694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11695     {
11696       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11697         return 1;
11698       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11699         return 1;
11700       else
11701         break;
11702     }
11703   return 0;
11704 }
11705
11706 uword
11707 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11708 {
11709   u8 *tagp = va_arg (*args, u8 *);
11710   u32 tag;
11711
11712   if (unformat (input, "%d", &tag))
11713     {
11714       tagp[0] = (tag >> 8) & 0x0F;
11715       tagp[1] = tag & 0xFF;
11716       return 1;
11717     }
11718
11719   return 0;
11720 }
11721
11722 uword
11723 unformat_l2_match (unformat_input_t * input, va_list * args)
11724 {
11725   u8 **matchp = va_arg (*args, u8 **);
11726   u8 *match = 0;
11727   u8 src = 0;
11728   u8 src_val[6];
11729   u8 dst = 0;
11730   u8 dst_val[6];
11731   u8 proto = 0;
11732   u16 proto_val;
11733   u8 tag1 = 0;
11734   u8 tag1_val[2];
11735   u8 tag2 = 0;
11736   u8 tag2_val[2];
11737   int len = 14;
11738   u8 ignore_tag1 = 0;
11739   u8 ignore_tag2 = 0;
11740   u8 cos1 = 0;
11741   u8 cos2 = 0;
11742   u32 cos1_val = 0;
11743   u32 cos2_val = 0;
11744
11745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11746     {
11747       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11748         src = 1;
11749       else
11750         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11751         dst = 1;
11752       else if (unformat (input, "proto %U",
11753                          unformat_ethernet_type_host_byte_order, &proto_val))
11754         proto = 1;
11755       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11756         tag1 = 1;
11757       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11758         tag2 = 1;
11759       else if (unformat (input, "ignore-tag1"))
11760         ignore_tag1 = 1;
11761       else if (unformat (input, "ignore-tag2"))
11762         ignore_tag2 = 1;
11763       else if (unformat (input, "cos1 %d", &cos1_val))
11764         cos1 = 1;
11765       else if (unformat (input, "cos2 %d", &cos2_val))
11766         cos2 = 1;
11767       else
11768         break;
11769     }
11770   if ((src + dst + proto + tag1 + tag2 +
11771        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11772     return 0;
11773
11774   if (tag1 || ignore_tag1 || cos1)
11775     len = 18;
11776   if (tag2 || ignore_tag2 || cos2)
11777     len = 22;
11778
11779   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11780
11781   if (dst)
11782     clib_memcpy (match, dst_val, 6);
11783
11784   if (src)
11785     clib_memcpy (match + 6, src_val, 6);
11786
11787   if (tag2)
11788     {
11789       /* inner vlan tag */
11790       match[19] = tag2_val[1];
11791       match[18] = tag2_val[0];
11792       if (cos2)
11793         match[18] |= (cos2_val & 0x7) << 5;
11794       if (proto)
11795         {
11796           match[21] = proto_val & 0xff;
11797           match[20] = proto_val >> 8;
11798         }
11799       if (tag1)
11800         {
11801           match[15] = tag1_val[1];
11802           match[14] = tag1_val[0];
11803         }
11804       if (cos1)
11805         match[14] |= (cos1_val & 0x7) << 5;
11806       *matchp = match;
11807       return 1;
11808     }
11809   if (tag1)
11810     {
11811       match[15] = tag1_val[1];
11812       match[14] = tag1_val[0];
11813       if (proto)
11814         {
11815           match[17] = proto_val & 0xff;
11816           match[16] = proto_val >> 8;
11817         }
11818       if (cos1)
11819         match[14] |= (cos1_val & 0x7) << 5;
11820
11821       *matchp = match;
11822       return 1;
11823     }
11824   if (cos2)
11825     match[18] |= (cos2_val & 0x7) << 5;
11826   if (cos1)
11827     match[14] |= (cos1_val & 0x7) << 5;
11828   if (proto)
11829     {
11830       match[13] = proto_val & 0xff;
11831       match[12] = proto_val >> 8;
11832     }
11833
11834   *matchp = match;
11835   return 1;
11836 }
11837
11838 uword
11839 unformat_qos_source (unformat_input_t * input, va_list * args)
11840 {
11841   int *qs = va_arg (*args, int *);
11842
11843   if (unformat (input, "ip"))
11844     *qs = QOS_SOURCE_IP;
11845   else if (unformat (input, "mpls"))
11846     *qs = QOS_SOURCE_MPLS;
11847   else if (unformat (input, "ext"))
11848     *qs = QOS_SOURCE_EXT;
11849   else if (unformat (input, "vlan"))
11850     *qs = QOS_SOURCE_VLAN;
11851   else
11852     return 0;
11853
11854   return 1;
11855 }
11856 #endif
11857
11858 uword
11859 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11860 {
11861   u8 **matchp = va_arg (*args, u8 **);
11862   u32 skip_n_vectors = va_arg (*args, u32);
11863   u32 match_n_vectors = va_arg (*args, u32);
11864
11865   u8 *match = 0;
11866   u8 *l2 = 0;
11867   u8 *l3 = 0;
11868   u8 *l4 = 0;
11869
11870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11871     {
11872       if (unformat (input, "hex %U", unformat_hex_string, &match))
11873         ;
11874       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11875         ;
11876       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11877         ;
11878       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11879         ;
11880       else
11881         break;
11882     }
11883
11884   if (l4 && !l3)
11885     {
11886       vec_free (match);
11887       vec_free (l2);
11888       vec_free (l4);
11889       return 0;
11890     }
11891
11892   if (match || l2 || l3 || l4)
11893     {
11894       if (l2 || l3 || l4)
11895         {
11896           /* "Win a free Ethernet header in every packet" */
11897           if (l2 == 0)
11898             vec_validate_aligned (l2, 13, sizeof (u32x4));
11899           match = l2;
11900           if (vec_len (l3))
11901             {
11902               vec_append_aligned (match, l3, sizeof (u32x4));
11903               vec_free (l3);
11904             }
11905           if (vec_len (l4))
11906             {
11907               vec_append_aligned (match, l4, sizeof (u32x4));
11908               vec_free (l4);
11909             }
11910         }
11911
11912       /* Make sure the vector is big enough even if key is all 0's */
11913       vec_validate_aligned
11914         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11915          sizeof (u32x4));
11916
11917       /* Set size, include skipped vectors */
11918       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11919
11920       *matchp = match;
11921
11922       return 1;
11923     }
11924
11925   return 0;
11926 }
11927
11928 static int
11929 api_classify_add_del_session (vat_main_t * vam)
11930 {
11931   unformat_input_t *i = vam->input;
11932   vl_api_classify_add_del_session_t *mp;
11933   int is_add = 1;
11934   u32 table_index = ~0;
11935   u32 hit_next_index = ~0;
11936   u32 opaque_index = ~0;
11937   u8 *match = 0;
11938   i32 advance = 0;
11939   u32 skip_n_vectors = 0;
11940   u32 match_n_vectors = 0;
11941   u32 action = 0;
11942   u32 metadata = 0;
11943   int ret;
11944
11945   /*
11946    * Warning: you have to supply skip_n and match_n
11947    * because the API client cant simply look at the classify
11948    * table object.
11949    */
11950
11951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11952     {
11953       if (unformat (i, "del"))
11954         is_add = 0;
11955       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11956                          &hit_next_index))
11957         ;
11958       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11959                          &hit_next_index))
11960         ;
11961       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11962                          &hit_next_index))
11963         ;
11964       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11965         ;
11966       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11967         ;
11968       else if (unformat (i, "opaque-index %d", &opaque_index))
11969         ;
11970       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11971         ;
11972       else if (unformat (i, "match_n %d", &match_n_vectors))
11973         ;
11974       else if (unformat (i, "match %U", api_unformat_classify_match,
11975                          &match, skip_n_vectors, match_n_vectors))
11976         ;
11977       else if (unformat (i, "advance %d", &advance))
11978         ;
11979       else if (unformat (i, "table-index %d", &table_index))
11980         ;
11981       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11982         action = 1;
11983       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11984         action = 2;
11985       else if (unformat (i, "action %d", &action))
11986         ;
11987       else if (unformat (i, "metadata %d", &metadata))
11988         ;
11989       else
11990         break;
11991     }
11992
11993   if (table_index == ~0)
11994     {
11995       errmsg ("Table index required");
11996       return -99;
11997     }
11998
11999   if (is_add && match == 0)
12000     {
12001       errmsg ("Match value required");
12002       return -99;
12003     }
12004
12005   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12006
12007   mp->is_add = is_add;
12008   mp->table_index = ntohl (table_index);
12009   mp->hit_next_index = ntohl (hit_next_index);
12010   mp->opaque_index = ntohl (opaque_index);
12011   mp->advance = ntohl (advance);
12012   mp->action = action;
12013   mp->metadata = ntohl (metadata);
12014   clib_memcpy (mp->match, match, vec_len (match));
12015   vec_free (match);
12016
12017   S (mp);
12018   W (ret);
12019   return ret;
12020 }
12021
12022 static int
12023 api_classify_set_interface_ip_table (vat_main_t * vam)
12024 {
12025   unformat_input_t *i = vam->input;
12026   vl_api_classify_set_interface_ip_table_t *mp;
12027   u32 sw_if_index;
12028   int sw_if_index_set;
12029   u32 table_index = ~0;
12030   u8 is_ipv6 = 0;
12031   int ret;
12032
12033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12034     {
12035       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12036         sw_if_index_set = 1;
12037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12038         sw_if_index_set = 1;
12039       else if (unformat (i, "table %d", &table_index))
12040         ;
12041       else
12042         {
12043           clib_warning ("parse error '%U'", format_unformat_error, i);
12044           return -99;
12045         }
12046     }
12047
12048   if (sw_if_index_set == 0)
12049     {
12050       errmsg ("missing interface name or sw_if_index");
12051       return -99;
12052     }
12053
12054
12055   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12056
12057   mp->sw_if_index = ntohl (sw_if_index);
12058   mp->table_index = ntohl (table_index);
12059   mp->is_ipv6 = is_ipv6;
12060
12061   S (mp);
12062   W (ret);
12063   return ret;
12064 }
12065
12066 static int
12067 api_classify_set_interface_l2_tables (vat_main_t * vam)
12068 {
12069   unformat_input_t *i = vam->input;
12070   vl_api_classify_set_interface_l2_tables_t *mp;
12071   u32 sw_if_index;
12072   int sw_if_index_set;
12073   u32 ip4_table_index = ~0;
12074   u32 ip6_table_index = ~0;
12075   u32 other_table_index = ~0;
12076   u32 is_input = 1;
12077   int ret;
12078
12079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12080     {
12081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12082         sw_if_index_set = 1;
12083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12084         sw_if_index_set = 1;
12085       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12086         ;
12087       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12088         ;
12089       else if (unformat (i, "other-table %d", &other_table_index))
12090         ;
12091       else if (unformat (i, "is-input %d", &is_input))
12092         ;
12093       else
12094         {
12095           clib_warning ("parse error '%U'", format_unformat_error, i);
12096           return -99;
12097         }
12098     }
12099
12100   if (sw_if_index_set == 0)
12101     {
12102       errmsg ("missing interface name or sw_if_index");
12103       return -99;
12104     }
12105
12106
12107   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12108
12109   mp->sw_if_index = ntohl (sw_if_index);
12110   mp->ip4_table_index = ntohl (ip4_table_index);
12111   mp->ip6_table_index = ntohl (ip6_table_index);
12112   mp->other_table_index = ntohl (other_table_index);
12113   mp->is_input = (u8) is_input;
12114
12115   S (mp);
12116   W (ret);
12117   return ret;
12118 }
12119
12120 static int
12121 api_set_ipfix_exporter (vat_main_t * vam)
12122 {
12123   unformat_input_t *i = vam->input;
12124   vl_api_set_ipfix_exporter_t *mp;
12125   ip4_address_t collector_address;
12126   u8 collector_address_set = 0;
12127   u32 collector_port = ~0;
12128   ip4_address_t src_address;
12129   u8 src_address_set = 0;
12130   u32 vrf_id = ~0;
12131   u32 path_mtu = ~0;
12132   u32 template_interval = ~0;
12133   u8 udp_checksum = 0;
12134   int ret;
12135
12136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12137     {
12138       if (unformat (i, "collector_address %U", unformat_ip4_address,
12139                     &collector_address))
12140         collector_address_set = 1;
12141       else if (unformat (i, "collector_port %d", &collector_port))
12142         ;
12143       else if (unformat (i, "src_address %U", unformat_ip4_address,
12144                          &src_address))
12145         src_address_set = 1;
12146       else if (unformat (i, "vrf_id %d", &vrf_id))
12147         ;
12148       else if (unformat (i, "path_mtu %d", &path_mtu))
12149         ;
12150       else if (unformat (i, "template_interval %d", &template_interval))
12151         ;
12152       else if (unformat (i, "udp_checksum"))
12153         udp_checksum = 1;
12154       else
12155         break;
12156     }
12157
12158   if (collector_address_set == 0)
12159     {
12160       errmsg ("collector_address required");
12161       return -99;
12162     }
12163
12164   if (src_address_set == 0)
12165     {
12166       errmsg ("src_address required");
12167       return -99;
12168     }
12169
12170   M (SET_IPFIX_EXPORTER, mp);
12171
12172   memcpy (mp->collector_address, collector_address.data,
12173           sizeof (collector_address.data));
12174   mp->collector_port = htons ((u16) collector_port);
12175   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12176   mp->vrf_id = htonl (vrf_id);
12177   mp->path_mtu = htonl (path_mtu);
12178   mp->template_interval = htonl (template_interval);
12179   mp->udp_checksum = udp_checksum;
12180
12181   S (mp);
12182   W (ret);
12183   return ret;
12184 }
12185
12186 static int
12187 api_set_ipfix_classify_stream (vat_main_t * vam)
12188 {
12189   unformat_input_t *i = vam->input;
12190   vl_api_set_ipfix_classify_stream_t *mp;
12191   u32 domain_id = 0;
12192   u32 src_port = UDP_DST_PORT_ipfix;
12193   int ret;
12194
12195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12196     {
12197       if (unformat (i, "domain %d", &domain_id))
12198         ;
12199       else if (unformat (i, "src_port %d", &src_port))
12200         ;
12201       else
12202         {
12203           errmsg ("unknown input `%U'", format_unformat_error, i);
12204           return -99;
12205         }
12206     }
12207
12208   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12209
12210   mp->domain_id = htonl (domain_id);
12211   mp->src_port = htons ((u16) src_port);
12212
12213   S (mp);
12214   W (ret);
12215   return ret;
12216 }
12217
12218 static int
12219 api_ipfix_classify_table_add_del (vat_main_t * vam)
12220 {
12221   unformat_input_t *i = vam->input;
12222   vl_api_ipfix_classify_table_add_del_t *mp;
12223   int is_add = -1;
12224   u32 classify_table_index = ~0;
12225   u8 ip_version = 0;
12226   u8 transport_protocol = 255;
12227   int ret;
12228
12229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12230     {
12231       if (unformat (i, "add"))
12232         is_add = 1;
12233       else if (unformat (i, "del"))
12234         is_add = 0;
12235       else if (unformat (i, "table %d", &classify_table_index))
12236         ;
12237       else if (unformat (i, "ip4"))
12238         ip_version = 4;
12239       else if (unformat (i, "ip6"))
12240         ip_version = 6;
12241       else if (unformat (i, "tcp"))
12242         transport_protocol = 6;
12243       else if (unformat (i, "udp"))
12244         transport_protocol = 17;
12245       else
12246         {
12247           errmsg ("unknown input `%U'", format_unformat_error, i);
12248           return -99;
12249         }
12250     }
12251
12252   if (is_add == -1)
12253     {
12254       errmsg ("expecting: add|del");
12255       return -99;
12256     }
12257   if (classify_table_index == ~0)
12258     {
12259       errmsg ("classifier table not specified");
12260       return -99;
12261     }
12262   if (ip_version == 0)
12263     {
12264       errmsg ("IP version not specified");
12265       return -99;
12266     }
12267
12268   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12269
12270   mp->is_add = is_add;
12271   mp->table_id = htonl (classify_table_index);
12272   mp->ip_version = ip_version;
12273   mp->transport_protocol = transport_protocol;
12274
12275   S (mp);
12276   W (ret);
12277   return ret;
12278 }
12279
12280 static int
12281 api_get_node_index (vat_main_t * vam)
12282 {
12283   unformat_input_t *i = vam->input;
12284   vl_api_get_node_index_t *mp;
12285   u8 *name = 0;
12286   int ret;
12287
12288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12289     {
12290       if (unformat (i, "node %s", &name))
12291         ;
12292       else
12293         break;
12294     }
12295   if (name == 0)
12296     {
12297       errmsg ("node name required");
12298       return -99;
12299     }
12300   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12301     {
12302       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12303       return -99;
12304     }
12305
12306   M (GET_NODE_INDEX, mp);
12307   clib_memcpy (mp->node_name, name, vec_len (name));
12308   vec_free (name);
12309
12310   S (mp);
12311   W (ret);
12312   return ret;
12313 }
12314
12315 static int
12316 api_get_next_index (vat_main_t * vam)
12317 {
12318   unformat_input_t *i = vam->input;
12319   vl_api_get_next_index_t *mp;
12320   u8 *node_name = 0, *next_node_name = 0;
12321   int ret;
12322
12323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12324     {
12325       if (unformat (i, "node-name %s", &node_name))
12326         ;
12327       else if (unformat (i, "next-node-name %s", &next_node_name))
12328         break;
12329     }
12330
12331   if (node_name == 0)
12332     {
12333       errmsg ("node name required");
12334       return -99;
12335     }
12336   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12337     {
12338       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12339       return -99;
12340     }
12341
12342   if (next_node_name == 0)
12343     {
12344       errmsg ("next node name required");
12345       return -99;
12346     }
12347   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12348     {
12349       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12350       return -99;
12351     }
12352
12353   M (GET_NEXT_INDEX, mp);
12354   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12355   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12356   vec_free (node_name);
12357   vec_free (next_node_name);
12358
12359   S (mp);
12360   W (ret);
12361   return ret;
12362 }
12363
12364 static int
12365 api_add_node_next (vat_main_t * vam)
12366 {
12367   unformat_input_t *i = vam->input;
12368   vl_api_add_node_next_t *mp;
12369   u8 *name = 0;
12370   u8 *next = 0;
12371   int ret;
12372
12373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12374     {
12375       if (unformat (i, "node %s", &name))
12376         ;
12377       else if (unformat (i, "next %s", &next))
12378         ;
12379       else
12380         break;
12381     }
12382   if (name == 0)
12383     {
12384       errmsg ("node name required");
12385       return -99;
12386     }
12387   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12388     {
12389       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12390       return -99;
12391     }
12392   if (next == 0)
12393     {
12394       errmsg ("next node required");
12395       return -99;
12396     }
12397   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12398     {
12399       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12400       return -99;
12401     }
12402
12403   M (ADD_NODE_NEXT, mp);
12404   clib_memcpy (mp->node_name, name, vec_len (name));
12405   clib_memcpy (mp->next_name, next, vec_len (next));
12406   vec_free (name);
12407   vec_free (next);
12408
12409   S (mp);
12410   W (ret);
12411   return ret;
12412 }
12413
12414 static int
12415 api_l2tpv3_create_tunnel (vat_main_t * vam)
12416 {
12417   unformat_input_t *i = vam->input;
12418   ip6_address_t client_address, our_address;
12419   int client_address_set = 0;
12420   int our_address_set = 0;
12421   u32 local_session_id = 0;
12422   u32 remote_session_id = 0;
12423   u64 local_cookie = 0;
12424   u64 remote_cookie = 0;
12425   u8 l2_sublayer_present = 0;
12426   vl_api_l2tpv3_create_tunnel_t *mp;
12427   int ret;
12428
12429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12430     {
12431       if (unformat (i, "client_address %U", unformat_ip6_address,
12432                     &client_address))
12433         client_address_set = 1;
12434       else if (unformat (i, "our_address %U", unformat_ip6_address,
12435                          &our_address))
12436         our_address_set = 1;
12437       else if (unformat (i, "local_session_id %d", &local_session_id))
12438         ;
12439       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12440         ;
12441       else if (unformat (i, "local_cookie %lld", &local_cookie))
12442         ;
12443       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12444         ;
12445       else if (unformat (i, "l2-sublayer-present"))
12446         l2_sublayer_present = 1;
12447       else
12448         break;
12449     }
12450
12451   if (client_address_set == 0)
12452     {
12453       errmsg ("client_address required");
12454       return -99;
12455     }
12456
12457   if (our_address_set == 0)
12458     {
12459       errmsg ("our_address required");
12460       return -99;
12461     }
12462
12463   M (L2TPV3_CREATE_TUNNEL, mp);
12464
12465   clib_memcpy (mp->client_address, client_address.as_u8,
12466                sizeof (mp->client_address));
12467
12468   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12469
12470   mp->local_session_id = ntohl (local_session_id);
12471   mp->remote_session_id = ntohl (remote_session_id);
12472   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12473   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12474   mp->l2_sublayer_present = l2_sublayer_present;
12475   mp->is_ipv6 = 1;
12476
12477   S (mp);
12478   W (ret);
12479   return ret;
12480 }
12481
12482 static int
12483 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12484 {
12485   unformat_input_t *i = vam->input;
12486   u32 sw_if_index;
12487   u8 sw_if_index_set = 0;
12488   u64 new_local_cookie = 0;
12489   u64 new_remote_cookie = 0;
12490   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12491   int ret;
12492
12493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12494     {
12495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12496         sw_if_index_set = 1;
12497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12498         sw_if_index_set = 1;
12499       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12500         ;
12501       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12502         ;
12503       else
12504         break;
12505     }
12506
12507   if (sw_if_index_set == 0)
12508     {
12509       errmsg ("missing interface name or sw_if_index");
12510       return -99;
12511     }
12512
12513   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12514
12515   mp->sw_if_index = ntohl (sw_if_index);
12516   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12517   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12518
12519   S (mp);
12520   W (ret);
12521   return ret;
12522 }
12523
12524 static int
12525 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12526 {
12527   unformat_input_t *i = vam->input;
12528   vl_api_l2tpv3_interface_enable_disable_t *mp;
12529   u32 sw_if_index;
12530   u8 sw_if_index_set = 0;
12531   u8 enable_disable = 1;
12532   int ret;
12533
12534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12535     {
12536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12537         sw_if_index_set = 1;
12538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12539         sw_if_index_set = 1;
12540       else if (unformat (i, "enable"))
12541         enable_disable = 1;
12542       else if (unformat (i, "disable"))
12543         enable_disable = 0;
12544       else
12545         break;
12546     }
12547
12548   if (sw_if_index_set == 0)
12549     {
12550       errmsg ("missing interface name or sw_if_index");
12551       return -99;
12552     }
12553
12554   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12555
12556   mp->sw_if_index = ntohl (sw_if_index);
12557   mp->enable_disable = enable_disable;
12558
12559   S (mp);
12560   W (ret);
12561   return ret;
12562 }
12563
12564 static int
12565 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12566 {
12567   unformat_input_t *i = vam->input;
12568   vl_api_l2tpv3_set_lookup_key_t *mp;
12569   u8 key = ~0;
12570   int ret;
12571
12572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12573     {
12574       if (unformat (i, "lookup_v6_src"))
12575         key = L2T_LOOKUP_SRC_ADDRESS;
12576       else if (unformat (i, "lookup_v6_dst"))
12577         key = L2T_LOOKUP_DST_ADDRESS;
12578       else if (unformat (i, "lookup_session_id"))
12579         key = L2T_LOOKUP_SESSION_ID;
12580       else
12581         break;
12582     }
12583
12584   if (key == (u8) ~ 0)
12585     {
12586       errmsg ("l2tp session lookup key unset");
12587       return -99;
12588     }
12589
12590   M (L2TPV3_SET_LOOKUP_KEY, mp);
12591
12592   mp->key = key;
12593
12594   S (mp);
12595   W (ret);
12596   return ret;
12597 }
12598
12599 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12600   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12601 {
12602   vat_main_t *vam = &vat_main;
12603
12604   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12605          format_ip6_address, mp->our_address,
12606          format_ip6_address, mp->client_address,
12607          clib_net_to_host_u32 (mp->sw_if_index));
12608
12609   print (vam->ofp,
12610          "   local cookies %016llx %016llx remote cookie %016llx",
12611          clib_net_to_host_u64 (mp->local_cookie[0]),
12612          clib_net_to_host_u64 (mp->local_cookie[1]),
12613          clib_net_to_host_u64 (mp->remote_cookie));
12614
12615   print (vam->ofp, "   local session-id %d remote session-id %d",
12616          clib_net_to_host_u32 (mp->local_session_id),
12617          clib_net_to_host_u32 (mp->remote_session_id));
12618
12619   print (vam->ofp, "   l2 specific sublayer %s\n",
12620          mp->l2_sublayer_present ? "preset" : "absent");
12621
12622 }
12623
12624 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12625   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12626 {
12627   vat_main_t *vam = &vat_main;
12628   vat_json_node_t *node = NULL;
12629   struct in6_addr addr;
12630
12631   if (VAT_JSON_ARRAY != vam->json_tree.type)
12632     {
12633       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12634       vat_json_init_array (&vam->json_tree);
12635     }
12636   node = vat_json_array_add (&vam->json_tree);
12637
12638   vat_json_init_object (node);
12639
12640   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12641   vat_json_object_add_ip6 (node, "our_address", addr);
12642   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12643   vat_json_object_add_ip6 (node, "client_address", addr);
12644
12645   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12646   vat_json_init_array (lc);
12647   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12648   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12649   vat_json_object_add_uint (node, "remote_cookie",
12650                             clib_net_to_host_u64 (mp->remote_cookie));
12651
12652   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12653   vat_json_object_add_uint (node, "local_session_id",
12654                             clib_net_to_host_u32 (mp->local_session_id));
12655   vat_json_object_add_uint (node, "remote_session_id",
12656                             clib_net_to_host_u32 (mp->remote_session_id));
12657   vat_json_object_add_string_copy (node, "l2_sublayer",
12658                                    mp->l2_sublayer_present ? (u8 *) "present"
12659                                    : (u8 *) "absent");
12660 }
12661
12662 static int
12663 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12664 {
12665   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12666   vl_api_control_ping_t *mp_ping;
12667   int ret;
12668
12669   /* Get list of l2tpv3-tunnel interfaces */
12670   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12671   S (mp);
12672
12673   /* Use a control ping for synchronization */
12674   MPING (CONTROL_PING, mp_ping);
12675   S (mp_ping);
12676
12677   W (ret);
12678   return ret;
12679 }
12680
12681
12682 static void vl_api_sw_interface_tap_details_t_handler
12683   (vl_api_sw_interface_tap_details_t * mp)
12684 {
12685   vat_main_t *vam = &vat_main;
12686
12687   print (vam->ofp, "%-16s %d",
12688          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12689 }
12690
12691 static void vl_api_sw_interface_tap_details_t_handler_json
12692   (vl_api_sw_interface_tap_details_t * mp)
12693 {
12694   vat_main_t *vam = &vat_main;
12695   vat_json_node_t *node = NULL;
12696
12697   if (VAT_JSON_ARRAY != vam->json_tree.type)
12698     {
12699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12700       vat_json_init_array (&vam->json_tree);
12701     }
12702   node = vat_json_array_add (&vam->json_tree);
12703
12704   vat_json_init_object (node);
12705   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12706   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12707 }
12708
12709 static int
12710 api_sw_interface_tap_dump (vat_main_t * vam)
12711 {
12712   vl_api_sw_interface_tap_dump_t *mp;
12713   vl_api_control_ping_t *mp_ping;
12714   int ret;
12715
12716   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12717   /* Get list of tap interfaces */
12718   M (SW_INTERFACE_TAP_DUMP, mp);
12719   S (mp);
12720
12721   /* Use a control ping for synchronization */
12722   MPING (CONTROL_PING, mp_ping);
12723   S (mp_ping);
12724
12725   W (ret);
12726   return ret;
12727 }
12728
12729 static void vl_api_sw_interface_tap_v2_details_t_handler
12730   (vl_api_sw_interface_tap_v2_details_t * mp)
12731 {
12732   vat_main_t *vam = &vat_main;
12733
12734   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12735                     mp->host_ip4_prefix_len);
12736   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12737                     mp->host_ip6_prefix_len);
12738
12739   print (vam->ofp,
12740          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12741          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12742          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12743          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12744          mp->host_bridge, ip4, ip6);
12745
12746   vec_free (ip4);
12747   vec_free (ip6);
12748 }
12749
12750 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12751   (vl_api_sw_interface_tap_v2_details_t * mp)
12752 {
12753   vat_main_t *vam = &vat_main;
12754   vat_json_node_t *node = NULL;
12755
12756   if (VAT_JSON_ARRAY != vam->json_tree.type)
12757     {
12758       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12759       vat_json_init_array (&vam->json_tree);
12760     }
12761   node = vat_json_array_add (&vam->json_tree);
12762
12763   vat_json_init_object (node);
12764   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12765   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12766   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12767   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12768   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12769   vat_json_object_add_string_copy (node, "host_mac_addr",
12770                                    format (0, "%U", format_ethernet_address,
12771                                            &mp->host_mac_addr));
12772   vat_json_object_add_string_copy (node, "host_namespace",
12773                                    mp->host_namespace);
12774   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12775   vat_json_object_add_string_copy (node, "host_ip4_addr",
12776                                    format (0, "%U/%d", format_ip4_address,
12777                                            mp->host_ip4_addr,
12778                                            mp->host_ip4_prefix_len));
12779   vat_json_object_add_string_copy (node, "host_ip6_addr",
12780                                    format (0, "%U/%d", format_ip6_address,
12781                                            mp->host_ip6_addr,
12782                                            mp->host_ip6_prefix_len));
12783
12784 }
12785
12786 static int
12787 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12788 {
12789   vl_api_sw_interface_tap_v2_dump_t *mp;
12790   vl_api_control_ping_t *mp_ping;
12791   int ret;
12792
12793   print (vam->ofp,
12794          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12795          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12796          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12797          "host_ip6_addr");
12798
12799   /* Get list of tap interfaces */
12800   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12801   S (mp);
12802
12803   /* Use a control ping for synchronization */
12804   MPING (CONTROL_PING, mp_ping);
12805   S (mp_ping);
12806
12807   W (ret);
12808   return ret;
12809 }
12810
12811 static int
12812 api_vxlan_offload_rx (vat_main_t * vam)
12813 {
12814   unformat_input_t *line_input = vam->input;
12815   vl_api_vxlan_offload_rx_t *mp;
12816   u32 hw_if_index = ~0, rx_if_index = ~0;
12817   u8 is_add = 1;
12818   int ret;
12819
12820   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12821     {
12822       if (unformat (line_input, "del"))
12823         is_add = 0;
12824       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12825                          &hw_if_index))
12826         ;
12827       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12828         ;
12829       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12830                          &rx_if_index))
12831         ;
12832       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12833         ;
12834       else
12835         {
12836           errmsg ("parse error '%U'", format_unformat_error, line_input);
12837           return -99;
12838         }
12839     }
12840
12841   if (hw_if_index == ~0)
12842     {
12843       errmsg ("no hw interface");
12844       return -99;
12845     }
12846
12847   if (rx_if_index == ~0)
12848     {
12849       errmsg ("no rx tunnel");
12850       return -99;
12851     }
12852
12853   M (VXLAN_OFFLOAD_RX, mp);
12854
12855   mp->hw_if_index = ntohl (hw_if_index);
12856   mp->sw_if_index = ntohl (rx_if_index);
12857   mp->enable = is_add;
12858
12859   S (mp);
12860   W (ret);
12861   return ret;
12862 }
12863
12864 static uword unformat_vxlan_decap_next
12865   (unformat_input_t * input, va_list * args)
12866 {
12867   u32 *result = va_arg (*args, u32 *);
12868   u32 tmp;
12869
12870   if (unformat (input, "l2"))
12871     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12872   else if (unformat (input, "%d", &tmp))
12873     *result = tmp;
12874   else
12875     return 0;
12876   return 1;
12877 }
12878
12879 static int
12880 api_vxlan_add_del_tunnel (vat_main_t * vam)
12881 {
12882   unformat_input_t *line_input = vam->input;
12883   vl_api_vxlan_add_del_tunnel_t *mp;
12884   ip46_address_t src, dst;
12885   u8 is_add = 1;
12886   u8 ipv4_set = 0, ipv6_set = 0;
12887   u8 src_set = 0;
12888   u8 dst_set = 0;
12889   u8 grp_set = 0;
12890   u32 instance = ~0;
12891   u32 mcast_sw_if_index = ~0;
12892   u32 encap_vrf_id = 0;
12893   u32 decap_next_index = ~0;
12894   u32 vni = 0;
12895   int ret;
12896
12897   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12898   memset (&src, 0, sizeof src);
12899   memset (&dst, 0, sizeof dst);
12900
12901   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12902     {
12903       if (unformat (line_input, "del"))
12904         is_add = 0;
12905       else if (unformat (line_input, "instance %d", &instance))
12906         ;
12907       else
12908         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12909         {
12910           ipv4_set = 1;
12911           src_set = 1;
12912         }
12913       else
12914         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12915         {
12916           ipv4_set = 1;
12917           dst_set = 1;
12918         }
12919       else
12920         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12921         {
12922           ipv6_set = 1;
12923           src_set = 1;
12924         }
12925       else
12926         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12927         {
12928           ipv6_set = 1;
12929           dst_set = 1;
12930         }
12931       else if (unformat (line_input, "group %U %U",
12932                          unformat_ip4_address, &dst.ip4,
12933                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12934         {
12935           grp_set = dst_set = 1;
12936           ipv4_set = 1;
12937         }
12938       else if (unformat (line_input, "group %U",
12939                          unformat_ip4_address, &dst.ip4))
12940         {
12941           grp_set = dst_set = 1;
12942           ipv4_set = 1;
12943         }
12944       else if (unformat (line_input, "group %U %U",
12945                          unformat_ip6_address, &dst.ip6,
12946                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12947         {
12948           grp_set = dst_set = 1;
12949           ipv6_set = 1;
12950         }
12951       else if (unformat (line_input, "group %U",
12952                          unformat_ip6_address, &dst.ip6))
12953         {
12954           grp_set = dst_set = 1;
12955           ipv6_set = 1;
12956         }
12957       else
12958         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12959         ;
12960       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12961         ;
12962       else if (unformat (line_input, "decap-next %U",
12963                          unformat_vxlan_decap_next, &decap_next_index))
12964         ;
12965       else if (unformat (line_input, "vni %d", &vni))
12966         ;
12967       else
12968         {
12969           errmsg ("parse error '%U'", format_unformat_error, line_input);
12970           return -99;
12971         }
12972     }
12973
12974   if (src_set == 0)
12975     {
12976       errmsg ("tunnel src address not specified");
12977       return -99;
12978     }
12979   if (dst_set == 0)
12980     {
12981       errmsg ("tunnel dst address not specified");
12982       return -99;
12983     }
12984
12985   if (grp_set && !ip46_address_is_multicast (&dst))
12986     {
12987       errmsg ("tunnel group address not multicast");
12988       return -99;
12989     }
12990   if (grp_set && mcast_sw_if_index == ~0)
12991     {
12992       errmsg ("tunnel nonexistent multicast device");
12993       return -99;
12994     }
12995   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12996     {
12997       errmsg ("tunnel dst address must be unicast");
12998       return -99;
12999     }
13000
13001
13002   if (ipv4_set && ipv6_set)
13003     {
13004       errmsg ("both IPv4 and IPv6 addresses specified");
13005       return -99;
13006     }
13007
13008   if ((vni == 0) || (vni >> 24))
13009     {
13010       errmsg ("vni not specified or out of range");
13011       return -99;
13012     }
13013
13014   M (VXLAN_ADD_DEL_TUNNEL, mp);
13015
13016   if (ipv6_set)
13017     {
13018       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13019       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13020     }
13021   else
13022     {
13023       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13024       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13025     }
13026
13027   mp->instance = htonl (instance);
13028   mp->encap_vrf_id = ntohl (encap_vrf_id);
13029   mp->decap_next_index = ntohl (decap_next_index);
13030   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13031   mp->vni = ntohl (vni);
13032   mp->is_add = is_add;
13033   mp->is_ipv6 = ipv6_set;
13034
13035   S (mp);
13036   W (ret);
13037   return ret;
13038 }
13039
13040 static void vl_api_vxlan_tunnel_details_t_handler
13041   (vl_api_vxlan_tunnel_details_t * mp)
13042 {
13043   vat_main_t *vam = &vat_main;
13044   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13045   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13046
13047   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13048          ntohl (mp->sw_if_index),
13049          ntohl (mp->instance),
13050          format_ip46_address, &src, IP46_TYPE_ANY,
13051          format_ip46_address, &dst, IP46_TYPE_ANY,
13052          ntohl (mp->encap_vrf_id),
13053          ntohl (mp->decap_next_index), ntohl (mp->vni),
13054          ntohl (mp->mcast_sw_if_index));
13055 }
13056
13057 static void vl_api_vxlan_tunnel_details_t_handler_json
13058   (vl_api_vxlan_tunnel_details_t * mp)
13059 {
13060   vat_main_t *vam = &vat_main;
13061   vat_json_node_t *node = NULL;
13062
13063   if (VAT_JSON_ARRAY != vam->json_tree.type)
13064     {
13065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13066       vat_json_init_array (&vam->json_tree);
13067     }
13068   node = vat_json_array_add (&vam->json_tree);
13069
13070   vat_json_init_object (node);
13071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13072
13073   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13074
13075   if (mp->is_ipv6)
13076     {
13077       struct in6_addr ip6;
13078
13079       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13080       vat_json_object_add_ip6 (node, "src_address", ip6);
13081       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13082       vat_json_object_add_ip6 (node, "dst_address", ip6);
13083     }
13084   else
13085     {
13086       struct in_addr ip4;
13087
13088       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13089       vat_json_object_add_ip4 (node, "src_address", ip4);
13090       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13091       vat_json_object_add_ip4 (node, "dst_address", ip4);
13092     }
13093   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13094   vat_json_object_add_uint (node, "decap_next_index",
13095                             ntohl (mp->decap_next_index));
13096   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13097   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13098   vat_json_object_add_uint (node, "mcast_sw_if_index",
13099                             ntohl (mp->mcast_sw_if_index));
13100 }
13101
13102 static int
13103 api_vxlan_tunnel_dump (vat_main_t * vam)
13104 {
13105   unformat_input_t *i = vam->input;
13106   vl_api_vxlan_tunnel_dump_t *mp;
13107   vl_api_control_ping_t *mp_ping;
13108   u32 sw_if_index;
13109   u8 sw_if_index_set = 0;
13110   int ret;
13111
13112   /* Parse args required to build the message */
13113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13114     {
13115       if (unformat (i, "sw_if_index %d", &sw_if_index))
13116         sw_if_index_set = 1;
13117       else
13118         break;
13119     }
13120
13121   if (sw_if_index_set == 0)
13122     {
13123       sw_if_index = ~0;
13124     }
13125
13126   if (!vam->json_output)
13127     {
13128       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13129              "sw_if_index", "instance", "src_address", "dst_address",
13130              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13131     }
13132
13133   /* Get list of vxlan-tunnel interfaces */
13134   M (VXLAN_TUNNEL_DUMP, mp);
13135
13136   mp->sw_if_index = htonl (sw_if_index);
13137
13138   S (mp);
13139
13140   /* Use a control ping for synchronization */
13141   MPING (CONTROL_PING, mp_ping);
13142   S (mp_ping);
13143
13144   W (ret);
13145   return ret;
13146 }
13147
13148 static uword unformat_geneve_decap_next
13149   (unformat_input_t * input, va_list * args)
13150 {
13151   u32 *result = va_arg (*args, u32 *);
13152   u32 tmp;
13153
13154   if (unformat (input, "l2"))
13155     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13156   else if (unformat (input, "%d", &tmp))
13157     *result = tmp;
13158   else
13159     return 0;
13160   return 1;
13161 }
13162
13163 static int
13164 api_geneve_add_del_tunnel (vat_main_t * vam)
13165 {
13166   unformat_input_t *line_input = vam->input;
13167   vl_api_geneve_add_del_tunnel_t *mp;
13168   ip46_address_t src, dst;
13169   u8 is_add = 1;
13170   u8 ipv4_set = 0, ipv6_set = 0;
13171   u8 src_set = 0;
13172   u8 dst_set = 0;
13173   u8 grp_set = 0;
13174   u32 mcast_sw_if_index = ~0;
13175   u32 encap_vrf_id = 0;
13176   u32 decap_next_index = ~0;
13177   u32 vni = 0;
13178   int ret;
13179
13180   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13181   memset (&src, 0, sizeof src);
13182   memset (&dst, 0, sizeof dst);
13183
13184   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13185     {
13186       if (unformat (line_input, "del"))
13187         is_add = 0;
13188       else
13189         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13190         {
13191           ipv4_set = 1;
13192           src_set = 1;
13193         }
13194       else
13195         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13196         {
13197           ipv4_set = 1;
13198           dst_set = 1;
13199         }
13200       else
13201         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13202         {
13203           ipv6_set = 1;
13204           src_set = 1;
13205         }
13206       else
13207         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13208         {
13209           ipv6_set = 1;
13210           dst_set = 1;
13211         }
13212       else if (unformat (line_input, "group %U %U",
13213                          unformat_ip4_address, &dst.ip4,
13214                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13215         {
13216           grp_set = dst_set = 1;
13217           ipv4_set = 1;
13218         }
13219       else if (unformat (line_input, "group %U",
13220                          unformat_ip4_address, &dst.ip4))
13221         {
13222           grp_set = dst_set = 1;
13223           ipv4_set = 1;
13224         }
13225       else if (unformat (line_input, "group %U %U",
13226                          unformat_ip6_address, &dst.ip6,
13227                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13228         {
13229           grp_set = dst_set = 1;
13230           ipv6_set = 1;
13231         }
13232       else if (unformat (line_input, "group %U",
13233                          unformat_ip6_address, &dst.ip6))
13234         {
13235           grp_set = dst_set = 1;
13236           ipv6_set = 1;
13237         }
13238       else
13239         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13240         ;
13241       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13242         ;
13243       else if (unformat (line_input, "decap-next %U",
13244                          unformat_geneve_decap_next, &decap_next_index))
13245         ;
13246       else if (unformat (line_input, "vni %d", &vni))
13247         ;
13248       else
13249         {
13250           errmsg ("parse error '%U'", format_unformat_error, line_input);
13251           return -99;
13252         }
13253     }
13254
13255   if (src_set == 0)
13256     {
13257       errmsg ("tunnel src address not specified");
13258       return -99;
13259     }
13260   if (dst_set == 0)
13261     {
13262       errmsg ("tunnel dst address not specified");
13263       return -99;
13264     }
13265
13266   if (grp_set && !ip46_address_is_multicast (&dst))
13267     {
13268       errmsg ("tunnel group address not multicast");
13269       return -99;
13270     }
13271   if (grp_set && mcast_sw_if_index == ~0)
13272     {
13273       errmsg ("tunnel nonexistent multicast device");
13274       return -99;
13275     }
13276   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13277     {
13278       errmsg ("tunnel dst address must be unicast");
13279       return -99;
13280     }
13281
13282
13283   if (ipv4_set && ipv6_set)
13284     {
13285       errmsg ("both IPv4 and IPv6 addresses specified");
13286       return -99;
13287     }
13288
13289   if ((vni == 0) || (vni >> 24))
13290     {
13291       errmsg ("vni not specified or out of range");
13292       return -99;
13293     }
13294
13295   M (GENEVE_ADD_DEL_TUNNEL, mp);
13296
13297   if (ipv6_set)
13298     {
13299       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13300       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13301     }
13302   else
13303     {
13304       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13305       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13306     }
13307   mp->encap_vrf_id = ntohl (encap_vrf_id);
13308   mp->decap_next_index = ntohl (decap_next_index);
13309   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13310   mp->vni = ntohl (vni);
13311   mp->is_add = is_add;
13312   mp->is_ipv6 = ipv6_set;
13313
13314   S (mp);
13315   W (ret);
13316   return ret;
13317 }
13318
13319 static void vl_api_geneve_tunnel_details_t_handler
13320   (vl_api_geneve_tunnel_details_t * mp)
13321 {
13322   vat_main_t *vam = &vat_main;
13323   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13324   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13325
13326   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13327          ntohl (mp->sw_if_index),
13328          format_ip46_address, &src, IP46_TYPE_ANY,
13329          format_ip46_address, &dst, IP46_TYPE_ANY,
13330          ntohl (mp->encap_vrf_id),
13331          ntohl (mp->decap_next_index), ntohl (mp->vni),
13332          ntohl (mp->mcast_sw_if_index));
13333 }
13334
13335 static void vl_api_geneve_tunnel_details_t_handler_json
13336   (vl_api_geneve_tunnel_details_t * mp)
13337 {
13338   vat_main_t *vam = &vat_main;
13339   vat_json_node_t *node = NULL;
13340
13341   if (VAT_JSON_ARRAY != vam->json_tree.type)
13342     {
13343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13344       vat_json_init_array (&vam->json_tree);
13345     }
13346   node = vat_json_array_add (&vam->json_tree);
13347
13348   vat_json_init_object (node);
13349   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13350   if (mp->is_ipv6)
13351     {
13352       struct in6_addr ip6;
13353
13354       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13355       vat_json_object_add_ip6 (node, "src_address", ip6);
13356       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13357       vat_json_object_add_ip6 (node, "dst_address", ip6);
13358     }
13359   else
13360     {
13361       struct in_addr ip4;
13362
13363       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13364       vat_json_object_add_ip4 (node, "src_address", ip4);
13365       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13366       vat_json_object_add_ip4 (node, "dst_address", ip4);
13367     }
13368   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13369   vat_json_object_add_uint (node, "decap_next_index",
13370                             ntohl (mp->decap_next_index));
13371   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13372   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13373   vat_json_object_add_uint (node, "mcast_sw_if_index",
13374                             ntohl (mp->mcast_sw_if_index));
13375 }
13376
13377 static int
13378 api_geneve_tunnel_dump (vat_main_t * vam)
13379 {
13380   unformat_input_t *i = vam->input;
13381   vl_api_geneve_tunnel_dump_t *mp;
13382   vl_api_control_ping_t *mp_ping;
13383   u32 sw_if_index;
13384   u8 sw_if_index_set = 0;
13385   int ret;
13386
13387   /* Parse args required to build the message */
13388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13389     {
13390       if (unformat (i, "sw_if_index %d", &sw_if_index))
13391         sw_if_index_set = 1;
13392       else
13393         break;
13394     }
13395
13396   if (sw_if_index_set == 0)
13397     {
13398       sw_if_index = ~0;
13399     }
13400
13401   if (!vam->json_output)
13402     {
13403       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13404              "sw_if_index", "local_address", "remote_address",
13405              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13406     }
13407
13408   /* Get list of geneve-tunnel interfaces */
13409   M (GENEVE_TUNNEL_DUMP, mp);
13410
13411   mp->sw_if_index = htonl (sw_if_index);
13412
13413   S (mp);
13414
13415   /* Use a control ping for synchronization */
13416   M (CONTROL_PING, mp_ping);
13417   S (mp_ping);
13418
13419   W (ret);
13420   return ret;
13421 }
13422
13423 static int
13424 api_gre_add_del_tunnel (vat_main_t * vam)
13425 {
13426   unformat_input_t *line_input = vam->input;
13427   vl_api_gre_add_del_tunnel_t *mp;
13428   ip4_address_t src4, dst4;
13429   ip6_address_t src6, dst6;
13430   u8 is_add = 1;
13431   u8 ipv4_set = 0;
13432   u8 ipv6_set = 0;
13433   u8 t_type = GRE_TUNNEL_TYPE_L3;
13434   u8 src_set = 0;
13435   u8 dst_set = 0;
13436   u32 outer_fib_id = 0;
13437   u32 session_id = 0;
13438   u32 instance = ~0;
13439   int ret;
13440
13441   memset (&src4, 0, sizeof src4);
13442   memset (&dst4, 0, sizeof dst4);
13443   memset (&src6, 0, sizeof src6);
13444   memset (&dst6, 0, sizeof dst6);
13445
13446   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13447     {
13448       if (unformat (line_input, "del"))
13449         is_add = 0;
13450       else if (unformat (line_input, "instance %d", &instance))
13451         ;
13452       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13453         {
13454           src_set = 1;
13455           ipv4_set = 1;
13456         }
13457       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13458         {
13459           dst_set = 1;
13460           ipv4_set = 1;
13461         }
13462       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13463         {
13464           src_set = 1;
13465           ipv6_set = 1;
13466         }
13467       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13468         {
13469           dst_set = 1;
13470           ipv6_set = 1;
13471         }
13472       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13473         ;
13474       else if (unformat (line_input, "teb"))
13475         t_type = GRE_TUNNEL_TYPE_TEB;
13476       else if (unformat (line_input, "erspan %d", &session_id))
13477         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13478       else
13479         {
13480           errmsg ("parse error '%U'", format_unformat_error, line_input);
13481           return -99;
13482         }
13483     }
13484
13485   if (src_set == 0)
13486     {
13487       errmsg ("tunnel src address not specified");
13488       return -99;
13489     }
13490   if (dst_set == 0)
13491     {
13492       errmsg ("tunnel dst address not specified");
13493       return -99;
13494     }
13495   if (ipv4_set && ipv6_set)
13496     {
13497       errmsg ("both IPv4 and IPv6 addresses specified");
13498       return -99;
13499     }
13500
13501
13502   M (GRE_ADD_DEL_TUNNEL, mp);
13503
13504   if (ipv4_set)
13505     {
13506       clib_memcpy (&mp->src_address, &src4, 4);
13507       clib_memcpy (&mp->dst_address, &dst4, 4);
13508     }
13509   else
13510     {
13511       clib_memcpy (&mp->src_address, &src6, 16);
13512       clib_memcpy (&mp->dst_address, &dst6, 16);
13513     }
13514   mp->instance = htonl (instance);
13515   mp->outer_fib_id = htonl (outer_fib_id);
13516   mp->is_add = is_add;
13517   mp->session_id = htons ((u16) session_id);
13518   mp->tunnel_type = t_type;
13519   mp->is_ipv6 = ipv6_set;
13520
13521   S (mp);
13522   W (ret);
13523   return ret;
13524 }
13525
13526 static void vl_api_gre_tunnel_details_t_handler
13527   (vl_api_gre_tunnel_details_t * mp)
13528 {
13529   vat_main_t *vam = &vat_main;
13530   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13531   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13532
13533   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13534          ntohl (mp->sw_if_index),
13535          ntohl (mp->instance),
13536          format_ip46_address, &src, IP46_TYPE_ANY,
13537          format_ip46_address, &dst, IP46_TYPE_ANY,
13538          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13539 }
13540
13541 static void vl_api_gre_tunnel_details_t_handler_json
13542   (vl_api_gre_tunnel_details_t * mp)
13543 {
13544   vat_main_t *vam = &vat_main;
13545   vat_json_node_t *node = NULL;
13546   struct in_addr ip4;
13547   struct in6_addr ip6;
13548
13549   if (VAT_JSON_ARRAY != vam->json_tree.type)
13550     {
13551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13552       vat_json_init_array (&vam->json_tree);
13553     }
13554   node = vat_json_array_add (&vam->json_tree);
13555
13556   vat_json_init_object (node);
13557   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13558   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13559   if (!mp->is_ipv6)
13560     {
13561       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13562       vat_json_object_add_ip4 (node, "src_address", ip4);
13563       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13564       vat_json_object_add_ip4 (node, "dst_address", ip4);
13565     }
13566   else
13567     {
13568       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13569       vat_json_object_add_ip6 (node, "src_address", ip6);
13570       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13571       vat_json_object_add_ip6 (node, "dst_address", ip6);
13572     }
13573   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13574   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13575   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13576   vat_json_object_add_uint (node, "session_id", mp->session_id);
13577 }
13578
13579 static int
13580 api_gre_tunnel_dump (vat_main_t * vam)
13581 {
13582   unformat_input_t *i = vam->input;
13583   vl_api_gre_tunnel_dump_t *mp;
13584   vl_api_control_ping_t *mp_ping;
13585   u32 sw_if_index;
13586   u8 sw_if_index_set = 0;
13587   int ret;
13588
13589   /* Parse args required to build the message */
13590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13591     {
13592       if (unformat (i, "sw_if_index %d", &sw_if_index))
13593         sw_if_index_set = 1;
13594       else
13595         break;
13596     }
13597
13598   if (sw_if_index_set == 0)
13599     {
13600       sw_if_index = ~0;
13601     }
13602
13603   if (!vam->json_output)
13604     {
13605       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13606              "sw_if_index", "instance", "src_address", "dst_address",
13607              "tunnel_type", "outer_fib_id", "session_id");
13608     }
13609
13610   /* Get list of gre-tunnel interfaces */
13611   M (GRE_TUNNEL_DUMP, mp);
13612
13613   mp->sw_if_index = htonl (sw_if_index);
13614
13615   S (mp);
13616
13617   /* Use a control ping for synchronization */
13618   MPING (CONTROL_PING, mp_ping);
13619   S (mp_ping);
13620
13621   W (ret);
13622   return ret;
13623 }
13624
13625 static int
13626 api_l2_fib_clear_table (vat_main_t * vam)
13627 {
13628 //  unformat_input_t * i = vam->input;
13629   vl_api_l2_fib_clear_table_t *mp;
13630   int ret;
13631
13632   M (L2_FIB_CLEAR_TABLE, mp);
13633
13634   S (mp);
13635   W (ret);
13636   return ret;
13637 }
13638
13639 static int
13640 api_l2_interface_efp_filter (vat_main_t * vam)
13641 {
13642   unformat_input_t *i = vam->input;
13643   vl_api_l2_interface_efp_filter_t *mp;
13644   u32 sw_if_index;
13645   u8 enable = 1;
13646   u8 sw_if_index_set = 0;
13647   int ret;
13648
13649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13650     {
13651       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13652         sw_if_index_set = 1;
13653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13654         sw_if_index_set = 1;
13655       else if (unformat (i, "enable"))
13656         enable = 1;
13657       else if (unformat (i, "disable"))
13658         enable = 0;
13659       else
13660         {
13661           clib_warning ("parse error '%U'", format_unformat_error, i);
13662           return -99;
13663         }
13664     }
13665
13666   if (sw_if_index_set == 0)
13667     {
13668       errmsg ("missing sw_if_index");
13669       return -99;
13670     }
13671
13672   M (L2_INTERFACE_EFP_FILTER, mp);
13673
13674   mp->sw_if_index = ntohl (sw_if_index);
13675   mp->enable_disable = enable;
13676
13677   S (mp);
13678   W (ret);
13679   return ret;
13680 }
13681
13682 #define foreach_vtr_op                          \
13683 _("disable",  L2_VTR_DISABLED)                  \
13684 _("push-1",  L2_VTR_PUSH_1)                     \
13685 _("push-2",  L2_VTR_PUSH_2)                     \
13686 _("pop-1",  L2_VTR_POP_1)                       \
13687 _("pop-2",  L2_VTR_POP_2)                       \
13688 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13689 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13690 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13691 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13692
13693 static int
13694 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13695 {
13696   unformat_input_t *i = vam->input;
13697   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13698   u32 sw_if_index;
13699   u8 sw_if_index_set = 0;
13700   u8 vtr_op_set = 0;
13701   u32 vtr_op = 0;
13702   u32 push_dot1q = 1;
13703   u32 tag1 = ~0;
13704   u32 tag2 = ~0;
13705   int ret;
13706
13707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13708     {
13709       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13710         sw_if_index_set = 1;
13711       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13712         sw_if_index_set = 1;
13713       else if (unformat (i, "vtr_op %d", &vtr_op))
13714         vtr_op_set = 1;
13715 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13716       foreach_vtr_op
13717 #undef _
13718         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13719         ;
13720       else if (unformat (i, "tag1 %d", &tag1))
13721         ;
13722       else if (unformat (i, "tag2 %d", &tag2))
13723         ;
13724       else
13725         {
13726           clib_warning ("parse error '%U'", format_unformat_error, i);
13727           return -99;
13728         }
13729     }
13730
13731   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13732     {
13733       errmsg ("missing vtr operation or sw_if_index");
13734       return -99;
13735     }
13736
13737   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13738   mp->sw_if_index = ntohl (sw_if_index);
13739   mp->vtr_op = ntohl (vtr_op);
13740   mp->push_dot1q = ntohl (push_dot1q);
13741   mp->tag1 = ntohl (tag1);
13742   mp->tag2 = ntohl (tag2);
13743
13744   S (mp);
13745   W (ret);
13746   return ret;
13747 }
13748
13749 static int
13750 api_create_vhost_user_if (vat_main_t * vam)
13751 {
13752   unformat_input_t *i = vam->input;
13753   vl_api_create_vhost_user_if_t *mp;
13754   u8 *file_name;
13755   u8 is_server = 0;
13756   u8 file_name_set = 0;
13757   u32 custom_dev_instance = ~0;
13758   u8 hwaddr[6];
13759   u8 use_custom_mac = 0;
13760   u8 *tag = 0;
13761   int ret;
13762
13763   /* Shut up coverity */
13764   memset (hwaddr, 0, sizeof (hwaddr));
13765
13766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13767     {
13768       if (unformat (i, "socket %s", &file_name))
13769         {
13770           file_name_set = 1;
13771         }
13772       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13773         ;
13774       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13775         use_custom_mac = 1;
13776       else if (unformat (i, "server"))
13777         is_server = 1;
13778       else if (unformat (i, "tag %s", &tag))
13779         ;
13780       else
13781         break;
13782     }
13783
13784   if (file_name_set == 0)
13785     {
13786       errmsg ("missing socket file name");
13787       return -99;
13788     }
13789
13790   if (vec_len (file_name) > 255)
13791     {
13792       errmsg ("socket file name too long");
13793       return -99;
13794     }
13795   vec_add1 (file_name, 0);
13796
13797   M (CREATE_VHOST_USER_IF, mp);
13798
13799   mp->is_server = is_server;
13800   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13801   vec_free (file_name);
13802   if (custom_dev_instance != ~0)
13803     {
13804       mp->renumber = 1;
13805       mp->custom_dev_instance = ntohl (custom_dev_instance);
13806     }
13807   mp->use_custom_mac = use_custom_mac;
13808   clib_memcpy (mp->mac_address, hwaddr, 6);
13809   if (tag)
13810     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13811   vec_free (tag);
13812
13813   S (mp);
13814   W (ret);
13815   return ret;
13816 }
13817
13818 static int
13819 api_modify_vhost_user_if (vat_main_t * vam)
13820 {
13821   unformat_input_t *i = vam->input;
13822   vl_api_modify_vhost_user_if_t *mp;
13823   u8 *file_name;
13824   u8 is_server = 0;
13825   u8 file_name_set = 0;
13826   u32 custom_dev_instance = ~0;
13827   u8 sw_if_index_set = 0;
13828   u32 sw_if_index = (u32) ~ 0;
13829   int ret;
13830
13831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13832     {
13833       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13834         sw_if_index_set = 1;
13835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13836         sw_if_index_set = 1;
13837       else if (unformat (i, "socket %s", &file_name))
13838         {
13839           file_name_set = 1;
13840         }
13841       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13842         ;
13843       else if (unformat (i, "server"))
13844         is_server = 1;
13845       else
13846         break;
13847     }
13848
13849   if (sw_if_index_set == 0)
13850     {
13851       errmsg ("missing sw_if_index or interface name");
13852       return -99;
13853     }
13854
13855   if (file_name_set == 0)
13856     {
13857       errmsg ("missing socket file name");
13858       return -99;
13859     }
13860
13861   if (vec_len (file_name) > 255)
13862     {
13863       errmsg ("socket file name too long");
13864       return -99;
13865     }
13866   vec_add1 (file_name, 0);
13867
13868   M (MODIFY_VHOST_USER_IF, mp);
13869
13870   mp->sw_if_index = ntohl (sw_if_index);
13871   mp->is_server = is_server;
13872   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13873   vec_free (file_name);
13874   if (custom_dev_instance != ~0)
13875     {
13876       mp->renumber = 1;
13877       mp->custom_dev_instance = ntohl (custom_dev_instance);
13878     }
13879
13880   S (mp);
13881   W (ret);
13882   return ret;
13883 }
13884
13885 static int
13886 api_delete_vhost_user_if (vat_main_t * vam)
13887 {
13888   unformat_input_t *i = vam->input;
13889   vl_api_delete_vhost_user_if_t *mp;
13890   u32 sw_if_index = ~0;
13891   u8 sw_if_index_set = 0;
13892   int ret;
13893
13894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13895     {
13896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13897         sw_if_index_set = 1;
13898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13899         sw_if_index_set = 1;
13900       else
13901         break;
13902     }
13903
13904   if (sw_if_index_set == 0)
13905     {
13906       errmsg ("missing sw_if_index or interface name");
13907       return -99;
13908     }
13909
13910
13911   M (DELETE_VHOST_USER_IF, mp);
13912
13913   mp->sw_if_index = ntohl (sw_if_index);
13914
13915   S (mp);
13916   W (ret);
13917   return ret;
13918 }
13919
13920 static void vl_api_sw_interface_vhost_user_details_t_handler
13921   (vl_api_sw_interface_vhost_user_details_t * mp)
13922 {
13923   vat_main_t *vam = &vat_main;
13924
13925   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13926          (char *) mp->interface_name,
13927          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13928          clib_net_to_host_u64 (mp->features), mp->is_server,
13929          ntohl (mp->num_regions), (char *) mp->sock_filename);
13930   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13931 }
13932
13933 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13934   (vl_api_sw_interface_vhost_user_details_t * mp)
13935 {
13936   vat_main_t *vam = &vat_main;
13937   vat_json_node_t *node = NULL;
13938
13939   if (VAT_JSON_ARRAY != vam->json_tree.type)
13940     {
13941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13942       vat_json_init_array (&vam->json_tree);
13943     }
13944   node = vat_json_array_add (&vam->json_tree);
13945
13946   vat_json_init_object (node);
13947   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13948   vat_json_object_add_string_copy (node, "interface_name",
13949                                    mp->interface_name);
13950   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13951                             ntohl (mp->virtio_net_hdr_sz));
13952   vat_json_object_add_uint (node, "features",
13953                             clib_net_to_host_u64 (mp->features));
13954   vat_json_object_add_uint (node, "is_server", mp->is_server);
13955   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13956   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13957   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13958 }
13959
13960 static int
13961 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13962 {
13963   vl_api_sw_interface_vhost_user_dump_t *mp;
13964   vl_api_control_ping_t *mp_ping;
13965   int ret;
13966   print (vam->ofp,
13967          "Interface name            idx hdr_sz features server regions filename");
13968
13969   /* Get list of vhost-user interfaces */
13970   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13971   S (mp);
13972
13973   /* Use a control ping for synchronization */
13974   MPING (CONTROL_PING, mp_ping);
13975   S (mp_ping);
13976
13977   W (ret);
13978   return ret;
13979 }
13980
13981 static int
13982 api_show_version (vat_main_t * vam)
13983 {
13984   vl_api_show_version_t *mp;
13985   int ret;
13986
13987   M (SHOW_VERSION, mp);
13988
13989   S (mp);
13990   W (ret);
13991   return ret;
13992 }
13993
13994
13995 static int
13996 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13997 {
13998   unformat_input_t *line_input = vam->input;
13999   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14000   ip4_address_t local4, remote4;
14001   ip6_address_t local6, remote6;
14002   u8 is_add = 1;
14003   u8 ipv4_set = 0, ipv6_set = 0;
14004   u8 local_set = 0;
14005   u8 remote_set = 0;
14006   u8 grp_set = 0;
14007   u32 mcast_sw_if_index = ~0;
14008   u32 encap_vrf_id = 0;
14009   u32 decap_vrf_id = 0;
14010   u8 protocol = ~0;
14011   u32 vni;
14012   u8 vni_set = 0;
14013   int ret;
14014
14015   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14016   memset (&local4, 0, sizeof local4);
14017   memset (&remote4, 0, sizeof remote4);
14018   memset (&local6, 0, sizeof local6);
14019   memset (&remote6, 0, sizeof remote6);
14020
14021   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14022     {
14023       if (unformat (line_input, "del"))
14024         is_add = 0;
14025       else if (unformat (line_input, "local %U",
14026                          unformat_ip4_address, &local4))
14027         {
14028           local_set = 1;
14029           ipv4_set = 1;
14030         }
14031       else if (unformat (line_input, "remote %U",
14032                          unformat_ip4_address, &remote4))
14033         {
14034           remote_set = 1;
14035           ipv4_set = 1;
14036         }
14037       else if (unformat (line_input, "local %U",
14038                          unformat_ip6_address, &local6))
14039         {
14040           local_set = 1;
14041           ipv6_set = 1;
14042         }
14043       else if (unformat (line_input, "remote %U",
14044                          unformat_ip6_address, &remote6))
14045         {
14046           remote_set = 1;
14047           ipv6_set = 1;
14048         }
14049       else if (unformat (line_input, "group %U %U",
14050                          unformat_ip4_address, &remote4,
14051                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14052         {
14053           grp_set = remote_set = 1;
14054           ipv4_set = 1;
14055         }
14056       else if (unformat (line_input, "group %U",
14057                          unformat_ip4_address, &remote4))
14058         {
14059           grp_set = remote_set = 1;
14060           ipv4_set = 1;
14061         }
14062       else if (unformat (line_input, "group %U %U",
14063                          unformat_ip6_address, &remote6,
14064                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14065         {
14066           grp_set = remote_set = 1;
14067           ipv6_set = 1;
14068         }
14069       else if (unformat (line_input, "group %U",
14070                          unformat_ip6_address, &remote6))
14071         {
14072           grp_set = remote_set = 1;
14073           ipv6_set = 1;
14074         }
14075       else
14076         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14077         ;
14078       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14079         ;
14080       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14081         ;
14082       else if (unformat (line_input, "vni %d", &vni))
14083         vni_set = 1;
14084       else if (unformat (line_input, "next-ip4"))
14085         protocol = 1;
14086       else if (unformat (line_input, "next-ip6"))
14087         protocol = 2;
14088       else if (unformat (line_input, "next-ethernet"))
14089         protocol = 3;
14090       else if (unformat (line_input, "next-nsh"))
14091         protocol = 4;
14092       else
14093         {
14094           errmsg ("parse error '%U'", format_unformat_error, line_input);
14095           return -99;
14096         }
14097     }
14098
14099   if (local_set == 0)
14100     {
14101       errmsg ("tunnel local address not specified");
14102       return -99;
14103     }
14104   if (remote_set == 0)
14105     {
14106       errmsg ("tunnel remote address not specified");
14107       return -99;
14108     }
14109   if (grp_set && mcast_sw_if_index == ~0)
14110     {
14111       errmsg ("tunnel nonexistent multicast device");
14112       return -99;
14113     }
14114   if (ipv4_set && ipv6_set)
14115     {
14116       errmsg ("both IPv4 and IPv6 addresses specified");
14117       return -99;
14118     }
14119
14120   if (vni_set == 0)
14121     {
14122       errmsg ("vni not specified");
14123       return -99;
14124     }
14125
14126   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14127
14128
14129   if (ipv6_set)
14130     {
14131       clib_memcpy (&mp->local, &local6, sizeof (local6));
14132       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14133     }
14134   else
14135     {
14136       clib_memcpy (&mp->local, &local4, sizeof (local4));
14137       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14138     }
14139
14140   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14141   mp->encap_vrf_id = ntohl (encap_vrf_id);
14142   mp->decap_vrf_id = ntohl (decap_vrf_id);
14143   mp->protocol = protocol;
14144   mp->vni = ntohl (vni);
14145   mp->is_add = is_add;
14146   mp->is_ipv6 = ipv6_set;
14147
14148   S (mp);
14149   W (ret);
14150   return ret;
14151 }
14152
14153 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14154   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14155 {
14156   vat_main_t *vam = &vat_main;
14157   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14158   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14159
14160   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14161          ntohl (mp->sw_if_index),
14162          format_ip46_address, &local, IP46_TYPE_ANY,
14163          format_ip46_address, &remote, IP46_TYPE_ANY,
14164          ntohl (mp->vni), mp->protocol,
14165          ntohl (mp->mcast_sw_if_index),
14166          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14167 }
14168
14169
14170 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14171   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14172 {
14173   vat_main_t *vam = &vat_main;
14174   vat_json_node_t *node = NULL;
14175   struct in_addr ip4;
14176   struct in6_addr ip6;
14177
14178   if (VAT_JSON_ARRAY != vam->json_tree.type)
14179     {
14180       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14181       vat_json_init_array (&vam->json_tree);
14182     }
14183   node = vat_json_array_add (&vam->json_tree);
14184
14185   vat_json_init_object (node);
14186   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14187   if (mp->is_ipv6)
14188     {
14189       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14190       vat_json_object_add_ip6 (node, "local", ip6);
14191       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14192       vat_json_object_add_ip6 (node, "remote", ip6);
14193     }
14194   else
14195     {
14196       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14197       vat_json_object_add_ip4 (node, "local", ip4);
14198       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14199       vat_json_object_add_ip4 (node, "remote", ip4);
14200     }
14201   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14202   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14203   vat_json_object_add_uint (node, "mcast_sw_if_index",
14204                             ntohl (mp->mcast_sw_if_index));
14205   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14206   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14207   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14208 }
14209
14210 static int
14211 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14212 {
14213   unformat_input_t *i = vam->input;
14214   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14215   vl_api_control_ping_t *mp_ping;
14216   u32 sw_if_index;
14217   u8 sw_if_index_set = 0;
14218   int ret;
14219
14220   /* Parse args required to build the message */
14221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14222     {
14223       if (unformat (i, "sw_if_index %d", &sw_if_index))
14224         sw_if_index_set = 1;
14225       else
14226         break;
14227     }
14228
14229   if (sw_if_index_set == 0)
14230     {
14231       sw_if_index = ~0;
14232     }
14233
14234   if (!vam->json_output)
14235     {
14236       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14237              "sw_if_index", "local", "remote", "vni",
14238              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14239     }
14240
14241   /* Get list of vxlan-tunnel interfaces */
14242   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14243
14244   mp->sw_if_index = htonl (sw_if_index);
14245
14246   S (mp);
14247
14248   /* Use a control ping for synchronization */
14249   MPING (CONTROL_PING, mp_ping);
14250   S (mp_ping);
14251
14252   W (ret);
14253   return ret;
14254 }
14255
14256 static void vl_api_l2_fib_table_details_t_handler
14257   (vl_api_l2_fib_table_details_t * mp)
14258 {
14259   vat_main_t *vam = &vat_main;
14260
14261   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14262          "       %d       %d     %d",
14263          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14264          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14265          mp->bvi_mac);
14266 }
14267
14268 static void vl_api_l2_fib_table_details_t_handler_json
14269   (vl_api_l2_fib_table_details_t * mp)
14270 {
14271   vat_main_t *vam = &vat_main;
14272   vat_json_node_t *node = NULL;
14273
14274   if (VAT_JSON_ARRAY != vam->json_tree.type)
14275     {
14276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14277       vat_json_init_array (&vam->json_tree);
14278     }
14279   node = vat_json_array_add (&vam->json_tree);
14280
14281   vat_json_init_object (node);
14282   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14283   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14284   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14285   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14286   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14287   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14288 }
14289
14290 static int
14291 api_l2_fib_table_dump (vat_main_t * vam)
14292 {
14293   unformat_input_t *i = vam->input;
14294   vl_api_l2_fib_table_dump_t *mp;
14295   vl_api_control_ping_t *mp_ping;
14296   u32 bd_id;
14297   u8 bd_id_set = 0;
14298   int ret;
14299
14300   /* Parse args required to build the message */
14301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14302     {
14303       if (unformat (i, "bd_id %d", &bd_id))
14304         bd_id_set = 1;
14305       else
14306         break;
14307     }
14308
14309   if (bd_id_set == 0)
14310     {
14311       errmsg ("missing bridge domain");
14312       return -99;
14313     }
14314
14315   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14316
14317   /* Get list of l2 fib entries */
14318   M (L2_FIB_TABLE_DUMP, mp);
14319
14320   mp->bd_id = ntohl (bd_id);
14321   S (mp);
14322
14323   /* Use a control ping for synchronization */
14324   MPING (CONTROL_PING, mp_ping);
14325   S (mp_ping);
14326
14327   W (ret);
14328   return ret;
14329 }
14330
14331
14332 static int
14333 api_interface_name_renumber (vat_main_t * vam)
14334 {
14335   unformat_input_t *line_input = vam->input;
14336   vl_api_interface_name_renumber_t *mp;
14337   u32 sw_if_index = ~0;
14338   u32 new_show_dev_instance = ~0;
14339   int ret;
14340
14341   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14342     {
14343       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14344                     &sw_if_index))
14345         ;
14346       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14347         ;
14348       else if (unformat (line_input, "new_show_dev_instance %d",
14349                          &new_show_dev_instance))
14350         ;
14351       else
14352         break;
14353     }
14354
14355   if (sw_if_index == ~0)
14356     {
14357       errmsg ("missing interface name or sw_if_index");
14358       return -99;
14359     }
14360
14361   if (new_show_dev_instance == ~0)
14362     {
14363       errmsg ("missing new_show_dev_instance");
14364       return -99;
14365     }
14366
14367   M (INTERFACE_NAME_RENUMBER, mp);
14368
14369   mp->sw_if_index = ntohl (sw_if_index);
14370   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14371
14372   S (mp);
14373   W (ret);
14374   return ret;
14375 }
14376
14377 static int
14378 api_ip_probe_neighbor (vat_main_t * vam)
14379 {
14380   unformat_input_t *i = vam->input;
14381   vl_api_ip_probe_neighbor_t *mp;
14382   u8 int_set = 0;
14383   u8 adr_set = 0;
14384   u8 is_ipv6 = 0;
14385   u8 dst_adr[16];
14386   u32 sw_if_index;
14387   int ret;
14388
14389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14390     {
14391       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14392         int_set = 1;
14393       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14394         int_set = 1;
14395       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14396         adr_set = 1;
14397       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14398         {
14399           adr_set = 1;
14400           is_ipv6 = 1;
14401         }
14402       else
14403         break;
14404     }
14405
14406   if (int_set == 0)
14407     {
14408       errmsg ("missing interface");
14409       return -99;
14410     }
14411
14412   if (adr_set == 0)
14413     {
14414       errmsg ("missing addresses");
14415       return -99;
14416     }
14417
14418   M (IP_PROBE_NEIGHBOR, mp);
14419
14420   mp->sw_if_index = ntohl (sw_if_index);
14421   mp->is_ipv6 = is_ipv6;
14422   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14423
14424   S (mp);
14425   W (ret);
14426   return ret;
14427 }
14428
14429 static int
14430 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14431 {
14432   unformat_input_t *i = vam->input;
14433   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14434   u8 mode = IP_SCAN_V46_NEIGHBORS;
14435   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14436   int ret;
14437
14438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14439     {
14440       if (unformat (i, "ip4"))
14441         mode = IP_SCAN_V4_NEIGHBORS;
14442       else if (unformat (i, "ip6"))
14443         mode = IP_SCAN_V6_NEIGHBORS;
14444       if (unformat (i, "both"))
14445         mode = IP_SCAN_V46_NEIGHBORS;
14446       else if (unformat (i, "disable"))
14447         mode = IP_SCAN_DISABLED;
14448       else if (unformat (i, "interval %d", &interval))
14449         ;
14450       else if (unformat (i, "max-time %d", &time))
14451         ;
14452       else if (unformat (i, "max-update %d", &update))
14453         ;
14454       else if (unformat (i, "delay %d", &delay))
14455         ;
14456       else if (unformat (i, "stale %d", &stale))
14457         ;
14458       else
14459         break;
14460     }
14461
14462   if (interval > 255)
14463     {
14464       errmsg ("interval cannot exceed 255 minutes.");
14465       return -99;
14466     }
14467   if (time > 255)
14468     {
14469       errmsg ("max-time cannot exceed 255 usec.");
14470       return -99;
14471     }
14472   if (update > 255)
14473     {
14474       errmsg ("max-update cannot exceed 255.");
14475       return -99;
14476     }
14477   if (delay > 255)
14478     {
14479       errmsg ("delay cannot exceed 255 msec.");
14480       return -99;
14481     }
14482   if (stale > 255)
14483     {
14484       errmsg ("stale cannot exceed 255 minutes.");
14485       return -99;
14486     }
14487
14488   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14489   mp->mode = mode;
14490   mp->scan_interval = interval;
14491   mp->max_proc_time = time;
14492   mp->max_update = update;
14493   mp->scan_int_delay = delay;
14494   mp->stale_threshold = stale;
14495
14496   S (mp);
14497   W (ret);
14498   return ret;
14499 }
14500
14501 static int
14502 api_want_ip4_arp_events (vat_main_t * vam)
14503 {
14504   unformat_input_t *line_input = vam->input;
14505   vl_api_want_ip4_arp_events_t *mp;
14506   ip4_address_t address;
14507   int address_set = 0;
14508   u32 enable_disable = 1;
14509   int ret;
14510
14511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14512     {
14513       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14514         address_set = 1;
14515       else if (unformat (line_input, "del"))
14516         enable_disable = 0;
14517       else
14518         break;
14519     }
14520
14521   if (address_set == 0)
14522     {
14523       errmsg ("missing addresses");
14524       return -99;
14525     }
14526
14527   M (WANT_IP4_ARP_EVENTS, mp);
14528   mp->enable_disable = enable_disable;
14529   mp->pid = htonl (getpid ());
14530   mp->address = address.as_u32;
14531
14532   S (mp);
14533   W (ret);
14534   return ret;
14535 }
14536
14537 static int
14538 api_want_ip6_nd_events (vat_main_t * vam)
14539 {
14540   unformat_input_t *line_input = vam->input;
14541   vl_api_want_ip6_nd_events_t *mp;
14542   ip6_address_t address;
14543   int address_set = 0;
14544   u32 enable_disable = 1;
14545   int ret;
14546
14547   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14548     {
14549       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14550         address_set = 1;
14551       else if (unformat (line_input, "del"))
14552         enable_disable = 0;
14553       else
14554         break;
14555     }
14556
14557   if (address_set == 0)
14558     {
14559       errmsg ("missing addresses");
14560       return -99;
14561     }
14562
14563   M (WANT_IP6_ND_EVENTS, mp);
14564   mp->enable_disable = enable_disable;
14565   mp->pid = htonl (getpid ());
14566   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14567
14568   S (mp);
14569   W (ret);
14570   return ret;
14571 }
14572
14573 static int
14574 api_want_l2_macs_events (vat_main_t * vam)
14575 {
14576   unformat_input_t *line_input = vam->input;
14577   vl_api_want_l2_macs_events_t *mp;
14578   u8 enable_disable = 1;
14579   u32 scan_delay = 0;
14580   u32 max_macs_in_event = 0;
14581   u32 learn_limit = 0;
14582   int ret;
14583
14584   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14585     {
14586       if (unformat (line_input, "learn-limit %d", &learn_limit))
14587         ;
14588       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14589         ;
14590       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14591         ;
14592       else if (unformat (line_input, "disable"))
14593         enable_disable = 0;
14594       else
14595         break;
14596     }
14597
14598   M (WANT_L2_MACS_EVENTS, mp);
14599   mp->enable_disable = enable_disable;
14600   mp->pid = htonl (getpid ());
14601   mp->learn_limit = htonl (learn_limit);
14602   mp->scan_delay = (u8) scan_delay;
14603   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14604   S (mp);
14605   W (ret);
14606   return ret;
14607 }
14608
14609 static int
14610 api_input_acl_set_interface (vat_main_t * vam)
14611 {
14612   unformat_input_t *i = vam->input;
14613   vl_api_input_acl_set_interface_t *mp;
14614   u32 sw_if_index;
14615   int sw_if_index_set;
14616   u32 ip4_table_index = ~0;
14617   u32 ip6_table_index = ~0;
14618   u32 l2_table_index = ~0;
14619   u8 is_add = 1;
14620   int ret;
14621
14622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14623     {
14624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14625         sw_if_index_set = 1;
14626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14627         sw_if_index_set = 1;
14628       else if (unformat (i, "del"))
14629         is_add = 0;
14630       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14631         ;
14632       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14633         ;
14634       else if (unformat (i, "l2-table %d", &l2_table_index))
14635         ;
14636       else
14637         {
14638           clib_warning ("parse error '%U'", format_unformat_error, i);
14639           return -99;
14640         }
14641     }
14642
14643   if (sw_if_index_set == 0)
14644     {
14645       errmsg ("missing interface name or sw_if_index");
14646       return -99;
14647     }
14648
14649   M (INPUT_ACL_SET_INTERFACE, mp);
14650
14651   mp->sw_if_index = ntohl (sw_if_index);
14652   mp->ip4_table_index = ntohl (ip4_table_index);
14653   mp->ip6_table_index = ntohl (ip6_table_index);
14654   mp->l2_table_index = ntohl (l2_table_index);
14655   mp->is_add = is_add;
14656
14657   S (mp);
14658   W (ret);
14659   return ret;
14660 }
14661
14662 static int
14663 api_output_acl_set_interface (vat_main_t * vam)
14664 {
14665   unformat_input_t *i = vam->input;
14666   vl_api_output_acl_set_interface_t *mp;
14667   u32 sw_if_index;
14668   int sw_if_index_set;
14669   u32 ip4_table_index = ~0;
14670   u32 ip6_table_index = ~0;
14671   u32 l2_table_index = ~0;
14672   u8 is_add = 1;
14673   int ret;
14674
14675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14676     {
14677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14678         sw_if_index_set = 1;
14679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14680         sw_if_index_set = 1;
14681       else if (unformat (i, "del"))
14682         is_add = 0;
14683       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14684         ;
14685       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14686         ;
14687       else if (unformat (i, "l2-table %d", &l2_table_index))
14688         ;
14689       else
14690         {
14691           clib_warning ("parse error '%U'", format_unformat_error, i);
14692           return -99;
14693         }
14694     }
14695
14696   if (sw_if_index_set == 0)
14697     {
14698       errmsg ("missing interface name or sw_if_index");
14699       return -99;
14700     }
14701
14702   M (OUTPUT_ACL_SET_INTERFACE, mp);
14703
14704   mp->sw_if_index = ntohl (sw_if_index);
14705   mp->ip4_table_index = ntohl (ip4_table_index);
14706   mp->ip6_table_index = ntohl (ip6_table_index);
14707   mp->l2_table_index = ntohl (l2_table_index);
14708   mp->is_add = is_add;
14709
14710   S (mp);
14711   W (ret);
14712   return ret;
14713 }
14714
14715 static int
14716 api_ip_address_dump (vat_main_t * vam)
14717 {
14718   unformat_input_t *i = vam->input;
14719   vl_api_ip_address_dump_t *mp;
14720   vl_api_control_ping_t *mp_ping;
14721   u32 sw_if_index = ~0;
14722   u8 sw_if_index_set = 0;
14723   u8 ipv4_set = 0;
14724   u8 ipv6_set = 0;
14725   int ret;
14726
14727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14728     {
14729       if (unformat (i, "sw_if_index %d", &sw_if_index))
14730         sw_if_index_set = 1;
14731       else
14732         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14733         sw_if_index_set = 1;
14734       else if (unformat (i, "ipv4"))
14735         ipv4_set = 1;
14736       else if (unformat (i, "ipv6"))
14737         ipv6_set = 1;
14738       else
14739         break;
14740     }
14741
14742   if (ipv4_set && ipv6_set)
14743     {
14744       errmsg ("ipv4 and ipv6 flags cannot be both set");
14745       return -99;
14746     }
14747
14748   if ((!ipv4_set) && (!ipv6_set))
14749     {
14750       errmsg ("no ipv4 nor ipv6 flag set");
14751       return -99;
14752     }
14753
14754   if (sw_if_index_set == 0)
14755     {
14756       errmsg ("missing interface name or sw_if_index");
14757       return -99;
14758     }
14759
14760   vam->current_sw_if_index = sw_if_index;
14761   vam->is_ipv6 = ipv6_set;
14762
14763   M (IP_ADDRESS_DUMP, mp);
14764   mp->sw_if_index = ntohl (sw_if_index);
14765   mp->is_ipv6 = ipv6_set;
14766   S (mp);
14767
14768   /* Use a control ping for synchronization */
14769   MPING (CONTROL_PING, mp_ping);
14770   S (mp_ping);
14771
14772   W (ret);
14773   return ret;
14774 }
14775
14776 static int
14777 api_ip_dump (vat_main_t * vam)
14778 {
14779   vl_api_ip_dump_t *mp;
14780   vl_api_control_ping_t *mp_ping;
14781   unformat_input_t *in = vam->input;
14782   int ipv4_set = 0;
14783   int ipv6_set = 0;
14784   int is_ipv6;
14785   int i;
14786   int ret;
14787
14788   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14789     {
14790       if (unformat (in, "ipv4"))
14791         ipv4_set = 1;
14792       else if (unformat (in, "ipv6"))
14793         ipv6_set = 1;
14794       else
14795         break;
14796     }
14797
14798   if (ipv4_set && ipv6_set)
14799     {
14800       errmsg ("ipv4 and ipv6 flags cannot be both set");
14801       return -99;
14802     }
14803
14804   if ((!ipv4_set) && (!ipv6_set))
14805     {
14806       errmsg ("no ipv4 nor ipv6 flag set");
14807       return -99;
14808     }
14809
14810   is_ipv6 = ipv6_set;
14811   vam->is_ipv6 = is_ipv6;
14812
14813   /* free old data */
14814   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14815     {
14816       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14817     }
14818   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14819
14820   M (IP_DUMP, mp);
14821   mp->is_ipv6 = ipv6_set;
14822   S (mp);
14823
14824   /* Use a control ping for synchronization */
14825   MPING (CONTROL_PING, mp_ping);
14826   S (mp_ping);
14827
14828   W (ret);
14829   return ret;
14830 }
14831
14832 static int
14833 api_ipsec_spd_add_del (vat_main_t * vam)
14834 {
14835   unformat_input_t *i = vam->input;
14836   vl_api_ipsec_spd_add_del_t *mp;
14837   u32 spd_id = ~0;
14838   u8 is_add = 1;
14839   int ret;
14840
14841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14842     {
14843       if (unformat (i, "spd_id %d", &spd_id))
14844         ;
14845       else if (unformat (i, "del"))
14846         is_add = 0;
14847       else
14848         {
14849           clib_warning ("parse error '%U'", format_unformat_error, i);
14850           return -99;
14851         }
14852     }
14853   if (spd_id == ~0)
14854     {
14855       errmsg ("spd_id must be set");
14856       return -99;
14857     }
14858
14859   M (IPSEC_SPD_ADD_DEL, mp);
14860
14861   mp->spd_id = ntohl (spd_id);
14862   mp->is_add = is_add;
14863
14864   S (mp);
14865   W (ret);
14866   return ret;
14867 }
14868
14869 static int
14870 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14871 {
14872   unformat_input_t *i = vam->input;
14873   vl_api_ipsec_interface_add_del_spd_t *mp;
14874   u32 sw_if_index;
14875   u8 sw_if_index_set = 0;
14876   u32 spd_id = (u32) ~ 0;
14877   u8 is_add = 1;
14878   int ret;
14879
14880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14881     {
14882       if (unformat (i, "del"))
14883         is_add = 0;
14884       else if (unformat (i, "spd_id %d", &spd_id))
14885         ;
14886       else
14887         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14888         sw_if_index_set = 1;
14889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14890         sw_if_index_set = 1;
14891       else
14892         {
14893           clib_warning ("parse error '%U'", format_unformat_error, i);
14894           return -99;
14895         }
14896
14897     }
14898
14899   if (spd_id == (u32) ~ 0)
14900     {
14901       errmsg ("spd_id must be set");
14902       return -99;
14903     }
14904
14905   if (sw_if_index_set == 0)
14906     {
14907       errmsg ("missing interface name or sw_if_index");
14908       return -99;
14909     }
14910
14911   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14912
14913   mp->spd_id = ntohl (spd_id);
14914   mp->sw_if_index = ntohl (sw_if_index);
14915   mp->is_add = is_add;
14916
14917   S (mp);
14918   W (ret);
14919   return ret;
14920 }
14921
14922 static int
14923 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14924 {
14925   unformat_input_t *i = vam->input;
14926   vl_api_ipsec_spd_add_del_entry_t *mp;
14927   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14928   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14929   i32 priority = 0;
14930   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14931   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14932   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14933   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14934   int ret;
14935
14936   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14937   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14938   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14939   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14940   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14941   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14942
14943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14944     {
14945       if (unformat (i, "del"))
14946         is_add = 0;
14947       if (unformat (i, "outbound"))
14948         is_outbound = 1;
14949       if (unformat (i, "inbound"))
14950         is_outbound = 0;
14951       else if (unformat (i, "spd_id %d", &spd_id))
14952         ;
14953       else if (unformat (i, "sa_id %d", &sa_id))
14954         ;
14955       else if (unformat (i, "priority %d", &priority))
14956         ;
14957       else if (unformat (i, "protocol %d", &protocol))
14958         ;
14959       else if (unformat (i, "lport_start %d", &lport_start))
14960         ;
14961       else if (unformat (i, "lport_stop %d", &lport_stop))
14962         ;
14963       else if (unformat (i, "rport_start %d", &rport_start))
14964         ;
14965       else if (unformat (i, "rport_stop %d", &rport_stop))
14966         ;
14967       else
14968         if (unformat
14969             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14970         {
14971           is_ipv6 = 0;
14972           is_ip_any = 0;
14973         }
14974       else
14975         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14976         {
14977           is_ipv6 = 0;
14978           is_ip_any = 0;
14979         }
14980       else
14981         if (unformat
14982             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14983         {
14984           is_ipv6 = 0;
14985           is_ip_any = 0;
14986         }
14987       else
14988         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14989         {
14990           is_ipv6 = 0;
14991           is_ip_any = 0;
14992         }
14993       else
14994         if (unformat
14995             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14996         {
14997           is_ipv6 = 1;
14998           is_ip_any = 0;
14999         }
15000       else
15001         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15002         {
15003           is_ipv6 = 1;
15004           is_ip_any = 0;
15005         }
15006       else
15007         if (unformat
15008             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15009         {
15010           is_ipv6 = 1;
15011           is_ip_any = 0;
15012         }
15013       else
15014         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15015         {
15016           is_ipv6 = 1;
15017           is_ip_any = 0;
15018         }
15019       else
15020         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15021         {
15022           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15023             {
15024               clib_warning ("unsupported action: 'resolve'");
15025               return -99;
15026             }
15027         }
15028       else
15029         {
15030           clib_warning ("parse error '%U'", format_unformat_error, i);
15031           return -99;
15032         }
15033
15034     }
15035
15036   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15037
15038   mp->spd_id = ntohl (spd_id);
15039   mp->priority = ntohl (priority);
15040   mp->is_outbound = is_outbound;
15041
15042   mp->is_ipv6 = is_ipv6;
15043   if (is_ipv6 || is_ip_any)
15044     {
15045       clib_memcpy (mp->remote_address_start, &raddr6_start,
15046                    sizeof (ip6_address_t));
15047       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15048                    sizeof (ip6_address_t));
15049       clib_memcpy (mp->local_address_start, &laddr6_start,
15050                    sizeof (ip6_address_t));
15051       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15052                    sizeof (ip6_address_t));
15053     }
15054   else
15055     {
15056       clib_memcpy (mp->remote_address_start, &raddr4_start,
15057                    sizeof (ip4_address_t));
15058       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15059                    sizeof (ip4_address_t));
15060       clib_memcpy (mp->local_address_start, &laddr4_start,
15061                    sizeof (ip4_address_t));
15062       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15063                    sizeof (ip4_address_t));
15064     }
15065   mp->protocol = (u8) protocol;
15066   mp->local_port_start = ntohs ((u16) lport_start);
15067   mp->local_port_stop = ntohs ((u16) lport_stop);
15068   mp->remote_port_start = ntohs ((u16) rport_start);
15069   mp->remote_port_stop = ntohs ((u16) rport_stop);
15070   mp->policy = (u8) policy;
15071   mp->sa_id = ntohl (sa_id);
15072   mp->is_add = is_add;
15073   mp->is_ip_any = is_ip_any;
15074   S (mp);
15075   W (ret);
15076   return ret;
15077 }
15078
15079 static int
15080 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15081 {
15082   unformat_input_t *i = vam->input;
15083   vl_api_ipsec_sad_add_del_entry_t *mp;
15084   u32 sad_id = 0, spi = 0;
15085   u8 *ck = 0, *ik = 0;
15086   u8 is_add = 1;
15087
15088   u8 protocol = IPSEC_PROTOCOL_AH;
15089   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15090   u32 crypto_alg = 0, integ_alg = 0;
15091   ip4_address_t tun_src4;
15092   ip4_address_t tun_dst4;
15093   ip6_address_t tun_src6;
15094   ip6_address_t tun_dst6;
15095   int ret;
15096
15097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15098     {
15099       if (unformat (i, "del"))
15100         is_add = 0;
15101       else if (unformat (i, "sad_id %d", &sad_id))
15102         ;
15103       else if (unformat (i, "spi %d", &spi))
15104         ;
15105       else if (unformat (i, "esp"))
15106         protocol = IPSEC_PROTOCOL_ESP;
15107       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15108         {
15109           is_tunnel = 1;
15110           is_tunnel_ipv6 = 0;
15111         }
15112       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15113         {
15114           is_tunnel = 1;
15115           is_tunnel_ipv6 = 0;
15116         }
15117       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15118         {
15119           is_tunnel = 1;
15120           is_tunnel_ipv6 = 1;
15121         }
15122       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15123         {
15124           is_tunnel = 1;
15125           is_tunnel_ipv6 = 1;
15126         }
15127       else
15128         if (unformat
15129             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15130         {
15131           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15132             {
15133               clib_warning ("unsupported crypto-alg: '%U'",
15134                             format_ipsec_crypto_alg, crypto_alg);
15135               return -99;
15136             }
15137         }
15138       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15139         ;
15140       else
15141         if (unformat
15142             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15143         {
15144           if (integ_alg >= IPSEC_INTEG_N_ALG)
15145             {
15146               clib_warning ("unsupported integ-alg: '%U'",
15147                             format_ipsec_integ_alg, integ_alg);
15148               return -99;
15149             }
15150         }
15151       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15152         ;
15153       else
15154         {
15155           clib_warning ("parse error '%U'", format_unformat_error, i);
15156           return -99;
15157         }
15158
15159     }
15160
15161   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15162
15163   mp->sad_id = ntohl (sad_id);
15164   mp->is_add = is_add;
15165   mp->protocol = protocol;
15166   mp->spi = ntohl (spi);
15167   mp->is_tunnel = is_tunnel;
15168   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15169   mp->crypto_algorithm = crypto_alg;
15170   mp->integrity_algorithm = integ_alg;
15171   mp->crypto_key_length = vec_len (ck);
15172   mp->integrity_key_length = vec_len (ik);
15173
15174   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15175     mp->crypto_key_length = sizeof (mp->crypto_key);
15176
15177   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15178     mp->integrity_key_length = sizeof (mp->integrity_key);
15179
15180   if (ck)
15181     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15182   if (ik)
15183     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15184
15185   if (is_tunnel)
15186     {
15187       if (is_tunnel_ipv6)
15188         {
15189           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15190                        sizeof (ip6_address_t));
15191           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15192                        sizeof (ip6_address_t));
15193         }
15194       else
15195         {
15196           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15197                        sizeof (ip4_address_t));
15198           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15199                        sizeof (ip4_address_t));
15200         }
15201     }
15202
15203   S (mp);
15204   W (ret);
15205   return ret;
15206 }
15207
15208 static int
15209 api_ipsec_sa_set_key (vat_main_t * vam)
15210 {
15211   unformat_input_t *i = vam->input;
15212   vl_api_ipsec_sa_set_key_t *mp;
15213   u32 sa_id;
15214   u8 *ck = 0, *ik = 0;
15215   int ret;
15216
15217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15218     {
15219       if (unformat (i, "sa_id %d", &sa_id))
15220         ;
15221       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15222         ;
15223       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15224         ;
15225       else
15226         {
15227           clib_warning ("parse error '%U'", format_unformat_error, i);
15228           return -99;
15229         }
15230     }
15231
15232   M (IPSEC_SA_SET_KEY, mp);
15233
15234   mp->sa_id = ntohl (sa_id);
15235   mp->crypto_key_length = vec_len (ck);
15236   mp->integrity_key_length = vec_len (ik);
15237
15238   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15239     mp->crypto_key_length = sizeof (mp->crypto_key);
15240
15241   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15242     mp->integrity_key_length = sizeof (mp->integrity_key);
15243
15244   if (ck)
15245     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15246   if (ik)
15247     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15248
15249   S (mp);
15250   W (ret);
15251   return ret;
15252 }
15253
15254 static int
15255 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15256 {
15257   unformat_input_t *i = vam->input;
15258   vl_api_ipsec_tunnel_if_add_del_t *mp;
15259   u32 local_spi = 0, remote_spi = 0;
15260   u32 crypto_alg = 0, integ_alg = 0;
15261   u8 *lck = NULL, *rck = NULL;
15262   u8 *lik = NULL, *rik = NULL;
15263   ip4_address_t local_ip = { {0} };
15264   ip4_address_t remote_ip = { {0} };
15265   u8 is_add = 1;
15266   u8 esn = 0;
15267   u8 anti_replay = 0;
15268   u8 renumber = 0;
15269   u32 instance = ~0;
15270   int ret;
15271
15272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15273     {
15274       if (unformat (i, "del"))
15275         is_add = 0;
15276       else if (unformat (i, "esn"))
15277         esn = 1;
15278       else if (unformat (i, "anti_replay"))
15279         anti_replay = 1;
15280       else if (unformat (i, "local_spi %d", &local_spi))
15281         ;
15282       else if (unformat (i, "remote_spi %d", &remote_spi))
15283         ;
15284       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15285         ;
15286       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15287         ;
15288       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15289         ;
15290       else
15291         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15292         ;
15293       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15294         ;
15295       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15296         ;
15297       else
15298         if (unformat
15299             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15300         {
15301           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15302             {
15303               errmsg ("unsupported crypto-alg: '%U'\n",
15304                       format_ipsec_crypto_alg, crypto_alg);
15305               return -99;
15306             }
15307         }
15308       else
15309         if (unformat
15310             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15311         {
15312           if (integ_alg >= IPSEC_INTEG_N_ALG)
15313             {
15314               errmsg ("unsupported integ-alg: '%U'\n",
15315                       format_ipsec_integ_alg, integ_alg);
15316               return -99;
15317             }
15318         }
15319       else if (unformat (i, "instance %u", &instance))
15320         renumber = 1;
15321       else
15322         {
15323           errmsg ("parse error '%U'\n", format_unformat_error, i);
15324           return -99;
15325         }
15326     }
15327
15328   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15329
15330   mp->is_add = is_add;
15331   mp->esn = esn;
15332   mp->anti_replay = anti_replay;
15333
15334   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15335   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15336
15337   mp->local_spi = htonl (local_spi);
15338   mp->remote_spi = htonl (remote_spi);
15339   mp->crypto_alg = (u8) crypto_alg;
15340
15341   mp->local_crypto_key_len = 0;
15342   if (lck)
15343     {
15344       mp->local_crypto_key_len = vec_len (lck);
15345       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15346         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15347       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15348     }
15349
15350   mp->remote_crypto_key_len = 0;
15351   if (rck)
15352     {
15353       mp->remote_crypto_key_len = vec_len (rck);
15354       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15355         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15356       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15357     }
15358
15359   mp->integ_alg = (u8) integ_alg;
15360
15361   mp->local_integ_key_len = 0;
15362   if (lik)
15363     {
15364       mp->local_integ_key_len = vec_len (lik);
15365       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15366         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15367       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15368     }
15369
15370   mp->remote_integ_key_len = 0;
15371   if (rik)
15372     {
15373       mp->remote_integ_key_len = vec_len (rik);
15374       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15375         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15376       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15377     }
15378
15379   if (renumber)
15380     {
15381       mp->renumber = renumber;
15382       mp->show_instance = ntohl (instance);
15383     }
15384
15385   S (mp);
15386   W (ret);
15387   return ret;
15388 }
15389
15390 static void
15391 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15392 {
15393   vat_main_t *vam = &vat_main;
15394
15395   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15396          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15397          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15398          "tunnel_src_addr %U tunnel_dst_addr %U "
15399          "salt %u seq_outbound %lu last_seq_inbound %lu "
15400          "replay_window %lu total_data_size %lu\n",
15401          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15402          mp->protocol,
15403          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15404          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15405          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15406          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15407          mp->tunnel_src_addr,
15408          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15409          mp->tunnel_dst_addr,
15410          ntohl (mp->salt),
15411          clib_net_to_host_u64 (mp->seq_outbound),
15412          clib_net_to_host_u64 (mp->last_seq_inbound),
15413          clib_net_to_host_u64 (mp->replay_window),
15414          clib_net_to_host_u64 (mp->total_data_size));
15415 }
15416
15417 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15418 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15419
15420 static void vl_api_ipsec_sa_details_t_handler_json
15421   (vl_api_ipsec_sa_details_t * mp)
15422 {
15423   vat_main_t *vam = &vat_main;
15424   vat_json_node_t *node = NULL;
15425   struct in_addr src_ip4, dst_ip4;
15426   struct in6_addr src_ip6, dst_ip6;
15427
15428   if (VAT_JSON_ARRAY != vam->json_tree.type)
15429     {
15430       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15431       vat_json_init_array (&vam->json_tree);
15432     }
15433   node = vat_json_array_add (&vam->json_tree);
15434
15435   vat_json_init_object (node);
15436   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15437   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15438   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15439   vat_json_object_add_uint (node, "proto", mp->protocol);
15440   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15441   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15442   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15443   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15444   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15445   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15446   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15447                              mp->crypto_key_len);
15448   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15449                              mp->integ_key_len);
15450   if (mp->is_tunnel_ip6)
15451     {
15452       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15453       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15454       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15455       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15456     }
15457   else
15458     {
15459       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15460       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15461       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15462       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15463     }
15464   vat_json_object_add_uint (node, "replay_window",
15465                             clib_net_to_host_u64 (mp->replay_window));
15466   vat_json_object_add_uint (node, "total_data_size",
15467                             clib_net_to_host_u64 (mp->total_data_size));
15468
15469 }
15470
15471 static int
15472 api_ipsec_sa_dump (vat_main_t * vam)
15473 {
15474   unformat_input_t *i = vam->input;
15475   vl_api_ipsec_sa_dump_t *mp;
15476   vl_api_control_ping_t *mp_ping;
15477   u32 sa_id = ~0;
15478   int ret;
15479
15480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15481     {
15482       if (unformat (i, "sa_id %d", &sa_id))
15483         ;
15484       else
15485         {
15486           clib_warning ("parse error '%U'", format_unformat_error, i);
15487           return -99;
15488         }
15489     }
15490
15491   M (IPSEC_SA_DUMP, mp);
15492
15493   mp->sa_id = ntohl (sa_id);
15494
15495   S (mp);
15496
15497   /* Use a control ping for synchronization */
15498   M (CONTROL_PING, mp_ping);
15499   S (mp_ping);
15500
15501   W (ret);
15502   return ret;
15503 }
15504
15505 static int
15506 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15507 {
15508   unformat_input_t *i = vam->input;
15509   vl_api_ipsec_tunnel_if_set_key_t *mp;
15510   u32 sw_if_index = ~0;
15511   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15512   u8 *key = 0;
15513   u32 alg = ~0;
15514   int ret;
15515
15516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15517     {
15518       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15519         ;
15520       else
15521         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15522         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15523       else
15524         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15525         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15526       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15527         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15528       else
15529         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15530         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15531       else if (unformat (i, "%U", unformat_hex_string, &key))
15532         ;
15533       else
15534         {
15535           clib_warning ("parse error '%U'", format_unformat_error, i);
15536           return -99;
15537         }
15538     }
15539
15540   if (sw_if_index == ~0)
15541     {
15542       errmsg ("interface must be specified");
15543       return -99;
15544     }
15545
15546   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15547     {
15548       errmsg ("key type must be specified");
15549       return -99;
15550     }
15551
15552   if (alg == ~0)
15553     {
15554       errmsg ("algorithm must be specified");
15555       return -99;
15556     }
15557
15558   if (vec_len (key) == 0)
15559     {
15560       errmsg ("key must be specified");
15561       return -99;
15562     }
15563
15564   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15565
15566   mp->sw_if_index = htonl (sw_if_index);
15567   mp->alg = alg;
15568   mp->key_type = key_type;
15569   mp->key_len = vec_len (key);
15570   clib_memcpy (mp->key, key, vec_len (key));
15571
15572   S (mp);
15573   W (ret);
15574
15575   return ret;
15576 }
15577
15578 static int
15579 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15580 {
15581   unformat_input_t *i = vam->input;
15582   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15583   u32 sw_if_index = ~0;
15584   u32 sa_id = ~0;
15585   u8 is_outbound = (u8) ~ 0;
15586   int ret;
15587
15588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15589     {
15590       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15591         ;
15592       else if (unformat (i, "sa_id %d", &sa_id))
15593         ;
15594       else if (unformat (i, "outbound"))
15595         is_outbound = 1;
15596       else if (unformat (i, "inbound"))
15597         is_outbound = 0;
15598       else
15599         {
15600           clib_warning ("parse error '%U'", format_unformat_error, i);
15601           return -99;
15602         }
15603     }
15604
15605   if (sw_if_index == ~0)
15606     {
15607       errmsg ("interface must be specified");
15608       return -99;
15609     }
15610
15611   if (sa_id == ~0)
15612     {
15613       errmsg ("SA ID must be specified");
15614       return -99;
15615     }
15616
15617   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15618
15619   mp->sw_if_index = htonl (sw_if_index);
15620   mp->sa_id = htonl (sa_id);
15621   mp->is_outbound = is_outbound;
15622
15623   S (mp);
15624   W (ret);
15625
15626   return ret;
15627 }
15628
15629 static int
15630 api_ikev2_profile_add_del (vat_main_t * vam)
15631 {
15632   unformat_input_t *i = vam->input;
15633   vl_api_ikev2_profile_add_del_t *mp;
15634   u8 is_add = 1;
15635   u8 *name = 0;
15636   int ret;
15637
15638   const char *valid_chars = "a-zA-Z0-9_";
15639
15640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15641     {
15642       if (unformat (i, "del"))
15643         is_add = 0;
15644       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15645         vec_add1 (name, 0);
15646       else
15647         {
15648           errmsg ("parse error '%U'", format_unformat_error, i);
15649           return -99;
15650         }
15651     }
15652
15653   if (!vec_len (name))
15654     {
15655       errmsg ("profile name must be specified");
15656       return -99;
15657     }
15658
15659   if (vec_len (name) > 64)
15660     {
15661       errmsg ("profile name too long");
15662       return -99;
15663     }
15664
15665   M (IKEV2_PROFILE_ADD_DEL, mp);
15666
15667   clib_memcpy (mp->name, name, vec_len (name));
15668   mp->is_add = is_add;
15669   vec_free (name);
15670
15671   S (mp);
15672   W (ret);
15673   return ret;
15674 }
15675
15676 static int
15677 api_ikev2_profile_set_auth (vat_main_t * vam)
15678 {
15679   unformat_input_t *i = vam->input;
15680   vl_api_ikev2_profile_set_auth_t *mp;
15681   u8 *name = 0;
15682   u8 *data = 0;
15683   u32 auth_method = 0;
15684   u8 is_hex = 0;
15685   int ret;
15686
15687   const char *valid_chars = "a-zA-Z0-9_";
15688
15689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15690     {
15691       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15692         vec_add1 (name, 0);
15693       else if (unformat (i, "auth_method %U",
15694                          unformat_ikev2_auth_method, &auth_method))
15695         ;
15696       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15697         is_hex = 1;
15698       else if (unformat (i, "auth_data %v", &data))
15699         ;
15700       else
15701         {
15702           errmsg ("parse error '%U'", format_unformat_error, i);
15703           return -99;
15704         }
15705     }
15706
15707   if (!vec_len (name))
15708     {
15709       errmsg ("profile name must be specified");
15710       return -99;
15711     }
15712
15713   if (vec_len (name) > 64)
15714     {
15715       errmsg ("profile name too long");
15716       return -99;
15717     }
15718
15719   if (!vec_len (data))
15720     {
15721       errmsg ("auth_data must be specified");
15722       return -99;
15723     }
15724
15725   if (!auth_method)
15726     {
15727       errmsg ("auth_method must be specified");
15728       return -99;
15729     }
15730
15731   M (IKEV2_PROFILE_SET_AUTH, mp);
15732
15733   mp->is_hex = is_hex;
15734   mp->auth_method = (u8) auth_method;
15735   mp->data_len = vec_len (data);
15736   clib_memcpy (mp->name, name, vec_len (name));
15737   clib_memcpy (mp->data, data, vec_len (data));
15738   vec_free (name);
15739   vec_free (data);
15740
15741   S (mp);
15742   W (ret);
15743   return ret;
15744 }
15745
15746 static int
15747 api_ikev2_profile_set_id (vat_main_t * vam)
15748 {
15749   unformat_input_t *i = vam->input;
15750   vl_api_ikev2_profile_set_id_t *mp;
15751   u8 *name = 0;
15752   u8 *data = 0;
15753   u8 is_local = 0;
15754   u32 id_type = 0;
15755   ip4_address_t ip4;
15756   int ret;
15757
15758   const char *valid_chars = "a-zA-Z0-9_";
15759
15760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15761     {
15762       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15763         vec_add1 (name, 0);
15764       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15765         ;
15766       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15767         {
15768           data = vec_new (u8, 4);
15769           clib_memcpy (data, ip4.as_u8, 4);
15770         }
15771       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15772         ;
15773       else if (unformat (i, "id_data %v", &data))
15774         ;
15775       else if (unformat (i, "local"))
15776         is_local = 1;
15777       else if (unformat (i, "remote"))
15778         is_local = 0;
15779       else
15780         {
15781           errmsg ("parse error '%U'", format_unformat_error, i);
15782           return -99;
15783         }
15784     }
15785
15786   if (!vec_len (name))
15787     {
15788       errmsg ("profile name must be specified");
15789       return -99;
15790     }
15791
15792   if (vec_len (name) > 64)
15793     {
15794       errmsg ("profile name too long");
15795       return -99;
15796     }
15797
15798   if (!vec_len (data))
15799     {
15800       errmsg ("id_data must be specified");
15801       return -99;
15802     }
15803
15804   if (!id_type)
15805     {
15806       errmsg ("id_type must be specified");
15807       return -99;
15808     }
15809
15810   M (IKEV2_PROFILE_SET_ID, mp);
15811
15812   mp->is_local = is_local;
15813   mp->id_type = (u8) id_type;
15814   mp->data_len = vec_len (data);
15815   clib_memcpy (mp->name, name, vec_len (name));
15816   clib_memcpy (mp->data, data, vec_len (data));
15817   vec_free (name);
15818   vec_free (data);
15819
15820   S (mp);
15821   W (ret);
15822   return ret;
15823 }
15824
15825 static int
15826 api_ikev2_profile_set_ts (vat_main_t * vam)
15827 {
15828   unformat_input_t *i = vam->input;
15829   vl_api_ikev2_profile_set_ts_t *mp;
15830   u8 *name = 0;
15831   u8 is_local = 0;
15832   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15833   ip4_address_t start_addr, end_addr;
15834
15835   const char *valid_chars = "a-zA-Z0-9_";
15836   int ret;
15837
15838   start_addr.as_u32 = 0;
15839   end_addr.as_u32 = (u32) ~ 0;
15840
15841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15842     {
15843       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15844         vec_add1 (name, 0);
15845       else if (unformat (i, "protocol %d", &proto))
15846         ;
15847       else if (unformat (i, "start_port %d", &start_port))
15848         ;
15849       else if (unformat (i, "end_port %d", &end_port))
15850         ;
15851       else
15852         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15853         ;
15854       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15855         ;
15856       else if (unformat (i, "local"))
15857         is_local = 1;
15858       else if (unformat (i, "remote"))
15859         is_local = 0;
15860       else
15861         {
15862           errmsg ("parse error '%U'", format_unformat_error, i);
15863           return -99;
15864         }
15865     }
15866
15867   if (!vec_len (name))
15868     {
15869       errmsg ("profile name must be specified");
15870       return -99;
15871     }
15872
15873   if (vec_len (name) > 64)
15874     {
15875       errmsg ("profile name too long");
15876       return -99;
15877     }
15878
15879   M (IKEV2_PROFILE_SET_TS, mp);
15880
15881   mp->is_local = is_local;
15882   mp->proto = (u8) proto;
15883   mp->start_port = (u16) start_port;
15884   mp->end_port = (u16) end_port;
15885   mp->start_addr = start_addr.as_u32;
15886   mp->end_addr = end_addr.as_u32;
15887   clib_memcpy (mp->name, name, vec_len (name));
15888   vec_free (name);
15889
15890   S (mp);
15891   W (ret);
15892   return ret;
15893 }
15894
15895 static int
15896 api_ikev2_set_local_key (vat_main_t * vam)
15897 {
15898   unformat_input_t *i = vam->input;
15899   vl_api_ikev2_set_local_key_t *mp;
15900   u8 *file = 0;
15901   int ret;
15902
15903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15904     {
15905       if (unformat (i, "file %v", &file))
15906         vec_add1 (file, 0);
15907       else
15908         {
15909           errmsg ("parse error '%U'", format_unformat_error, i);
15910           return -99;
15911         }
15912     }
15913
15914   if (!vec_len (file))
15915     {
15916       errmsg ("RSA key file must be specified");
15917       return -99;
15918     }
15919
15920   if (vec_len (file) > 256)
15921     {
15922       errmsg ("file name too long");
15923       return -99;
15924     }
15925
15926   M (IKEV2_SET_LOCAL_KEY, mp);
15927
15928   clib_memcpy (mp->key_file, file, vec_len (file));
15929   vec_free (file);
15930
15931   S (mp);
15932   W (ret);
15933   return ret;
15934 }
15935
15936 static int
15937 api_ikev2_set_responder (vat_main_t * vam)
15938 {
15939   unformat_input_t *i = vam->input;
15940   vl_api_ikev2_set_responder_t *mp;
15941   int ret;
15942   u8 *name = 0;
15943   u32 sw_if_index = ~0;
15944   ip4_address_t address;
15945
15946   const char *valid_chars = "a-zA-Z0-9_";
15947
15948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15949     {
15950       if (unformat
15951           (i, "%U interface %d address %U", unformat_token, valid_chars,
15952            &name, &sw_if_index, unformat_ip4_address, &address))
15953         vec_add1 (name, 0);
15954       else
15955         {
15956           errmsg ("parse error '%U'", format_unformat_error, i);
15957           return -99;
15958         }
15959     }
15960
15961   if (!vec_len (name))
15962     {
15963       errmsg ("profile name must be specified");
15964       return -99;
15965     }
15966
15967   if (vec_len (name) > 64)
15968     {
15969       errmsg ("profile name too long");
15970       return -99;
15971     }
15972
15973   M (IKEV2_SET_RESPONDER, mp);
15974
15975   clib_memcpy (mp->name, name, vec_len (name));
15976   vec_free (name);
15977
15978   mp->sw_if_index = sw_if_index;
15979   clib_memcpy (mp->address, &address, sizeof (address));
15980
15981   S (mp);
15982   W (ret);
15983   return ret;
15984 }
15985
15986 static int
15987 api_ikev2_set_ike_transforms (vat_main_t * vam)
15988 {
15989   unformat_input_t *i = vam->input;
15990   vl_api_ikev2_set_ike_transforms_t *mp;
15991   int ret;
15992   u8 *name = 0;
15993   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15994
15995   const char *valid_chars = "a-zA-Z0-9_";
15996
15997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15998     {
15999       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16000                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16001         vec_add1 (name, 0);
16002       else
16003         {
16004           errmsg ("parse error '%U'", format_unformat_error, i);
16005           return -99;
16006         }
16007     }
16008
16009   if (!vec_len (name))
16010     {
16011       errmsg ("profile name must be specified");
16012       return -99;
16013     }
16014
16015   if (vec_len (name) > 64)
16016     {
16017       errmsg ("profile name too long");
16018       return -99;
16019     }
16020
16021   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16022
16023   clib_memcpy (mp->name, name, vec_len (name));
16024   vec_free (name);
16025   mp->crypto_alg = crypto_alg;
16026   mp->crypto_key_size = crypto_key_size;
16027   mp->integ_alg = integ_alg;
16028   mp->dh_group = dh_group;
16029
16030   S (mp);
16031   W (ret);
16032   return ret;
16033 }
16034
16035
16036 static int
16037 api_ikev2_set_esp_transforms (vat_main_t * vam)
16038 {
16039   unformat_input_t *i = vam->input;
16040   vl_api_ikev2_set_esp_transforms_t *mp;
16041   int ret;
16042   u8 *name = 0;
16043   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16044
16045   const char *valid_chars = "a-zA-Z0-9_";
16046
16047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16048     {
16049       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16050                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16051         vec_add1 (name, 0);
16052       else
16053         {
16054           errmsg ("parse error '%U'", format_unformat_error, i);
16055           return -99;
16056         }
16057     }
16058
16059   if (!vec_len (name))
16060     {
16061       errmsg ("profile name must be specified");
16062       return -99;
16063     }
16064
16065   if (vec_len (name) > 64)
16066     {
16067       errmsg ("profile name too long");
16068       return -99;
16069     }
16070
16071   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16072
16073   clib_memcpy (mp->name, name, vec_len (name));
16074   vec_free (name);
16075   mp->crypto_alg = crypto_alg;
16076   mp->crypto_key_size = crypto_key_size;
16077   mp->integ_alg = integ_alg;
16078   mp->dh_group = dh_group;
16079
16080   S (mp);
16081   W (ret);
16082   return ret;
16083 }
16084
16085 static int
16086 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16087 {
16088   unformat_input_t *i = vam->input;
16089   vl_api_ikev2_set_sa_lifetime_t *mp;
16090   int ret;
16091   u8 *name = 0;
16092   u64 lifetime, lifetime_maxdata;
16093   u32 lifetime_jitter, handover;
16094
16095   const char *valid_chars = "a-zA-Z0-9_";
16096
16097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16098     {
16099       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16100                     &lifetime, &lifetime_jitter, &handover,
16101                     &lifetime_maxdata))
16102         vec_add1 (name, 0);
16103       else
16104         {
16105           errmsg ("parse error '%U'", format_unformat_error, i);
16106           return -99;
16107         }
16108     }
16109
16110   if (!vec_len (name))
16111     {
16112       errmsg ("profile name must be specified");
16113       return -99;
16114     }
16115
16116   if (vec_len (name) > 64)
16117     {
16118       errmsg ("profile name too long");
16119       return -99;
16120     }
16121
16122   M (IKEV2_SET_SA_LIFETIME, mp);
16123
16124   clib_memcpy (mp->name, name, vec_len (name));
16125   vec_free (name);
16126   mp->lifetime = lifetime;
16127   mp->lifetime_jitter = lifetime_jitter;
16128   mp->handover = handover;
16129   mp->lifetime_maxdata = lifetime_maxdata;
16130
16131   S (mp);
16132   W (ret);
16133   return ret;
16134 }
16135
16136 static int
16137 api_ikev2_initiate_sa_init (vat_main_t * vam)
16138 {
16139   unformat_input_t *i = vam->input;
16140   vl_api_ikev2_initiate_sa_init_t *mp;
16141   int ret;
16142   u8 *name = 0;
16143
16144   const char *valid_chars = "a-zA-Z0-9_";
16145
16146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16147     {
16148       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16149         vec_add1 (name, 0);
16150       else
16151         {
16152           errmsg ("parse error '%U'", format_unformat_error, i);
16153           return -99;
16154         }
16155     }
16156
16157   if (!vec_len (name))
16158     {
16159       errmsg ("profile name must be specified");
16160       return -99;
16161     }
16162
16163   if (vec_len (name) > 64)
16164     {
16165       errmsg ("profile name too long");
16166       return -99;
16167     }
16168
16169   M (IKEV2_INITIATE_SA_INIT, mp);
16170
16171   clib_memcpy (mp->name, name, vec_len (name));
16172   vec_free (name);
16173
16174   S (mp);
16175   W (ret);
16176   return ret;
16177 }
16178
16179 static int
16180 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16181 {
16182   unformat_input_t *i = vam->input;
16183   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16184   int ret;
16185   u64 ispi;
16186
16187
16188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16189     {
16190       if (unformat (i, "%lx", &ispi))
16191         ;
16192       else
16193         {
16194           errmsg ("parse error '%U'", format_unformat_error, i);
16195           return -99;
16196         }
16197     }
16198
16199   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16200
16201   mp->ispi = ispi;
16202
16203   S (mp);
16204   W (ret);
16205   return ret;
16206 }
16207
16208 static int
16209 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16210 {
16211   unformat_input_t *i = vam->input;
16212   vl_api_ikev2_initiate_del_child_sa_t *mp;
16213   int ret;
16214   u32 ispi;
16215
16216
16217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16218     {
16219       if (unformat (i, "%x", &ispi))
16220         ;
16221       else
16222         {
16223           errmsg ("parse error '%U'", format_unformat_error, i);
16224           return -99;
16225         }
16226     }
16227
16228   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16229
16230   mp->ispi = ispi;
16231
16232   S (mp);
16233   W (ret);
16234   return ret;
16235 }
16236
16237 static int
16238 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16239 {
16240   unformat_input_t *i = vam->input;
16241   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16242   int ret;
16243   u32 ispi;
16244
16245
16246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16247     {
16248       if (unformat (i, "%x", &ispi))
16249         ;
16250       else
16251         {
16252           errmsg ("parse error '%U'", format_unformat_error, i);
16253           return -99;
16254         }
16255     }
16256
16257   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16258
16259   mp->ispi = ispi;
16260
16261   S (mp);
16262   W (ret);
16263   return ret;
16264 }
16265
16266 static int
16267 api_get_first_msg_id (vat_main_t * vam)
16268 {
16269   vl_api_get_first_msg_id_t *mp;
16270   unformat_input_t *i = vam->input;
16271   u8 *name;
16272   u8 name_set = 0;
16273   int ret;
16274
16275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16276     {
16277       if (unformat (i, "client %s", &name))
16278         name_set = 1;
16279       else
16280         break;
16281     }
16282
16283   if (name_set == 0)
16284     {
16285       errmsg ("missing client name");
16286       return -99;
16287     }
16288   vec_add1 (name, 0);
16289
16290   if (vec_len (name) > 63)
16291     {
16292       errmsg ("client name too long");
16293       return -99;
16294     }
16295
16296   M (GET_FIRST_MSG_ID, mp);
16297   clib_memcpy (mp->name, name, vec_len (name));
16298   S (mp);
16299   W (ret);
16300   return ret;
16301 }
16302
16303 static int
16304 api_cop_interface_enable_disable (vat_main_t * vam)
16305 {
16306   unformat_input_t *line_input = vam->input;
16307   vl_api_cop_interface_enable_disable_t *mp;
16308   u32 sw_if_index = ~0;
16309   u8 enable_disable = 1;
16310   int ret;
16311
16312   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16313     {
16314       if (unformat (line_input, "disable"))
16315         enable_disable = 0;
16316       if (unformat (line_input, "enable"))
16317         enable_disable = 1;
16318       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16319                          vam, &sw_if_index))
16320         ;
16321       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16322         ;
16323       else
16324         break;
16325     }
16326
16327   if (sw_if_index == ~0)
16328     {
16329       errmsg ("missing interface name or sw_if_index");
16330       return -99;
16331     }
16332
16333   /* Construct the API message */
16334   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16335   mp->sw_if_index = ntohl (sw_if_index);
16336   mp->enable_disable = enable_disable;
16337
16338   /* send it... */
16339   S (mp);
16340   /* Wait for the reply */
16341   W (ret);
16342   return ret;
16343 }
16344
16345 static int
16346 api_cop_whitelist_enable_disable (vat_main_t * vam)
16347 {
16348   unformat_input_t *line_input = vam->input;
16349   vl_api_cop_whitelist_enable_disable_t *mp;
16350   u32 sw_if_index = ~0;
16351   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16352   u32 fib_id = 0;
16353   int ret;
16354
16355   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16356     {
16357       if (unformat (line_input, "ip4"))
16358         ip4 = 1;
16359       else if (unformat (line_input, "ip6"))
16360         ip6 = 1;
16361       else if (unformat (line_input, "default"))
16362         default_cop = 1;
16363       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16364                          vam, &sw_if_index))
16365         ;
16366       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16367         ;
16368       else if (unformat (line_input, "fib-id %d", &fib_id))
16369         ;
16370       else
16371         break;
16372     }
16373
16374   if (sw_if_index == ~0)
16375     {
16376       errmsg ("missing interface name or sw_if_index");
16377       return -99;
16378     }
16379
16380   /* Construct the API message */
16381   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16382   mp->sw_if_index = ntohl (sw_if_index);
16383   mp->fib_id = ntohl (fib_id);
16384   mp->ip4 = ip4;
16385   mp->ip6 = ip6;
16386   mp->default_cop = default_cop;
16387
16388   /* send it... */
16389   S (mp);
16390   /* Wait for the reply */
16391   W (ret);
16392   return ret;
16393 }
16394
16395 static int
16396 api_get_node_graph (vat_main_t * vam)
16397 {
16398   vl_api_get_node_graph_t *mp;
16399   int ret;
16400
16401   M (GET_NODE_GRAPH, mp);
16402
16403   /* send it... */
16404   S (mp);
16405   /* Wait for the reply */
16406   W (ret);
16407   return ret;
16408 }
16409
16410 /* *INDENT-OFF* */
16411 /** Used for parsing LISP eids */
16412 typedef CLIB_PACKED(struct{
16413   u8 addr[16];   /**< eid address */
16414   u32 len;       /**< prefix length if IP */
16415   u8 type;      /**< type of eid */
16416 }) lisp_eid_vat_t;
16417 /* *INDENT-ON* */
16418
16419 static uword
16420 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16421 {
16422   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16423
16424   memset (a, 0, sizeof (a[0]));
16425
16426   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16427     {
16428       a->type = 0;              /* ipv4 type */
16429     }
16430   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16431     {
16432       a->type = 1;              /* ipv6 type */
16433     }
16434   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16435     {
16436       a->type = 2;              /* mac type */
16437     }
16438   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16439     {
16440       a->type = 3;              /* NSH type */
16441       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16442       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16443     }
16444   else
16445     {
16446       return 0;
16447     }
16448
16449   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16450     {
16451       return 0;
16452     }
16453
16454   return 1;
16455 }
16456
16457 static int
16458 lisp_eid_size_vat (u8 type)
16459 {
16460   switch (type)
16461     {
16462     case 0:
16463       return 4;
16464     case 1:
16465       return 16;
16466     case 2:
16467       return 6;
16468     case 3:
16469       return 5;
16470     }
16471   return 0;
16472 }
16473
16474 static void
16475 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16476 {
16477   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16478 }
16479
16480 static int
16481 api_one_add_del_locator_set (vat_main_t * vam)
16482 {
16483   unformat_input_t *input = vam->input;
16484   vl_api_one_add_del_locator_set_t *mp;
16485   u8 is_add = 1;
16486   u8 *locator_set_name = NULL;
16487   u8 locator_set_name_set = 0;
16488   vl_api_local_locator_t locator, *locators = 0;
16489   u32 sw_if_index, priority, weight;
16490   u32 data_len = 0;
16491
16492   int ret;
16493   /* Parse args required to build the message */
16494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16495     {
16496       if (unformat (input, "del"))
16497         {
16498           is_add = 0;
16499         }
16500       else if (unformat (input, "locator-set %s", &locator_set_name))
16501         {
16502           locator_set_name_set = 1;
16503         }
16504       else if (unformat (input, "sw_if_index %u p %u w %u",
16505                          &sw_if_index, &priority, &weight))
16506         {
16507           locator.sw_if_index = htonl (sw_if_index);
16508           locator.priority = priority;
16509           locator.weight = weight;
16510           vec_add1 (locators, locator);
16511         }
16512       else
16513         if (unformat
16514             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16515              &sw_if_index, &priority, &weight))
16516         {
16517           locator.sw_if_index = htonl (sw_if_index);
16518           locator.priority = priority;
16519           locator.weight = weight;
16520           vec_add1 (locators, locator);
16521         }
16522       else
16523         break;
16524     }
16525
16526   if (locator_set_name_set == 0)
16527     {
16528       errmsg ("missing locator-set name");
16529       vec_free (locators);
16530       return -99;
16531     }
16532
16533   if (vec_len (locator_set_name) > 64)
16534     {
16535       errmsg ("locator-set name too long");
16536       vec_free (locator_set_name);
16537       vec_free (locators);
16538       return -99;
16539     }
16540   vec_add1 (locator_set_name, 0);
16541
16542   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16543
16544   /* Construct the API message */
16545   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16546
16547   mp->is_add = is_add;
16548   clib_memcpy (mp->locator_set_name, locator_set_name,
16549                vec_len (locator_set_name));
16550   vec_free (locator_set_name);
16551
16552   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16553   if (locators)
16554     clib_memcpy (mp->locators, locators, data_len);
16555   vec_free (locators);
16556
16557   /* send it... */
16558   S (mp);
16559
16560   /* Wait for a reply... */
16561   W (ret);
16562   return ret;
16563 }
16564
16565 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16566
16567 static int
16568 api_one_add_del_locator (vat_main_t * vam)
16569 {
16570   unformat_input_t *input = vam->input;
16571   vl_api_one_add_del_locator_t *mp;
16572   u32 tmp_if_index = ~0;
16573   u32 sw_if_index = ~0;
16574   u8 sw_if_index_set = 0;
16575   u8 sw_if_index_if_name_set = 0;
16576   u32 priority = ~0;
16577   u8 priority_set = 0;
16578   u32 weight = ~0;
16579   u8 weight_set = 0;
16580   u8 is_add = 1;
16581   u8 *locator_set_name = NULL;
16582   u8 locator_set_name_set = 0;
16583   int ret;
16584
16585   /* Parse args required to build the message */
16586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16587     {
16588       if (unformat (input, "del"))
16589         {
16590           is_add = 0;
16591         }
16592       else if (unformat (input, "locator-set %s", &locator_set_name))
16593         {
16594           locator_set_name_set = 1;
16595         }
16596       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16597                          &tmp_if_index))
16598         {
16599           sw_if_index_if_name_set = 1;
16600           sw_if_index = tmp_if_index;
16601         }
16602       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16603         {
16604           sw_if_index_set = 1;
16605           sw_if_index = tmp_if_index;
16606         }
16607       else if (unformat (input, "p %d", &priority))
16608         {
16609           priority_set = 1;
16610         }
16611       else if (unformat (input, "w %d", &weight))
16612         {
16613           weight_set = 1;
16614         }
16615       else
16616         break;
16617     }
16618
16619   if (locator_set_name_set == 0)
16620     {
16621       errmsg ("missing locator-set name");
16622       return -99;
16623     }
16624
16625   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16626     {
16627       errmsg ("missing sw_if_index");
16628       vec_free (locator_set_name);
16629       return -99;
16630     }
16631
16632   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16633     {
16634       errmsg ("cannot use both params interface name and sw_if_index");
16635       vec_free (locator_set_name);
16636       return -99;
16637     }
16638
16639   if (priority_set == 0)
16640     {
16641       errmsg ("missing locator-set priority");
16642       vec_free (locator_set_name);
16643       return -99;
16644     }
16645
16646   if (weight_set == 0)
16647     {
16648       errmsg ("missing locator-set weight");
16649       vec_free (locator_set_name);
16650       return -99;
16651     }
16652
16653   if (vec_len (locator_set_name) > 64)
16654     {
16655       errmsg ("locator-set name too long");
16656       vec_free (locator_set_name);
16657       return -99;
16658     }
16659   vec_add1 (locator_set_name, 0);
16660
16661   /* Construct the API message */
16662   M (ONE_ADD_DEL_LOCATOR, mp);
16663
16664   mp->is_add = is_add;
16665   mp->sw_if_index = ntohl (sw_if_index);
16666   mp->priority = priority;
16667   mp->weight = weight;
16668   clib_memcpy (mp->locator_set_name, locator_set_name,
16669                vec_len (locator_set_name));
16670   vec_free (locator_set_name);
16671
16672   /* send it... */
16673   S (mp);
16674
16675   /* Wait for a reply... */
16676   W (ret);
16677   return ret;
16678 }
16679
16680 #define api_lisp_add_del_locator api_one_add_del_locator
16681
16682 uword
16683 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16684 {
16685   u32 *key_id = va_arg (*args, u32 *);
16686   u8 *s = 0;
16687
16688   if (unformat (input, "%s", &s))
16689     {
16690       if (!strcmp ((char *) s, "sha1"))
16691         key_id[0] = HMAC_SHA_1_96;
16692       else if (!strcmp ((char *) s, "sha256"))
16693         key_id[0] = HMAC_SHA_256_128;
16694       else
16695         {
16696           clib_warning ("invalid key_id: '%s'", s);
16697           key_id[0] = HMAC_NO_KEY;
16698         }
16699     }
16700   else
16701     return 0;
16702
16703   vec_free (s);
16704   return 1;
16705 }
16706
16707 static int
16708 api_one_add_del_local_eid (vat_main_t * vam)
16709 {
16710   unformat_input_t *input = vam->input;
16711   vl_api_one_add_del_local_eid_t *mp;
16712   u8 is_add = 1;
16713   u8 eid_set = 0;
16714   lisp_eid_vat_t _eid, *eid = &_eid;
16715   u8 *locator_set_name = 0;
16716   u8 locator_set_name_set = 0;
16717   u32 vni = 0;
16718   u16 key_id = 0;
16719   u8 *key = 0;
16720   int ret;
16721
16722   /* Parse args required to build the message */
16723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16724     {
16725       if (unformat (input, "del"))
16726         {
16727           is_add = 0;
16728         }
16729       else if (unformat (input, "vni %d", &vni))
16730         {
16731           ;
16732         }
16733       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16734         {
16735           eid_set = 1;
16736         }
16737       else if (unformat (input, "locator-set %s", &locator_set_name))
16738         {
16739           locator_set_name_set = 1;
16740         }
16741       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16742         ;
16743       else if (unformat (input, "secret-key %_%v%_", &key))
16744         ;
16745       else
16746         break;
16747     }
16748
16749   if (locator_set_name_set == 0)
16750     {
16751       errmsg ("missing locator-set name");
16752       return -99;
16753     }
16754
16755   if (0 == eid_set)
16756     {
16757       errmsg ("EID address not set!");
16758       vec_free (locator_set_name);
16759       return -99;
16760     }
16761
16762   if (key && (0 == key_id))
16763     {
16764       errmsg ("invalid key_id!");
16765       return -99;
16766     }
16767
16768   if (vec_len (key) > 64)
16769     {
16770       errmsg ("key too long");
16771       vec_free (key);
16772       return -99;
16773     }
16774
16775   if (vec_len (locator_set_name) > 64)
16776     {
16777       errmsg ("locator-set name too long");
16778       vec_free (locator_set_name);
16779       return -99;
16780     }
16781   vec_add1 (locator_set_name, 0);
16782
16783   /* Construct the API message */
16784   M (ONE_ADD_DEL_LOCAL_EID, mp);
16785
16786   mp->is_add = is_add;
16787   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16788   mp->eid_type = eid->type;
16789   mp->prefix_len = eid->len;
16790   mp->vni = clib_host_to_net_u32 (vni);
16791   mp->key_id = clib_host_to_net_u16 (key_id);
16792   clib_memcpy (mp->locator_set_name, locator_set_name,
16793                vec_len (locator_set_name));
16794   clib_memcpy (mp->key, key, vec_len (key));
16795
16796   vec_free (locator_set_name);
16797   vec_free (key);
16798
16799   /* send it... */
16800   S (mp);
16801
16802   /* Wait for a reply... */
16803   W (ret);
16804   return ret;
16805 }
16806
16807 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16808
16809 static int
16810 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16811 {
16812   u32 dp_table = 0, vni = 0;;
16813   unformat_input_t *input = vam->input;
16814   vl_api_gpe_add_del_fwd_entry_t *mp;
16815   u8 is_add = 1;
16816   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16817   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16818   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16819   u32 action = ~0, w;
16820   ip4_address_t rmt_rloc4, lcl_rloc4;
16821   ip6_address_t rmt_rloc6, lcl_rloc6;
16822   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16823   int ret;
16824
16825   memset (&rloc, 0, sizeof (rloc));
16826
16827   /* Parse args required to build the message */
16828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16829     {
16830       if (unformat (input, "del"))
16831         is_add = 0;
16832       else if (unformat (input, "add"))
16833         is_add = 1;
16834       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16835         {
16836           rmt_eid_set = 1;
16837         }
16838       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16839         {
16840           lcl_eid_set = 1;
16841         }
16842       else if (unformat (input, "vrf %d", &dp_table))
16843         ;
16844       else if (unformat (input, "bd %d", &dp_table))
16845         ;
16846       else if (unformat (input, "vni %d", &vni))
16847         ;
16848       else if (unformat (input, "w %d", &w))
16849         {
16850           if (!curr_rloc)
16851             {
16852               errmsg ("No RLOC configured for setting priority/weight!");
16853               return -99;
16854             }
16855           curr_rloc->weight = w;
16856         }
16857       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16858                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16859         {
16860           rloc.is_ip4 = 1;
16861
16862           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16863           rloc.weight = 0;
16864           vec_add1 (lcl_locs, rloc);
16865
16866           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16867           vec_add1 (rmt_locs, rloc);
16868           /* weight saved in rmt loc */
16869           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16870         }
16871       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16872                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16873         {
16874           rloc.is_ip4 = 0;
16875           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16876           rloc.weight = 0;
16877           vec_add1 (lcl_locs, rloc);
16878
16879           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16880           vec_add1 (rmt_locs, rloc);
16881           /* weight saved in rmt loc */
16882           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16883         }
16884       else if (unformat (input, "action %d", &action))
16885         {
16886           ;
16887         }
16888       else
16889         {
16890           clib_warning ("parse error '%U'", format_unformat_error, input);
16891           return -99;
16892         }
16893     }
16894
16895   if (!rmt_eid_set)
16896     {
16897       errmsg ("remote eid addresses not set");
16898       return -99;
16899     }
16900
16901   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16902     {
16903       errmsg ("eid types don't match");
16904       return -99;
16905     }
16906
16907   if (0 == rmt_locs && (u32) ~ 0 == action)
16908     {
16909       errmsg ("action not set for negative mapping");
16910       return -99;
16911     }
16912
16913   /* Construct the API message */
16914   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16915       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16916
16917   mp->is_add = is_add;
16918   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16919   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16920   mp->eid_type = rmt_eid->type;
16921   mp->dp_table = clib_host_to_net_u32 (dp_table);
16922   mp->vni = clib_host_to_net_u32 (vni);
16923   mp->rmt_len = rmt_eid->len;
16924   mp->lcl_len = lcl_eid->len;
16925   mp->action = action;
16926
16927   if (0 != rmt_locs && 0 != lcl_locs)
16928     {
16929       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16930       clib_memcpy (mp->locs, lcl_locs,
16931                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16932
16933       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16934       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16935                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16936     }
16937   vec_free (lcl_locs);
16938   vec_free (rmt_locs);
16939
16940   /* send it... */
16941   S (mp);
16942
16943   /* Wait for a reply... */
16944   W (ret);
16945   return ret;
16946 }
16947
16948 static int
16949 api_one_add_del_map_server (vat_main_t * vam)
16950 {
16951   unformat_input_t *input = vam->input;
16952   vl_api_one_add_del_map_server_t *mp;
16953   u8 is_add = 1;
16954   u8 ipv4_set = 0;
16955   u8 ipv6_set = 0;
16956   ip4_address_t ipv4;
16957   ip6_address_t ipv6;
16958   int ret;
16959
16960   /* Parse args required to build the message */
16961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16962     {
16963       if (unformat (input, "del"))
16964         {
16965           is_add = 0;
16966         }
16967       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16968         {
16969           ipv4_set = 1;
16970         }
16971       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16972         {
16973           ipv6_set = 1;
16974         }
16975       else
16976         break;
16977     }
16978
16979   if (ipv4_set && ipv6_set)
16980     {
16981       errmsg ("both eid v4 and v6 addresses set");
16982       return -99;
16983     }
16984
16985   if (!ipv4_set && !ipv6_set)
16986     {
16987       errmsg ("eid addresses not set");
16988       return -99;
16989     }
16990
16991   /* Construct the API message */
16992   M (ONE_ADD_DEL_MAP_SERVER, mp);
16993
16994   mp->is_add = is_add;
16995   if (ipv6_set)
16996     {
16997       mp->is_ipv6 = 1;
16998       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16999     }
17000   else
17001     {
17002       mp->is_ipv6 = 0;
17003       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17004     }
17005
17006   /* send it... */
17007   S (mp);
17008
17009   /* Wait for a reply... */
17010   W (ret);
17011   return ret;
17012 }
17013
17014 #define api_lisp_add_del_map_server api_one_add_del_map_server
17015
17016 static int
17017 api_one_add_del_map_resolver (vat_main_t * vam)
17018 {
17019   unformat_input_t *input = vam->input;
17020   vl_api_one_add_del_map_resolver_t *mp;
17021   u8 is_add = 1;
17022   u8 ipv4_set = 0;
17023   u8 ipv6_set = 0;
17024   ip4_address_t ipv4;
17025   ip6_address_t ipv6;
17026   int ret;
17027
17028   /* Parse args required to build the message */
17029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17030     {
17031       if (unformat (input, "del"))
17032         {
17033           is_add = 0;
17034         }
17035       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17036         {
17037           ipv4_set = 1;
17038         }
17039       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17040         {
17041           ipv6_set = 1;
17042         }
17043       else
17044         break;
17045     }
17046
17047   if (ipv4_set && ipv6_set)
17048     {
17049       errmsg ("both eid v4 and v6 addresses set");
17050       return -99;
17051     }
17052
17053   if (!ipv4_set && !ipv6_set)
17054     {
17055       errmsg ("eid addresses not set");
17056       return -99;
17057     }
17058
17059   /* Construct the API message */
17060   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17061
17062   mp->is_add = is_add;
17063   if (ipv6_set)
17064     {
17065       mp->is_ipv6 = 1;
17066       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17067     }
17068   else
17069     {
17070       mp->is_ipv6 = 0;
17071       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17072     }
17073
17074   /* send it... */
17075   S (mp);
17076
17077   /* Wait for a reply... */
17078   W (ret);
17079   return ret;
17080 }
17081
17082 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17083
17084 static int
17085 api_lisp_gpe_enable_disable (vat_main_t * vam)
17086 {
17087   unformat_input_t *input = vam->input;
17088   vl_api_gpe_enable_disable_t *mp;
17089   u8 is_set = 0;
17090   u8 is_en = 1;
17091   int ret;
17092
17093   /* Parse args required to build the message */
17094   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17095     {
17096       if (unformat (input, "enable"))
17097         {
17098           is_set = 1;
17099           is_en = 1;
17100         }
17101       else if (unformat (input, "disable"))
17102         {
17103           is_set = 1;
17104           is_en = 0;
17105         }
17106       else
17107         break;
17108     }
17109
17110   if (is_set == 0)
17111     {
17112       errmsg ("Value not set");
17113       return -99;
17114     }
17115
17116   /* Construct the API message */
17117   M (GPE_ENABLE_DISABLE, mp);
17118
17119   mp->is_en = is_en;
17120
17121   /* send it... */
17122   S (mp);
17123
17124   /* Wait for a reply... */
17125   W (ret);
17126   return ret;
17127 }
17128
17129 static int
17130 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17131 {
17132   unformat_input_t *input = vam->input;
17133   vl_api_one_rloc_probe_enable_disable_t *mp;
17134   u8 is_set = 0;
17135   u8 is_en = 0;
17136   int ret;
17137
17138   /* Parse args required to build the message */
17139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17140     {
17141       if (unformat (input, "enable"))
17142         {
17143           is_set = 1;
17144           is_en = 1;
17145         }
17146       else if (unformat (input, "disable"))
17147         is_set = 1;
17148       else
17149         break;
17150     }
17151
17152   if (!is_set)
17153     {
17154       errmsg ("Value not set");
17155       return -99;
17156     }
17157
17158   /* Construct the API message */
17159   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17160
17161   mp->is_enabled = is_en;
17162
17163   /* send it... */
17164   S (mp);
17165
17166   /* Wait for a reply... */
17167   W (ret);
17168   return ret;
17169 }
17170
17171 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17172
17173 static int
17174 api_one_map_register_enable_disable (vat_main_t * vam)
17175 {
17176   unformat_input_t *input = vam->input;
17177   vl_api_one_map_register_enable_disable_t *mp;
17178   u8 is_set = 0;
17179   u8 is_en = 0;
17180   int ret;
17181
17182   /* Parse args required to build the message */
17183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17184     {
17185       if (unformat (input, "enable"))
17186         {
17187           is_set = 1;
17188           is_en = 1;
17189         }
17190       else if (unformat (input, "disable"))
17191         is_set = 1;
17192       else
17193         break;
17194     }
17195
17196   if (!is_set)
17197     {
17198       errmsg ("Value not set");
17199       return -99;
17200     }
17201
17202   /* Construct the API message */
17203   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17204
17205   mp->is_enabled = is_en;
17206
17207   /* send it... */
17208   S (mp);
17209
17210   /* Wait for a reply... */
17211   W (ret);
17212   return ret;
17213 }
17214
17215 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17216
17217 static int
17218 api_one_enable_disable (vat_main_t * vam)
17219 {
17220   unformat_input_t *input = vam->input;
17221   vl_api_one_enable_disable_t *mp;
17222   u8 is_set = 0;
17223   u8 is_en = 0;
17224   int ret;
17225
17226   /* Parse args required to build the message */
17227   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17228     {
17229       if (unformat (input, "enable"))
17230         {
17231           is_set = 1;
17232           is_en = 1;
17233         }
17234       else if (unformat (input, "disable"))
17235         {
17236           is_set = 1;
17237         }
17238       else
17239         break;
17240     }
17241
17242   if (!is_set)
17243     {
17244       errmsg ("Value not set");
17245       return -99;
17246     }
17247
17248   /* Construct the API message */
17249   M (ONE_ENABLE_DISABLE, mp);
17250
17251   mp->is_en = is_en;
17252
17253   /* send it... */
17254   S (mp);
17255
17256   /* Wait for a reply... */
17257   W (ret);
17258   return ret;
17259 }
17260
17261 #define api_lisp_enable_disable api_one_enable_disable
17262
17263 static int
17264 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17265 {
17266   unformat_input_t *input = vam->input;
17267   vl_api_one_enable_disable_xtr_mode_t *mp;
17268   u8 is_set = 0;
17269   u8 is_en = 0;
17270   int ret;
17271
17272   /* Parse args required to build the message */
17273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17274     {
17275       if (unformat (input, "enable"))
17276         {
17277           is_set = 1;
17278           is_en = 1;
17279         }
17280       else if (unformat (input, "disable"))
17281         {
17282           is_set = 1;
17283         }
17284       else
17285         break;
17286     }
17287
17288   if (!is_set)
17289     {
17290       errmsg ("Value not set");
17291       return -99;
17292     }
17293
17294   /* Construct the API message */
17295   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17296
17297   mp->is_en = is_en;
17298
17299   /* send it... */
17300   S (mp);
17301
17302   /* Wait for a reply... */
17303   W (ret);
17304   return ret;
17305 }
17306
17307 static int
17308 api_one_show_xtr_mode (vat_main_t * vam)
17309 {
17310   vl_api_one_show_xtr_mode_t *mp;
17311   int ret;
17312
17313   /* Construct the API message */
17314   M (ONE_SHOW_XTR_MODE, mp);
17315
17316   /* send it... */
17317   S (mp);
17318
17319   /* Wait for a reply... */
17320   W (ret);
17321   return ret;
17322 }
17323
17324 static int
17325 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17326 {
17327   unformat_input_t *input = vam->input;
17328   vl_api_one_enable_disable_pitr_mode_t *mp;
17329   u8 is_set = 0;
17330   u8 is_en = 0;
17331   int ret;
17332
17333   /* Parse args required to build the message */
17334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17335     {
17336       if (unformat (input, "enable"))
17337         {
17338           is_set = 1;
17339           is_en = 1;
17340         }
17341       else if (unformat (input, "disable"))
17342         {
17343           is_set = 1;
17344         }
17345       else
17346         break;
17347     }
17348
17349   if (!is_set)
17350     {
17351       errmsg ("Value not set");
17352       return -99;
17353     }
17354
17355   /* Construct the API message */
17356   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17357
17358   mp->is_en = is_en;
17359
17360   /* send it... */
17361   S (mp);
17362
17363   /* Wait for a reply... */
17364   W (ret);
17365   return ret;
17366 }
17367
17368 static int
17369 api_one_show_pitr_mode (vat_main_t * vam)
17370 {
17371   vl_api_one_show_pitr_mode_t *mp;
17372   int ret;
17373
17374   /* Construct the API message */
17375   M (ONE_SHOW_PITR_MODE, mp);
17376
17377   /* send it... */
17378   S (mp);
17379
17380   /* Wait for a reply... */
17381   W (ret);
17382   return ret;
17383 }
17384
17385 static int
17386 api_one_enable_disable_petr_mode (vat_main_t * vam)
17387 {
17388   unformat_input_t *input = vam->input;
17389   vl_api_one_enable_disable_petr_mode_t *mp;
17390   u8 is_set = 0;
17391   u8 is_en = 0;
17392   int ret;
17393
17394   /* Parse args required to build the message */
17395   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17396     {
17397       if (unformat (input, "enable"))
17398         {
17399           is_set = 1;
17400           is_en = 1;
17401         }
17402       else if (unformat (input, "disable"))
17403         {
17404           is_set = 1;
17405         }
17406       else
17407         break;
17408     }
17409
17410   if (!is_set)
17411     {
17412       errmsg ("Value not set");
17413       return -99;
17414     }
17415
17416   /* Construct the API message */
17417   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17418
17419   mp->is_en = is_en;
17420
17421   /* send it... */
17422   S (mp);
17423
17424   /* Wait for a reply... */
17425   W (ret);
17426   return ret;
17427 }
17428
17429 static int
17430 api_one_show_petr_mode (vat_main_t * vam)
17431 {
17432   vl_api_one_show_petr_mode_t *mp;
17433   int ret;
17434
17435   /* Construct the API message */
17436   M (ONE_SHOW_PETR_MODE, mp);
17437
17438   /* send it... */
17439   S (mp);
17440
17441   /* Wait for a reply... */
17442   W (ret);
17443   return ret;
17444 }
17445
17446 static int
17447 api_show_one_map_register_state (vat_main_t * vam)
17448 {
17449   vl_api_show_one_map_register_state_t *mp;
17450   int ret;
17451
17452   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17453
17454   /* send */
17455   S (mp);
17456
17457   /* wait for reply */
17458   W (ret);
17459   return ret;
17460 }
17461
17462 #define api_show_lisp_map_register_state api_show_one_map_register_state
17463
17464 static int
17465 api_show_one_rloc_probe_state (vat_main_t * vam)
17466 {
17467   vl_api_show_one_rloc_probe_state_t *mp;
17468   int ret;
17469
17470   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17471
17472   /* send */
17473   S (mp);
17474
17475   /* wait for reply */
17476   W (ret);
17477   return ret;
17478 }
17479
17480 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17481
17482 static int
17483 api_one_add_del_ndp_entry (vat_main_t * vam)
17484 {
17485   vl_api_one_add_del_ndp_entry_t *mp;
17486   unformat_input_t *input = vam->input;
17487   u8 is_add = 1;
17488   u8 mac_set = 0;
17489   u8 bd_set = 0;
17490   u8 ip_set = 0;
17491   u8 mac[6] = { 0, };
17492   u8 ip6[16] = { 0, };
17493   u32 bd = ~0;
17494   int ret;
17495
17496   /* Parse args required to build the message */
17497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17498     {
17499       if (unformat (input, "del"))
17500         is_add = 0;
17501       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17502         mac_set = 1;
17503       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17504         ip_set = 1;
17505       else if (unformat (input, "bd %d", &bd))
17506         bd_set = 1;
17507       else
17508         {
17509           errmsg ("parse error '%U'", format_unformat_error, input);
17510           return -99;
17511         }
17512     }
17513
17514   if (!bd_set || !ip_set || (!mac_set && is_add))
17515     {
17516       errmsg ("Missing BD, IP or MAC!");
17517       return -99;
17518     }
17519
17520   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17521   mp->is_add = is_add;
17522   clib_memcpy (mp->mac, mac, 6);
17523   mp->bd = clib_host_to_net_u32 (bd);
17524   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17525
17526   /* send */
17527   S (mp);
17528
17529   /* wait for reply */
17530   W (ret);
17531   return ret;
17532 }
17533
17534 static int
17535 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17536 {
17537   vl_api_one_add_del_l2_arp_entry_t *mp;
17538   unformat_input_t *input = vam->input;
17539   u8 is_add = 1;
17540   u8 mac_set = 0;
17541   u8 bd_set = 0;
17542   u8 ip_set = 0;
17543   u8 mac[6] = { 0, };
17544   u32 ip4 = 0, bd = ~0;
17545   int ret;
17546
17547   /* Parse args required to build the message */
17548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17549     {
17550       if (unformat (input, "del"))
17551         is_add = 0;
17552       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17553         mac_set = 1;
17554       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17555         ip_set = 1;
17556       else if (unformat (input, "bd %d", &bd))
17557         bd_set = 1;
17558       else
17559         {
17560           errmsg ("parse error '%U'", format_unformat_error, input);
17561           return -99;
17562         }
17563     }
17564
17565   if (!bd_set || !ip_set || (!mac_set && is_add))
17566     {
17567       errmsg ("Missing BD, IP or MAC!");
17568       return -99;
17569     }
17570
17571   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17572   mp->is_add = is_add;
17573   clib_memcpy (mp->mac, mac, 6);
17574   mp->bd = clib_host_to_net_u32 (bd);
17575   mp->ip4 = ip4;
17576
17577   /* send */
17578   S (mp);
17579
17580   /* wait for reply */
17581   W (ret);
17582   return ret;
17583 }
17584
17585 static int
17586 api_one_ndp_bd_get (vat_main_t * vam)
17587 {
17588   vl_api_one_ndp_bd_get_t *mp;
17589   int ret;
17590
17591   M (ONE_NDP_BD_GET, mp);
17592
17593   /* send */
17594   S (mp);
17595
17596   /* wait for reply */
17597   W (ret);
17598   return ret;
17599 }
17600
17601 static int
17602 api_one_ndp_entries_get (vat_main_t * vam)
17603 {
17604   vl_api_one_ndp_entries_get_t *mp;
17605   unformat_input_t *input = vam->input;
17606   u8 bd_set = 0;
17607   u32 bd = ~0;
17608   int ret;
17609
17610   /* Parse args required to build the message */
17611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17612     {
17613       if (unformat (input, "bd %d", &bd))
17614         bd_set = 1;
17615       else
17616         {
17617           errmsg ("parse error '%U'", format_unformat_error, input);
17618           return -99;
17619         }
17620     }
17621
17622   if (!bd_set)
17623     {
17624       errmsg ("Expected bridge domain!");
17625       return -99;
17626     }
17627
17628   M (ONE_NDP_ENTRIES_GET, mp);
17629   mp->bd = clib_host_to_net_u32 (bd);
17630
17631   /* send */
17632   S (mp);
17633
17634   /* wait for reply */
17635   W (ret);
17636   return ret;
17637 }
17638
17639 static int
17640 api_one_l2_arp_bd_get (vat_main_t * vam)
17641 {
17642   vl_api_one_l2_arp_bd_get_t *mp;
17643   int ret;
17644
17645   M (ONE_L2_ARP_BD_GET, mp);
17646
17647   /* send */
17648   S (mp);
17649
17650   /* wait for reply */
17651   W (ret);
17652   return ret;
17653 }
17654
17655 static int
17656 api_one_l2_arp_entries_get (vat_main_t * vam)
17657 {
17658   vl_api_one_l2_arp_entries_get_t *mp;
17659   unformat_input_t *input = vam->input;
17660   u8 bd_set = 0;
17661   u32 bd = ~0;
17662   int ret;
17663
17664   /* Parse args required to build the message */
17665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17666     {
17667       if (unformat (input, "bd %d", &bd))
17668         bd_set = 1;
17669       else
17670         {
17671           errmsg ("parse error '%U'", format_unformat_error, input);
17672           return -99;
17673         }
17674     }
17675
17676   if (!bd_set)
17677     {
17678       errmsg ("Expected bridge domain!");
17679       return -99;
17680     }
17681
17682   M (ONE_L2_ARP_ENTRIES_GET, mp);
17683   mp->bd = clib_host_to_net_u32 (bd);
17684
17685   /* send */
17686   S (mp);
17687
17688   /* wait for reply */
17689   W (ret);
17690   return ret;
17691 }
17692
17693 static int
17694 api_one_stats_enable_disable (vat_main_t * vam)
17695 {
17696   vl_api_one_stats_enable_disable_t *mp;
17697   unformat_input_t *input = vam->input;
17698   u8 is_set = 0;
17699   u8 is_en = 0;
17700   int ret;
17701
17702   /* Parse args required to build the message */
17703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17704     {
17705       if (unformat (input, "enable"))
17706         {
17707           is_set = 1;
17708           is_en = 1;
17709         }
17710       else if (unformat (input, "disable"))
17711         {
17712           is_set = 1;
17713         }
17714       else
17715         break;
17716     }
17717
17718   if (!is_set)
17719     {
17720       errmsg ("Value not set");
17721       return -99;
17722     }
17723
17724   M (ONE_STATS_ENABLE_DISABLE, mp);
17725   mp->is_en = is_en;
17726
17727   /* send */
17728   S (mp);
17729
17730   /* wait for reply */
17731   W (ret);
17732   return ret;
17733 }
17734
17735 static int
17736 api_show_one_stats_enable_disable (vat_main_t * vam)
17737 {
17738   vl_api_show_one_stats_enable_disable_t *mp;
17739   int ret;
17740
17741   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17742
17743   /* send */
17744   S (mp);
17745
17746   /* wait for reply */
17747   W (ret);
17748   return ret;
17749 }
17750
17751 static int
17752 api_show_one_map_request_mode (vat_main_t * vam)
17753 {
17754   vl_api_show_one_map_request_mode_t *mp;
17755   int ret;
17756
17757   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17758
17759   /* send */
17760   S (mp);
17761
17762   /* wait for reply */
17763   W (ret);
17764   return ret;
17765 }
17766
17767 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17768
17769 static int
17770 api_one_map_request_mode (vat_main_t * vam)
17771 {
17772   unformat_input_t *input = vam->input;
17773   vl_api_one_map_request_mode_t *mp;
17774   u8 mode = 0;
17775   int ret;
17776
17777   /* Parse args required to build the message */
17778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17779     {
17780       if (unformat (input, "dst-only"))
17781         mode = 0;
17782       else if (unformat (input, "src-dst"))
17783         mode = 1;
17784       else
17785         {
17786           errmsg ("parse error '%U'", format_unformat_error, input);
17787           return -99;
17788         }
17789     }
17790
17791   M (ONE_MAP_REQUEST_MODE, mp);
17792
17793   mp->mode = mode;
17794
17795   /* send */
17796   S (mp);
17797
17798   /* wait for reply */
17799   W (ret);
17800   return ret;
17801 }
17802
17803 #define api_lisp_map_request_mode api_one_map_request_mode
17804
17805 /**
17806  * Enable/disable ONE proxy ITR.
17807  *
17808  * @param vam vpp API test context
17809  * @return return code
17810  */
17811 static int
17812 api_one_pitr_set_locator_set (vat_main_t * vam)
17813 {
17814   u8 ls_name_set = 0;
17815   unformat_input_t *input = vam->input;
17816   vl_api_one_pitr_set_locator_set_t *mp;
17817   u8 is_add = 1;
17818   u8 *ls_name = 0;
17819   int ret;
17820
17821   /* Parse args required to build the message */
17822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17823     {
17824       if (unformat (input, "del"))
17825         is_add = 0;
17826       else if (unformat (input, "locator-set %s", &ls_name))
17827         ls_name_set = 1;
17828       else
17829         {
17830           errmsg ("parse error '%U'", format_unformat_error, input);
17831           return -99;
17832         }
17833     }
17834
17835   if (!ls_name_set)
17836     {
17837       errmsg ("locator-set name not set!");
17838       return -99;
17839     }
17840
17841   M (ONE_PITR_SET_LOCATOR_SET, mp);
17842
17843   mp->is_add = is_add;
17844   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17845   vec_free (ls_name);
17846
17847   /* send */
17848   S (mp);
17849
17850   /* wait for reply */
17851   W (ret);
17852   return ret;
17853 }
17854
17855 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17856
17857 static int
17858 api_one_nsh_set_locator_set (vat_main_t * vam)
17859 {
17860   u8 ls_name_set = 0;
17861   unformat_input_t *input = vam->input;
17862   vl_api_one_nsh_set_locator_set_t *mp;
17863   u8 is_add = 1;
17864   u8 *ls_name = 0;
17865   int ret;
17866
17867   /* Parse args required to build the message */
17868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17869     {
17870       if (unformat (input, "del"))
17871         is_add = 0;
17872       else if (unformat (input, "ls %s", &ls_name))
17873         ls_name_set = 1;
17874       else
17875         {
17876           errmsg ("parse error '%U'", format_unformat_error, input);
17877           return -99;
17878         }
17879     }
17880
17881   if (!ls_name_set && is_add)
17882     {
17883       errmsg ("locator-set name not set!");
17884       return -99;
17885     }
17886
17887   M (ONE_NSH_SET_LOCATOR_SET, mp);
17888
17889   mp->is_add = is_add;
17890   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17891   vec_free (ls_name);
17892
17893   /* send */
17894   S (mp);
17895
17896   /* wait for reply */
17897   W (ret);
17898   return ret;
17899 }
17900
17901 static int
17902 api_show_one_pitr (vat_main_t * vam)
17903 {
17904   vl_api_show_one_pitr_t *mp;
17905   int ret;
17906
17907   if (!vam->json_output)
17908     {
17909       print (vam->ofp, "%=20s", "lisp status:");
17910     }
17911
17912   M (SHOW_ONE_PITR, mp);
17913   /* send it... */
17914   S (mp);
17915
17916   /* Wait for a reply... */
17917   W (ret);
17918   return ret;
17919 }
17920
17921 #define api_show_lisp_pitr api_show_one_pitr
17922
17923 static int
17924 api_one_use_petr (vat_main_t * vam)
17925 {
17926   unformat_input_t *input = vam->input;
17927   vl_api_one_use_petr_t *mp;
17928   u8 is_add = 0;
17929   ip_address_t ip;
17930   int ret;
17931
17932   memset (&ip, 0, sizeof (ip));
17933
17934   /* Parse args required to build the message */
17935   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17936     {
17937       if (unformat (input, "disable"))
17938         is_add = 0;
17939       else
17940         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17941         {
17942           is_add = 1;
17943           ip_addr_version (&ip) = IP4;
17944         }
17945       else
17946         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17947         {
17948           is_add = 1;
17949           ip_addr_version (&ip) = IP6;
17950         }
17951       else
17952         {
17953           errmsg ("parse error '%U'", format_unformat_error, input);
17954           return -99;
17955         }
17956     }
17957
17958   M (ONE_USE_PETR, mp);
17959
17960   mp->is_add = is_add;
17961   if (is_add)
17962     {
17963       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17964       if (mp->is_ip4)
17965         clib_memcpy (mp->address, &ip, 4);
17966       else
17967         clib_memcpy (mp->address, &ip, 16);
17968     }
17969
17970   /* send */
17971   S (mp);
17972
17973   /* wait for reply */
17974   W (ret);
17975   return ret;
17976 }
17977
17978 #define api_lisp_use_petr api_one_use_petr
17979
17980 static int
17981 api_show_one_nsh_mapping (vat_main_t * vam)
17982 {
17983   vl_api_show_one_use_petr_t *mp;
17984   int ret;
17985
17986   if (!vam->json_output)
17987     {
17988       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17989     }
17990
17991   M (SHOW_ONE_NSH_MAPPING, mp);
17992   /* send it... */
17993   S (mp);
17994
17995   /* Wait for a reply... */
17996   W (ret);
17997   return ret;
17998 }
17999
18000 static int
18001 api_show_one_use_petr (vat_main_t * vam)
18002 {
18003   vl_api_show_one_use_petr_t *mp;
18004   int ret;
18005
18006   if (!vam->json_output)
18007     {
18008       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18009     }
18010
18011   M (SHOW_ONE_USE_PETR, mp);
18012   /* send it... */
18013   S (mp);
18014
18015   /* Wait for a reply... */
18016   W (ret);
18017   return ret;
18018 }
18019
18020 #define api_show_lisp_use_petr api_show_one_use_petr
18021
18022 /**
18023  * Add/delete mapping between vni and vrf
18024  */
18025 static int
18026 api_one_eid_table_add_del_map (vat_main_t * vam)
18027 {
18028   unformat_input_t *input = vam->input;
18029   vl_api_one_eid_table_add_del_map_t *mp;
18030   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18031   u32 vni, vrf, bd_index;
18032   int ret;
18033
18034   /* Parse args required to build the message */
18035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18036     {
18037       if (unformat (input, "del"))
18038         is_add = 0;
18039       else if (unformat (input, "vrf %d", &vrf))
18040         vrf_set = 1;
18041       else if (unformat (input, "bd_index %d", &bd_index))
18042         bd_index_set = 1;
18043       else if (unformat (input, "vni %d", &vni))
18044         vni_set = 1;
18045       else
18046         break;
18047     }
18048
18049   if (!vni_set || (!vrf_set && !bd_index_set))
18050     {
18051       errmsg ("missing arguments!");
18052       return -99;
18053     }
18054
18055   if (vrf_set && bd_index_set)
18056     {
18057       errmsg ("error: both vrf and bd entered!");
18058       return -99;
18059     }
18060
18061   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18062
18063   mp->is_add = is_add;
18064   mp->vni = htonl (vni);
18065   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18066   mp->is_l2 = bd_index_set;
18067
18068   /* send */
18069   S (mp);
18070
18071   /* wait for reply */
18072   W (ret);
18073   return ret;
18074 }
18075
18076 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18077
18078 uword
18079 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18080 {
18081   u32 *action = va_arg (*args, u32 *);
18082   u8 *s = 0;
18083
18084   if (unformat (input, "%s", &s))
18085     {
18086       if (!strcmp ((char *) s, "no-action"))
18087         action[0] = 0;
18088       else if (!strcmp ((char *) s, "natively-forward"))
18089         action[0] = 1;
18090       else if (!strcmp ((char *) s, "send-map-request"))
18091         action[0] = 2;
18092       else if (!strcmp ((char *) s, "drop"))
18093         action[0] = 3;
18094       else
18095         {
18096           clib_warning ("invalid action: '%s'", s);
18097           action[0] = 3;
18098         }
18099     }
18100   else
18101     return 0;
18102
18103   vec_free (s);
18104   return 1;
18105 }
18106
18107 /**
18108  * Add/del remote mapping to/from ONE control plane
18109  *
18110  * @param vam vpp API test context
18111  * @return return code
18112  */
18113 static int
18114 api_one_add_del_remote_mapping (vat_main_t * vam)
18115 {
18116   unformat_input_t *input = vam->input;
18117   vl_api_one_add_del_remote_mapping_t *mp;
18118   u32 vni = 0;
18119   lisp_eid_vat_t _eid, *eid = &_eid;
18120   lisp_eid_vat_t _seid, *seid = &_seid;
18121   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18122   u32 action = ~0, p, w, data_len;
18123   ip4_address_t rloc4;
18124   ip6_address_t rloc6;
18125   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18126   int ret;
18127
18128   memset (&rloc, 0, sizeof (rloc));
18129
18130   /* Parse args required to build the message */
18131   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18132     {
18133       if (unformat (input, "del-all"))
18134         {
18135           del_all = 1;
18136         }
18137       else if (unformat (input, "del"))
18138         {
18139           is_add = 0;
18140         }
18141       else if (unformat (input, "add"))
18142         {
18143           is_add = 1;
18144         }
18145       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18146         {
18147           eid_set = 1;
18148         }
18149       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18150         {
18151           seid_set = 1;
18152         }
18153       else if (unformat (input, "vni %d", &vni))
18154         {
18155           ;
18156         }
18157       else if (unformat (input, "p %d w %d", &p, &w))
18158         {
18159           if (!curr_rloc)
18160             {
18161               errmsg ("No RLOC configured for setting priority/weight!");
18162               return -99;
18163             }
18164           curr_rloc->priority = p;
18165           curr_rloc->weight = w;
18166         }
18167       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18168         {
18169           rloc.is_ip4 = 1;
18170           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18171           vec_add1 (rlocs, rloc);
18172           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18173         }
18174       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18175         {
18176           rloc.is_ip4 = 0;
18177           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18178           vec_add1 (rlocs, rloc);
18179           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18180         }
18181       else if (unformat (input, "action %U",
18182                          unformat_negative_mapping_action, &action))
18183         {
18184           ;
18185         }
18186       else
18187         {
18188           clib_warning ("parse error '%U'", format_unformat_error, input);
18189           return -99;
18190         }
18191     }
18192
18193   if (0 == eid_set)
18194     {
18195       errmsg ("missing params!");
18196       return -99;
18197     }
18198
18199   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18200     {
18201       errmsg ("no action set for negative map-reply!");
18202       return -99;
18203     }
18204
18205   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18206
18207   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18208   mp->is_add = is_add;
18209   mp->vni = htonl (vni);
18210   mp->action = (u8) action;
18211   mp->is_src_dst = seid_set;
18212   mp->eid_len = eid->len;
18213   mp->seid_len = seid->len;
18214   mp->del_all = del_all;
18215   mp->eid_type = eid->type;
18216   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18217   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18218
18219   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18220   clib_memcpy (mp->rlocs, rlocs, data_len);
18221   vec_free (rlocs);
18222
18223   /* send it... */
18224   S (mp);
18225
18226   /* Wait for a reply... */
18227   W (ret);
18228   return ret;
18229 }
18230
18231 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18232
18233 /**
18234  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18235  * forwarding entries in data-plane accordingly.
18236  *
18237  * @param vam vpp API test context
18238  * @return return code
18239  */
18240 static int
18241 api_one_add_del_adjacency (vat_main_t * vam)
18242 {
18243   unformat_input_t *input = vam->input;
18244   vl_api_one_add_del_adjacency_t *mp;
18245   u32 vni = 0;
18246   ip4_address_t leid4, reid4;
18247   ip6_address_t leid6, reid6;
18248   u8 reid_mac[6] = { 0 };
18249   u8 leid_mac[6] = { 0 };
18250   u8 reid_type, leid_type;
18251   u32 leid_len = 0, reid_len = 0, len;
18252   u8 is_add = 1;
18253   int ret;
18254
18255   leid_type = reid_type = (u8) ~ 0;
18256
18257   /* Parse args required to build the message */
18258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18259     {
18260       if (unformat (input, "del"))
18261         {
18262           is_add = 0;
18263         }
18264       else if (unformat (input, "add"))
18265         {
18266           is_add = 1;
18267         }
18268       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18269                          &reid4, &len))
18270         {
18271           reid_type = 0;        /* ipv4 */
18272           reid_len = len;
18273         }
18274       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18275                          &reid6, &len))
18276         {
18277           reid_type = 1;        /* ipv6 */
18278           reid_len = len;
18279         }
18280       else if (unformat (input, "reid %U", unformat_ethernet_address,
18281                          reid_mac))
18282         {
18283           reid_type = 2;        /* mac */
18284         }
18285       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18286                          &leid4, &len))
18287         {
18288           leid_type = 0;        /* ipv4 */
18289           leid_len = len;
18290         }
18291       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18292                          &leid6, &len))
18293         {
18294           leid_type = 1;        /* ipv6 */
18295           leid_len = len;
18296         }
18297       else if (unformat (input, "leid %U", unformat_ethernet_address,
18298                          leid_mac))
18299         {
18300           leid_type = 2;        /* mac */
18301         }
18302       else if (unformat (input, "vni %d", &vni))
18303         {
18304           ;
18305         }
18306       else
18307         {
18308           errmsg ("parse error '%U'", format_unformat_error, input);
18309           return -99;
18310         }
18311     }
18312
18313   if ((u8) ~ 0 == reid_type)
18314     {
18315       errmsg ("missing params!");
18316       return -99;
18317     }
18318
18319   if (leid_type != reid_type)
18320     {
18321       errmsg ("remote and local EIDs are of different types!");
18322       return -99;
18323     }
18324
18325   M (ONE_ADD_DEL_ADJACENCY, mp);
18326   mp->is_add = is_add;
18327   mp->vni = htonl (vni);
18328   mp->leid_len = leid_len;
18329   mp->reid_len = reid_len;
18330   mp->eid_type = reid_type;
18331
18332   switch (mp->eid_type)
18333     {
18334     case 0:
18335       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18336       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18337       break;
18338     case 1:
18339       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18340       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18341       break;
18342     case 2:
18343       clib_memcpy (mp->leid, leid_mac, 6);
18344       clib_memcpy (mp->reid, reid_mac, 6);
18345       break;
18346     default:
18347       errmsg ("unknown EID type %d!", mp->eid_type);
18348       return 0;
18349     }
18350
18351   /* send it... */
18352   S (mp);
18353
18354   /* Wait for a reply... */
18355   W (ret);
18356   return ret;
18357 }
18358
18359 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18360
18361 uword
18362 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18363 {
18364   u32 *mode = va_arg (*args, u32 *);
18365
18366   if (unformat (input, "lisp"))
18367     *mode = 0;
18368   else if (unformat (input, "vxlan"))
18369     *mode = 1;
18370   else
18371     return 0;
18372
18373   return 1;
18374 }
18375
18376 static int
18377 api_gpe_get_encap_mode (vat_main_t * vam)
18378 {
18379   vl_api_gpe_get_encap_mode_t *mp;
18380   int ret;
18381
18382   /* Construct the API message */
18383   M (GPE_GET_ENCAP_MODE, mp);
18384
18385   /* send it... */
18386   S (mp);
18387
18388   /* Wait for a reply... */
18389   W (ret);
18390   return ret;
18391 }
18392
18393 static int
18394 api_gpe_set_encap_mode (vat_main_t * vam)
18395 {
18396   unformat_input_t *input = vam->input;
18397   vl_api_gpe_set_encap_mode_t *mp;
18398   int ret;
18399   u32 mode = 0;
18400
18401   /* Parse args required to build the message */
18402   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18403     {
18404       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18405         ;
18406       else
18407         break;
18408     }
18409
18410   /* Construct the API message */
18411   M (GPE_SET_ENCAP_MODE, mp);
18412
18413   mp->mode = mode;
18414
18415   /* send it... */
18416   S (mp);
18417
18418   /* Wait for a reply... */
18419   W (ret);
18420   return ret;
18421 }
18422
18423 static int
18424 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18425 {
18426   unformat_input_t *input = vam->input;
18427   vl_api_gpe_add_del_iface_t *mp;
18428   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18429   u32 dp_table = 0, vni = 0;
18430   int ret;
18431
18432   /* Parse args required to build the message */
18433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18434     {
18435       if (unformat (input, "up"))
18436         {
18437           action_set = 1;
18438           is_add = 1;
18439         }
18440       else if (unformat (input, "down"))
18441         {
18442           action_set = 1;
18443           is_add = 0;
18444         }
18445       else if (unformat (input, "table_id %d", &dp_table))
18446         {
18447           dp_table_set = 1;
18448         }
18449       else if (unformat (input, "bd_id %d", &dp_table))
18450         {
18451           dp_table_set = 1;
18452           is_l2 = 1;
18453         }
18454       else if (unformat (input, "vni %d", &vni))
18455         {
18456           vni_set = 1;
18457         }
18458       else
18459         break;
18460     }
18461
18462   if (action_set == 0)
18463     {
18464       errmsg ("Action not set");
18465       return -99;
18466     }
18467   if (dp_table_set == 0 || vni_set == 0)
18468     {
18469       errmsg ("vni and dp_table must be set");
18470       return -99;
18471     }
18472
18473   /* Construct the API message */
18474   M (GPE_ADD_DEL_IFACE, mp);
18475
18476   mp->is_add = is_add;
18477   mp->dp_table = clib_host_to_net_u32 (dp_table);
18478   mp->is_l2 = is_l2;
18479   mp->vni = clib_host_to_net_u32 (vni);
18480
18481   /* send it... */
18482   S (mp);
18483
18484   /* Wait for a reply... */
18485   W (ret);
18486   return ret;
18487 }
18488
18489 static int
18490 api_one_map_register_fallback_threshold (vat_main_t * vam)
18491 {
18492   unformat_input_t *input = vam->input;
18493   vl_api_one_map_register_fallback_threshold_t *mp;
18494   u32 value = 0;
18495   u8 is_set = 0;
18496   int ret;
18497
18498   /* Parse args required to build the message */
18499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18500     {
18501       if (unformat (input, "%u", &value))
18502         is_set = 1;
18503       else
18504         {
18505           clib_warning ("parse error '%U'", format_unformat_error, input);
18506           return -99;
18507         }
18508     }
18509
18510   if (!is_set)
18511     {
18512       errmsg ("fallback threshold value is missing!");
18513       return -99;
18514     }
18515
18516   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18517   mp->value = clib_host_to_net_u32 (value);
18518
18519   /* send it... */
18520   S (mp);
18521
18522   /* Wait for a reply... */
18523   W (ret);
18524   return ret;
18525 }
18526
18527 static int
18528 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18529 {
18530   vl_api_show_one_map_register_fallback_threshold_t *mp;
18531   int ret;
18532
18533   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18534
18535   /* send it... */
18536   S (mp);
18537
18538   /* Wait for a reply... */
18539   W (ret);
18540   return ret;
18541 }
18542
18543 uword
18544 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18545 {
18546   u32 *proto = va_arg (*args, u32 *);
18547
18548   if (unformat (input, "udp"))
18549     *proto = 1;
18550   else if (unformat (input, "api"))
18551     *proto = 2;
18552   else
18553     return 0;
18554
18555   return 1;
18556 }
18557
18558 static int
18559 api_one_set_transport_protocol (vat_main_t * vam)
18560 {
18561   unformat_input_t *input = vam->input;
18562   vl_api_one_set_transport_protocol_t *mp;
18563   u8 is_set = 0;
18564   u32 protocol = 0;
18565   int ret;
18566
18567   /* Parse args required to build the message */
18568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18569     {
18570       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18571         is_set = 1;
18572       else
18573         {
18574           clib_warning ("parse error '%U'", format_unformat_error, input);
18575           return -99;
18576         }
18577     }
18578
18579   if (!is_set)
18580     {
18581       errmsg ("Transport protocol missing!");
18582       return -99;
18583     }
18584
18585   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18586   mp->protocol = (u8) protocol;
18587
18588   /* send it... */
18589   S (mp);
18590
18591   /* Wait for a reply... */
18592   W (ret);
18593   return ret;
18594 }
18595
18596 static int
18597 api_one_get_transport_protocol (vat_main_t * vam)
18598 {
18599   vl_api_one_get_transport_protocol_t *mp;
18600   int ret;
18601
18602   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18603
18604   /* send it... */
18605   S (mp);
18606
18607   /* Wait for a reply... */
18608   W (ret);
18609   return ret;
18610 }
18611
18612 static int
18613 api_one_map_register_set_ttl (vat_main_t * vam)
18614 {
18615   unformat_input_t *input = vam->input;
18616   vl_api_one_map_register_set_ttl_t *mp;
18617   u32 ttl = 0;
18618   u8 is_set = 0;
18619   int ret;
18620
18621   /* Parse args required to build the message */
18622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18623     {
18624       if (unformat (input, "%u", &ttl))
18625         is_set = 1;
18626       else
18627         {
18628           clib_warning ("parse error '%U'", format_unformat_error, input);
18629           return -99;
18630         }
18631     }
18632
18633   if (!is_set)
18634     {
18635       errmsg ("TTL value missing!");
18636       return -99;
18637     }
18638
18639   M (ONE_MAP_REGISTER_SET_TTL, mp);
18640   mp->ttl = clib_host_to_net_u32 (ttl);
18641
18642   /* send it... */
18643   S (mp);
18644
18645   /* Wait for a reply... */
18646   W (ret);
18647   return ret;
18648 }
18649
18650 static int
18651 api_show_one_map_register_ttl (vat_main_t * vam)
18652 {
18653   vl_api_show_one_map_register_ttl_t *mp;
18654   int ret;
18655
18656   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18657
18658   /* send it... */
18659   S (mp);
18660
18661   /* Wait for a reply... */
18662   W (ret);
18663   return ret;
18664 }
18665
18666 /**
18667  * Add/del map request itr rlocs from ONE control plane and updates
18668  *
18669  * @param vam vpp API test context
18670  * @return return code
18671  */
18672 static int
18673 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18674 {
18675   unformat_input_t *input = vam->input;
18676   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18677   u8 *locator_set_name = 0;
18678   u8 locator_set_name_set = 0;
18679   u8 is_add = 1;
18680   int ret;
18681
18682   /* Parse args required to build the message */
18683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18684     {
18685       if (unformat (input, "del"))
18686         {
18687           is_add = 0;
18688         }
18689       else if (unformat (input, "%_%v%_", &locator_set_name))
18690         {
18691           locator_set_name_set = 1;
18692         }
18693       else
18694         {
18695           clib_warning ("parse error '%U'", format_unformat_error, input);
18696           return -99;
18697         }
18698     }
18699
18700   if (is_add && !locator_set_name_set)
18701     {
18702       errmsg ("itr-rloc is not set!");
18703       return -99;
18704     }
18705
18706   if (is_add && vec_len (locator_set_name) > 64)
18707     {
18708       errmsg ("itr-rloc locator-set name too long");
18709       vec_free (locator_set_name);
18710       return -99;
18711     }
18712
18713   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18714   mp->is_add = is_add;
18715   if (is_add)
18716     {
18717       clib_memcpy (mp->locator_set_name, locator_set_name,
18718                    vec_len (locator_set_name));
18719     }
18720   else
18721     {
18722       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18723     }
18724   vec_free (locator_set_name);
18725
18726   /* send it... */
18727   S (mp);
18728
18729   /* Wait for a reply... */
18730   W (ret);
18731   return ret;
18732 }
18733
18734 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18735
18736 static int
18737 api_one_locator_dump (vat_main_t * vam)
18738 {
18739   unformat_input_t *input = vam->input;
18740   vl_api_one_locator_dump_t *mp;
18741   vl_api_control_ping_t *mp_ping;
18742   u8 is_index_set = 0, is_name_set = 0;
18743   u8 *ls_name = 0;
18744   u32 ls_index = ~0;
18745   int ret;
18746
18747   /* Parse args required to build the message */
18748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18749     {
18750       if (unformat (input, "ls_name %_%v%_", &ls_name))
18751         {
18752           is_name_set = 1;
18753         }
18754       else if (unformat (input, "ls_index %d", &ls_index))
18755         {
18756           is_index_set = 1;
18757         }
18758       else
18759         {
18760           errmsg ("parse error '%U'", format_unformat_error, input);
18761           return -99;
18762         }
18763     }
18764
18765   if (!is_index_set && !is_name_set)
18766     {
18767       errmsg ("error: expected one of index or name!");
18768       return -99;
18769     }
18770
18771   if (is_index_set && is_name_set)
18772     {
18773       errmsg ("error: only one param expected!");
18774       return -99;
18775     }
18776
18777   if (vec_len (ls_name) > 62)
18778     {
18779       errmsg ("error: locator set name too long!");
18780       return -99;
18781     }
18782
18783   if (!vam->json_output)
18784     {
18785       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18786     }
18787
18788   M (ONE_LOCATOR_DUMP, mp);
18789   mp->is_index_set = is_index_set;
18790
18791   if (is_index_set)
18792     mp->ls_index = clib_host_to_net_u32 (ls_index);
18793   else
18794     {
18795       vec_add1 (ls_name, 0);
18796       strncpy ((char *) mp->ls_name, (char *) ls_name,
18797                sizeof (mp->ls_name) - 1);
18798     }
18799
18800   /* send it... */
18801   S (mp);
18802
18803   /* Use a control ping for synchronization */
18804   MPING (CONTROL_PING, mp_ping);
18805   S (mp_ping);
18806
18807   /* Wait for a reply... */
18808   W (ret);
18809   return ret;
18810 }
18811
18812 #define api_lisp_locator_dump api_one_locator_dump
18813
18814 static int
18815 api_one_locator_set_dump (vat_main_t * vam)
18816 {
18817   vl_api_one_locator_set_dump_t *mp;
18818   vl_api_control_ping_t *mp_ping;
18819   unformat_input_t *input = vam->input;
18820   u8 filter = 0;
18821   int ret;
18822
18823   /* Parse args required to build the message */
18824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18825     {
18826       if (unformat (input, "local"))
18827         {
18828           filter = 1;
18829         }
18830       else if (unformat (input, "remote"))
18831         {
18832           filter = 2;
18833         }
18834       else
18835         {
18836           errmsg ("parse error '%U'", format_unformat_error, input);
18837           return -99;
18838         }
18839     }
18840
18841   if (!vam->json_output)
18842     {
18843       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18844     }
18845
18846   M (ONE_LOCATOR_SET_DUMP, mp);
18847
18848   mp->filter = filter;
18849
18850   /* send it... */
18851   S (mp);
18852
18853   /* Use a control ping for synchronization */
18854   MPING (CONTROL_PING, mp_ping);
18855   S (mp_ping);
18856
18857   /* Wait for a reply... */
18858   W (ret);
18859   return ret;
18860 }
18861
18862 #define api_lisp_locator_set_dump api_one_locator_set_dump
18863
18864 static int
18865 api_one_eid_table_map_dump (vat_main_t * vam)
18866 {
18867   u8 is_l2 = 0;
18868   u8 mode_set = 0;
18869   unformat_input_t *input = vam->input;
18870   vl_api_one_eid_table_map_dump_t *mp;
18871   vl_api_control_ping_t *mp_ping;
18872   int ret;
18873
18874   /* Parse args required to build the message */
18875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18876     {
18877       if (unformat (input, "l2"))
18878         {
18879           is_l2 = 1;
18880           mode_set = 1;
18881         }
18882       else if (unformat (input, "l3"))
18883         {
18884           is_l2 = 0;
18885           mode_set = 1;
18886         }
18887       else
18888         {
18889           errmsg ("parse error '%U'", format_unformat_error, input);
18890           return -99;
18891         }
18892     }
18893
18894   if (!mode_set)
18895     {
18896       errmsg ("expected one of 'l2' or 'l3' parameter!");
18897       return -99;
18898     }
18899
18900   if (!vam->json_output)
18901     {
18902       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18903     }
18904
18905   M (ONE_EID_TABLE_MAP_DUMP, mp);
18906   mp->is_l2 = is_l2;
18907
18908   /* send it... */
18909   S (mp);
18910
18911   /* Use a control ping for synchronization */
18912   MPING (CONTROL_PING, mp_ping);
18913   S (mp_ping);
18914
18915   /* Wait for a reply... */
18916   W (ret);
18917   return ret;
18918 }
18919
18920 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18921
18922 static int
18923 api_one_eid_table_vni_dump (vat_main_t * vam)
18924 {
18925   vl_api_one_eid_table_vni_dump_t *mp;
18926   vl_api_control_ping_t *mp_ping;
18927   int ret;
18928
18929   if (!vam->json_output)
18930     {
18931       print (vam->ofp, "VNI");
18932     }
18933
18934   M (ONE_EID_TABLE_VNI_DUMP, mp);
18935
18936   /* send it... */
18937   S (mp);
18938
18939   /* Use a control ping for synchronization */
18940   MPING (CONTROL_PING, mp_ping);
18941   S (mp_ping);
18942
18943   /* Wait for a reply... */
18944   W (ret);
18945   return ret;
18946 }
18947
18948 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18949
18950 static int
18951 api_one_eid_table_dump (vat_main_t * vam)
18952 {
18953   unformat_input_t *i = vam->input;
18954   vl_api_one_eid_table_dump_t *mp;
18955   vl_api_control_ping_t *mp_ping;
18956   struct in_addr ip4;
18957   struct in6_addr ip6;
18958   u8 mac[6];
18959   u8 eid_type = ~0, eid_set = 0;
18960   u32 prefix_length = ~0, t, vni = 0;
18961   u8 filter = 0;
18962   int ret;
18963   lisp_nsh_api_t nsh;
18964
18965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18966     {
18967       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18968         {
18969           eid_set = 1;
18970           eid_type = 0;
18971           prefix_length = t;
18972         }
18973       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18974         {
18975           eid_set = 1;
18976           eid_type = 1;
18977           prefix_length = t;
18978         }
18979       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18980         {
18981           eid_set = 1;
18982           eid_type = 2;
18983         }
18984       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18985         {
18986           eid_set = 1;
18987           eid_type = 3;
18988         }
18989       else if (unformat (i, "vni %d", &t))
18990         {
18991           vni = t;
18992         }
18993       else if (unformat (i, "local"))
18994         {
18995           filter = 1;
18996         }
18997       else if (unformat (i, "remote"))
18998         {
18999           filter = 2;
19000         }
19001       else
19002         {
19003           errmsg ("parse error '%U'", format_unformat_error, i);
19004           return -99;
19005         }
19006     }
19007
19008   if (!vam->json_output)
19009     {
19010       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19011              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19012     }
19013
19014   M (ONE_EID_TABLE_DUMP, mp);
19015
19016   mp->filter = filter;
19017   if (eid_set)
19018     {
19019       mp->eid_set = 1;
19020       mp->vni = htonl (vni);
19021       mp->eid_type = eid_type;
19022       switch (eid_type)
19023         {
19024         case 0:
19025           mp->prefix_length = prefix_length;
19026           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19027           break;
19028         case 1:
19029           mp->prefix_length = prefix_length;
19030           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19031           break;
19032         case 2:
19033           clib_memcpy (mp->eid, mac, sizeof (mac));
19034           break;
19035         case 3:
19036           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19037           break;
19038         default:
19039           errmsg ("unknown EID type %d!", eid_type);
19040           return -99;
19041         }
19042     }
19043
19044   /* send it... */
19045   S (mp);
19046
19047   /* Use a control ping for synchronization */
19048   MPING (CONTROL_PING, mp_ping);
19049   S (mp_ping);
19050
19051   /* Wait for a reply... */
19052   W (ret);
19053   return ret;
19054 }
19055
19056 #define api_lisp_eid_table_dump api_one_eid_table_dump
19057
19058 static int
19059 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19060 {
19061   unformat_input_t *i = vam->input;
19062   vl_api_gpe_fwd_entries_get_t *mp;
19063   u8 vni_set = 0;
19064   u32 vni = ~0;
19065   int ret;
19066
19067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19068     {
19069       if (unformat (i, "vni %d", &vni))
19070         {
19071           vni_set = 1;
19072         }
19073       else
19074         {
19075           errmsg ("parse error '%U'", format_unformat_error, i);
19076           return -99;
19077         }
19078     }
19079
19080   if (!vni_set)
19081     {
19082       errmsg ("vni not set!");
19083       return -99;
19084     }
19085
19086   if (!vam->json_output)
19087     {
19088       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19089              "leid", "reid");
19090     }
19091
19092   M (GPE_FWD_ENTRIES_GET, mp);
19093   mp->vni = clib_host_to_net_u32 (vni);
19094
19095   /* send it... */
19096   S (mp);
19097
19098   /* Wait for a reply... */
19099   W (ret);
19100   return ret;
19101 }
19102
19103 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19104 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19105 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19106 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19107 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19108 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19109 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19110 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19111
19112 static int
19113 api_one_adjacencies_get (vat_main_t * vam)
19114 {
19115   unformat_input_t *i = vam->input;
19116   vl_api_one_adjacencies_get_t *mp;
19117   u8 vni_set = 0;
19118   u32 vni = ~0;
19119   int ret;
19120
19121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19122     {
19123       if (unformat (i, "vni %d", &vni))
19124         {
19125           vni_set = 1;
19126         }
19127       else
19128         {
19129           errmsg ("parse error '%U'", format_unformat_error, i);
19130           return -99;
19131         }
19132     }
19133
19134   if (!vni_set)
19135     {
19136       errmsg ("vni not set!");
19137       return -99;
19138     }
19139
19140   if (!vam->json_output)
19141     {
19142       print (vam->ofp, "%s %40s", "leid", "reid");
19143     }
19144
19145   M (ONE_ADJACENCIES_GET, mp);
19146   mp->vni = clib_host_to_net_u32 (vni);
19147
19148   /* send it... */
19149   S (mp);
19150
19151   /* Wait for a reply... */
19152   W (ret);
19153   return ret;
19154 }
19155
19156 #define api_lisp_adjacencies_get api_one_adjacencies_get
19157
19158 static int
19159 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19160 {
19161   unformat_input_t *i = vam->input;
19162   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19163   int ret;
19164   u8 ip_family_set = 0, is_ip4 = 1;
19165
19166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19167     {
19168       if (unformat (i, "ip4"))
19169         {
19170           ip_family_set = 1;
19171           is_ip4 = 1;
19172         }
19173       else if (unformat (i, "ip6"))
19174         {
19175           ip_family_set = 1;
19176           is_ip4 = 0;
19177         }
19178       else
19179         {
19180           errmsg ("parse error '%U'", format_unformat_error, i);
19181           return -99;
19182         }
19183     }
19184
19185   if (!ip_family_set)
19186     {
19187       errmsg ("ip family not set!");
19188       return -99;
19189     }
19190
19191   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19192   mp->is_ip4 = is_ip4;
19193
19194   /* send it... */
19195   S (mp);
19196
19197   /* Wait for a reply... */
19198   W (ret);
19199   return ret;
19200 }
19201
19202 static int
19203 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19204 {
19205   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19206   int ret;
19207
19208   if (!vam->json_output)
19209     {
19210       print (vam->ofp, "VNIs");
19211     }
19212
19213   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19214
19215   /* send it... */
19216   S (mp);
19217
19218   /* Wait for a reply... */
19219   W (ret);
19220   return ret;
19221 }
19222
19223 static int
19224 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19225 {
19226   unformat_input_t *i = vam->input;
19227   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19228   int ret = 0;
19229   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19230   struct in_addr ip4;
19231   struct in6_addr ip6;
19232   u32 table_id = 0, nh_sw_if_index = ~0;
19233
19234   memset (&ip4, 0, sizeof (ip4));
19235   memset (&ip6, 0, sizeof (ip6));
19236
19237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19238     {
19239       if (unformat (i, "del"))
19240         is_add = 0;
19241       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19242                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19243         {
19244           ip_set = 1;
19245           is_ip4 = 1;
19246         }
19247       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19248                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19249         {
19250           ip_set = 1;
19251           is_ip4 = 0;
19252         }
19253       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19254         {
19255           ip_set = 1;
19256           is_ip4 = 1;
19257           nh_sw_if_index = ~0;
19258         }
19259       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19260         {
19261           ip_set = 1;
19262           is_ip4 = 0;
19263           nh_sw_if_index = ~0;
19264         }
19265       else if (unformat (i, "table %d", &table_id))
19266         ;
19267       else
19268         {
19269           errmsg ("parse error '%U'", format_unformat_error, i);
19270           return -99;
19271         }
19272     }
19273
19274   if (!ip_set)
19275     {
19276       errmsg ("nh addr not set!");
19277       return -99;
19278     }
19279
19280   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19281   mp->is_add = is_add;
19282   mp->table_id = clib_host_to_net_u32 (table_id);
19283   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19284   mp->is_ip4 = is_ip4;
19285   if (is_ip4)
19286     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19287   else
19288     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19289
19290   /* send it... */
19291   S (mp);
19292
19293   /* Wait for a reply... */
19294   W (ret);
19295   return ret;
19296 }
19297
19298 static int
19299 api_one_map_server_dump (vat_main_t * vam)
19300 {
19301   vl_api_one_map_server_dump_t *mp;
19302   vl_api_control_ping_t *mp_ping;
19303   int ret;
19304
19305   if (!vam->json_output)
19306     {
19307       print (vam->ofp, "%=20s", "Map server");
19308     }
19309
19310   M (ONE_MAP_SERVER_DUMP, mp);
19311   /* send it... */
19312   S (mp);
19313
19314   /* Use a control ping for synchronization */
19315   MPING (CONTROL_PING, mp_ping);
19316   S (mp_ping);
19317
19318   /* Wait for a reply... */
19319   W (ret);
19320   return ret;
19321 }
19322
19323 #define api_lisp_map_server_dump api_one_map_server_dump
19324
19325 static int
19326 api_one_map_resolver_dump (vat_main_t * vam)
19327 {
19328   vl_api_one_map_resolver_dump_t *mp;
19329   vl_api_control_ping_t *mp_ping;
19330   int ret;
19331
19332   if (!vam->json_output)
19333     {
19334       print (vam->ofp, "%=20s", "Map resolver");
19335     }
19336
19337   M (ONE_MAP_RESOLVER_DUMP, mp);
19338   /* send it... */
19339   S (mp);
19340
19341   /* Use a control ping for synchronization */
19342   MPING (CONTROL_PING, mp_ping);
19343   S (mp_ping);
19344
19345   /* Wait for a reply... */
19346   W (ret);
19347   return ret;
19348 }
19349
19350 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19351
19352 static int
19353 api_one_stats_flush (vat_main_t * vam)
19354 {
19355   vl_api_one_stats_flush_t *mp;
19356   int ret = 0;
19357
19358   M (ONE_STATS_FLUSH, mp);
19359   S (mp);
19360   W (ret);
19361   return ret;
19362 }
19363
19364 static int
19365 api_one_stats_dump (vat_main_t * vam)
19366 {
19367   vl_api_one_stats_dump_t *mp;
19368   vl_api_control_ping_t *mp_ping;
19369   int ret;
19370
19371   M (ONE_STATS_DUMP, mp);
19372   /* send it... */
19373   S (mp);
19374
19375   /* Use a control ping for synchronization */
19376   MPING (CONTROL_PING, mp_ping);
19377   S (mp_ping);
19378
19379   /* Wait for a reply... */
19380   W (ret);
19381   return ret;
19382 }
19383
19384 static int
19385 api_show_one_status (vat_main_t * vam)
19386 {
19387   vl_api_show_one_status_t *mp;
19388   int ret;
19389
19390   if (!vam->json_output)
19391     {
19392       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19393     }
19394
19395   M (SHOW_ONE_STATUS, mp);
19396   /* send it... */
19397   S (mp);
19398   /* Wait for a reply... */
19399   W (ret);
19400   return ret;
19401 }
19402
19403 #define api_show_lisp_status api_show_one_status
19404
19405 static int
19406 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19407 {
19408   vl_api_gpe_fwd_entry_path_dump_t *mp;
19409   vl_api_control_ping_t *mp_ping;
19410   unformat_input_t *i = vam->input;
19411   u32 fwd_entry_index = ~0;
19412   int ret;
19413
19414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19415     {
19416       if (unformat (i, "index %d", &fwd_entry_index))
19417         ;
19418       else
19419         break;
19420     }
19421
19422   if (~0 == fwd_entry_index)
19423     {
19424       errmsg ("no index specified!");
19425       return -99;
19426     }
19427
19428   if (!vam->json_output)
19429     {
19430       print (vam->ofp, "first line");
19431     }
19432
19433   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19434
19435   /* send it... */
19436   S (mp);
19437   /* Use a control ping for synchronization */
19438   MPING (CONTROL_PING, mp_ping);
19439   S (mp_ping);
19440
19441   /* Wait for a reply... */
19442   W (ret);
19443   return ret;
19444 }
19445
19446 static int
19447 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19448 {
19449   vl_api_one_get_map_request_itr_rlocs_t *mp;
19450   int ret;
19451
19452   if (!vam->json_output)
19453     {
19454       print (vam->ofp, "%=20s", "itr-rlocs:");
19455     }
19456
19457   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19458   /* send it... */
19459   S (mp);
19460   /* Wait for a reply... */
19461   W (ret);
19462   return ret;
19463 }
19464
19465 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19466
19467 static int
19468 api_af_packet_create (vat_main_t * vam)
19469 {
19470   unformat_input_t *i = vam->input;
19471   vl_api_af_packet_create_t *mp;
19472   u8 *host_if_name = 0;
19473   u8 hw_addr[6];
19474   u8 random_hw_addr = 1;
19475   int ret;
19476
19477   memset (hw_addr, 0, sizeof (hw_addr));
19478
19479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19480     {
19481       if (unformat (i, "name %s", &host_if_name))
19482         vec_add1 (host_if_name, 0);
19483       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19484         random_hw_addr = 0;
19485       else
19486         break;
19487     }
19488
19489   if (!vec_len (host_if_name))
19490     {
19491       errmsg ("host-interface name must be specified");
19492       return -99;
19493     }
19494
19495   if (vec_len (host_if_name) > 64)
19496     {
19497       errmsg ("host-interface name too long");
19498       return -99;
19499     }
19500
19501   M (AF_PACKET_CREATE, mp);
19502
19503   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19504   clib_memcpy (mp->hw_addr, hw_addr, 6);
19505   mp->use_random_hw_addr = random_hw_addr;
19506   vec_free (host_if_name);
19507
19508   S (mp);
19509
19510   /* *INDENT-OFF* */
19511   W2 (ret,
19512       ({
19513         if (ret == 0)
19514           fprintf (vam->ofp ? vam->ofp : stderr,
19515                    " new sw_if_index = %d\n", vam->sw_if_index);
19516       }));
19517   /* *INDENT-ON* */
19518   return ret;
19519 }
19520
19521 static int
19522 api_af_packet_delete (vat_main_t * vam)
19523 {
19524   unformat_input_t *i = vam->input;
19525   vl_api_af_packet_delete_t *mp;
19526   u8 *host_if_name = 0;
19527   int ret;
19528
19529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19530     {
19531       if (unformat (i, "name %s", &host_if_name))
19532         vec_add1 (host_if_name, 0);
19533       else
19534         break;
19535     }
19536
19537   if (!vec_len (host_if_name))
19538     {
19539       errmsg ("host-interface name must be specified");
19540       return -99;
19541     }
19542
19543   if (vec_len (host_if_name) > 64)
19544     {
19545       errmsg ("host-interface name too long");
19546       return -99;
19547     }
19548
19549   M (AF_PACKET_DELETE, mp);
19550
19551   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19552   vec_free (host_if_name);
19553
19554   S (mp);
19555   W (ret);
19556   return ret;
19557 }
19558
19559 static void vl_api_af_packet_details_t_handler
19560   (vl_api_af_packet_details_t * mp)
19561 {
19562   vat_main_t *vam = &vat_main;
19563
19564   print (vam->ofp, "%-16s %d",
19565          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19566 }
19567
19568 static void vl_api_af_packet_details_t_handler_json
19569   (vl_api_af_packet_details_t * mp)
19570 {
19571   vat_main_t *vam = &vat_main;
19572   vat_json_node_t *node = NULL;
19573
19574   if (VAT_JSON_ARRAY != vam->json_tree.type)
19575     {
19576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19577       vat_json_init_array (&vam->json_tree);
19578     }
19579   node = vat_json_array_add (&vam->json_tree);
19580
19581   vat_json_init_object (node);
19582   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19583   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19584 }
19585
19586 static int
19587 api_af_packet_dump (vat_main_t * vam)
19588 {
19589   vl_api_af_packet_dump_t *mp;
19590   vl_api_control_ping_t *mp_ping;
19591   int ret;
19592
19593   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19594   /* Get list of tap interfaces */
19595   M (AF_PACKET_DUMP, mp);
19596   S (mp);
19597
19598   /* Use a control ping for synchronization */
19599   MPING (CONTROL_PING, mp_ping);
19600   S (mp_ping);
19601
19602   W (ret);
19603   return ret;
19604 }
19605
19606 static int
19607 api_policer_add_del (vat_main_t * vam)
19608 {
19609   unformat_input_t *i = vam->input;
19610   vl_api_policer_add_del_t *mp;
19611   u8 is_add = 1;
19612   u8 *name = 0;
19613   u32 cir = 0;
19614   u32 eir = 0;
19615   u64 cb = 0;
19616   u64 eb = 0;
19617   u8 rate_type = 0;
19618   u8 round_type = 0;
19619   u8 type = 0;
19620   u8 color_aware = 0;
19621   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19622   int ret;
19623
19624   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19625   conform_action.dscp = 0;
19626   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19627   exceed_action.dscp = 0;
19628   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19629   violate_action.dscp = 0;
19630
19631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19632     {
19633       if (unformat (i, "del"))
19634         is_add = 0;
19635       else if (unformat (i, "name %s", &name))
19636         vec_add1 (name, 0);
19637       else if (unformat (i, "cir %u", &cir))
19638         ;
19639       else if (unformat (i, "eir %u", &eir))
19640         ;
19641       else if (unformat (i, "cb %u", &cb))
19642         ;
19643       else if (unformat (i, "eb %u", &eb))
19644         ;
19645       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19646                          &rate_type))
19647         ;
19648       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19649                          &round_type))
19650         ;
19651       else if (unformat (i, "type %U", unformat_policer_type, &type))
19652         ;
19653       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19654                          &conform_action))
19655         ;
19656       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19657                          &exceed_action))
19658         ;
19659       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19660                          &violate_action))
19661         ;
19662       else if (unformat (i, "color-aware"))
19663         color_aware = 1;
19664       else
19665         break;
19666     }
19667
19668   if (!vec_len (name))
19669     {
19670       errmsg ("policer name must be specified");
19671       return -99;
19672     }
19673
19674   if (vec_len (name) > 64)
19675     {
19676       errmsg ("policer name too long");
19677       return -99;
19678     }
19679
19680   M (POLICER_ADD_DEL, mp);
19681
19682   clib_memcpy (mp->name, name, vec_len (name));
19683   vec_free (name);
19684   mp->is_add = is_add;
19685   mp->cir = ntohl (cir);
19686   mp->eir = ntohl (eir);
19687   mp->cb = clib_net_to_host_u64 (cb);
19688   mp->eb = clib_net_to_host_u64 (eb);
19689   mp->rate_type = rate_type;
19690   mp->round_type = round_type;
19691   mp->type = type;
19692   mp->conform_action_type = conform_action.action_type;
19693   mp->conform_dscp = conform_action.dscp;
19694   mp->exceed_action_type = exceed_action.action_type;
19695   mp->exceed_dscp = exceed_action.dscp;
19696   mp->violate_action_type = violate_action.action_type;
19697   mp->violate_dscp = violate_action.dscp;
19698   mp->color_aware = color_aware;
19699
19700   S (mp);
19701   W (ret);
19702   return ret;
19703 }
19704
19705 static int
19706 api_policer_dump (vat_main_t * vam)
19707 {
19708   unformat_input_t *i = vam->input;
19709   vl_api_policer_dump_t *mp;
19710   vl_api_control_ping_t *mp_ping;
19711   u8 *match_name = 0;
19712   u8 match_name_valid = 0;
19713   int ret;
19714
19715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19716     {
19717       if (unformat (i, "name %s", &match_name))
19718         {
19719           vec_add1 (match_name, 0);
19720           match_name_valid = 1;
19721         }
19722       else
19723         break;
19724     }
19725
19726   M (POLICER_DUMP, mp);
19727   mp->match_name_valid = match_name_valid;
19728   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19729   vec_free (match_name);
19730   /* send it... */
19731   S (mp);
19732
19733   /* Use a control ping for synchronization */
19734   MPING (CONTROL_PING, mp_ping);
19735   S (mp_ping);
19736
19737   /* Wait for a reply... */
19738   W (ret);
19739   return ret;
19740 }
19741
19742 static int
19743 api_policer_classify_set_interface (vat_main_t * vam)
19744 {
19745   unformat_input_t *i = vam->input;
19746   vl_api_policer_classify_set_interface_t *mp;
19747   u32 sw_if_index;
19748   int sw_if_index_set;
19749   u32 ip4_table_index = ~0;
19750   u32 ip6_table_index = ~0;
19751   u32 l2_table_index = ~0;
19752   u8 is_add = 1;
19753   int ret;
19754
19755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19756     {
19757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19758         sw_if_index_set = 1;
19759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19760         sw_if_index_set = 1;
19761       else if (unformat (i, "del"))
19762         is_add = 0;
19763       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19764         ;
19765       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19766         ;
19767       else if (unformat (i, "l2-table %d", &l2_table_index))
19768         ;
19769       else
19770         {
19771           clib_warning ("parse error '%U'", format_unformat_error, i);
19772           return -99;
19773         }
19774     }
19775
19776   if (sw_if_index_set == 0)
19777     {
19778       errmsg ("missing interface name or sw_if_index");
19779       return -99;
19780     }
19781
19782   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19783
19784   mp->sw_if_index = ntohl (sw_if_index);
19785   mp->ip4_table_index = ntohl (ip4_table_index);
19786   mp->ip6_table_index = ntohl (ip6_table_index);
19787   mp->l2_table_index = ntohl (l2_table_index);
19788   mp->is_add = is_add;
19789
19790   S (mp);
19791   W (ret);
19792   return ret;
19793 }
19794
19795 static int
19796 api_policer_classify_dump (vat_main_t * vam)
19797 {
19798   unformat_input_t *i = vam->input;
19799   vl_api_policer_classify_dump_t *mp;
19800   vl_api_control_ping_t *mp_ping;
19801   u8 type = POLICER_CLASSIFY_N_TABLES;
19802   int ret;
19803
19804   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19805     ;
19806   else
19807     {
19808       errmsg ("classify table type must be specified");
19809       return -99;
19810     }
19811
19812   if (!vam->json_output)
19813     {
19814       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19815     }
19816
19817   M (POLICER_CLASSIFY_DUMP, mp);
19818   mp->type = type;
19819   /* send it... */
19820   S (mp);
19821
19822   /* Use a control ping for synchronization */
19823   MPING (CONTROL_PING, mp_ping);
19824   S (mp_ping);
19825
19826   /* Wait for a reply... */
19827   W (ret);
19828   return ret;
19829 }
19830
19831 static int
19832 api_netmap_create (vat_main_t * vam)
19833 {
19834   unformat_input_t *i = vam->input;
19835   vl_api_netmap_create_t *mp;
19836   u8 *if_name = 0;
19837   u8 hw_addr[6];
19838   u8 random_hw_addr = 1;
19839   u8 is_pipe = 0;
19840   u8 is_master = 0;
19841   int ret;
19842
19843   memset (hw_addr, 0, sizeof (hw_addr));
19844
19845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19846     {
19847       if (unformat (i, "name %s", &if_name))
19848         vec_add1 (if_name, 0);
19849       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19850         random_hw_addr = 0;
19851       else if (unformat (i, "pipe"))
19852         is_pipe = 1;
19853       else if (unformat (i, "master"))
19854         is_master = 1;
19855       else if (unformat (i, "slave"))
19856         is_master = 0;
19857       else
19858         break;
19859     }
19860
19861   if (!vec_len (if_name))
19862     {
19863       errmsg ("interface name must be specified");
19864       return -99;
19865     }
19866
19867   if (vec_len (if_name) > 64)
19868     {
19869       errmsg ("interface name too long");
19870       return -99;
19871     }
19872
19873   M (NETMAP_CREATE, mp);
19874
19875   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19876   clib_memcpy (mp->hw_addr, hw_addr, 6);
19877   mp->use_random_hw_addr = random_hw_addr;
19878   mp->is_pipe = is_pipe;
19879   mp->is_master = is_master;
19880   vec_free (if_name);
19881
19882   S (mp);
19883   W (ret);
19884   return ret;
19885 }
19886
19887 static int
19888 api_netmap_delete (vat_main_t * vam)
19889 {
19890   unformat_input_t *i = vam->input;
19891   vl_api_netmap_delete_t *mp;
19892   u8 *if_name = 0;
19893   int ret;
19894
19895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19896     {
19897       if (unformat (i, "name %s", &if_name))
19898         vec_add1 (if_name, 0);
19899       else
19900         break;
19901     }
19902
19903   if (!vec_len (if_name))
19904     {
19905       errmsg ("interface name must be specified");
19906       return -99;
19907     }
19908
19909   if (vec_len (if_name) > 64)
19910     {
19911       errmsg ("interface name too long");
19912       return -99;
19913     }
19914
19915   M (NETMAP_DELETE, mp);
19916
19917   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19918   vec_free (if_name);
19919
19920   S (mp);
19921   W (ret);
19922   return ret;
19923 }
19924
19925 static void
19926 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19927 {
19928   if (fp->afi == IP46_TYPE_IP6)
19929     print (vam->ofp,
19930            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19931            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19932            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19933            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19934            format_ip6_address, fp->next_hop);
19935   else if (fp->afi == IP46_TYPE_IP4)
19936     print (vam->ofp,
19937            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19938            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19939            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19940            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19941            format_ip4_address, fp->next_hop);
19942 }
19943
19944 static void
19945 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19946                                  vl_api_fib_path_t * fp)
19947 {
19948   struct in_addr ip4;
19949   struct in6_addr ip6;
19950
19951   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19952   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19953   vat_json_object_add_uint (node, "is_local", fp->is_local);
19954   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19955   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19956   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19957   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19958   if (fp->afi == IP46_TYPE_IP4)
19959     {
19960       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19961       vat_json_object_add_ip4 (node, "next_hop", ip4);
19962     }
19963   else if (fp->afi == IP46_TYPE_IP6)
19964     {
19965       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19966       vat_json_object_add_ip6 (node, "next_hop", ip6);
19967     }
19968 }
19969
19970 static void
19971 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19972 {
19973   vat_main_t *vam = &vat_main;
19974   int count = ntohl (mp->mt_count);
19975   vl_api_fib_path_t *fp;
19976   i32 i;
19977
19978   print (vam->ofp, "[%d]: sw_if_index %d via:",
19979          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19980   fp = mp->mt_paths;
19981   for (i = 0; i < count; i++)
19982     {
19983       vl_api_mpls_fib_path_print (vam, fp);
19984       fp++;
19985     }
19986
19987   print (vam->ofp, "");
19988 }
19989
19990 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19991 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19992
19993 static void
19994 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19995 {
19996   vat_main_t *vam = &vat_main;
19997   vat_json_node_t *node = NULL;
19998   int count = ntohl (mp->mt_count);
19999   vl_api_fib_path_t *fp;
20000   i32 i;
20001
20002   if (VAT_JSON_ARRAY != vam->json_tree.type)
20003     {
20004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20005       vat_json_init_array (&vam->json_tree);
20006     }
20007   node = vat_json_array_add (&vam->json_tree);
20008
20009   vat_json_init_object (node);
20010   vat_json_object_add_uint (node, "tunnel_index",
20011                             ntohl (mp->mt_tunnel_index));
20012   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20013
20014   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20015
20016   fp = mp->mt_paths;
20017   for (i = 0; i < count; i++)
20018     {
20019       vl_api_mpls_fib_path_json_print (node, fp);
20020       fp++;
20021     }
20022 }
20023
20024 static int
20025 api_mpls_tunnel_dump (vat_main_t * vam)
20026 {
20027   vl_api_mpls_tunnel_dump_t *mp;
20028   vl_api_control_ping_t *mp_ping;
20029   i32 index = -1;
20030   int ret;
20031
20032   /* Parse args required to build the message */
20033   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20034     {
20035       if (!unformat (vam->input, "tunnel_index %d", &index))
20036         {
20037           index = -1;
20038           break;
20039         }
20040     }
20041
20042   print (vam->ofp, "  tunnel_index %d", index);
20043
20044   M (MPLS_TUNNEL_DUMP, mp);
20045   mp->tunnel_index = htonl (index);
20046   S (mp);
20047
20048   /* Use a control ping for synchronization */
20049   MPING (CONTROL_PING, mp_ping);
20050   S (mp_ping);
20051
20052   W (ret);
20053   return ret;
20054 }
20055
20056 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20057 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20058
20059
20060 static void
20061 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20062 {
20063   vat_main_t *vam = &vat_main;
20064   int count = ntohl (mp->count);
20065   vl_api_fib_path_t *fp;
20066   int i;
20067
20068   print (vam->ofp,
20069          "table-id %d, label %u, ess_bit %u",
20070          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20071   fp = mp->path;
20072   for (i = 0; i < count; i++)
20073     {
20074       vl_api_mpls_fib_path_print (vam, fp);
20075       fp++;
20076     }
20077 }
20078
20079 static void vl_api_mpls_fib_details_t_handler_json
20080   (vl_api_mpls_fib_details_t * mp)
20081 {
20082   vat_main_t *vam = &vat_main;
20083   int count = ntohl (mp->count);
20084   vat_json_node_t *node = NULL;
20085   vl_api_fib_path_t *fp;
20086   int i;
20087
20088   if (VAT_JSON_ARRAY != vam->json_tree.type)
20089     {
20090       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20091       vat_json_init_array (&vam->json_tree);
20092     }
20093   node = vat_json_array_add (&vam->json_tree);
20094
20095   vat_json_init_object (node);
20096   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20097   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20098   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20099   vat_json_object_add_uint (node, "path_count", count);
20100   fp = mp->path;
20101   for (i = 0; i < count; i++)
20102     {
20103       vl_api_mpls_fib_path_json_print (node, fp);
20104       fp++;
20105     }
20106 }
20107
20108 static int
20109 api_mpls_fib_dump (vat_main_t * vam)
20110 {
20111   vl_api_mpls_fib_dump_t *mp;
20112   vl_api_control_ping_t *mp_ping;
20113   int ret;
20114
20115   M (MPLS_FIB_DUMP, mp);
20116   S (mp);
20117
20118   /* Use a control ping for synchronization */
20119   MPING (CONTROL_PING, mp_ping);
20120   S (mp_ping);
20121
20122   W (ret);
20123   return ret;
20124 }
20125
20126 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20127 #define vl_api_ip_fib_details_t_print vl_noop_handler
20128
20129 static void
20130 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20131 {
20132   vat_main_t *vam = &vat_main;
20133   int count = ntohl (mp->count);
20134   vl_api_fib_path_t *fp;
20135   int i;
20136
20137   print (vam->ofp,
20138          "table-id %d, prefix %U/%d",
20139          ntohl (mp->table_id), format_ip4_address, mp->address,
20140          mp->address_length);
20141   fp = mp->path;
20142   for (i = 0; i < count; i++)
20143     {
20144       if (fp->afi == IP46_TYPE_IP6)
20145         print (vam->ofp,
20146                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20147                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20148                "next_hop_table %d",
20149                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20150                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20151                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20152       else if (fp->afi == IP46_TYPE_IP4)
20153         print (vam->ofp,
20154                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20155                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20156                "next_hop_table %d",
20157                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20158                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20159                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20160       fp++;
20161     }
20162 }
20163
20164 static void vl_api_ip_fib_details_t_handler_json
20165   (vl_api_ip_fib_details_t * mp)
20166 {
20167   vat_main_t *vam = &vat_main;
20168   int count = ntohl (mp->count);
20169   vat_json_node_t *node = NULL;
20170   struct in_addr ip4;
20171   struct in6_addr ip6;
20172   vl_api_fib_path_t *fp;
20173   int i;
20174
20175   if (VAT_JSON_ARRAY != vam->json_tree.type)
20176     {
20177       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20178       vat_json_init_array (&vam->json_tree);
20179     }
20180   node = vat_json_array_add (&vam->json_tree);
20181
20182   vat_json_init_object (node);
20183   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20184   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20185   vat_json_object_add_ip4 (node, "prefix", ip4);
20186   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20187   vat_json_object_add_uint (node, "path_count", count);
20188   fp = mp->path;
20189   for (i = 0; i < count; i++)
20190     {
20191       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20192       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20193       vat_json_object_add_uint (node, "is_local", fp->is_local);
20194       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20195       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20196       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20197       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20198       if (fp->afi == IP46_TYPE_IP4)
20199         {
20200           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20201           vat_json_object_add_ip4 (node, "next_hop", ip4);
20202         }
20203       else if (fp->afi == IP46_TYPE_IP6)
20204         {
20205           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20206           vat_json_object_add_ip6 (node, "next_hop", ip6);
20207         }
20208     }
20209 }
20210
20211 static int
20212 api_ip_fib_dump (vat_main_t * vam)
20213 {
20214   vl_api_ip_fib_dump_t *mp;
20215   vl_api_control_ping_t *mp_ping;
20216   int ret;
20217
20218   M (IP_FIB_DUMP, mp);
20219   S (mp);
20220
20221   /* Use a control ping for synchronization */
20222   MPING (CONTROL_PING, mp_ping);
20223   S (mp_ping);
20224
20225   W (ret);
20226   return ret;
20227 }
20228
20229 static int
20230 api_ip_mfib_dump (vat_main_t * vam)
20231 {
20232   vl_api_ip_mfib_dump_t *mp;
20233   vl_api_control_ping_t *mp_ping;
20234   int ret;
20235
20236   M (IP_MFIB_DUMP, mp);
20237   S (mp);
20238
20239   /* Use a control ping for synchronization */
20240   MPING (CONTROL_PING, mp_ping);
20241   S (mp_ping);
20242
20243   W (ret);
20244   return ret;
20245 }
20246
20247 static void vl_api_ip_neighbor_details_t_handler
20248   (vl_api_ip_neighbor_details_t * mp)
20249 {
20250   vat_main_t *vam = &vat_main;
20251
20252   print (vam->ofp, "%c %U %U",
20253          (mp->is_static) ? 'S' : 'D',
20254          format_ethernet_address, &mp->mac_address,
20255          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20256          &mp->ip_address);
20257 }
20258
20259 static void vl_api_ip_neighbor_details_t_handler_json
20260   (vl_api_ip_neighbor_details_t * mp)
20261 {
20262
20263   vat_main_t *vam = &vat_main;
20264   vat_json_node_t *node;
20265   struct in_addr ip4;
20266   struct in6_addr ip6;
20267
20268   if (VAT_JSON_ARRAY != vam->json_tree.type)
20269     {
20270       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20271       vat_json_init_array (&vam->json_tree);
20272     }
20273   node = vat_json_array_add (&vam->json_tree);
20274
20275   vat_json_init_object (node);
20276   vat_json_object_add_string_copy (node, "flag",
20277                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20278                                    "dynamic");
20279
20280   vat_json_object_add_string_copy (node, "link_layer",
20281                                    format (0, "%U", format_ethernet_address,
20282                                            &mp->mac_address));
20283
20284   if (mp->is_ipv6)
20285     {
20286       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20287       vat_json_object_add_ip6 (node, "ip_address", ip6);
20288     }
20289   else
20290     {
20291       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20292       vat_json_object_add_ip4 (node, "ip_address", ip4);
20293     }
20294 }
20295
20296 static int
20297 api_ip_neighbor_dump (vat_main_t * vam)
20298 {
20299   unformat_input_t *i = vam->input;
20300   vl_api_ip_neighbor_dump_t *mp;
20301   vl_api_control_ping_t *mp_ping;
20302   u8 is_ipv6 = 0;
20303   u32 sw_if_index = ~0;
20304   int ret;
20305
20306   /* Parse args required to build the message */
20307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20308     {
20309       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20310         ;
20311       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20312         ;
20313       else if (unformat (i, "ip6"))
20314         is_ipv6 = 1;
20315       else
20316         break;
20317     }
20318
20319   if (sw_if_index == ~0)
20320     {
20321       errmsg ("missing interface name or sw_if_index");
20322       return -99;
20323     }
20324
20325   M (IP_NEIGHBOR_DUMP, mp);
20326   mp->is_ipv6 = (u8) is_ipv6;
20327   mp->sw_if_index = ntohl (sw_if_index);
20328   S (mp);
20329
20330   /* Use a control ping for synchronization */
20331   MPING (CONTROL_PING, mp_ping);
20332   S (mp_ping);
20333
20334   W (ret);
20335   return ret;
20336 }
20337
20338 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20339 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20340
20341 static void
20342 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20343 {
20344   vat_main_t *vam = &vat_main;
20345   int count = ntohl (mp->count);
20346   vl_api_fib_path_t *fp;
20347   int i;
20348
20349   print (vam->ofp,
20350          "table-id %d, prefix %U/%d",
20351          ntohl (mp->table_id), format_ip6_address, mp->address,
20352          mp->address_length);
20353   fp = mp->path;
20354   for (i = 0; i < count; i++)
20355     {
20356       if (fp->afi == IP46_TYPE_IP6)
20357         print (vam->ofp,
20358                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20359                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20360                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20361                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20362                format_ip6_address, fp->next_hop);
20363       else if (fp->afi == IP46_TYPE_IP4)
20364         print (vam->ofp,
20365                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20366                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20367                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20368                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20369                format_ip4_address, fp->next_hop);
20370       fp++;
20371     }
20372 }
20373
20374 static void vl_api_ip6_fib_details_t_handler_json
20375   (vl_api_ip6_fib_details_t * mp)
20376 {
20377   vat_main_t *vam = &vat_main;
20378   int count = ntohl (mp->count);
20379   vat_json_node_t *node = NULL;
20380   struct in_addr ip4;
20381   struct in6_addr ip6;
20382   vl_api_fib_path_t *fp;
20383   int i;
20384
20385   if (VAT_JSON_ARRAY != vam->json_tree.type)
20386     {
20387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20388       vat_json_init_array (&vam->json_tree);
20389     }
20390   node = vat_json_array_add (&vam->json_tree);
20391
20392   vat_json_init_object (node);
20393   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20394   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20395   vat_json_object_add_ip6 (node, "prefix", ip6);
20396   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20397   vat_json_object_add_uint (node, "path_count", count);
20398   fp = mp->path;
20399   for (i = 0; i < count; i++)
20400     {
20401       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20402       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20403       vat_json_object_add_uint (node, "is_local", fp->is_local);
20404       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20405       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20406       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20407       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20408       if (fp->afi == IP46_TYPE_IP4)
20409         {
20410           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20411           vat_json_object_add_ip4 (node, "next_hop", ip4);
20412         }
20413       else if (fp->afi == IP46_TYPE_IP6)
20414         {
20415           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20416           vat_json_object_add_ip6 (node, "next_hop", ip6);
20417         }
20418     }
20419 }
20420
20421 static int
20422 api_ip6_fib_dump (vat_main_t * vam)
20423 {
20424   vl_api_ip6_fib_dump_t *mp;
20425   vl_api_control_ping_t *mp_ping;
20426   int ret;
20427
20428   M (IP6_FIB_DUMP, mp);
20429   S (mp);
20430
20431   /* Use a control ping for synchronization */
20432   MPING (CONTROL_PING, mp_ping);
20433   S (mp_ping);
20434
20435   W (ret);
20436   return ret;
20437 }
20438
20439 static int
20440 api_ip6_mfib_dump (vat_main_t * vam)
20441 {
20442   vl_api_ip6_mfib_dump_t *mp;
20443   vl_api_control_ping_t *mp_ping;
20444   int ret;
20445
20446   M (IP6_MFIB_DUMP, mp);
20447   S (mp);
20448
20449   /* Use a control ping for synchronization */
20450   MPING (CONTROL_PING, mp_ping);
20451   S (mp_ping);
20452
20453   W (ret);
20454   return ret;
20455 }
20456
20457 int
20458 api_classify_table_ids (vat_main_t * vam)
20459 {
20460   vl_api_classify_table_ids_t *mp;
20461   int ret;
20462
20463   /* Construct the API message */
20464   M (CLASSIFY_TABLE_IDS, mp);
20465   mp->context = 0;
20466
20467   S (mp);
20468   W (ret);
20469   return ret;
20470 }
20471
20472 int
20473 api_classify_table_by_interface (vat_main_t * vam)
20474 {
20475   unformat_input_t *input = vam->input;
20476   vl_api_classify_table_by_interface_t *mp;
20477
20478   u32 sw_if_index = ~0;
20479   int ret;
20480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20481     {
20482       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20483         ;
20484       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20485         ;
20486       else
20487         break;
20488     }
20489   if (sw_if_index == ~0)
20490     {
20491       errmsg ("missing interface name or sw_if_index");
20492       return -99;
20493     }
20494
20495   /* Construct the API message */
20496   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20497   mp->context = 0;
20498   mp->sw_if_index = ntohl (sw_if_index);
20499
20500   S (mp);
20501   W (ret);
20502   return ret;
20503 }
20504
20505 int
20506 api_classify_table_info (vat_main_t * vam)
20507 {
20508   unformat_input_t *input = vam->input;
20509   vl_api_classify_table_info_t *mp;
20510
20511   u32 table_id = ~0;
20512   int ret;
20513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20514     {
20515       if (unformat (input, "table_id %d", &table_id))
20516         ;
20517       else
20518         break;
20519     }
20520   if (table_id == ~0)
20521     {
20522       errmsg ("missing table id");
20523       return -99;
20524     }
20525
20526   /* Construct the API message */
20527   M (CLASSIFY_TABLE_INFO, mp);
20528   mp->context = 0;
20529   mp->table_id = ntohl (table_id);
20530
20531   S (mp);
20532   W (ret);
20533   return ret;
20534 }
20535
20536 int
20537 api_classify_session_dump (vat_main_t * vam)
20538 {
20539   unformat_input_t *input = vam->input;
20540   vl_api_classify_session_dump_t *mp;
20541   vl_api_control_ping_t *mp_ping;
20542
20543   u32 table_id = ~0;
20544   int ret;
20545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20546     {
20547       if (unformat (input, "table_id %d", &table_id))
20548         ;
20549       else
20550         break;
20551     }
20552   if (table_id == ~0)
20553     {
20554       errmsg ("missing table id");
20555       return -99;
20556     }
20557
20558   /* Construct the API message */
20559   M (CLASSIFY_SESSION_DUMP, mp);
20560   mp->context = 0;
20561   mp->table_id = ntohl (table_id);
20562   S (mp);
20563
20564   /* Use a control ping for synchronization */
20565   MPING (CONTROL_PING, mp_ping);
20566   S (mp_ping);
20567
20568   W (ret);
20569   return ret;
20570 }
20571
20572 static void
20573 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20574 {
20575   vat_main_t *vam = &vat_main;
20576
20577   print (vam->ofp, "collector_address %U, collector_port %d, "
20578          "src_address %U, vrf_id %d, path_mtu %u, "
20579          "template_interval %u, udp_checksum %d",
20580          format_ip4_address, mp->collector_address,
20581          ntohs (mp->collector_port),
20582          format_ip4_address, mp->src_address,
20583          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20584          ntohl (mp->template_interval), mp->udp_checksum);
20585
20586   vam->retval = 0;
20587   vam->result_ready = 1;
20588 }
20589
20590 static void
20591   vl_api_ipfix_exporter_details_t_handler_json
20592   (vl_api_ipfix_exporter_details_t * mp)
20593 {
20594   vat_main_t *vam = &vat_main;
20595   vat_json_node_t node;
20596   struct in_addr collector_address;
20597   struct in_addr src_address;
20598
20599   vat_json_init_object (&node);
20600   clib_memcpy (&collector_address, &mp->collector_address,
20601                sizeof (collector_address));
20602   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20603   vat_json_object_add_uint (&node, "collector_port",
20604                             ntohs (mp->collector_port));
20605   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20606   vat_json_object_add_ip4 (&node, "src_address", src_address);
20607   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20608   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20609   vat_json_object_add_uint (&node, "template_interval",
20610                             ntohl (mp->template_interval));
20611   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20612
20613   vat_json_print (vam->ofp, &node);
20614   vat_json_free (&node);
20615   vam->retval = 0;
20616   vam->result_ready = 1;
20617 }
20618
20619 int
20620 api_ipfix_exporter_dump (vat_main_t * vam)
20621 {
20622   vl_api_ipfix_exporter_dump_t *mp;
20623   int ret;
20624
20625   /* Construct the API message */
20626   M (IPFIX_EXPORTER_DUMP, mp);
20627   mp->context = 0;
20628
20629   S (mp);
20630   W (ret);
20631   return ret;
20632 }
20633
20634 static int
20635 api_ipfix_classify_stream_dump (vat_main_t * vam)
20636 {
20637   vl_api_ipfix_classify_stream_dump_t *mp;
20638   int ret;
20639
20640   /* Construct the API message */
20641   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20642   mp->context = 0;
20643
20644   S (mp);
20645   W (ret);
20646   return ret;
20647   /* NOTREACHED */
20648   return 0;
20649 }
20650
20651 static void
20652   vl_api_ipfix_classify_stream_details_t_handler
20653   (vl_api_ipfix_classify_stream_details_t * mp)
20654 {
20655   vat_main_t *vam = &vat_main;
20656   print (vam->ofp, "domain_id %d, src_port %d",
20657          ntohl (mp->domain_id), ntohs (mp->src_port));
20658   vam->retval = 0;
20659   vam->result_ready = 1;
20660 }
20661
20662 static void
20663   vl_api_ipfix_classify_stream_details_t_handler_json
20664   (vl_api_ipfix_classify_stream_details_t * mp)
20665 {
20666   vat_main_t *vam = &vat_main;
20667   vat_json_node_t node;
20668
20669   vat_json_init_object (&node);
20670   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20671   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20672
20673   vat_json_print (vam->ofp, &node);
20674   vat_json_free (&node);
20675   vam->retval = 0;
20676   vam->result_ready = 1;
20677 }
20678
20679 static int
20680 api_ipfix_classify_table_dump (vat_main_t * vam)
20681 {
20682   vl_api_ipfix_classify_table_dump_t *mp;
20683   vl_api_control_ping_t *mp_ping;
20684   int ret;
20685
20686   if (!vam->json_output)
20687     {
20688       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20689              "transport_protocol");
20690     }
20691
20692   /* Construct the API message */
20693   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20694
20695   /* send it... */
20696   S (mp);
20697
20698   /* Use a control ping for synchronization */
20699   MPING (CONTROL_PING, mp_ping);
20700   S (mp_ping);
20701
20702   W (ret);
20703   return ret;
20704 }
20705
20706 static void
20707   vl_api_ipfix_classify_table_details_t_handler
20708   (vl_api_ipfix_classify_table_details_t * mp)
20709 {
20710   vat_main_t *vam = &vat_main;
20711   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20712          mp->transport_protocol);
20713 }
20714
20715 static void
20716   vl_api_ipfix_classify_table_details_t_handler_json
20717   (vl_api_ipfix_classify_table_details_t * mp)
20718 {
20719   vat_json_node_t *node = NULL;
20720   vat_main_t *vam = &vat_main;
20721
20722   if (VAT_JSON_ARRAY != vam->json_tree.type)
20723     {
20724       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20725       vat_json_init_array (&vam->json_tree);
20726     }
20727
20728   node = vat_json_array_add (&vam->json_tree);
20729   vat_json_init_object (node);
20730
20731   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20732   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20733   vat_json_object_add_uint (node, "transport_protocol",
20734                             mp->transport_protocol);
20735 }
20736
20737 static int
20738 api_sw_interface_span_enable_disable (vat_main_t * vam)
20739 {
20740   unformat_input_t *i = vam->input;
20741   vl_api_sw_interface_span_enable_disable_t *mp;
20742   u32 src_sw_if_index = ~0;
20743   u32 dst_sw_if_index = ~0;
20744   u8 state = 3;
20745   int ret;
20746   u8 is_l2 = 0;
20747
20748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20749     {
20750       if (unformat
20751           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20752         ;
20753       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20754         ;
20755       else
20756         if (unformat
20757             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20758         ;
20759       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20760         ;
20761       else if (unformat (i, "disable"))
20762         state = 0;
20763       else if (unformat (i, "rx"))
20764         state = 1;
20765       else if (unformat (i, "tx"))
20766         state = 2;
20767       else if (unformat (i, "both"))
20768         state = 3;
20769       else if (unformat (i, "l2"))
20770         is_l2 = 1;
20771       else
20772         break;
20773     }
20774
20775   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20776
20777   mp->sw_if_index_from = htonl (src_sw_if_index);
20778   mp->sw_if_index_to = htonl (dst_sw_if_index);
20779   mp->state = state;
20780   mp->is_l2 = is_l2;
20781
20782   S (mp);
20783   W (ret);
20784   return ret;
20785 }
20786
20787 static void
20788 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20789                                             * mp)
20790 {
20791   vat_main_t *vam = &vat_main;
20792   u8 *sw_if_from_name = 0;
20793   u8 *sw_if_to_name = 0;
20794   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20795   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20796   char *states[] = { "none", "rx", "tx", "both" };
20797   hash_pair_t *p;
20798
20799   /* *INDENT-OFF* */
20800   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20801   ({
20802     if ((u32) p->value[0] == sw_if_index_from)
20803       {
20804         sw_if_from_name = (u8 *)(p->key);
20805         if (sw_if_to_name)
20806           break;
20807       }
20808     if ((u32) p->value[0] == sw_if_index_to)
20809       {
20810         sw_if_to_name = (u8 *)(p->key);
20811         if (sw_if_from_name)
20812           break;
20813       }
20814   }));
20815   /* *INDENT-ON* */
20816   print (vam->ofp, "%20s => %20s (%s) %s",
20817          sw_if_from_name, sw_if_to_name, states[mp->state],
20818          mp->is_l2 ? "l2" : "device");
20819 }
20820
20821 static void
20822   vl_api_sw_interface_span_details_t_handler_json
20823   (vl_api_sw_interface_span_details_t * mp)
20824 {
20825   vat_main_t *vam = &vat_main;
20826   vat_json_node_t *node = NULL;
20827   u8 *sw_if_from_name = 0;
20828   u8 *sw_if_to_name = 0;
20829   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20830   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20831   hash_pair_t *p;
20832
20833   /* *INDENT-OFF* */
20834   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20835   ({
20836     if ((u32) p->value[0] == sw_if_index_from)
20837       {
20838         sw_if_from_name = (u8 *)(p->key);
20839         if (sw_if_to_name)
20840           break;
20841       }
20842     if ((u32) p->value[0] == sw_if_index_to)
20843       {
20844         sw_if_to_name = (u8 *)(p->key);
20845         if (sw_if_from_name)
20846           break;
20847       }
20848   }));
20849   /* *INDENT-ON* */
20850
20851   if (VAT_JSON_ARRAY != vam->json_tree.type)
20852     {
20853       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20854       vat_json_init_array (&vam->json_tree);
20855     }
20856   node = vat_json_array_add (&vam->json_tree);
20857
20858   vat_json_init_object (node);
20859   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20860   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20861   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20862   if (0 != sw_if_to_name)
20863     {
20864       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20865     }
20866   vat_json_object_add_uint (node, "state", mp->state);
20867   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20868 }
20869
20870 static int
20871 api_sw_interface_span_dump (vat_main_t * vam)
20872 {
20873   unformat_input_t *input = vam->input;
20874   vl_api_sw_interface_span_dump_t *mp;
20875   vl_api_control_ping_t *mp_ping;
20876   u8 is_l2 = 0;
20877   int ret;
20878
20879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20880     {
20881       if (unformat (input, "l2"))
20882         is_l2 = 1;
20883       else
20884         break;
20885     }
20886
20887   M (SW_INTERFACE_SPAN_DUMP, mp);
20888   mp->is_l2 = is_l2;
20889   S (mp);
20890
20891   /* Use a control ping for synchronization */
20892   MPING (CONTROL_PING, mp_ping);
20893   S (mp_ping);
20894
20895   W (ret);
20896   return ret;
20897 }
20898
20899 int
20900 api_pg_create_interface (vat_main_t * vam)
20901 {
20902   unformat_input_t *input = vam->input;
20903   vl_api_pg_create_interface_t *mp;
20904
20905   u32 if_id = ~0;
20906   int ret;
20907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20908     {
20909       if (unformat (input, "if_id %d", &if_id))
20910         ;
20911       else
20912         break;
20913     }
20914   if (if_id == ~0)
20915     {
20916       errmsg ("missing pg interface index");
20917       return -99;
20918     }
20919
20920   /* Construct the API message */
20921   M (PG_CREATE_INTERFACE, mp);
20922   mp->context = 0;
20923   mp->interface_id = ntohl (if_id);
20924
20925   S (mp);
20926   W (ret);
20927   return ret;
20928 }
20929
20930 int
20931 api_pg_capture (vat_main_t * vam)
20932 {
20933   unformat_input_t *input = vam->input;
20934   vl_api_pg_capture_t *mp;
20935
20936   u32 if_id = ~0;
20937   u8 enable = 1;
20938   u32 count = 1;
20939   u8 pcap_file_set = 0;
20940   u8 *pcap_file = 0;
20941   int ret;
20942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20943     {
20944       if (unformat (input, "if_id %d", &if_id))
20945         ;
20946       else if (unformat (input, "pcap %s", &pcap_file))
20947         pcap_file_set = 1;
20948       else if (unformat (input, "count %d", &count))
20949         ;
20950       else if (unformat (input, "disable"))
20951         enable = 0;
20952       else
20953         break;
20954     }
20955   if (if_id == ~0)
20956     {
20957       errmsg ("missing pg interface index");
20958       return -99;
20959     }
20960   if (pcap_file_set > 0)
20961     {
20962       if (vec_len (pcap_file) > 255)
20963         {
20964           errmsg ("pcap file name is too long");
20965           return -99;
20966         }
20967     }
20968
20969   u32 name_len = vec_len (pcap_file);
20970   /* Construct the API message */
20971   M (PG_CAPTURE, mp);
20972   mp->context = 0;
20973   mp->interface_id = ntohl (if_id);
20974   mp->is_enabled = enable;
20975   mp->count = ntohl (count);
20976   mp->pcap_name_length = ntohl (name_len);
20977   if (pcap_file_set != 0)
20978     {
20979       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20980     }
20981   vec_free (pcap_file);
20982
20983   S (mp);
20984   W (ret);
20985   return ret;
20986 }
20987
20988 int
20989 api_pg_enable_disable (vat_main_t * vam)
20990 {
20991   unformat_input_t *input = vam->input;
20992   vl_api_pg_enable_disable_t *mp;
20993
20994   u8 enable = 1;
20995   u8 stream_name_set = 0;
20996   u8 *stream_name = 0;
20997   int ret;
20998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20999     {
21000       if (unformat (input, "stream %s", &stream_name))
21001         stream_name_set = 1;
21002       else if (unformat (input, "disable"))
21003         enable = 0;
21004       else
21005         break;
21006     }
21007
21008   if (stream_name_set > 0)
21009     {
21010       if (vec_len (stream_name) > 255)
21011         {
21012           errmsg ("stream name too long");
21013           return -99;
21014         }
21015     }
21016
21017   u32 name_len = vec_len (stream_name);
21018   /* Construct the API message */
21019   M (PG_ENABLE_DISABLE, mp);
21020   mp->context = 0;
21021   mp->is_enabled = enable;
21022   if (stream_name_set != 0)
21023     {
21024       mp->stream_name_length = ntohl (name_len);
21025       clib_memcpy (mp->stream_name, stream_name, name_len);
21026     }
21027   vec_free (stream_name);
21028
21029   S (mp);
21030   W (ret);
21031   return ret;
21032 }
21033
21034 int
21035 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21036 {
21037   unformat_input_t *input = vam->input;
21038   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21039
21040   u16 *low_ports = 0;
21041   u16 *high_ports = 0;
21042   u16 this_low;
21043   u16 this_hi;
21044   ip4_address_t ip4_addr;
21045   ip6_address_t ip6_addr;
21046   u32 length;
21047   u32 tmp, tmp2;
21048   u8 prefix_set = 0;
21049   u32 vrf_id = ~0;
21050   u8 is_add = 1;
21051   u8 is_ipv6 = 0;
21052   int ret;
21053
21054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21055     {
21056       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21057         {
21058           prefix_set = 1;
21059         }
21060       else
21061         if (unformat
21062             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21063         {
21064           prefix_set = 1;
21065           is_ipv6 = 1;
21066         }
21067       else if (unformat (input, "vrf %d", &vrf_id))
21068         ;
21069       else if (unformat (input, "del"))
21070         is_add = 0;
21071       else if (unformat (input, "port %d", &tmp))
21072         {
21073           if (tmp == 0 || tmp > 65535)
21074             {
21075               errmsg ("port %d out of range", tmp);
21076               return -99;
21077             }
21078           this_low = tmp;
21079           this_hi = this_low + 1;
21080           vec_add1 (low_ports, this_low);
21081           vec_add1 (high_ports, this_hi);
21082         }
21083       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21084         {
21085           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21086             {
21087               errmsg ("incorrect range parameters");
21088               return -99;
21089             }
21090           this_low = tmp;
21091           /* Note: in debug CLI +1 is added to high before
21092              passing to real fn that does "the work"
21093              (ip_source_and_port_range_check_add_del).
21094              This fn is a wrapper around the binary API fn a
21095              control plane will call, which expects this increment
21096              to have occurred. Hence letting the binary API control
21097              plane fn do the increment for consistency between VAT
21098              and other control planes.
21099            */
21100           this_hi = tmp2;
21101           vec_add1 (low_ports, this_low);
21102           vec_add1 (high_ports, this_hi);
21103         }
21104       else
21105         break;
21106     }
21107
21108   if (prefix_set == 0)
21109     {
21110       errmsg ("<address>/<mask> not specified");
21111       return -99;
21112     }
21113
21114   if (vrf_id == ~0)
21115     {
21116       errmsg ("VRF ID required, not specified");
21117       return -99;
21118     }
21119
21120   if (vrf_id == 0)
21121     {
21122       errmsg
21123         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21124       return -99;
21125     }
21126
21127   if (vec_len (low_ports) == 0)
21128     {
21129       errmsg ("At least one port or port range required");
21130       return -99;
21131     }
21132
21133   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21134
21135   mp->is_add = is_add;
21136
21137   if (is_ipv6)
21138     {
21139       mp->is_ipv6 = 1;
21140       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21141     }
21142   else
21143     {
21144       mp->is_ipv6 = 0;
21145       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21146     }
21147
21148   mp->mask_length = length;
21149   mp->number_of_ranges = vec_len (low_ports);
21150
21151   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21152   vec_free (low_ports);
21153
21154   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21155   vec_free (high_ports);
21156
21157   mp->vrf_id = ntohl (vrf_id);
21158
21159   S (mp);
21160   W (ret);
21161   return ret;
21162 }
21163
21164 int
21165 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21166 {
21167   unformat_input_t *input = vam->input;
21168   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21169   u32 sw_if_index = ~0;
21170   int vrf_set = 0;
21171   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21172   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21173   u8 is_add = 1;
21174   int ret;
21175
21176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21177     {
21178       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21179         ;
21180       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21181         ;
21182       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21183         vrf_set = 1;
21184       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21185         vrf_set = 1;
21186       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21187         vrf_set = 1;
21188       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21189         vrf_set = 1;
21190       else if (unformat (input, "del"))
21191         is_add = 0;
21192       else
21193         break;
21194     }
21195
21196   if (sw_if_index == ~0)
21197     {
21198       errmsg ("Interface required but not specified");
21199       return -99;
21200     }
21201
21202   if (vrf_set == 0)
21203     {
21204       errmsg ("VRF ID required but not specified");
21205       return -99;
21206     }
21207
21208   if (tcp_out_vrf_id == 0
21209       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21210     {
21211       errmsg
21212         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21213       return -99;
21214     }
21215
21216   /* Construct the API message */
21217   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21218
21219   mp->sw_if_index = ntohl (sw_if_index);
21220   mp->is_add = is_add;
21221   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21222   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21223   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21224   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21225
21226   /* send it... */
21227   S (mp);
21228
21229   /* Wait for a reply... */
21230   W (ret);
21231   return ret;
21232 }
21233
21234 static int
21235 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21236 {
21237   unformat_input_t *i = vam->input;
21238   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21239   u32 local_sa_id = 0;
21240   u32 remote_sa_id = 0;
21241   ip4_address_t src_address;
21242   ip4_address_t dst_address;
21243   u8 is_add = 1;
21244   int ret;
21245
21246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21247     {
21248       if (unformat (i, "local_sa %d", &local_sa_id))
21249         ;
21250       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21251         ;
21252       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21253         ;
21254       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21255         ;
21256       else if (unformat (i, "del"))
21257         is_add = 0;
21258       else
21259         {
21260           clib_warning ("parse error '%U'", format_unformat_error, i);
21261           return -99;
21262         }
21263     }
21264
21265   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21266
21267   mp->local_sa_id = ntohl (local_sa_id);
21268   mp->remote_sa_id = ntohl (remote_sa_id);
21269   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21270   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21271   mp->is_add = is_add;
21272
21273   S (mp);
21274   W (ret);
21275   return ret;
21276 }
21277
21278 static int
21279 api_punt (vat_main_t * vam)
21280 {
21281   unformat_input_t *i = vam->input;
21282   vl_api_punt_t *mp;
21283   u32 ipv = ~0;
21284   u32 protocol = ~0;
21285   u32 port = ~0;
21286   int is_add = 1;
21287   int ret;
21288
21289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21290     {
21291       if (unformat (i, "ip %d", &ipv))
21292         ;
21293       else if (unformat (i, "protocol %d", &protocol))
21294         ;
21295       else if (unformat (i, "port %d", &port))
21296         ;
21297       else if (unformat (i, "del"))
21298         is_add = 0;
21299       else
21300         {
21301           clib_warning ("parse error '%U'", format_unformat_error, i);
21302           return -99;
21303         }
21304     }
21305
21306   M (PUNT, mp);
21307
21308   mp->is_add = (u8) is_add;
21309   mp->ipv = (u8) ipv;
21310   mp->l4_protocol = (u8) protocol;
21311   mp->l4_port = htons ((u16) port);
21312
21313   S (mp);
21314   W (ret);
21315   return ret;
21316 }
21317
21318 static void vl_api_ipsec_gre_tunnel_details_t_handler
21319   (vl_api_ipsec_gre_tunnel_details_t * mp)
21320 {
21321   vat_main_t *vam = &vat_main;
21322
21323   print (vam->ofp, "%11d%15U%15U%14d%14d",
21324          ntohl (mp->sw_if_index),
21325          format_ip4_address, &mp->src_address,
21326          format_ip4_address, &mp->dst_address,
21327          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21328 }
21329
21330 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21331   (vl_api_ipsec_gre_tunnel_details_t * mp)
21332 {
21333   vat_main_t *vam = &vat_main;
21334   vat_json_node_t *node = NULL;
21335   struct in_addr ip4;
21336
21337   if (VAT_JSON_ARRAY != vam->json_tree.type)
21338     {
21339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21340       vat_json_init_array (&vam->json_tree);
21341     }
21342   node = vat_json_array_add (&vam->json_tree);
21343
21344   vat_json_init_object (node);
21345   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21346   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21347   vat_json_object_add_ip4 (node, "src_address", ip4);
21348   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21349   vat_json_object_add_ip4 (node, "dst_address", ip4);
21350   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21351   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21352 }
21353
21354 static int
21355 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21356 {
21357   unformat_input_t *i = vam->input;
21358   vl_api_ipsec_gre_tunnel_dump_t *mp;
21359   vl_api_control_ping_t *mp_ping;
21360   u32 sw_if_index;
21361   u8 sw_if_index_set = 0;
21362   int ret;
21363
21364   /* Parse args required to build the message */
21365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21366     {
21367       if (unformat (i, "sw_if_index %d", &sw_if_index))
21368         sw_if_index_set = 1;
21369       else
21370         break;
21371     }
21372
21373   if (sw_if_index_set == 0)
21374     {
21375       sw_if_index = ~0;
21376     }
21377
21378   if (!vam->json_output)
21379     {
21380       print (vam->ofp, "%11s%15s%15s%14s%14s",
21381              "sw_if_index", "src_address", "dst_address",
21382              "local_sa_id", "remote_sa_id");
21383     }
21384
21385   /* Get list of gre-tunnel interfaces */
21386   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21387
21388   mp->sw_if_index = htonl (sw_if_index);
21389
21390   S (mp);
21391
21392   /* Use a control ping for synchronization */
21393   MPING (CONTROL_PING, mp_ping);
21394   S (mp_ping);
21395
21396   W (ret);
21397   return ret;
21398 }
21399
21400 static int
21401 api_delete_subif (vat_main_t * vam)
21402 {
21403   unformat_input_t *i = vam->input;
21404   vl_api_delete_subif_t *mp;
21405   u32 sw_if_index = ~0;
21406   int ret;
21407
21408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21409     {
21410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21411         ;
21412       if (unformat (i, "sw_if_index %d", &sw_if_index))
21413         ;
21414       else
21415         break;
21416     }
21417
21418   if (sw_if_index == ~0)
21419     {
21420       errmsg ("missing sw_if_index");
21421       return -99;
21422     }
21423
21424   /* Construct the API message */
21425   M (DELETE_SUBIF, mp);
21426   mp->sw_if_index = ntohl (sw_if_index);
21427
21428   S (mp);
21429   W (ret);
21430   return ret;
21431 }
21432
21433 #define foreach_pbb_vtr_op      \
21434 _("disable",  L2_VTR_DISABLED)  \
21435 _("pop",  L2_VTR_POP_2)         \
21436 _("push",  L2_VTR_PUSH_2)
21437
21438 static int
21439 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21440 {
21441   unformat_input_t *i = vam->input;
21442   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21443   u32 sw_if_index = ~0, vtr_op = ~0;
21444   u16 outer_tag = ~0;
21445   u8 dmac[6], smac[6];
21446   u8 dmac_set = 0, smac_set = 0;
21447   u16 vlanid = 0;
21448   u32 sid = ~0;
21449   u32 tmp;
21450   int ret;
21451
21452   /* Shut up coverity */
21453   memset (dmac, 0, sizeof (dmac));
21454   memset (smac, 0, sizeof (smac));
21455
21456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21457     {
21458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21459         ;
21460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21461         ;
21462       else if (unformat (i, "vtr_op %d", &vtr_op))
21463         ;
21464 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21465       foreach_pbb_vtr_op
21466 #undef _
21467         else if (unformat (i, "translate_pbb_stag"))
21468         {
21469           if (unformat (i, "%d", &tmp))
21470             {
21471               vtr_op = L2_VTR_TRANSLATE_2_1;
21472               outer_tag = tmp;
21473             }
21474           else
21475             {
21476               errmsg
21477                 ("translate_pbb_stag operation requires outer tag definition");
21478               return -99;
21479             }
21480         }
21481       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21482         dmac_set++;
21483       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21484         smac_set++;
21485       else if (unformat (i, "sid %d", &sid))
21486         ;
21487       else if (unformat (i, "vlanid %d", &tmp))
21488         vlanid = tmp;
21489       else
21490         {
21491           clib_warning ("parse error '%U'", format_unformat_error, i);
21492           return -99;
21493         }
21494     }
21495
21496   if ((sw_if_index == ~0) || (vtr_op == ~0))
21497     {
21498       errmsg ("missing sw_if_index or vtr operation");
21499       return -99;
21500     }
21501   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21502       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21503     {
21504       errmsg
21505         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21506       return -99;
21507     }
21508
21509   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21510   mp->sw_if_index = ntohl (sw_if_index);
21511   mp->vtr_op = ntohl (vtr_op);
21512   mp->outer_tag = ntohs (outer_tag);
21513   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21514   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21515   mp->b_vlanid = ntohs (vlanid);
21516   mp->i_sid = ntohl (sid);
21517
21518   S (mp);
21519   W (ret);
21520   return ret;
21521 }
21522
21523 static int
21524 api_flow_classify_set_interface (vat_main_t * vam)
21525 {
21526   unformat_input_t *i = vam->input;
21527   vl_api_flow_classify_set_interface_t *mp;
21528   u32 sw_if_index;
21529   int sw_if_index_set;
21530   u32 ip4_table_index = ~0;
21531   u32 ip6_table_index = ~0;
21532   u8 is_add = 1;
21533   int ret;
21534
21535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21536     {
21537       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21538         sw_if_index_set = 1;
21539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21540         sw_if_index_set = 1;
21541       else if (unformat (i, "del"))
21542         is_add = 0;
21543       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21544         ;
21545       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21546         ;
21547       else
21548         {
21549           clib_warning ("parse error '%U'", format_unformat_error, i);
21550           return -99;
21551         }
21552     }
21553
21554   if (sw_if_index_set == 0)
21555     {
21556       errmsg ("missing interface name or sw_if_index");
21557       return -99;
21558     }
21559
21560   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21561
21562   mp->sw_if_index = ntohl (sw_if_index);
21563   mp->ip4_table_index = ntohl (ip4_table_index);
21564   mp->ip6_table_index = ntohl (ip6_table_index);
21565   mp->is_add = is_add;
21566
21567   S (mp);
21568   W (ret);
21569   return ret;
21570 }
21571
21572 static int
21573 api_flow_classify_dump (vat_main_t * vam)
21574 {
21575   unformat_input_t *i = vam->input;
21576   vl_api_flow_classify_dump_t *mp;
21577   vl_api_control_ping_t *mp_ping;
21578   u8 type = FLOW_CLASSIFY_N_TABLES;
21579   int ret;
21580
21581   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21582     ;
21583   else
21584     {
21585       errmsg ("classify table type must be specified");
21586       return -99;
21587     }
21588
21589   if (!vam->json_output)
21590     {
21591       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21592     }
21593
21594   M (FLOW_CLASSIFY_DUMP, mp);
21595   mp->type = type;
21596   /* send it... */
21597   S (mp);
21598
21599   /* Use a control ping for synchronization */
21600   MPING (CONTROL_PING, mp_ping);
21601   S (mp_ping);
21602
21603   /* Wait for a reply... */
21604   W (ret);
21605   return ret;
21606 }
21607
21608 static int
21609 api_feature_enable_disable (vat_main_t * vam)
21610 {
21611   unformat_input_t *i = vam->input;
21612   vl_api_feature_enable_disable_t *mp;
21613   u8 *arc_name = 0;
21614   u8 *feature_name = 0;
21615   u32 sw_if_index = ~0;
21616   u8 enable = 1;
21617   int ret;
21618
21619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21620     {
21621       if (unformat (i, "arc_name %s", &arc_name))
21622         ;
21623       else if (unformat (i, "feature_name %s", &feature_name))
21624         ;
21625       else
21626         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21627         ;
21628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21629         ;
21630       else if (unformat (i, "disable"))
21631         enable = 0;
21632       else
21633         break;
21634     }
21635
21636   if (arc_name == 0)
21637     {
21638       errmsg ("missing arc name");
21639       return -99;
21640     }
21641   if (vec_len (arc_name) > 63)
21642     {
21643       errmsg ("arc name too long");
21644     }
21645
21646   if (feature_name == 0)
21647     {
21648       errmsg ("missing feature name");
21649       return -99;
21650     }
21651   if (vec_len (feature_name) > 63)
21652     {
21653       errmsg ("feature name too long");
21654     }
21655
21656   if (sw_if_index == ~0)
21657     {
21658       errmsg ("missing interface name or sw_if_index");
21659       return -99;
21660     }
21661
21662   /* Construct the API message */
21663   M (FEATURE_ENABLE_DISABLE, mp);
21664   mp->sw_if_index = ntohl (sw_if_index);
21665   mp->enable = enable;
21666   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21667   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21668   vec_free (arc_name);
21669   vec_free (feature_name);
21670
21671   S (mp);
21672   W (ret);
21673   return ret;
21674 }
21675
21676 static int
21677 api_sw_interface_tag_add_del (vat_main_t * vam)
21678 {
21679   unformat_input_t *i = vam->input;
21680   vl_api_sw_interface_tag_add_del_t *mp;
21681   u32 sw_if_index = ~0;
21682   u8 *tag = 0;
21683   u8 enable = 1;
21684   int ret;
21685
21686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21687     {
21688       if (unformat (i, "tag %s", &tag))
21689         ;
21690       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21691         ;
21692       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21693         ;
21694       else if (unformat (i, "del"))
21695         enable = 0;
21696       else
21697         break;
21698     }
21699
21700   if (sw_if_index == ~0)
21701     {
21702       errmsg ("missing interface name or sw_if_index");
21703       return -99;
21704     }
21705
21706   if (enable && (tag == 0))
21707     {
21708       errmsg ("no tag specified");
21709       return -99;
21710     }
21711
21712   /* Construct the API message */
21713   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21714   mp->sw_if_index = ntohl (sw_if_index);
21715   mp->is_add = enable;
21716   if (enable)
21717     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21718   vec_free (tag);
21719
21720   S (mp);
21721   W (ret);
21722   return ret;
21723 }
21724
21725 static void vl_api_l2_xconnect_details_t_handler
21726   (vl_api_l2_xconnect_details_t * mp)
21727 {
21728   vat_main_t *vam = &vat_main;
21729
21730   print (vam->ofp, "%15d%15d",
21731          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21732 }
21733
21734 static void vl_api_l2_xconnect_details_t_handler_json
21735   (vl_api_l2_xconnect_details_t * mp)
21736 {
21737   vat_main_t *vam = &vat_main;
21738   vat_json_node_t *node = NULL;
21739
21740   if (VAT_JSON_ARRAY != vam->json_tree.type)
21741     {
21742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21743       vat_json_init_array (&vam->json_tree);
21744     }
21745   node = vat_json_array_add (&vam->json_tree);
21746
21747   vat_json_init_object (node);
21748   vat_json_object_add_uint (node, "rx_sw_if_index",
21749                             ntohl (mp->rx_sw_if_index));
21750   vat_json_object_add_uint (node, "tx_sw_if_index",
21751                             ntohl (mp->tx_sw_if_index));
21752 }
21753
21754 static int
21755 api_l2_xconnect_dump (vat_main_t * vam)
21756 {
21757   vl_api_l2_xconnect_dump_t *mp;
21758   vl_api_control_ping_t *mp_ping;
21759   int ret;
21760
21761   if (!vam->json_output)
21762     {
21763       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21764     }
21765
21766   M (L2_XCONNECT_DUMP, mp);
21767
21768   S (mp);
21769
21770   /* Use a control ping for synchronization */
21771   MPING (CONTROL_PING, mp_ping);
21772   S (mp_ping);
21773
21774   W (ret);
21775   return ret;
21776 }
21777
21778 static int
21779 api_hw_interface_set_mtu (vat_main_t * vam)
21780 {
21781   unformat_input_t *i = vam->input;
21782   vl_api_hw_interface_set_mtu_t *mp;
21783   u32 sw_if_index = ~0;
21784   u32 mtu = 0;
21785   int ret;
21786
21787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21788     {
21789       if (unformat (i, "mtu %d", &mtu))
21790         ;
21791       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21792         ;
21793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21794         ;
21795       else
21796         break;
21797     }
21798
21799   if (sw_if_index == ~0)
21800     {
21801       errmsg ("missing interface name or sw_if_index");
21802       return -99;
21803     }
21804
21805   if (mtu == 0)
21806     {
21807       errmsg ("no mtu specified");
21808       return -99;
21809     }
21810
21811   /* Construct the API message */
21812   M (HW_INTERFACE_SET_MTU, mp);
21813   mp->sw_if_index = ntohl (sw_if_index);
21814   mp->mtu = ntohs ((u16) mtu);
21815
21816   S (mp);
21817   W (ret);
21818   return ret;
21819 }
21820
21821 static int
21822 api_p2p_ethernet_add (vat_main_t * vam)
21823 {
21824   unformat_input_t *i = vam->input;
21825   vl_api_p2p_ethernet_add_t *mp;
21826   u32 parent_if_index = ~0;
21827   u32 sub_id = ~0;
21828   u8 remote_mac[6];
21829   u8 mac_set = 0;
21830   int ret;
21831
21832   memset (remote_mac, 0, sizeof (remote_mac));
21833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21834     {
21835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21836         ;
21837       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21838         ;
21839       else
21840         if (unformat
21841             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21842         mac_set++;
21843       else if (unformat (i, "sub_id %d", &sub_id))
21844         ;
21845       else
21846         {
21847           clib_warning ("parse error '%U'", format_unformat_error, i);
21848           return -99;
21849         }
21850     }
21851
21852   if (parent_if_index == ~0)
21853     {
21854       errmsg ("missing interface name or sw_if_index");
21855       return -99;
21856     }
21857   if (mac_set == 0)
21858     {
21859       errmsg ("missing remote mac address");
21860       return -99;
21861     }
21862   if (sub_id == ~0)
21863     {
21864       errmsg ("missing sub-interface id");
21865       return -99;
21866     }
21867
21868   M (P2P_ETHERNET_ADD, mp);
21869   mp->parent_if_index = ntohl (parent_if_index);
21870   mp->subif_id = ntohl (sub_id);
21871   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21872
21873   S (mp);
21874   W (ret);
21875   return ret;
21876 }
21877
21878 static int
21879 api_p2p_ethernet_del (vat_main_t * vam)
21880 {
21881   unformat_input_t *i = vam->input;
21882   vl_api_p2p_ethernet_del_t *mp;
21883   u32 parent_if_index = ~0;
21884   u8 remote_mac[6];
21885   u8 mac_set = 0;
21886   int ret;
21887
21888   memset (remote_mac, 0, sizeof (remote_mac));
21889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21890     {
21891       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21892         ;
21893       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21894         ;
21895       else
21896         if (unformat
21897             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21898         mac_set++;
21899       else
21900         {
21901           clib_warning ("parse error '%U'", format_unformat_error, i);
21902           return -99;
21903         }
21904     }
21905
21906   if (parent_if_index == ~0)
21907     {
21908       errmsg ("missing interface name or sw_if_index");
21909       return -99;
21910     }
21911   if (mac_set == 0)
21912     {
21913       errmsg ("missing remote mac address");
21914       return -99;
21915     }
21916
21917   M (P2P_ETHERNET_DEL, mp);
21918   mp->parent_if_index = ntohl (parent_if_index);
21919   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21920
21921   S (mp);
21922   W (ret);
21923   return ret;
21924 }
21925
21926 static int
21927 api_lldp_config (vat_main_t * vam)
21928 {
21929   unformat_input_t *i = vam->input;
21930   vl_api_lldp_config_t *mp;
21931   int tx_hold = 0;
21932   int tx_interval = 0;
21933   u8 *sys_name = NULL;
21934   int ret;
21935
21936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21937     {
21938       if (unformat (i, "system-name %s", &sys_name))
21939         ;
21940       else if (unformat (i, "tx-hold %d", &tx_hold))
21941         ;
21942       else if (unformat (i, "tx-interval %d", &tx_interval))
21943         ;
21944       else
21945         {
21946           clib_warning ("parse error '%U'", format_unformat_error, i);
21947           return -99;
21948         }
21949     }
21950
21951   vec_add1 (sys_name, 0);
21952
21953   M (LLDP_CONFIG, mp);
21954   mp->tx_hold = htonl (tx_hold);
21955   mp->tx_interval = htonl (tx_interval);
21956   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21957   vec_free (sys_name);
21958
21959   S (mp);
21960   W (ret);
21961   return ret;
21962 }
21963
21964 static int
21965 api_sw_interface_set_lldp (vat_main_t * vam)
21966 {
21967   unformat_input_t *i = vam->input;
21968   vl_api_sw_interface_set_lldp_t *mp;
21969   u32 sw_if_index = ~0;
21970   u32 enable = 1;
21971   u8 *port_desc = NULL, *mgmt_oid = NULL;
21972   ip4_address_t ip4_addr;
21973   ip6_address_t ip6_addr;
21974   int ret;
21975
21976   memset (&ip4_addr, 0, sizeof (ip4_addr));
21977   memset (&ip6_addr, 0, sizeof (ip6_addr));
21978
21979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21980     {
21981       if (unformat (i, "disable"))
21982         enable = 0;
21983       else
21984         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21985         ;
21986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21987         ;
21988       else if (unformat (i, "port-desc %s", &port_desc))
21989         ;
21990       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21991         ;
21992       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21993         ;
21994       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21995         ;
21996       else
21997         break;
21998     }
21999
22000   if (sw_if_index == ~0)
22001     {
22002       errmsg ("missing interface name or sw_if_index");
22003       return -99;
22004     }
22005
22006   /* Construct the API message */
22007   vec_add1 (port_desc, 0);
22008   vec_add1 (mgmt_oid, 0);
22009   M (SW_INTERFACE_SET_LLDP, mp);
22010   mp->sw_if_index = ntohl (sw_if_index);
22011   mp->enable = enable;
22012   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22013   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22014   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22015   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22016   vec_free (port_desc);
22017   vec_free (mgmt_oid);
22018
22019   S (mp);
22020   W (ret);
22021   return ret;
22022 }
22023
22024 static int
22025 api_tcp_configure_src_addresses (vat_main_t * vam)
22026 {
22027   vl_api_tcp_configure_src_addresses_t *mp;
22028   unformat_input_t *i = vam->input;
22029   ip4_address_t v4first, v4last;
22030   ip6_address_t v6first, v6last;
22031   u8 range_set = 0;
22032   u32 vrf_id = 0;
22033   int ret;
22034
22035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22036     {
22037       if (unformat (i, "%U - %U",
22038                     unformat_ip4_address, &v4first,
22039                     unformat_ip4_address, &v4last))
22040         {
22041           if (range_set)
22042             {
22043               errmsg ("one range per message (range already set)");
22044               return -99;
22045             }
22046           range_set = 1;
22047         }
22048       else if (unformat (i, "%U - %U",
22049                          unformat_ip6_address, &v6first,
22050                          unformat_ip6_address, &v6last))
22051         {
22052           if (range_set)
22053             {
22054               errmsg ("one range per message (range already set)");
22055               return -99;
22056             }
22057           range_set = 2;
22058         }
22059       else if (unformat (i, "vrf %d", &vrf_id))
22060         ;
22061       else
22062         break;
22063     }
22064
22065   if (range_set == 0)
22066     {
22067       errmsg ("address range not set");
22068       return -99;
22069     }
22070
22071   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22072   mp->vrf_id = ntohl (vrf_id);
22073   /* ipv6? */
22074   if (range_set == 2)
22075     {
22076       mp->is_ipv6 = 1;
22077       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22078       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22079     }
22080   else
22081     {
22082       mp->is_ipv6 = 0;
22083       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22084       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22085     }
22086   S (mp);
22087   W (ret);
22088   return ret;
22089 }
22090
22091 static void vl_api_app_namespace_add_del_reply_t_handler
22092   (vl_api_app_namespace_add_del_reply_t * mp)
22093 {
22094   vat_main_t *vam = &vat_main;
22095   i32 retval = ntohl (mp->retval);
22096   if (vam->async_mode)
22097     {
22098       vam->async_errors += (retval < 0);
22099     }
22100   else
22101     {
22102       vam->retval = retval;
22103       if (retval == 0)
22104         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22105       vam->result_ready = 1;
22106     }
22107 }
22108
22109 static void vl_api_app_namespace_add_del_reply_t_handler_json
22110   (vl_api_app_namespace_add_del_reply_t * mp)
22111 {
22112   vat_main_t *vam = &vat_main;
22113   vat_json_node_t node;
22114
22115   vat_json_init_object (&node);
22116   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22117   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22118
22119   vat_json_print (vam->ofp, &node);
22120   vat_json_free (&node);
22121
22122   vam->retval = ntohl (mp->retval);
22123   vam->result_ready = 1;
22124 }
22125
22126 static int
22127 api_app_namespace_add_del (vat_main_t * vam)
22128 {
22129   vl_api_app_namespace_add_del_t *mp;
22130   unformat_input_t *i = vam->input;
22131   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22132   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22133   u64 secret;
22134   int ret;
22135
22136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22137     {
22138       if (unformat (i, "id %_%v%_", &ns_id))
22139         ;
22140       else if (unformat (i, "secret %lu", &secret))
22141         secret_set = 1;
22142       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22143         sw_if_index_set = 1;
22144       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22145         ;
22146       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22147         ;
22148       else
22149         break;
22150     }
22151   if (!ns_id || !secret_set || !sw_if_index_set)
22152     {
22153       errmsg ("namespace id, secret and sw_if_index must be set");
22154       return -99;
22155     }
22156   if (vec_len (ns_id) > 64)
22157     {
22158       errmsg ("namespace id too long");
22159       return -99;
22160     }
22161   M (APP_NAMESPACE_ADD_DEL, mp);
22162
22163   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22164   mp->namespace_id_len = vec_len (ns_id);
22165   mp->secret = clib_host_to_net_u64 (secret);
22166   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22167   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22168   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22169   vec_free (ns_id);
22170   S (mp);
22171   W (ret);
22172   return ret;
22173 }
22174
22175 static int
22176 api_sock_init_shm (vat_main_t * vam)
22177 {
22178 #if VPP_API_TEST_BUILTIN == 0
22179   unformat_input_t *i = vam->input;
22180   vl_api_shm_elem_config_t *config = 0;
22181   u64 size = 64 << 20;
22182   int rv;
22183
22184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22185     {
22186       if (unformat (i, "size %U", unformat_memory_size, &size))
22187         ;
22188       else
22189         break;
22190     }
22191
22192   /*
22193    * Canned custom ring allocator config.
22194    * Should probably parse all of this
22195    */
22196   vec_validate (config, 6);
22197   config[0].type = VL_API_VLIB_RING;
22198   config[0].size = 256;
22199   config[0].count = 32;
22200
22201   config[1].type = VL_API_VLIB_RING;
22202   config[1].size = 1024;
22203   config[1].count = 16;
22204
22205   config[2].type = VL_API_VLIB_RING;
22206   config[2].size = 4096;
22207   config[2].count = 2;
22208
22209   config[3].type = VL_API_CLIENT_RING;
22210   config[3].size = 256;
22211   config[3].count = 32;
22212
22213   config[4].type = VL_API_CLIENT_RING;
22214   config[4].size = 1024;
22215   config[4].count = 16;
22216
22217   config[5].type = VL_API_CLIENT_RING;
22218   config[5].size = 4096;
22219   config[5].count = 2;
22220
22221   config[6].type = VL_API_QUEUE;
22222   config[6].count = 128;
22223   config[6].size = sizeof (uword);
22224
22225   rv = vl_socket_client_init_shm (config);
22226   if (!rv)
22227     vam->client_index_invalid = 1;
22228   return rv;
22229 #else
22230   return -99;
22231 #endif
22232 }
22233
22234 static int
22235 api_dns_enable_disable (vat_main_t * vam)
22236 {
22237   unformat_input_t *line_input = vam->input;
22238   vl_api_dns_enable_disable_t *mp;
22239   u8 enable_disable = 1;
22240   int ret;
22241
22242   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22243     {
22244       if (unformat (line_input, "disable"))
22245         enable_disable = 0;
22246       if (unformat (line_input, "enable"))
22247         enable_disable = 1;
22248       else
22249         break;
22250     }
22251
22252   /* Construct the API message */
22253   M (DNS_ENABLE_DISABLE, mp);
22254   mp->enable = enable_disable;
22255
22256   /* send it... */
22257   S (mp);
22258   /* Wait for the reply */
22259   W (ret);
22260   return ret;
22261 }
22262
22263 static int
22264 api_dns_resolve_name (vat_main_t * vam)
22265 {
22266   unformat_input_t *line_input = vam->input;
22267   vl_api_dns_resolve_name_t *mp;
22268   u8 *name = 0;
22269   int ret;
22270
22271   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22272     {
22273       if (unformat (line_input, "%s", &name))
22274         ;
22275       else
22276         break;
22277     }
22278
22279   if (vec_len (name) > 127)
22280     {
22281       errmsg ("name too long");
22282       return -99;
22283     }
22284
22285   /* Construct the API message */
22286   M (DNS_RESOLVE_NAME, mp);
22287   memcpy (mp->name, name, vec_len (name));
22288   vec_free (name);
22289
22290   /* send it... */
22291   S (mp);
22292   /* Wait for the reply */
22293   W (ret);
22294   return ret;
22295 }
22296
22297 static int
22298 api_dns_resolve_ip (vat_main_t * vam)
22299 {
22300   unformat_input_t *line_input = vam->input;
22301   vl_api_dns_resolve_ip_t *mp;
22302   int is_ip6 = -1;
22303   ip4_address_t addr4;
22304   ip6_address_t addr6;
22305   int ret;
22306
22307   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22308     {
22309       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22310         is_ip6 = 1;
22311       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22312         is_ip6 = 0;
22313       else
22314         break;
22315     }
22316
22317   if (is_ip6 == -1)
22318     {
22319       errmsg ("missing address");
22320       return -99;
22321     }
22322
22323   /* Construct the API message */
22324   M (DNS_RESOLVE_IP, mp);
22325   mp->is_ip6 = is_ip6;
22326   if (is_ip6)
22327     memcpy (mp->address, &addr6, sizeof (addr6));
22328   else
22329     memcpy (mp->address, &addr4, sizeof (addr4));
22330
22331   /* send it... */
22332   S (mp);
22333   /* Wait for the reply */
22334   W (ret);
22335   return ret;
22336 }
22337
22338 static int
22339 api_dns_name_server_add_del (vat_main_t * vam)
22340 {
22341   unformat_input_t *i = vam->input;
22342   vl_api_dns_name_server_add_del_t *mp;
22343   u8 is_add = 1;
22344   ip6_address_t ip6_server;
22345   ip4_address_t ip4_server;
22346   int ip6_set = 0;
22347   int ip4_set = 0;
22348   int ret = 0;
22349
22350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22351     {
22352       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22353         ip6_set = 1;
22354       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22355         ip4_set = 1;
22356       else if (unformat (i, "del"))
22357         is_add = 0;
22358       else
22359         {
22360           clib_warning ("parse error '%U'", format_unformat_error, i);
22361           return -99;
22362         }
22363     }
22364
22365   if (ip4_set && ip6_set)
22366     {
22367       errmsg ("Only one server address allowed per message");
22368       return -99;
22369     }
22370   if ((ip4_set + ip6_set) == 0)
22371     {
22372       errmsg ("Server address required");
22373       return -99;
22374     }
22375
22376   /* Construct the API message */
22377   M (DNS_NAME_SERVER_ADD_DEL, mp);
22378
22379   if (ip6_set)
22380     {
22381       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22382       mp->is_ip6 = 1;
22383     }
22384   else
22385     {
22386       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22387       mp->is_ip6 = 0;
22388     }
22389
22390   mp->is_add = is_add;
22391
22392   /* send it... */
22393   S (mp);
22394
22395   /* Wait for a reply, return good/bad news  */
22396   W (ret);
22397   return ret;
22398 }
22399
22400 static void
22401 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22402 {
22403   vat_main_t *vam = &vat_main;
22404
22405   if (mp->is_ip4)
22406     {
22407       print (vam->ofp,
22408              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22409              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22410              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22411              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22412              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22413              clib_net_to_host_u32 (mp->action_index), mp->tag);
22414     }
22415   else
22416     {
22417       print (vam->ofp,
22418              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22419              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22420              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22421              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22422              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22423              clib_net_to_host_u32 (mp->action_index), mp->tag);
22424     }
22425 }
22426
22427 static void
22428 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22429                                              mp)
22430 {
22431   vat_main_t *vam = &vat_main;
22432   vat_json_node_t *node = NULL;
22433   struct in6_addr ip6;
22434   struct in_addr ip4;
22435
22436   if (VAT_JSON_ARRAY != vam->json_tree.type)
22437     {
22438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22439       vat_json_init_array (&vam->json_tree);
22440     }
22441   node = vat_json_array_add (&vam->json_tree);
22442   vat_json_init_object (node);
22443
22444   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22445   vat_json_object_add_uint (node, "appns_index",
22446                             clib_net_to_host_u32 (mp->appns_index));
22447   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22448   vat_json_object_add_uint (node, "scope", mp->scope);
22449   vat_json_object_add_uint (node, "action_index",
22450                             clib_net_to_host_u32 (mp->action_index));
22451   vat_json_object_add_uint (node, "lcl_port",
22452                             clib_net_to_host_u16 (mp->lcl_port));
22453   vat_json_object_add_uint (node, "rmt_port",
22454                             clib_net_to_host_u16 (mp->rmt_port));
22455   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22456   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22457   vat_json_object_add_string_copy (node, "tag", mp->tag);
22458   if (mp->is_ip4)
22459     {
22460       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22461       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22462       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22463       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22464     }
22465   else
22466     {
22467       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22468       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22469       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22470       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22471     }
22472 }
22473
22474 static int
22475 api_session_rule_add_del (vat_main_t * vam)
22476 {
22477   vl_api_session_rule_add_del_t *mp;
22478   unformat_input_t *i = vam->input;
22479   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22480   u32 appns_index = 0, scope = 0;
22481   ip4_address_t lcl_ip4, rmt_ip4;
22482   ip6_address_t lcl_ip6, rmt_ip6;
22483   u8 is_ip4 = 1, conn_set = 0;
22484   u8 is_add = 1, *tag = 0;
22485   int ret;
22486
22487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22488     {
22489       if (unformat (i, "del"))
22490         is_add = 0;
22491       else if (unformat (i, "add"))
22492         ;
22493       else if (unformat (i, "proto tcp"))
22494         proto = 0;
22495       else if (unformat (i, "proto udp"))
22496         proto = 1;
22497       else if (unformat (i, "appns %d", &appns_index))
22498         ;
22499       else if (unformat (i, "scope %d", &scope))
22500         ;
22501       else if (unformat (i, "tag %_%v%_", &tag))
22502         ;
22503       else
22504         if (unformat
22505             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22506              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22507              &rmt_port))
22508         {
22509           is_ip4 = 1;
22510           conn_set = 1;
22511         }
22512       else
22513         if (unformat
22514             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22515              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22516              &rmt_port))
22517         {
22518           is_ip4 = 0;
22519           conn_set = 1;
22520         }
22521       else if (unformat (i, "action %d", &action))
22522         ;
22523       else
22524         break;
22525     }
22526   if (proto == ~0 || !conn_set || action == ~0)
22527     {
22528       errmsg ("transport proto, connection and action must be set");
22529       return -99;
22530     }
22531
22532   if (scope > 3)
22533     {
22534       errmsg ("scope should be 0-3");
22535       return -99;
22536     }
22537
22538   M (SESSION_RULE_ADD_DEL, mp);
22539
22540   mp->is_ip4 = is_ip4;
22541   mp->transport_proto = proto;
22542   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22543   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22544   mp->lcl_plen = lcl_plen;
22545   mp->rmt_plen = rmt_plen;
22546   mp->action_index = clib_host_to_net_u32 (action);
22547   mp->appns_index = clib_host_to_net_u32 (appns_index);
22548   mp->scope = scope;
22549   mp->is_add = is_add;
22550   if (is_ip4)
22551     {
22552       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22553       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22554     }
22555   else
22556     {
22557       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22558       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22559     }
22560   if (tag)
22561     {
22562       clib_memcpy (mp->tag, tag, vec_len (tag));
22563       vec_free (tag);
22564     }
22565
22566   S (mp);
22567   W (ret);
22568   return ret;
22569 }
22570
22571 static int
22572 api_session_rules_dump (vat_main_t * vam)
22573 {
22574   vl_api_session_rules_dump_t *mp;
22575   vl_api_control_ping_t *mp_ping;
22576   int ret;
22577
22578   if (!vam->json_output)
22579     {
22580       print (vam->ofp, "%=20s", "Session Rules");
22581     }
22582
22583   M (SESSION_RULES_DUMP, mp);
22584   /* send it... */
22585   S (mp);
22586
22587   /* Use a control ping for synchronization */
22588   MPING (CONTROL_PING, mp_ping);
22589   S (mp_ping);
22590
22591   /* Wait for a reply... */
22592   W (ret);
22593   return ret;
22594 }
22595
22596 static int
22597 api_ip_container_proxy_add_del (vat_main_t * vam)
22598 {
22599   vl_api_ip_container_proxy_add_del_t *mp;
22600   unformat_input_t *i = vam->input;
22601   u32 plen = ~0, sw_if_index = ~0;
22602   ip4_address_t ip4;
22603   ip6_address_t ip6;
22604   u8 is_ip4 = 1;
22605   u8 is_add = 1;
22606   int ret;
22607
22608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22609     {
22610       if (unformat (i, "del"))
22611         is_add = 0;
22612       else if (unformat (i, "add"))
22613         ;
22614       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22615         {
22616           is_ip4 = 1;
22617           plen = 32;
22618         }
22619       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22620         {
22621           is_ip4 = 0;
22622           plen = 128;
22623         }
22624       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22625         ;
22626       else
22627         break;
22628     }
22629   if (sw_if_index == ~0 || plen == ~0)
22630     {
22631       errmsg ("address and sw_if_index must be set");
22632       return -99;
22633     }
22634
22635   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22636
22637   mp->is_ip4 = is_ip4;
22638   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22639   mp->plen = plen;
22640   mp->is_add = is_add;
22641   if (is_ip4)
22642     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22643   else
22644     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22645
22646   S (mp);
22647   W (ret);
22648   return ret;
22649 }
22650
22651 static int
22652 api_qos_record_enable_disable (vat_main_t * vam)
22653 {
22654   unformat_input_t *i = vam->input;
22655   vl_api_qos_record_enable_disable_t *mp;
22656   u32 sw_if_index, qs = 0xff;
22657   u8 sw_if_index_set = 0;
22658   u8 enable = 1;
22659   int ret;
22660
22661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22662     {
22663       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22664         sw_if_index_set = 1;
22665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22666         sw_if_index_set = 1;
22667       else if (unformat (i, "%U", unformat_qos_source, &qs))
22668         ;
22669       else if (unformat (i, "disable"))
22670         enable = 0;
22671       else
22672         {
22673           clib_warning ("parse error '%U'", format_unformat_error, i);
22674           return -99;
22675         }
22676     }
22677
22678   if (sw_if_index_set == 0)
22679     {
22680       errmsg ("missing interface name or sw_if_index");
22681       return -99;
22682     }
22683   if (qs == 0xff)
22684     {
22685       errmsg ("input location must be specified");
22686       return -99;
22687     }
22688
22689   M (QOS_RECORD_ENABLE_DISABLE, mp);
22690
22691   mp->sw_if_index = ntohl (sw_if_index);
22692   mp->input_source = qs;
22693   mp->enable = enable;
22694
22695   S (mp);
22696   W (ret);
22697   return ret;
22698 }
22699
22700
22701 static int
22702 q_or_quit (vat_main_t * vam)
22703 {
22704 #if VPP_API_TEST_BUILTIN == 0
22705   longjmp (vam->jump_buf, 1);
22706 #endif
22707   return 0;                     /* not so much */
22708 }
22709
22710 static int
22711 q (vat_main_t * vam)
22712 {
22713   return q_or_quit (vam);
22714 }
22715
22716 static int
22717 quit (vat_main_t * vam)
22718 {
22719   return q_or_quit (vam);
22720 }
22721
22722 static int
22723 comment (vat_main_t * vam)
22724 {
22725   return 0;
22726 }
22727
22728 static int
22729 statseg (vat_main_t * vam)
22730 {
22731   ssvm_private_t *ssvmp = &vam->stat_segment;
22732   ssvm_shared_header_t *shared_header = ssvmp->sh;
22733   vlib_counter_t **counters;
22734   u64 thread0_index1_packets;
22735   u64 thread0_index1_bytes;
22736   f64 vector_rate, input_rate;
22737   uword *p;
22738
22739   uword *counter_vector_by_name;
22740   if (vam->stat_segment_lockp == 0)
22741     {
22742       errmsg ("Stat segment not mapped...");
22743       return -99;
22744     }
22745
22746   /* look up "/if/rx for sw_if_index 1 as a test */
22747
22748   clib_spinlock_lock (vam->stat_segment_lockp);
22749
22750   counter_vector_by_name = (uword *) shared_header->opaque[1];
22751
22752   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22753   if (p == 0)
22754     {
22755       clib_spinlock_unlock (vam->stat_segment_lockp);
22756       errmsg ("/if/tx not found?");
22757       return -99;
22758     }
22759
22760   /* Fish per-thread vector of combined counters from shared memory */
22761   counters = (vlib_counter_t **) p[0];
22762
22763   if (vec_len (counters[0]) < 2)
22764     {
22765       clib_spinlock_unlock (vam->stat_segment_lockp);
22766       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22767       return -99;
22768     }
22769
22770   /* Read thread 0 sw_if_index 1 counter */
22771   thread0_index1_packets = counters[0][1].packets;
22772   thread0_index1_bytes = counters[0][1].bytes;
22773
22774   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22775   if (p == 0)
22776     {
22777       clib_spinlock_unlock (vam->stat_segment_lockp);
22778       errmsg ("vector_rate not found?");
22779       return -99;
22780     }
22781
22782   vector_rate = *(f64 *) (p[0]);
22783   p = hash_get_mem (counter_vector_by_name, "input_rate");
22784   if (p == 0)
22785     {
22786       clib_spinlock_unlock (vam->stat_segment_lockp);
22787       errmsg ("input_rate not found?");
22788       return -99;
22789     }
22790   input_rate = *(f64 *) (p[0]);
22791
22792   clib_spinlock_unlock (vam->stat_segment_lockp);
22793
22794   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22795          vector_rate, input_rate);
22796   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22797          thread0_index1_packets, thread0_index1_bytes);
22798
22799   return 0;
22800 }
22801
22802 static int
22803 cmd_cmp (void *a1, void *a2)
22804 {
22805   u8 **c1 = a1;
22806   u8 **c2 = a2;
22807
22808   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22809 }
22810
22811 static int
22812 help (vat_main_t * vam)
22813 {
22814   u8 **cmds = 0;
22815   u8 *name = 0;
22816   hash_pair_t *p;
22817   unformat_input_t *i = vam->input;
22818   int j;
22819
22820   if (unformat (i, "%s", &name))
22821     {
22822       uword *hs;
22823
22824       vec_add1 (name, 0);
22825
22826       hs = hash_get_mem (vam->help_by_name, name);
22827       if (hs)
22828         print (vam->ofp, "usage: %s %s", name, hs[0]);
22829       else
22830         print (vam->ofp, "No such msg / command '%s'", name);
22831       vec_free (name);
22832       return 0;
22833     }
22834
22835   print (vam->ofp, "Help is available for the following:");
22836
22837     /* *INDENT-OFF* */
22838     hash_foreach_pair (p, vam->function_by_name,
22839     ({
22840       vec_add1 (cmds, (u8 *)(p->key));
22841     }));
22842     /* *INDENT-ON* */
22843
22844   vec_sort_with_function (cmds, cmd_cmp);
22845
22846   for (j = 0; j < vec_len (cmds); j++)
22847     print (vam->ofp, "%s", cmds[j]);
22848
22849   vec_free (cmds);
22850   return 0;
22851 }
22852
22853 static int
22854 set (vat_main_t * vam)
22855 {
22856   u8 *name = 0, *value = 0;
22857   unformat_input_t *i = vam->input;
22858
22859   if (unformat (i, "%s", &name))
22860     {
22861       /* The input buffer is a vector, not a string. */
22862       value = vec_dup (i->buffer);
22863       vec_delete (value, i->index, 0);
22864       /* Almost certainly has a trailing newline */
22865       if (value[vec_len (value) - 1] == '\n')
22866         value[vec_len (value) - 1] = 0;
22867       /* Make sure it's a proper string, one way or the other */
22868       vec_add1 (value, 0);
22869       (void) clib_macro_set_value (&vam->macro_main,
22870                                    (char *) name, (char *) value);
22871     }
22872   else
22873     errmsg ("usage: set <name> <value>");
22874
22875   vec_free (name);
22876   vec_free (value);
22877   return 0;
22878 }
22879
22880 static int
22881 unset (vat_main_t * vam)
22882 {
22883   u8 *name = 0;
22884
22885   if (unformat (vam->input, "%s", &name))
22886     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22887       errmsg ("unset: %s wasn't set", name);
22888   vec_free (name);
22889   return 0;
22890 }
22891
22892 typedef struct
22893 {
22894   u8 *name;
22895   u8 *value;
22896 } macro_sort_t;
22897
22898
22899 static int
22900 macro_sort_cmp (void *a1, void *a2)
22901 {
22902   macro_sort_t *s1 = a1;
22903   macro_sort_t *s2 = a2;
22904
22905   return strcmp ((char *) (s1->name), (char *) (s2->name));
22906 }
22907
22908 static int
22909 dump_macro_table (vat_main_t * vam)
22910 {
22911   macro_sort_t *sort_me = 0, *sm;
22912   int i;
22913   hash_pair_t *p;
22914
22915     /* *INDENT-OFF* */
22916     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22917     ({
22918       vec_add2 (sort_me, sm, 1);
22919       sm->name = (u8 *)(p->key);
22920       sm->value = (u8 *) (p->value[0]);
22921     }));
22922     /* *INDENT-ON* */
22923
22924   vec_sort_with_function (sort_me, macro_sort_cmp);
22925
22926   if (vec_len (sort_me))
22927     print (vam->ofp, "%-15s%s", "Name", "Value");
22928   else
22929     print (vam->ofp, "The macro table is empty...");
22930
22931   for (i = 0; i < vec_len (sort_me); i++)
22932     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22933   return 0;
22934 }
22935
22936 static int
22937 dump_node_table (vat_main_t * vam)
22938 {
22939   int i, j;
22940   vlib_node_t *node, *next_node;
22941
22942   if (vec_len (vam->graph_nodes) == 0)
22943     {
22944       print (vam->ofp, "Node table empty, issue get_node_graph...");
22945       return 0;
22946     }
22947
22948   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22949     {
22950       node = vam->graph_nodes[0][i];
22951       print (vam->ofp, "[%d] %s", i, node->name);
22952       for (j = 0; j < vec_len (node->next_nodes); j++)
22953         {
22954           if (node->next_nodes[j] != ~0)
22955             {
22956               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22957               print (vam->ofp, "  [%d] %s", j, next_node->name);
22958             }
22959         }
22960     }
22961   return 0;
22962 }
22963
22964 static int
22965 value_sort_cmp (void *a1, void *a2)
22966 {
22967   name_sort_t *n1 = a1;
22968   name_sort_t *n2 = a2;
22969
22970   if (n1->value < n2->value)
22971     return -1;
22972   if (n1->value > n2->value)
22973     return 1;
22974   return 0;
22975 }
22976
22977
22978 static int
22979 dump_msg_api_table (vat_main_t * vam)
22980 {
22981   api_main_t *am = &api_main;
22982   name_sort_t *nses = 0, *ns;
22983   hash_pair_t *hp;
22984   int i;
22985
22986   /* *INDENT-OFF* */
22987   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22988   ({
22989     vec_add2 (nses, ns, 1);
22990     ns->name = (u8 *)(hp->key);
22991     ns->value = (u32) hp->value[0];
22992   }));
22993   /* *INDENT-ON* */
22994
22995   vec_sort_with_function (nses, value_sort_cmp);
22996
22997   for (i = 0; i < vec_len (nses); i++)
22998     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22999   vec_free (nses);
23000   return 0;
23001 }
23002
23003 static int
23004 get_msg_id (vat_main_t * vam)
23005 {
23006   u8 *name_and_crc;
23007   u32 message_index;
23008
23009   if (unformat (vam->input, "%s", &name_and_crc))
23010     {
23011       message_index = vl_msg_api_get_msg_index (name_and_crc);
23012       if (message_index == ~0)
23013         {
23014           print (vam->ofp, " '%s' not found", name_and_crc);
23015           return 0;
23016         }
23017       print (vam->ofp, " '%s' has message index %d",
23018              name_and_crc, message_index);
23019       return 0;
23020     }
23021   errmsg ("name_and_crc required...");
23022   return 0;
23023 }
23024
23025 static int
23026 search_node_table (vat_main_t * vam)
23027 {
23028   unformat_input_t *line_input = vam->input;
23029   u8 *node_to_find;
23030   int j;
23031   vlib_node_t *node, *next_node;
23032   uword *p;
23033
23034   if (vam->graph_node_index_by_name == 0)
23035     {
23036       print (vam->ofp, "Node table empty, issue get_node_graph...");
23037       return 0;
23038     }
23039
23040   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23041     {
23042       if (unformat (line_input, "%s", &node_to_find))
23043         {
23044           vec_add1 (node_to_find, 0);
23045           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23046           if (p == 0)
23047             {
23048               print (vam->ofp, "%s not found...", node_to_find);
23049               goto out;
23050             }
23051           node = vam->graph_nodes[0][p[0]];
23052           print (vam->ofp, "[%d] %s", p[0], node->name);
23053           for (j = 0; j < vec_len (node->next_nodes); j++)
23054             {
23055               if (node->next_nodes[j] != ~0)
23056                 {
23057                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23058                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23059                 }
23060             }
23061         }
23062
23063       else
23064         {
23065           clib_warning ("parse error '%U'", format_unformat_error,
23066                         line_input);
23067           return -99;
23068         }
23069
23070     out:
23071       vec_free (node_to_find);
23072
23073     }
23074
23075   return 0;
23076 }
23077
23078
23079 static int
23080 script (vat_main_t * vam)
23081 {
23082 #if (VPP_API_TEST_BUILTIN==0)
23083   u8 *s = 0;
23084   char *save_current_file;
23085   unformat_input_t save_input;
23086   jmp_buf save_jump_buf;
23087   u32 save_line_number;
23088
23089   FILE *new_fp, *save_ifp;
23090
23091   if (unformat (vam->input, "%s", &s))
23092     {
23093       new_fp = fopen ((char *) s, "r");
23094       if (new_fp == 0)
23095         {
23096           errmsg ("Couldn't open script file %s", s);
23097           vec_free (s);
23098           return -99;
23099         }
23100     }
23101   else
23102     {
23103       errmsg ("Missing script name");
23104       return -99;
23105     }
23106
23107   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23108   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23109   save_ifp = vam->ifp;
23110   save_line_number = vam->input_line_number;
23111   save_current_file = (char *) vam->current_file;
23112
23113   vam->input_line_number = 0;
23114   vam->ifp = new_fp;
23115   vam->current_file = s;
23116   do_one_file (vam);
23117
23118   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23119   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23120   vam->ifp = save_ifp;
23121   vam->input_line_number = save_line_number;
23122   vam->current_file = (u8 *) save_current_file;
23123   vec_free (s);
23124
23125   return 0;
23126 #else
23127   clib_warning ("use the exec command...");
23128   return -99;
23129 #endif
23130 }
23131
23132 static int
23133 echo (vat_main_t * vam)
23134 {
23135   print (vam->ofp, "%v", vam->input->buffer);
23136   return 0;
23137 }
23138
23139 /* List of API message constructors, CLI names map to api_xxx */
23140 #define foreach_vpe_api_msg                                             \
23141 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23142 _(sw_interface_dump,"")                                                 \
23143 _(sw_interface_set_flags,                                               \
23144   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23145 _(sw_interface_add_del_address,                                         \
23146   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23147 _(sw_interface_set_rx_mode,                                             \
23148   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23149 _(sw_interface_set_table,                                               \
23150   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23151 _(sw_interface_set_mpls_enable,                                         \
23152   "<intfc> | sw_if_index [disable | dis]")                              \
23153 _(sw_interface_set_vpath,                                               \
23154   "<intfc> | sw_if_index <id> enable | disable")                        \
23155 _(sw_interface_set_vxlan_bypass,                                        \
23156   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23157 _(sw_interface_set_geneve_bypass,                                       \
23158   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23159 _(sw_interface_set_l2_xconnect,                                         \
23160   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23161   "enable | disable")                                                   \
23162 _(sw_interface_set_l2_bridge,                                           \
23163   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23164   "[shg <split-horizon-group>] [bvi]\n"                                 \
23165   "enable | disable")                                                   \
23166 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23167 _(bridge_domain_add_del,                                                \
23168   "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") \
23169 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23170 _(l2fib_add_del,                                                        \
23171   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23172 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23173 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23174 _(l2_flags,                                                             \
23175   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23176 _(bridge_flags,                                                         \
23177   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23178 _(tap_connect,                                                          \
23179   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23180 _(tap_modify,                                                           \
23181   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23182 _(tap_delete,                                                           \
23183   "<vpp-if-name> | sw_if_index <id>")                                   \
23184 _(sw_interface_tap_dump, "")                                            \
23185 _(tap_create_v2,                                                        \
23186   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23187 _(tap_delete_v2,                                                        \
23188   "<vpp-if-name> | sw_if_index <id>")                                   \
23189 _(sw_interface_tap_v2_dump, "")                                         \
23190 _(bond_create,                                                          \
23191   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23192   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23193 _(bond_delete,                                                          \
23194   "<vpp-if-name> | sw_if_index <id>")                                   \
23195 _(bond_enslave,                                                         \
23196   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23197 _(bond_detach_slave,                                                    \
23198   "sw_if_index <n>")                                                    \
23199 _(sw_interface_bond_dump, "")                                           \
23200 _(sw_interface_slave_dump,                                              \
23201   "<vpp-if-name> | sw_if_index <id>")                                   \
23202 _(ip_table_add_del,                                                     \
23203   "table-id <n> [ipv6]\n")                                              \
23204 _(ip_add_del_route,                                                     \
23205   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23206   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23207   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23208   "[multipath] [count <n>]")                                            \
23209 _(ip_mroute_add_del,                                                    \
23210   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23211   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23212 _(mpls_table_add_del,                                                   \
23213   "table-id <n>\n")                                                     \
23214 _(mpls_route_add_del,                                                   \
23215   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23216   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23217   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23218   "[multipath] [count <n>]")                                            \
23219 _(mpls_ip_bind_unbind,                                                  \
23220   "<label> <addr/len>")                                                 \
23221 _(mpls_tunnel_add_del,                                                  \
23222   " via <addr> [table-id <n>]\n"                                        \
23223   "sw_if_index <id>] [l2]  [del]")                                      \
23224 _(bier_table_add_del,                                                   \
23225   "<label> <sub-domain> <set> <bsl> [del]")                             \
23226 _(bier_route_add_del,                                                   \
23227   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23228   "[<intfc> | sw_if_index <id>]"                                        \
23229   "[weight <n>] [del] [multipath]")                                     \
23230 _(proxy_arp_add_del,                                                    \
23231   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23232 _(proxy_arp_intfc_enable_disable,                                       \
23233   "<intfc> | sw_if_index <id> enable | disable")                        \
23234 _(sw_interface_set_unnumbered,                                          \
23235   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23236 _(ip_neighbor_add_del,                                                  \
23237   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23238   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23239 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23240 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23241   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23242   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23243   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23244 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23245 _(reset_fib, "vrf <n> [ipv6]")                                          \
23246 _(dhcp_proxy_config,                                                    \
23247   "svr <v46-address> src <v46-address>\n"                               \
23248    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23249 _(dhcp_proxy_set_vss,                                                   \
23250   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23251 _(dhcp_proxy_dump, "ip6")                                               \
23252 _(dhcp_client_config,                                                   \
23253   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23254 _(set_ip_flow_hash,                                                     \
23255   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23256 _(sw_interface_ip6_enable_disable,                                      \
23257   "<intfc> | sw_if_index <id> enable | disable")                        \
23258 _(sw_interface_ip6_set_link_local_address,                              \
23259   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23260 _(ip6nd_proxy_add_del,                                                  \
23261   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23262 _(ip6nd_proxy_dump, "")                                                 \
23263 _(sw_interface_ip6nd_ra_prefix,                                         \
23264   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23265   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23266   "[nolink] [isno]")                                                    \
23267 _(sw_interface_ip6nd_ra_config,                                         \
23268   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23269   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23270   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23271 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23272 _(l2_patch_add_del,                                                     \
23273   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23274   "enable | disable")                                                   \
23275 _(sr_localsid_add_del,                                                  \
23276   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23277   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23278 _(classify_add_del_table,                                               \
23279   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23280   " [del] [del-chain] mask <mask-value>\n"                              \
23281   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23282   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23283 _(classify_add_del_session,                                             \
23284   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23285   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23286   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23287   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23288 _(classify_set_interface_ip_table,                                      \
23289   "<intfc> | sw_if_index <nn> table <nn>")                              \
23290 _(classify_set_interface_l2_tables,                                     \
23291   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23292   "  [other-table <nn>]")                                               \
23293 _(get_node_index, "node <node-name")                                    \
23294 _(add_node_next, "node <node-name> next <next-node-name>")              \
23295 _(l2tpv3_create_tunnel,                                                 \
23296   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23297   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23298   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23299 _(l2tpv3_set_tunnel_cookies,                                            \
23300   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23301   "[new_remote_cookie <nn>]\n")                                         \
23302 _(l2tpv3_interface_enable_disable,                                      \
23303   "<intfc> | sw_if_index <nn> enable | disable")                        \
23304 _(l2tpv3_set_lookup_key,                                                \
23305   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23306 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23307 _(vxlan_offload_rx,                                                     \
23308   "hw { <interface name> | hw_if_index <nn>} "                          \
23309   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23310 _(vxlan_add_del_tunnel,                                                 \
23311   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23312   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23313   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23314 _(geneve_add_del_tunnel,                                                \
23315   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23316   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23317   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23318 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23319 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23320 _(gre_add_del_tunnel,                                                   \
23321   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23322   "[teb | erspan <session-id>] [del]")                                  \
23323 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23324 _(l2_fib_clear_table, "")                                               \
23325 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23326 _(l2_interface_vlan_tag_rewrite,                                        \
23327   "<intfc> | sw_if_index <nn> \n"                                       \
23328   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23329   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23330 _(create_vhost_user_if,                                                 \
23331         "socket <filename> [server] [renumber <dev_instance>] "         \
23332         "[mac <mac_address>]")                                          \
23333 _(modify_vhost_user_if,                                                 \
23334         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23335         "[server] [renumber <dev_instance>]")                           \
23336 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23337 _(sw_interface_vhost_user_dump, "")                                     \
23338 _(show_version, "")                                                     \
23339 _(vxlan_gpe_add_del_tunnel,                                             \
23340   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23341   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23342   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23343   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23344 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23345 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23346 _(interface_name_renumber,                                              \
23347   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23348 _(input_acl_set_interface,                                              \
23349   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23350   "  [l2-table <nn>] [del]")                                            \
23351 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23352 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23353   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23354 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23355 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23356 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23357 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23358 _(ip_dump, "ipv4 | ipv6")                                               \
23359 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23360 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23361   "  spid_id <n> ")                                                     \
23362 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23363   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23364   "  integ_alg <alg> integ_key <hex>")                                  \
23365 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23366   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23367   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23368   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23369 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23370 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23371   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23372   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23373   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23374   "  [instance <n>]")     \
23375 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23376 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23377   "  <alg> <hex>\n")                                                    \
23378 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23379 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23380 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23381   "(auth_data 0x<data> | auth_data <data>)")                            \
23382 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23383   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23384 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23385   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23386   "(local|remote)")                                                     \
23387 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23388 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23389 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23390 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23391 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23392 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23393 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23394 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23395 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23396 _(delete_loopback,"sw_if_index <nn>")                                   \
23397 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23398 _(want_interface_events,  "enable|disable")                             \
23399 _(want_stats,"enable|disable")                                          \
23400 _(get_first_msg_id, "client <name>")                                    \
23401 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23402 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23403   "fib-id <nn> [ip4][ip6][default]")                                    \
23404 _(get_node_graph, " ")                                                  \
23405 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23406 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23407 _(ioam_disable, "")                                                     \
23408 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23409                             " sw_if_index <sw_if_index> p <priority> "  \
23410                             "w <weight>] [del]")                        \
23411 _(one_add_del_locator, "locator-set <locator_name> "                    \
23412                         "iface <intf> | sw_if_index <sw_if_index> "     \
23413                         "p <priority> w <weight> [del]")                \
23414 _(one_add_del_local_eid,"vni <vni> eid "                                \
23415                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23416                          "locator-set <locator_name> [del]"             \
23417                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23418 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23419 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23420 _(one_enable_disable, "enable|disable")                                 \
23421 _(one_map_register_enable_disable, "enable|disable")                    \
23422 _(one_map_register_fallback_threshold, "<value>")                       \
23423 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23424 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23425                                "[seid <seid>] "                         \
23426                                "rloc <locator> p <prio> "               \
23427                                "w <weight> [rloc <loc> ... ] "          \
23428                                "action <action> [del-all]")             \
23429 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23430                           "<local-eid>")                                \
23431 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23432 _(one_use_petr, "ip-address> | disable")                                \
23433 _(one_map_request_mode, "src-dst|dst-only")                             \
23434 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23435 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23436 _(one_locator_set_dump, "[local | remote]")                             \
23437 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23438 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23439                        "[local] | [remote]")                            \
23440 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23441 _(one_ndp_bd_get, "")                                                   \
23442 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23443 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23444 _(one_l2_arp_bd_get, "")                                                \
23445 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23446 _(one_stats_enable_disable, "enable|disalbe")                           \
23447 _(show_one_stats_enable_disable, "")                                    \
23448 _(one_eid_table_vni_dump, "")                                           \
23449 _(one_eid_table_map_dump, "l2|l3")                                      \
23450 _(one_map_resolver_dump, "")                                            \
23451 _(one_map_server_dump, "")                                              \
23452 _(one_adjacencies_get, "vni <vni>")                                     \
23453 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23454 _(show_one_rloc_probe_state, "")                                        \
23455 _(show_one_map_register_state, "")                                      \
23456 _(show_one_status, "")                                                  \
23457 _(one_stats_dump, "")                                                   \
23458 _(one_stats_flush, "")                                                  \
23459 _(one_get_map_request_itr_rlocs, "")                                    \
23460 _(one_map_register_set_ttl, "<ttl>")                                    \
23461 _(one_set_transport_protocol, "udp|api")                                \
23462 _(one_get_transport_protocol, "")                                       \
23463 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23464 _(one_show_xtr_mode, "")                                                \
23465 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23466 _(one_show_pitr_mode, "")                                               \
23467 _(one_enable_disable_petr_mode, "enable|disable")                       \
23468 _(one_show_petr_mode, "")                                               \
23469 _(show_one_nsh_mapping, "")                                             \
23470 _(show_one_pitr, "")                                                    \
23471 _(show_one_use_petr, "")                                                \
23472 _(show_one_map_request_mode, "")                                        \
23473 _(show_one_map_register_ttl, "")                                        \
23474 _(show_one_map_register_fallback_threshold, "")                         \
23475 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23476                             " sw_if_index <sw_if_index> p <priority> "  \
23477                             "w <weight>] [del]")                        \
23478 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23479                         "iface <intf> | sw_if_index <sw_if_index> "     \
23480                         "p <priority> w <weight> [del]")                \
23481 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23482                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23483                          "locator-set <locator_name> [del]"             \
23484                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23485 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23486 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23487 _(lisp_enable_disable, "enable|disable")                                \
23488 _(lisp_map_register_enable_disable, "enable|disable")                   \
23489 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23490 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23491                                "[seid <seid>] "                         \
23492                                "rloc <locator> p <prio> "               \
23493                                "w <weight> [rloc <loc> ... ] "          \
23494                                "action <action> [del-all]")             \
23495 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23496                           "<local-eid>")                                \
23497 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23498 _(lisp_use_petr, "<ip-address> | disable")                              \
23499 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23500 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23501 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23502 _(lisp_locator_set_dump, "[local | remote]")                            \
23503 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23504 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23505                        "[local] | [remote]")                            \
23506 _(lisp_eid_table_vni_dump, "")                                          \
23507 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23508 _(lisp_map_resolver_dump, "")                                           \
23509 _(lisp_map_server_dump, "")                                             \
23510 _(lisp_adjacencies_get, "vni <vni>")                                    \
23511 _(gpe_fwd_entry_vnis_get, "")                                           \
23512 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23513 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23514                                 "[table <table-id>]")                   \
23515 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23516 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23517 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23518 _(gpe_get_encap_mode, "")                                               \
23519 _(lisp_gpe_add_del_iface, "up|down")                                    \
23520 _(lisp_gpe_enable_disable, "enable|disable")                            \
23521 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23522   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23523 _(show_lisp_rloc_probe_state, "")                                       \
23524 _(show_lisp_map_register_state, "")                                     \
23525 _(show_lisp_status, "")                                                 \
23526 _(lisp_get_map_request_itr_rlocs, "")                                   \
23527 _(show_lisp_pitr, "")                                                   \
23528 _(show_lisp_use_petr, "")                                               \
23529 _(show_lisp_map_request_mode, "")                                       \
23530 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23531 _(af_packet_delete, "name <host interface name>")                       \
23532 _(af_packet_dump, "")                                                   \
23533 _(policer_add_del, "name <policer name> <params> [del]")                \
23534 _(policer_dump, "[name <policer name>]")                                \
23535 _(policer_classify_set_interface,                                       \
23536   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23537   "  [l2-table <nn>] [del]")                                            \
23538 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23539 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23540     "[master|slave]")                                                   \
23541 _(netmap_delete, "name <interface name>")                               \
23542 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23543 _(mpls_fib_dump, "")                                                    \
23544 _(classify_table_ids, "")                                               \
23545 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23546 _(classify_table_info, "table_id <nn>")                                 \
23547 _(classify_session_dump, "table_id <nn>")                               \
23548 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23549     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23550     "[template_interval <nn>] [udp_checksum]")                          \
23551 _(ipfix_exporter_dump, "")                                              \
23552 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23553 _(ipfix_classify_stream_dump, "")                                       \
23554 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23555 _(ipfix_classify_table_dump, "")                                        \
23556 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23557 _(sw_interface_span_dump, "[l2]")                                           \
23558 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23559 _(pg_create_interface, "if_id <nn>")                                    \
23560 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23561 _(pg_enable_disable, "[stream <id>] disable")                           \
23562 _(ip_source_and_port_range_check_add_del,                               \
23563   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23564 _(ip_source_and_port_range_check_interface_add_del,                     \
23565   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23566   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23567 _(ipsec_gre_add_del_tunnel,                                             \
23568   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23569 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23570 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23571 _(l2_interface_pbb_tag_rewrite,                                         \
23572   "<intfc> | sw_if_index <nn> \n"                                       \
23573   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23574   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23575 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23576 _(flow_classify_set_interface,                                          \
23577   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23578 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23579 _(ip_fib_dump, "")                                                      \
23580 _(ip_mfib_dump, "")                                                     \
23581 _(ip6_fib_dump, "")                                                     \
23582 _(ip6_mfib_dump, "")                                                    \
23583 _(feature_enable_disable, "arc_name <arc_name> "                        \
23584   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23585 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23586 "[disable]")                                                            \
23587 _(l2_xconnect_dump, "")                                                 \
23588 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23589 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23590 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23591 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23592 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23593 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23594 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23595   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23596 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23597 _(sock_init_shm, "size <nnn>")                                          \
23598 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23599 _(dns_enable_disable, "[enable][disable]")                              \
23600 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23601 _(dns_resolve_name, "<hostname>")                                       \
23602 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23603 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23604 _(dns_resolve_name, "<hostname>")                                       \
23605 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23606   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23607 _(session_rules_dump, "")                                               \
23608 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23609 _(output_acl_set_interface,                                             \
23610   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23611   "  [l2-table <nn>] [del]")                                            \
23612 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23613
23614 /* List of command functions, CLI names map directly to functions */
23615 #define foreach_cli_function                                    \
23616 _(comment, "usage: comment <ignore-rest-of-line>")              \
23617 _(dump_interface_table, "usage: dump_interface_table")          \
23618 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23619 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23620 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23621 _(dump_stats_table, "usage: dump_stats_table")                  \
23622 _(dump_macro_table, "usage: dump_macro_table ")                 \
23623 _(dump_node_table, "usage: dump_node_table")                    \
23624 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23625 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23626 _(echo, "usage: echo <message>")                                \
23627 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23628 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23629 _(help, "usage: help")                                          \
23630 _(q, "usage: quit")                                             \
23631 _(quit, "usage: quit")                                          \
23632 _(search_node_table, "usage: search_node_table <name>...")      \
23633 _(set, "usage: set <variable-name> <value>")                    \
23634 _(script, "usage: script <file-name>")                          \
23635 _(statseg, "usage: statseg");                                   \
23636 _(unset, "usage: unset <variable-name>")
23637
23638 #define _(N,n)                                  \
23639     static void vl_api_##n##_t_handler_uni      \
23640     (vl_api_##n##_t * mp)                       \
23641     {                                           \
23642         vat_main_t * vam = &vat_main;           \
23643         if (vam->json_output) {                 \
23644             vl_api_##n##_t_handler_json(mp);    \
23645         } else {                                \
23646             vl_api_##n##_t_handler(mp);         \
23647         }                                       \
23648     }
23649 foreach_vpe_api_reply_msg;
23650 #if VPP_API_TEST_BUILTIN == 0
23651 foreach_standalone_reply_msg;
23652 #endif
23653 #undef _
23654
23655 void
23656 vat_api_hookup (vat_main_t * vam)
23657 {
23658 #define _(N,n)                                                  \
23659     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23660                            vl_api_##n##_t_handler_uni,          \
23661                            vl_noop_handler,                     \
23662                            vl_api_##n##_t_endian,               \
23663                            vl_api_##n##_t_print,                \
23664                            sizeof(vl_api_##n##_t), 1);
23665   foreach_vpe_api_reply_msg;
23666 #if VPP_API_TEST_BUILTIN == 0
23667   foreach_standalone_reply_msg;
23668 #endif
23669 #undef _
23670
23671 #if (VPP_API_TEST_BUILTIN==0)
23672   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23673
23674   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23675
23676   vam->function_by_name = hash_create_string (0, sizeof (uword));
23677
23678   vam->help_by_name = hash_create_string (0, sizeof (uword));
23679 #endif
23680
23681   /* API messages we can send */
23682 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23683   foreach_vpe_api_msg;
23684 #undef _
23685
23686   /* Help strings */
23687 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23688   foreach_vpe_api_msg;
23689 #undef _
23690
23691   /* CLI functions */
23692 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23693   foreach_cli_function;
23694 #undef _
23695
23696   /* Help strings */
23697 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23698   foreach_cli_function;
23699 #undef _
23700 }
23701
23702 #if VPP_API_TEST_BUILTIN
23703 static clib_error_t *
23704 vat_api_hookup_shim (vlib_main_t * vm)
23705 {
23706   vat_api_hookup (&vat_main);
23707   return 0;
23708 }
23709
23710 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23711 #endif
23712
23713 /*
23714  * fd.io coding-style-patch-verification: ON
23715  *
23716  * Local Variables:
23717  * eval: (c-set-style "gnu")
23718  * End:
23719  */