l2: arp termination dump
[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 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5688 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5689 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5690 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5691 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5692 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5693 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5694 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5695 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5696 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5697 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5698 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5699 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5700 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5701 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5702 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5703 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5704 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5705 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5706 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5707   one_map_register_enable_disable_reply)                                \
5708 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5709 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5710 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5711 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5712   one_map_register_fallback_threshold_reply)                            \
5713 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5714   one_rloc_probe_enable_disable_reply)                                  \
5715 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5716 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5717 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5718 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5719 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5720 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5721 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5722 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5723 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5724 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5725 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5726 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5727 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5728 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5729 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5730 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5731   show_one_stats_enable_disable_reply)                                  \
5732 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5733 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5734 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5735 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5736 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5737 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5738 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5739 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5740   one_enable_disable_pitr_mode_reply)                                   \
5741 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5742   one_enable_disable_petr_mode_reply)                                   \
5743 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5744 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5745 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5746 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5747 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5748 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5749 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5750 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5751 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5752 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5753 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5754 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5755   gpe_add_del_native_fwd_rpath_reply)                                   \
5756 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5757   gpe_fwd_entry_path_details)                                           \
5758 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5759 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5760   one_add_del_map_request_itr_rlocs_reply)                              \
5761 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5762   one_get_map_request_itr_rlocs_reply)                                  \
5763 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5764 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5765 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5766 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5767 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5768 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5769   show_one_map_register_state_reply)                                    \
5770 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5771 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5772   show_one_map_register_fallback_threshold_reply)                       \
5773 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5774 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5775 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5776 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5777 _(POLICER_DETAILS, policer_details)                                     \
5778 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5779 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5780 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5781 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5782 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5783 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5784 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5785 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5786 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5787 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5788 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5789 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5790 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5791 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5792 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5793 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5794 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5795 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5796 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5797 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5798 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5799 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5800 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5801 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5802 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5803  ip_source_and_port_range_check_add_del_reply)                          \
5804 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5805  ip_source_and_port_range_check_interface_add_del_reply)                \
5806 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5807 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5808 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5809 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5810 _(PUNT_REPLY, punt_reply)                                               \
5811 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5812 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5813 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5814 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5815 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5816 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5817 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5818 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5819 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5820 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5821 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5822 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5823 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5824 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5825 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5826 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5827 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5828 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5829 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5830 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5831 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5832 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5833 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5834
5835 #define foreach_standalone_reply_msg                                    \
5836 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5837 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5838 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5839 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5840 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5841 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5842 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5843
5844 typedef struct
5845 {
5846   u8 *name;
5847   u32 value;
5848 } name_sort_t;
5849
5850 #define STR_VTR_OP_CASE(op)     \
5851     case L2_VTR_ ## op:         \
5852         return "" # op;
5853
5854 static const char *
5855 str_vtr_op (u32 vtr_op)
5856 {
5857   switch (vtr_op)
5858     {
5859       STR_VTR_OP_CASE (DISABLED);
5860       STR_VTR_OP_CASE (PUSH_1);
5861       STR_VTR_OP_CASE (PUSH_2);
5862       STR_VTR_OP_CASE (POP_1);
5863       STR_VTR_OP_CASE (POP_2);
5864       STR_VTR_OP_CASE (TRANSLATE_1_1);
5865       STR_VTR_OP_CASE (TRANSLATE_1_2);
5866       STR_VTR_OP_CASE (TRANSLATE_2_1);
5867       STR_VTR_OP_CASE (TRANSLATE_2_2);
5868     }
5869
5870   return "UNKNOWN";
5871 }
5872
5873 static int
5874 dump_sub_interface_table (vat_main_t * vam)
5875 {
5876   const sw_interface_subif_t *sub = NULL;
5877
5878   if (vam->json_output)
5879     {
5880       clib_warning
5881         ("JSON output supported only for VPE API calls and dump_stats_table");
5882       return -99;
5883     }
5884
5885   print (vam->ofp,
5886          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5887          "Interface", "sw_if_index",
5888          "sub id", "dot1ad", "tags", "outer id",
5889          "inner id", "exact", "default", "outer any", "inner any");
5890
5891   vec_foreach (sub, vam->sw_if_subif_table)
5892   {
5893     print (vam->ofp,
5894            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5895            sub->interface_name,
5896            sub->sw_if_index,
5897            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5898            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5899            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5900            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5901     if (sub->vtr_op != L2_VTR_DISABLED)
5902       {
5903         print (vam->ofp,
5904                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5905                "tag1: %d tag2: %d ]",
5906                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5907                sub->vtr_tag1, sub->vtr_tag2);
5908       }
5909   }
5910
5911   return 0;
5912 }
5913
5914 static int
5915 name_sort_cmp (void *a1, void *a2)
5916 {
5917   name_sort_t *n1 = a1;
5918   name_sort_t *n2 = a2;
5919
5920   return strcmp ((char *) n1->name, (char *) n2->name);
5921 }
5922
5923 static int
5924 dump_interface_table (vat_main_t * vam)
5925 {
5926   hash_pair_t *p;
5927   name_sort_t *nses = 0, *ns;
5928
5929   if (vam->json_output)
5930     {
5931       clib_warning
5932         ("JSON output supported only for VPE API calls and dump_stats_table");
5933       return -99;
5934     }
5935
5936   /* *INDENT-OFF* */
5937   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5938   ({
5939     vec_add2 (nses, ns, 1);
5940     ns->name = (u8 *)(p->key);
5941     ns->value = (u32) p->value[0];
5942   }));
5943   /* *INDENT-ON* */
5944
5945   vec_sort_with_function (nses, name_sort_cmp);
5946
5947   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5948   vec_foreach (ns, nses)
5949   {
5950     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5951   }
5952   vec_free (nses);
5953   return 0;
5954 }
5955
5956 static int
5957 dump_ip_table (vat_main_t * vam, int is_ipv6)
5958 {
5959   const ip_details_t *det = NULL;
5960   const ip_address_details_t *address = NULL;
5961   u32 i = ~0;
5962
5963   print (vam->ofp, "%-12s", "sw_if_index");
5964
5965   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5966   {
5967     i++;
5968     if (!det->present)
5969       {
5970         continue;
5971       }
5972     print (vam->ofp, "%-12d", i);
5973     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5974     if (!det->addr)
5975       {
5976         continue;
5977       }
5978     vec_foreach (address, det->addr)
5979     {
5980       print (vam->ofp,
5981              "            %-30U%-13d",
5982              is_ipv6 ? format_ip6_address : format_ip4_address,
5983              address->ip, address->prefix_length);
5984     }
5985   }
5986
5987   return 0;
5988 }
5989
5990 static int
5991 dump_ipv4_table (vat_main_t * vam)
5992 {
5993   if (vam->json_output)
5994     {
5995       clib_warning
5996         ("JSON output supported only for VPE API calls and dump_stats_table");
5997       return -99;
5998     }
5999
6000   return dump_ip_table (vam, 0);
6001 }
6002
6003 static int
6004 dump_ipv6_table (vat_main_t * vam)
6005 {
6006   if (vam->json_output)
6007     {
6008       clib_warning
6009         ("JSON output supported only for VPE API calls and dump_stats_table");
6010       return -99;
6011     }
6012
6013   return dump_ip_table (vam, 1);
6014 }
6015
6016 static char *
6017 counter_type_to_str (u8 counter_type, u8 is_combined)
6018 {
6019   if (!is_combined)
6020     {
6021       switch (counter_type)
6022         {
6023         case VNET_INTERFACE_COUNTER_DROP:
6024           return "drop";
6025         case VNET_INTERFACE_COUNTER_PUNT:
6026           return "punt";
6027         case VNET_INTERFACE_COUNTER_IP4:
6028           return "ip4";
6029         case VNET_INTERFACE_COUNTER_IP6:
6030           return "ip6";
6031         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6032           return "rx-no-buf";
6033         case VNET_INTERFACE_COUNTER_RX_MISS:
6034           return "rx-miss";
6035         case VNET_INTERFACE_COUNTER_RX_ERROR:
6036           return "rx-error";
6037         case VNET_INTERFACE_COUNTER_TX_ERROR:
6038           return "tx-error";
6039         default:
6040           return "INVALID-COUNTER-TYPE";
6041         }
6042     }
6043   else
6044     {
6045       switch (counter_type)
6046         {
6047         case VNET_INTERFACE_COUNTER_RX:
6048           return "rx";
6049         case VNET_INTERFACE_COUNTER_TX:
6050           return "tx";
6051         default:
6052           return "INVALID-COUNTER-TYPE";
6053         }
6054     }
6055 }
6056
6057 static int
6058 dump_stats_table (vat_main_t * vam)
6059 {
6060   vat_json_node_t node;
6061   vat_json_node_t *msg_array;
6062   vat_json_node_t *msg;
6063   vat_json_node_t *counter_array;
6064   vat_json_node_t *counter;
6065   interface_counter_t c;
6066   u64 packets;
6067   ip4_fib_counter_t *c4;
6068   ip6_fib_counter_t *c6;
6069   ip4_nbr_counter_t *n4;
6070   ip6_nbr_counter_t *n6;
6071   int i, j;
6072
6073   if (!vam->json_output)
6074     {
6075       clib_warning ("dump_stats_table supported only in JSON format");
6076       return -99;
6077     }
6078
6079   vat_json_init_object (&node);
6080
6081   /* interface counters */
6082   msg_array = vat_json_object_add (&node, "interface_counters");
6083   vat_json_init_array (msg_array);
6084   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6085     {
6086       msg = vat_json_array_add (msg_array);
6087       vat_json_init_object (msg);
6088       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6089                                        (u8 *) counter_type_to_str (i, 0));
6090       vat_json_object_add_int (msg, "is_combined", 0);
6091       counter_array = vat_json_object_add (msg, "data");
6092       vat_json_init_array (counter_array);
6093       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6094         {
6095           packets = vam->simple_interface_counters[i][j];
6096           vat_json_array_add_uint (counter_array, packets);
6097         }
6098     }
6099   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6100     {
6101       msg = vat_json_array_add (msg_array);
6102       vat_json_init_object (msg);
6103       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6104                                        (u8 *) counter_type_to_str (i, 1));
6105       vat_json_object_add_int (msg, "is_combined", 1);
6106       counter_array = vat_json_object_add (msg, "data");
6107       vat_json_init_array (counter_array);
6108       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6109         {
6110           c = vam->combined_interface_counters[i][j];
6111           counter = vat_json_array_add (counter_array);
6112           vat_json_init_object (counter);
6113           vat_json_object_add_uint (counter, "packets", c.packets);
6114           vat_json_object_add_uint (counter, "bytes", c.bytes);
6115         }
6116     }
6117
6118   /* ip4 fib counters */
6119   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6120   vat_json_init_array (msg_array);
6121   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6122     {
6123       msg = vat_json_array_add (msg_array);
6124       vat_json_init_object (msg);
6125       vat_json_object_add_uint (msg, "vrf_id",
6126                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6127       counter_array = vat_json_object_add (msg, "c");
6128       vat_json_init_array (counter_array);
6129       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6130         {
6131           counter = vat_json_array_add (counter_array);
6132           vat_json_init_object (counter);
6133           c4 = &vam->ip4_fib_counters[i][j];
6134           vat_json_object_add_ip4 (counter, "address", c4->address);
6135           vat_json_object_add_uint (counter, "address_length",
6136                                     c4->address_length);
6137           vat_json_object_add_uint (counter, "packets", c4->packets);
6138           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6139         }
6140     }
6141
6142   /* ip6 fib counters */
6143   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6144   vat_json_init_array (msg_array);
6145   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6146     {
6147       msg = vat_json_array_add (msg_array);
6148       vat_json_init_object (msg);
6149       vat_json_object_add_uint (msg, "vrf_id",
6150                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6151       counter_array = vat_json_object_add (msg, "c");
6152       vat_json_init_array (counter_array);
6153       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6154         {
6155           counter = vat_json_array_add (counter_array);
6156           vat_json_init_object (counter);
6157           c6 = &vam->ip6_fib_counters[i][j];
6158           vat_json_object_add_ip6 (counter, "address", c6->address);
6159           vat_json_object_add_uint (counter, "address_length",
6160                                     c6->address_length);
6161           vat_json_object_add_uint (counter, "packets", c6->packets);
6162           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6163         }
6164     }
6165
6166   /* ip4 nbr counters */
6167   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6168   vat_json_init_array (msg_array);
6169   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6170     {
6171       msg = vat_json_array_add (msg_array);
6172       vat_json_init_object (msg);
6173       vat_json_object_add_uint (msg, "sw_if_index", i);
6174       counter_array = vat_json_object_add (msg, "c");
6175       vat_json_init_array (counter_array);
6176       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6177         {
6178           counter = vat_json_array_add (counter_array);
6179           vat_json_init_object (counter);
6180           n4 = &vam->ip4_nbr_counters[i][j];
6181           vat_json_object_add_ip4 (counter, "address", n4->address);
6182           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6183           vat_json_object_add_uint (counter, "packets", n4->packets);
6184           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6185         }
6186     }
6187
6188   /* ip6 nbr counters */
6189   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6190   vat_json_init_array (msg_array);
6191   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6192     {
6193       msg = vat_json_array_add (msg_array);
6194       vat_json_init_object (msg);
6195       vat_json_object_add_uint (msg, "sw_if_index", i);
6196       counter_array = vat_json_object_add (msg, "c");
6197       vat_json_init_array (counter_array);
6198       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6199         {
6200           counter = vat_json_array_add (counter_array);
6201           vat_json_init_object (counter);
6202           n6 = &vam->ip6_nbr_counters[i][j];
6203           vat_json_object_add_ip6 (counter, "address", n6->address);
6204           vat_json_object_add_uint (counter, "packets", n6->packets);
6205           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6206         }
6207     }
6208
6209   vat_json_print (vam->ofp, &node);
6210   vat_json_free (&node);
6211
6212   return 0;
6213 }
6214
6215 /*
6216  * Pass CLI buffers directly in the CLI_INBAND API message,
6217  * instead of an additional shared memory area.
6218  */
6219 static int
6220 exec_inband (vat_main_t * vam)
6221 {
6222   vl_api_cli_inband_t *mp;
6223   unformat_input_t *i = vam->input;
6224   int ret;
6225
6226   if (vec_len (i->buffer) == 0)
6227     return -1;
6228
6229   if (vam->exec_mode == 0 && unformat (i, "mode"))
6230     {
6231       vam->exec_mode = 1;
6232       return 0;
6233     }
6234   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6235     {
6236       vam->exec_mode = 0;
6237       return 0;
6238     }
6239
6240   /*
6241    * In order for the CLI command to work, it
6242    * must be a vector ending in \n, not a C-string ending
6243    * in \n\0.
6244    */
6245   u32 len = vec_len (vam->input->buffer);
6246   M2 (CLI_INBAND, mp, len);
6247   clib_memcpy (mp->cmd, vam->input->buffer, len);
6248   mp->length = htonl (len);
6249
6250   S (mp);
6251   W (ret);
6252   /* json responses may or may not include a useful reply... */
6253   if (vec_len (vam->cmd_reply))
6254     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6255   return ret;
6256 }
6257
6258 int
6259 exec (vat_main_t * vam)
6260 {
6261   return exec_inband (vam);
6262 }
6263
6264 static int
6265 api_create_loopback (vat_main_t * vam)
6266 {
6267   unformat_input_t *i = vam->input;
6268   vl_api_create_loopback_t *mp;
6269   vl_api_create_loopback_instance_t *mp_lbi;
6270   u8 mac_address[6];
6271   u8 mac_set = 0;
6272   u8 is_specified = 0;
6273   u32 user_instance = 0;
6274   int ret;
6275
6276   memset (mac_address, 0, sizeof (mac_address));
6277
6278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6279     {
6280       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6281         mac_set = 1;
6282       if (unformat (i, "instance %d", &user_instance))
6283         is_specified = 1;
6284       else
6285         break;
6286     }
6287
6288   if (is_specified)
6289     {
6290       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6291       mp_lbi->is_specified = is_specified;
6292       if (is_specified)
6293         mp_lbi->user_instance = htonl (user_instance);
6294       if (mac_set)
6295         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6296       S (mp_lbi);
6297     }
6298   else
6299     {
6300       /* Construct the API message */
6301       M (CREATE_LOOPBACK, mp);
6302       if (mac_set)
6303         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6304       S (mp);
6305     }
6306
6307   W (ret);
6308   return ret;
6309 }
6310
6311 static int
6312 api_delete_loopback (vat_main_t * vam)
6313 {
6314   unformat_input_t *i = vam->input;
6315   vl_api_delete_loopback_t *mp;
6316   u32 sw_if_index = ~0;
6317   int ret;
6318
6319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6320     {
6321       if (unformat (i, "sw_if_index %d", &sw_if_index))
6322         ;
6323       else
6324         break;
6325     }
6326
6327   if (sw_if_index == ~0)
6328     {
6329       errmsg ("missing sw_if_index");
6330       return -99;
6331     }
6332
6333   /* Construct the API message */
6334   M (DELETE_LOOPBACK, mp);
6335   mp->sw_if_index = ntohl (sw_if_index);
6336
6337   S (mp);
6338   W (ret);
6339   return ret;
6340 }
6341
6342 static int
6343 api_want_stats (vat_main_t * vam)
6344 {
6345   unformat_input_t *i = vam->input;
6346   vl_api_want_stats_t *mp;
6347   int enable = -1;
6348   int ret;
6349
6350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6351     {
6352       if (unformat (i, "enable"))
6353         enable = 1;
6354       else if (unformat (i, "disable"))
6355         enable = 0;
6356       else
6357         break;
6358     }
6359
6360   if (enable == -1)
6361     {
6362       errmsg ("missing enable|disable");
6363       return -99;
6364     }
6365
6366   M (WANT_STATS, mp);
6367   mp->enable_disable = enable;
6368
6369   S (mp);
6370   W (ret);
6371   return ret;
6372 }
6373
6374 static int
6375 api_want_interface_events (vat_main_t * vam)
6376 {
6377   unformat_input_t *i = vam->input;
6378   vl_api_want_interface_events_t *mp;
6379   int enable = -1;
6380   int ret;
6381
6382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6383     {
6384       if (unformat (i, "enable"))
6385         enable = 1;
6386       else if (unformat (i, "disable"))
6387         enable = 0;
6388       else
6389         break;
6390     }
6391
6392   if (enable == -1)
6393     {
6394       errmsg ("missing enable|disable");
6395       return -99;
6396     }
6397
6398   M (WANT_INTERFACE_EVENTS, mp);
6399   mp->enable_disable = enable;
6400
6401   vam->interface_event_display = enable;
6402
6403   S (mp);
6404   W (ret);
6405   return ret;
6406 }
6407
6408
6409 /* Note: non-static, called once to set up the initial intfc table */
6410 int
6411 api_sw_interface_dump (vat_main_t * vam)
6412 {
6413   vl_api_sw_interface_dump_t *mp;
6414   vl_api_control_ping_t *mp_ping;
6415   hash_pair_t *p;
6416   name_sort_t *nses = 0, *ns;
6417   sw_interface_subif_t *sub = NULL;
6418   int ret;
6419
6420   /* Toss the old name table */
6421   /* *INDENT-OFF* */
6422   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6423   ({
6424     vec_add2 (nses, ns, 1);
6425     ns->name = (u8 *)(p->key);
6426     ns->value = (u32) p->value[0];
6427   }));
6428   /* *INDENT-ON* */
6429
6430   hash_free (vam->sw_if_index_by_interface_name);
6431
6432   vec_foreach (ns, nses) vec_free (ns->name);
6433
6434   vec_free (nses);
6435
6436   vec_foreach (sub, vam->sw_if_subif_table)
6437   {
6438     vec_free (sub->interface_name);
6439   }
6440   vec_free (vam->sw_if_subif_table);
6441
6442   /* recreate the interface name hash table */
6443   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6444
6445   /*
6446    * Ask for all interface names. Otherwise, the epic catalog of
6447    * name filters becomes ridiculously long, and vat ends up needing
6448    * to be taught about new interface types.
6449    */
6450   M (SW_INTERFACE_DUMP, mp);
6451   S (mp);
6452
6453   /* Use a control ping for synchronization */
6454   MPING (CONTROL_PING, mp_ping);
6455   S (mp_ping);
6456
6457   W (ret);
6458   return ret;
6459 }
6460
6461 static int
6462 api_sw_interface_set_flags (vat_main_t * vam)
6463 {
6464   unformat_input_t *i = vam->input;
6465   vl_api_sw_interface_set_flags_t *mp;
6466   u32 sw_if_index;
6467   u8 sw_if_index_set = 0;
6468   u8 admin_up = 0;
6469   int ret;
6470
6471   /* Parse args required to build the message */
6472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6473     {
6474       if (unformat (i, "admin-up"))
6475         admin_up = 1;
6476       else if (unformat (i, "admin-down"))
6477         admin_up = 0;
6478       else
6479         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6480         sw_if_index_set = 1;
6481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6482         sw_if_index_set = 1;
6483       else
6484         break;
6485     }
6486
6487   if (sw_if_index_set == 0)
6488     {
6489       errmsg ("missing interface name or sw_if_index");
6490       return -99;
6491     }
6492
6493   /* Construct the API message */
6494   M (SW_INTERFACE_SET_FLAGS, mp);
6495   mp->sw_if_index = ntohl (sw_if_index);
6496   mp->admin_up_down = admin_up;
6497
6498   /* send it... */
6499   S (mp);
6500
6501   /* Wait for a reply, return the good/bad news... */
6502   W (ret);
6503   return ret;
6504 }
6505
6506 static int
6507 api_sw_interface_set_rx_mode (vat_main_t * vam)
6508 {
6509   unformat_input_t *i = vam->input;
6510   vl_api_sw_interface_set_rx_mode_t *mp;
6511   u32 sw_if_index;
6512   u8 sw_if_index_set = 0;
6513   int ret;
6514   u8 queue_id_valid = 0;
6515   u32 queue_id;
6516   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6517
6518   /* Parse args required to build the message */
6519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6520     {
6521       if (unformat (i, "queue %d", &queue_id))
6522         queue_id_valid = 1;
6523       else if (unformat (i, "polling"))
6524         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6525       else if (unformat (i, "interrupt"))
6526         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6527       else if (unformat (i, "adaptive"))
6528         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6529       else
6530         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6531         sw_if_index_set = 1;
6532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6533         sw_if_index_set = 1;
6534       else
6535         break;
6536     }
6537
6538   if (sw_if_index_set == 0)
6539     {
6540       errmsg ("missing interface name or sw_if_index");
6541       return -99;
6542     }
6543   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6544     {
6545       errmsg ("missing rx-mode");
6546       return -99;
6547     }
6548
6549   /* Construct the API message */
6550   M (SW_INTERFACE_SET_RX_MODE, mp);
6551   mp->sw_if_index = ntohl (sw_if_index);
6552   mp->mode = mode;
6553   mp->queue_id_valid = queue_id_valid;
6554   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6555
6556   /* send it... */
6557   S (mp);
6558
6559   /* Wait for a reply, return the good/bad news... */
6560   W (ret);
6561   return ret;
6562 }
6563
6564 static int
6565 api_sw_interface_clear_stats (vat_main_t * vam)
6566 {
6567   unformat_input_t *i = vam->input;
6568   vl_api_sw_interface_clear_stats_t *mp;
6569   u32 sw_if_index;
6570   u8 sw_if_index_set = 0;
6571   int ret;
6572
6573   /* Parse args required to build the message */
6574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6575     {
6576       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6577         sw_if_index_set = 1;
6578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6579         sw_if_index_set = 1;
6580       else
6581         break;
6582     }
6583
6584   /* Construct the API message */
6585   M (SW_INTERFACE_CLEAR_STATS, mp);
6586
6587   if (sw_if_index_set == 1)
6588     mp->sw_if_index = ntohl (sw_if_index);
6589   else
6590     mp->sw_if_index = ~0;
6591
6592   /* send it... */
6593   S (mp);
6594
6595   /* Wait for a reply, return the good/bad news... */
6596   W (ret);
6597   return ret;
6598 }
6599
6600 static int
6601 api_sw_interface_add_del_address (vat_main_t * vam)
6602 {
6603   unformat_input_t *i = vam->input;
6604   vl_api_sw_interface_add_del_address_t *mp;
6605   u32 sw_if_index;
6606   u8 sw_if_index_set = 0;
6607   u8 is_add = 1, del_all = 0;
6608   u32 address_length = 0;
6609   u8 v4_address_set = 0;
6610   u8 v6_address_set = 0;
6611   ip4_address_t v4address;
6612   ip6_address_t v6address;
6613   int ret;
6614
6615   /* Parse args required to build the message */
6616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6617     {
6618       if (unformat (i, "del-all"))
6619         del_all = 1;
6620       else if (unformat (i, "del"))
6621         is_add = 0;
6622       else
6623         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6624         sw_if_index_set = 1;
6625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6626         sw_if_index_set = 1;
6627       else if (unformat (i, "%U/%d",
6628                          unformat_ip4_address, &v4address, &address_length))
6629         v4_address_set = 1;
6630       else if (unformat (i, "%U/%d",
6631                          unformat_ip6_address, &v6address, &address_length))
6632         v6_address_set = 1;
6633       else
6634         break;
6635     }
6636
6637   if (sw_if_index_set == 0)
6638     {
6639       errmsg ("missing interface name or sw_if_index");
6640       return -99;
6641     }
6642   if (v4_address_set && v6_address_set)
6643     {
6644       errmsg ("both v4 and v6 addresses set");
6645       return -99;
6646     }
6647   if (!v4_address_set && !v6_address_set && !del_all)
6648     {
6649       errmsg ("no addresses set");
6650       return -99;
6651     }
6652
6653   /* Construct the API message */
6654   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6655
6656   mp->sw_if_index = ntohl (sw_if_index);
6657   mp->is_add = is_add;
6658   mp->del_all = del_all;
6659   if (v6_address_set)
6660     {
6661       mp->is_ipv6 = 1;
6662       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6663     }
6664   else
6665     {
6666       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6667     }
6668   mp->address_length = address_length;
6669
6670   /* send it... */
6671   S (mp);
6672
6673   /* Wait for a reply, return good/bad news  */
6674   W (ret);
6675   return ret;
6676 }
6677
6678 static int
6679 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6680 {
6681   unformat_input_t *i = vam->input;
6682   vl_api_sw_interface_set_mpls_enable_t *mp;
6683   u32 sw_if_index;
6684   u8 sw_if_index_set = 0;
6685   u8 enable = 1;
6686   int ret;
6687
6688   /* Parse args required to build the message */
6689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6690     {
6691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6692         sw_if_index_set = 1;
6693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6694         sw_if_index_set = 1;
6695       else if (unformat (i, "disable"))
6696         enable = 0;
6697       else if (unformat (i, "dis"))
6698         enable = 0;
6699       else
6700         break;
6701     }
6702
6703   if (sw_if_index_set == 0)
6704     {
6705       errmsg ("missing interface name or sw_if_index");
6706       return -99;
6707     }
6708
6709   /* Construct the API message */
6710   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6711
6712   mp->sw_if_index = ntohl (sw_if_index);
6713   mp->enable = enable;
6714
6715   /* send it... */
6716   S (mp);
6717
6718   /* Wait for a reply... */
6719   W (ret);
6720   return ret;
6721 }
6722
6723 static int
6724 api_sw_interface_set_table (vat_main_t * vam)
6725 {
6726   unformat_input_t *i = vam->input;
6727   vl_api_sw_interface_set_table_t *mp;
6728   u32 sw_if_index, vrf_id = 0;
6729   u8 sw_if_index_set = 0;
6730   u8 is_ipv6 = 0;
6731   int ret;
6732
6733   /* Parse args required to build the message */
6734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6735     {
6736       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6737         sw_if_index_set = 1;
6738       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6739         sw_if_index_set = 1;
6740       else if (unformat (i, "vrf %d", &vrf_id))
6741         ;
6742       else if (unformat (i, "ipv6"))
6743         is_ipv6 = 1;
6744       else
6745         break;
6746     }
6747
6748   if (sw_if_index_set == 0)
6749     {
6750       errmsg ("missing interface name or sw_if_index");
6751       return -99;
6752     }
6753
6754   /* Construct the API message */
6755   M (SW_INTERFACE_SET_TABLE, mp);
6756
6757   mp->sw_if_index = ntohl (sw_if_index);
6758   mp->is_ipv6 = is_ipv6;
6759   mp->vrf_id = ntohl (vrf_id);
6760
6761   /* send it... */
6762   S (mp);
6763
6764   /* Wait for a reply... */
6765   W (ret);
6766   return ret;
6767 }
6768
6769 static void vl_api_sw_interface_get_table_reply_t_handler
6770   (vl_api_sw_interface_get_table_reply_t * mp)
6771 {
6772   vat_main_t *vam = &vat_main;
6773
6774   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6775
6776   vam->retval = ntohl (mp->retval);
6777   vam->result_ready = 1;
6778
6779 }
6780
6781 static void vl_api_sw_interface_get_table_reply_t_handler_json
6782   (vl_api_sw_interface_get_table_reply_t * mp)
6783 {
6784   vat_main_t *vam = &vat_main;
6785   vat_json_node_t node;
6786
6787   vat_json_init_object (&node);
6788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6789   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6790
6791   vat_json_print (vam->ofp, &node);
6792   vat_json_free (&node);
6793
6794   vam->retval = ntohl (mp->retval);
6795   vam->result_ready = 1;
6796 }
6797
6798 static int
6799 api_sw_interface_get_table (vat_main_t * vam)
6800 {
6801   unformat_input_t *i = vam->input;
6802   vl_api_sw_interface_get_table_t *mp;
6803   u32 sw_if_index;
6804   u8 sw_if_index_set = 0;
6805   u8 is_ipv6 = 0;
6806   int ret;
6807
6808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6809     {
6810       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6811         sw_if_index_set = 1;
6812       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6813         sw_if_index_set = 1;
6814       else if (unformat (i, "ipv6"))
6815         is_ipv6 = 1;
6816       else
6817         break;
6818     }
6819
6820   if (sw_if_index_set == 0)
6821     {
6822       errmsg ("missing interface name or sw_if_index");
6823       return -99;
6824     }
6825
6826   M (SW_INTERFACE_GET_TABLE, mp);
6827   mp->sw_if_index = htonl (sw_if_index);
6828   mp->is_ipv6 = is_ipv6;
6829
6830   S (mp);
6831   W (ret);
6832   return ret;
6833 }
6834
6835 static int
6836 api_sw_interface_set_vpath (vat_main_t * vam)
6837 {
6838   unformat_input_t *i = vam->input;
6839   vl_api_sw_interface_set_vpath_t *mp;
6840   u32 sw_if_index = 0;
6841   u8 sw_if_index_set = 0;
6842   u8 is_enable = 0;
6843   int ret;
6844
6845   /* Parse args required to build the message */
6846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6847     {
6848       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6849         sw_if_index_set = 1;
6850       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6851         sw_if_index_set = 1;
6852       else if (unformat (i, "enable"))
6853         is_enable = 1;
6854       else if (unformat (i, "disable"))
6855         is_enable = 0;
6856       else
6857         break;
6858     }
6859
6860   if (sw_if_index_set == 0)
6861     {
6862       errmsg ("missing interface name or sw_if_index");
6863       return -99;
6864     }
6865
6866   /* Construct the API message */
6867   M (SW_INTERFACE_SET_VPATH, mp);
6868
6869   mp->sw_if_index = ntohl (sw_if_index);
6870   mp->enable = is_enable;
6871
6872   /* send it... */
6873   S (mp);
6874
6875   /* Wait for a reply... */
6876   W (ret);
6877   return ret;
6878 }
6879
6880 static int
6881 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6882 {
6883   unformat_input_t *i = vam->input;
6884   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6885   u32 sw_if_index = 0;
6886   u8 sw_if_index_set = 0;
6887   u8 is_enable = 1;
6888   u8 is_ipv6 = 0;
6889   int ret;
6890
6891   /* Parse args required to build the message */
6892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6893     {
6894       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6895         sw_if_index_set = 1;
6896       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6897         sw_if_index_set = 1;
6898       else if (unformat (i, "enable"))
6899         is_enable = 1;
6900       else if (unformat (i, "disable"))
6901         is_enable = 0;
6902       else if (unformat (i, "ip4"))
6903         is_ipv6 = 0;
6904       else if (unformat (i, "ip6"))
6905         is_ipv6 = 1;
6906       else
6907         break;
6908     }
6909
6910   if (sw_if_index_set == 0)
6911     {
6912       errmsg ("missing interface name or sw_if_index");
6913       return -99;
6914     }
6915
6916   /* Construct the API message */
6917   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6918
6919   mp->sw_if_index = ntohl (sw_if_index);
6920   mp->enable = is_enable;
6921   mp->is_ipv6 = is_ipv6;
6922
6923   /* send it... */
6924   S (mp);
6925
6926   /* Wait for a reply... */
6927   W (ret);
6928   return ret;
6929 }
6930
6931 static int
6932 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6933 {
6934   unformat_input_t *i = vam->input;
6935   vl_api_sw_interface_set_geneve_bypass_t *mp;
6936   u32 sw_if_index = 0;
6937   u8 sw_if_index_set = 0;
6938   u8 is_enable = 1;
6939   u8 is_ipv6 = 0;
6940   int ret;
6941
6942   /* Parse args required to build the message */
6943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6944     {
6945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6946         sw_if_index_set = 1;
6947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6948         sw_if_index_set = 1;
6949       else if (unformat (i, "enable"))
6950         is_enable = 1;
6951       else if (unformat (i, "disable"))
6952         is_enable = 0;
6953       else if (unformat (i, "ip4"))
6954         is_ipv6 = 0;
6955       else if (unformat (i, "ip6"))
6956         is_ipv6 = 1;
6957       else
6958         break;
6959     }
6960
6961   if (sw_if_index_set == 0)
6962     {
6963       errmsg ("missing interface name or sw_if_index");
6964       return -99;
6965     }
6966
6967   /* Construct the API message */
6968   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6969
6970   mp->sw_if_index = ntohl (sw_if_index);
6971   mp->enable = is_enable;
6972   mp->is_ipv6 = is_ipv6;
6973
6974   /* send it... */
6975   S (mp);
6976
6977   /* Wait for a reply... */
6978   W (ret);
6979   return ret;
6980 }
6981
6982 static int
6983 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6984 {
6985   unformat_input_t *i = vam->input;
6986   vl_api_sw_interface_set_l2_xconnect_t *mp;
6987   u32 rx_sw_if_index;
6988   u8 rx_sw_if_index_set = 0;
6989   u32 tx_sw_if_index;
6990   u8 tx_sw_if_index_set = 0;
6991   u8 enable = 1;
6992   int ret;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6998         rx_sw_if_index_set = 1;
6999       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7000         tx_sw_if_index_set = 1;
7001       else if (unformat (i, "rx"))
7002         {
7003           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7004             {
7005               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7006                             &rx_sw_if_index))
7007                 rx_sw_if_index_set = 1;
7008             }
7009           else
7010             break;
7011         }
7012       else if (unformat (i, "tx"))
7013         {
7014           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7015             {
7016               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7017                             &tx_sw_if_index))
7018                 tx_sw_if_index_set = 1;
7019             }
7020           else
7021             break;
7022         }
7023       else if (unformat (i, "enable"))
7024         enable = 1;
7025       else if (unformat (i, "disable"))
7026         enable = 0;
7027       else
7028         break;
7029     }
7030
7031   if (rx_sw_if_index_set == 0)
7032     {
7033       errmsg ("missing rx interface name or rx_sw_if_index");
7034       return -99;
7035     }
7036
7037   if (enable && (tx_sw_if_index_set == 0))
7038     {
7039       errmsg ("missing tx interface name or tx_sw_if_index");
7040       return -99;
7041     }
7042
7043   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7044
7045   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7046   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7047   mp->enable = enable;
7048
7049   S (mp);
7050   W (ret);
7051   return ret;
7052 }
7053
7054 static int
7055 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7056 {
7057   unformat_input_t *i = vam->input;
7058   vl_api_sw_interface_set_l2_bridge_t *mp;
7059   u32 rx_sw_if_index;
7060   u8 rx_sw_if_index_set = 0;
7061   u32 bd_id;
7062   u8 bd_id_set = 0;
7063   u8 bvi = 0;
7064   u32 shg = 0;
7065   u8 enable = 1;
7066   int ret;
7067
7068   /* Parse args required to build the message */
7069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7070     {
7071       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7072         rx_sw_if_index_set = 1;
7073       else if (unformat (i, "bd_id %d", &bd_id))
7074         bd_id_set = 1;
7075       else
7076         if (unformat
7077             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7078         rx_sw_if_index_set = 1;
7079       else if (unformat (i, "shg %d", &shg))
7080         ;
7081       else if (unformat (i, "bvi"))
7082         bvi = 1;
7083       else if (unformat (i, "enable"))
7084         enable = 1;
7085       else if (unformat (i, "disable"))
7086         enable = 0;
7087       else
7088         break;
7089     }
7090
7091   if (rx_sw_if_index_set == 0)
7092     {
7093       errmsg ("missing rx interface name or sw_if_index");
7094       return -99;
7095     }
7096
7097   if (enable && (bd_id_set == 0))
7098     {
7099       errmsg ("missing bridge domain");
7100       return -99;
7101     }
7102
7103   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7104
7105   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7106   mp->bd_id = ntohl (bd_id);
7107   mp->shg = (u8) shg;
7108   mp->bvi = bvi;
7109   mp->enable = enable;
7110
7111   S (mp);
7112   W (ret);
7113   return ret;
7114 }
7115
7116 static int
7117 api_bridge_domain_dump (vat_main_t * vam)
7118 {
7119   unformat_input_t *i = vam->input;
7120   vl_api_bridge_domain_dump_t *mp;
7121   vl_api_control_ping_t *mp_ping;
7122   u32 bd_id = ~0;
7123   int ret;
7124
7125   /* Parse args required to build the message */
7126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7127     {
7128       if (unformat (i, "bd_id %d", &bd_id))
7129         ;
7130       else
7131         break;
7132     }
7133
7134   M (BRIDGE_DOMAIN_DUMP, mp);
7135   mp->bd_id = ntohl (bd_id);
7136   S (mp);
7137
7138   /* Use a control ping for synchronization */
7139   MPING (CONTROL_PING, mp_ping);
7140   S (mp_ping);
7141
7142   W (ret);
7143   return ret;
7144 }
7145
7146 static int
7147 api_bridge_domain_add_del (vat_main_t * vam)
7148 {
7149   unformat_input_t *i = vam->input;
7150   vl_api_bridge_domain_add_del_t *mp;
7151   u32 bd_id = ~0;
7152   u8 is_add = 1;
7153   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7154   u8 *bd_tag = NULL;
7155   u32 mac_age = 0;
7156   int ret;
7157
7158   /* Parse args required to build the message */
7159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7160     {
7161       if (unformat (i, "bd_id %d", &bd_id))
7162         ;
7163       else if (unformat (i, "flood %d", &flood))
7164         ;
7165       else if (unformat (i, "uu-flood %d", &uu_flood))
7166         ;
7167       else if (unformat (i, "forward %d", &forward))
7168         ;
7169       else if (unformat (i, "learn %d", &learn))
7170         ;
7171       else if (unformat (i, "arp-term %d", &arp_term))
7172         ;
7173       else if (unformat (i, "mac-age %d", &mac_age))
7174         ;
7175       else if (unformat (i, "bd-tag %s", &bd_tag))
7176         ;
7177       else if (unformat (i, "del"))
7178         {
7179           is_add = 0;
7180           flood = uu_flood = forward = learn = 0;
7181         }
7182       else
7183         break;
7184     }
7185
7186   if (bd_id == ~0)
7187     {
7188       errmsg ("missing bridge domain");
7189       ret = -99;
7190       goto done;
7191     }
7192
7193   if (mac_age > 255)
7194     {
7195       errmsg ("mac age must be less than 256 ");
7196       ret = -99;
7197       goto done;
7198     }
7199
7200   if ((bd_tag) && (vec_len (bd_tag) > 63))
7201     {
7202       errmsg ("bd-tag cannot be longer than 63");
7203       ret = -99;
7204       goto done;
7205     }
7206
7207   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7208
7209   mp->bd_id = ntohl (bd_id);
7210   mp->flood = flood;
7211   mp->uu_flood = uu_flood;
7212   mp->forward = forward;
7213   mp->learn = learn;
7214   mp->arp_term = arp_term;
7215   mp->is_add = is_add;
7216   mp->mac_age = (u8) mac_age;
7217   if (bd_tag)
7218     {
7219       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7220       mp->bd_tag[vec_len (bd_tag)] = 0;
7221     }
7222   S (mp);
7223   W (ret);
7224
7225 done:
7226   vec_free (bd_tag);
7227   return ret;
7228 }
7229
7230 static int
7231 api_l2fib_flush_bd (vat_main_t * vam)
7232 {
7233   unformat_input_t *i = vam->input;
7234   vl_api_l2fib_flush_bd_t *mp;
7235   u32 bd_id = ~0;
7236   int ret;
7237
7238   /* Parse args required to build the message */
7239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7240     {
7241       if (unformat (i, "bd_id %d", &bd_id));
7242       else
7243         break;
7244     }
7245
7246   if (bd_id == ~0)
7247     {
7248       errmsg ("missing bridge domain");
7249       return -99;
7250     }
7251
7252   M (L2FIB_FLUSH_BD, mp);
7253
7254   mp->bd_id = htonl (bd_id);
7255
7256   S (mp);
7257   W (ret);
7258   return ret;
7259 }
7260
7261 static int
7262 api_l2fib_flush_int (vat_main_t * vam)
7263 {
7264   unformat_input_t *i = vam->input;
7265   vl_api_l2fib_flush_int_t *mp;
7266   u32 sw_if_index = ~0;
7267   int ret;
7268
7269   /* Parse args required to build the message */
7270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7271     {
7272       if (unformat (i, "sw_if_index %d", &sw_if_index));
7273       else
7274         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7275       else
7276         break;
7277     }
7278
7279   if (sw_if_index == ~0)
7280     {
7281       errmsg ("missing interface name or sw_if_index");
7282       return -99;
7283     }
7284
7285   M (L2FIB_FLUSH_INT, mp);
7286
7287   mp->sw_if_index = ntohl (sw_if_index);
7288
7289   S (mp);
7290   W (ret);
7291   return ret;
7292 }
7293
7294 static int
7295 api_l2fib_add_del (vat_main_t * vam)
7296 {
7297   unformat_input_t *i = vam->input;
7298   vl_api_l2fib_add_del_t *mp;
7299   f64 timeout;
7300   u8 mac[6] = { 0 };
7301   u8 mac_set = 0;
7302   u32 bd_id;
7303   u8 bd_id_set = 0;
7304   u32 sw_if_index = 0;
7305   u8 sw_if_index_set = 0;
7306   u8 is_add = 1;
7307   u8 static_mac = 0;
7308   u8 filter_mac = 0;
7309   u8 bvi_mac = 0;
7310   int count = 1;
7311   f64 before = 0;
7312   int j;
7313
7314   /* Parse args required to build the message */
7315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7316     {
7317       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7318         mac_set = 1;
7319       else if (unformat (i, "bd_id %d", &bd_id))
7320         bd_id_set = 1;
7321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7322         sw_if_index_set = 1;
7323       else if (unformat (i, "sw_if"))
7324         {
7325           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7326             {
7327               if (unformat
7328                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7329                 sw_if_index_set = 1;
7330             }
7331           else
7332             break;
7333         }
7334       else if (unformat (i, "static"))
7335         static_mac = 1;
7336       else if (unformat (i, "filter"))
7337         {
7338           filter_mac = 1;
7339           static_mac = 1;
7340         }
7341       else if (unformat (i, "bvi"))
7342         {
7343           bvi_mac = 1;
7344           static_mac = 1;
7345         }
7346       else if (unformat (i, "del"))
7347         is_add = 0;
7348       else if (unformat (i, "count %d", &count))
7349         ;
7350       else
7351         break;
7352     }
7353
7354   if (mac_set == 0)
7355     {
7356       errmsg ("missing mac address");
7357       return -99;
7358     }
7359
7360   if (bd_id_set == 0)
7361     {
7362       errmsg ("missing bridge domain");
7363       return -99;
7364     }
7365
7366   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7367     {
7368       errmsg ("missing interface name or sw_if_index");
7369       return -99;
7370     }
7371
7372   if (count > 1)
7373     {
7374       /* Turn on async mode */
7375       vam->async_mode = 1;
7376       vam->async_errors = 0;
7377       before = vat_time_now (vam);
7378     }
7379
7380   for (j = 0; j < count; j++)
7381     {
7382       M (L2FIB_ADD_DEL, mp);
7383
7384       clib_memcpy (mp->mac, mac, 6);
7385       mp->bd_id = ntohl (bd_id);
7386       mp->is_add = is_add;
7387       mp->sw_if_index = ntohl (sw_if_index);
7388
7389       if (is_add)
7390         {
7391           mp->static_mac = static_mac;
7392           mp->filter_mac = filter_mac;
7393           mp->bvi_mac = bvi_mac;
7394         }
7395       increment_mac_address (mac);
7396       /* send it... */
7397       S (mp);
7398     }
7399
7400   if (count > 1)
7401     {
7402       vl_api_control_ping_t *mp_ping;
7403       f64 after;
7404
7405       /* Shut off async mode */
7406       vam->async_mode = 0;
7407
7408       MPING (CONTROL_PING, mp_ping);
7409       S (mp_ping);
7410
7411       timeout = vat_time_now (vam) + 1.0;
7412       while (vat_time_now (vam) < timeout)
7413         if (vam->result_ready == 1)
7414           goto out;
7415       vam->retval = -99;
7416
7417     out:
7418       if (vam->retval == -99)
7419         errmsg ("timeout");
7420
7421       if (vam->async_errors > 0)
7422         {
7423           errmsg ("%d asynchronous errors", vam->async_errors);
7424           vam->retval = -98;
7425         }
7426       vam->async_errors = 0;
7427       after = vat_time_now (vam);
7428
7429       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7430              count, after - before, count / (after - before));
7431     }
7432   else
7433     {
7434       int ret;
7435
7436       /* Wait for a reply... */
7437       W (ret);
7438       return ret;
7439     }
7440   /* Return the good/bad news */
7441   return (vam->retval);
7442 }
7443
7444 static int
7445 api_bridge_domain_set_mac_age (vat_main_t * vam)
7446 {
7447   unformat_input_t *i = vam->input;
7448   vl_api_bridge_domain_set_mac_age_t *mp;
7449   u32 bd_id = ~0;
7450   u32 mac_age = 0;
7451   int ret;
7452
7453   /* Parse args required to build the message */
7454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7455     {
7456       if (unformat (i, "bd_id %d", &bd_id));
7457       else if (unformat (i, "mac-age %d", &mac_age));
7458       else
7459         break;
7460     }
7461
7462   if (bd_id == ~0)
7463     {
7464       errmsg ("missing bridge domain");
7465       return -99;
7466     }
7467
7468   if (mac_age > 255)
7469     {
7470       errmsg ("mac age must be less than 256 ");
7471       return -99;
7472     }
7473
7474   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7475
7476   mp->bd_id = htonl (bd_id);
7477   mp->mac_age = (u8) mac_age;
7478
7479   S (mp);
7480   W (ret);
7481   return ret;
7482 }
7483
7484 static int
7485 api_l2_flags (vat_main_t * vam)
7486 {
7487   unformat_input_t *i = vam->input;
7488   vl_api_l2_flags_t *mp;
7489   u32 sw_if_index;
7490   u32 flags = 0;
7491   u8 sw_if_index_set = 0;
7492   u8 is_set = 0;
7493   int ret;
7494
7495   /* Parse args required to build the message */
7496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7497     {
7498       if (unformat (i, "sw_if_index %d", &sw_if_index))
7499         sw_if_index_set = 1;
7500       else if (unformat (i, "sw_if"))
7501         {
7502           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7503             {
7504               if (unformat
7505                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7506                 sw_if_index_set = 1;
7507             }
7508           else
7509             break;
7510         }
7511       else if (unformat (i, "learn"))
7512         flags |= L2_LEARN;
7513       else if (unformat (i, "forward"))
7514         flags |= L2_FWD;
7515       else if (unformat (i, "flood"))
7516         flags |= L2_FLOOD;
7517       else if (unformat (i, "uu-flood"))
7518         flags |= L2_UU_FLOOD;
7519       else if (unformat (i, "arp-term"))
7520         flags |= L2_ARP_TERM;
7521       else if (unformat (i, "off"))
7522         is_set = 0;
7523       else if (unformat (i, "disable"))
7524         is_set = 0;
7525       else
7526         break;
7527     }
7528
7529   if (sw_if_index_set == 0)
7530     {
7531       errmsg ("missing interface name or sw_if_index");
7532       return -99;
7533     }
7534
7535   M (L2_FLAGS, mp);
7536
7537   mp->sw_if_index = ntohl (sw_if_index);
7538   mp->feature_bitmap = ntohl (flags);
7539   mp->is_set = is_set;
7540
7541   S (mp);
7542   W (ret);
7543   return ret;
7544 }
7545
7546 static int
7547 api_bridge_flags (vat_main_t * vam)
7548 {
7549   unformat_input_t *i = vam->input;
7550   vl_api_bridge_flags_t *mp;
7551   u32 bd_id;
7552   u8 bd_id_set = 0;
7553   u8 is_set = 1;
7554   u32 flags = 0;
7555   int ret;
7556
7557   /* Parse args required to build the message */
7558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7559     {
7560       if (unformat (i, "bd_id %d", &bd_id))
7561         bd_id_set = 1;
7562       else if (unformat (i, "learn"))
7563         flags |= L2_LEARN;
7564       else if (unformat (i, "forward"))
7565         flags |= L2_FWD;
7566       else if (unformat (i, "flood"))
7567         flags |= L2_FLOOD;
7568       else if (unformat (i, "uu-flood"))
7569         flags |= L2_UU_FLOOD;
7570       else if (unformat (i, "arp-term"))
7571         flags |= L2_ARP_TERM;
7572       else if (unformat (i, "off"))
7573         is_set = 0;
7574       else if (unformat (i, "disable"))
7575         is_set = 0;
7576       else
7577         break;
7578     }
7579
7580   if (bd_id_set == 0)
7581     {
7582       errmsg ("missing bridge domain");
7583       return -99;
7584     }
7585
7586   M (BRIDGE_FLAGS, mp);
7587
7588   mp->bd_id = ntohl (bd_id);
7589   mp->feature_bitmap = ntohl (flags);
7590   mp->is_set = is_set;
7591
7592   S (mp);
7593   W (ret);
7594   return ret;
7595 }
7596
7597 static int
7598 api_bd_ip_mac_add_del (vat_main_t * vam)
7599 {
7600   unformat_input_t *i = vam->input;
7601   vl_api_bd_ip_mac_add_del_t *mp;
7602   u32 bd_id;
7603   u8 is_ipv6 = 0;
7604   u8 is_add = 1;
7605   u8 bd_id_set = 0;
7606   u8 ip_set = 0;
7607   u8 mac_set = 0;
7608   ip4_address_t v4addr;
7609   ip6_address_t v6addr;
7610   u8 macaddr[6];
7611   int ret;
7612
7613
7614   /* Parse args required to build the message */
7615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7616     {
7617       if (unformat (i, "bd_id %d", &bd_id))
7618         {
7619           bd_id_set++;
7620         }
7621       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7622         {
7623           ip_set++;
7624         }
7625       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7626         {
7627           ip_set++;
7628           is_ipv6++;
7629         }
7630       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7631         {
7632           mac_set++;
7633         }
7634       else if (unformat (i, "del"))
7635         is_add = 0;
7636       else
7637         break;
7638     }
7639
7640   if (bd_id_set == 0)
7641     {
7642       errmsg ("missing bridge domain");
7643       return -99;
7644     }
7645   else if (ip_set == 0)
7646     {
7647       errmsg ("missing IP address");
7648       return -99;
7649     }
7650   else if (mac_set == 0)
7651     {
7652       errmsg ("missing MAC address");
7653       return -99;
7654     }
7655
7656   M (BD_IP_MAC_ADD_DEL, mp);
7657
7658   mp->bd_id = ntohl (bd_id);
7659   mp->is_ipv6 = is_ipv6;
7660   mp->is_add = is_add;
7661   if (is_ipv6)
7662     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7663   else
7664     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7665   clib_memcpy (mp->mac_address, macaddr, 6);
7666   S (mp);
7667   W (ret);
7668   return ret;
7669 }
7670
7671 static void vl_api_bd_ip_mac_details_t_handler
7672   (vl_api_bd_ip_mac_details_t * mp)
7673 {
7674   vat_main_t *vam = &vat_main;
7675   u8 *ip = 0;
7676
7677   if (!mp->is_ipv6)
7678     ip =
7679       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7680   else
7681     ip =
7682       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7683
7684   print (vam->ofp,
7685          "\n%-5d %-7s %-20U %-30s",
7686          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7687          format_ethernet_address, mp->mac_address, ip);
7688
7689   vec_free (ip);
7690 }
7691
7692 static void vl_api_bd_ip_mac_details_t_handler_json
7693   (vl_api_bd_ip_mac_details_t * mp)
7694 {
7695   vat_main_t *vam = &vat_main;
7696   vat_json_node_t *node = NULL;
7697
7698   if (VAT_JSON_ARRAY != vam->json_tree.type)
7699     {
7700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7701       vat_json_init_array (&vam->json_tree);
7702     }
7703   node = vat_json_array_add (&vam->json_tree);
7704
7705   vat_json_init_object (node);
7706   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7707   vat_json_object_add_uint (node, "is_ipv6", ntohl (mp->is_ipv6));
7708   vat_json_object_add_string_copy (node, "mac_address",
7709                                    format (0, "%U", format_ethernet_address,
7710                                            &mp->mac_address));
7711   u8 *ip = 0;
7712
7713   if (!mp->is_ipv6)
7714     ip =
7715       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7716   else
7717     ip =
7718       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7719   vat_json_object_add_string_copy (node, "ip_address", ip);
7720   vec_free (ip);
7721 }
7722
7723 static int
7724 api_bd_ip_mac_dump (vat_main_t * vam)
7725 {
7726   unformat_input_t *i = vam->input;
7727   vl_api_bd_ip_mac_dump_t *mp;
7728   vl_api_control_ping_t *mp_ping;
7729   int ret;
7730   u32 bd_id;
7731   u8 bd_id_set = 0;
7732
7733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7734     {
7735       if (unformat (i, "bd_id %d", &bd_id))
7736         {
7737           bd_id_set++;
7738         }
7739       else
7740         break;
7741     }
7742
7743   print (vam->ofp,
7744          "\n%-5s %-7s %-20s %-30s",
7745          "bd_id", "is_ipv6", "mac_address", "ip_address");
7746
7747   /* Dump Bridge Domain Ip to Mac entries */
7748   M (BD_IP_MAC_DUMP, mp);
7749
7750   if (bd_id_set)
7751     mp->bd_id = htonl (bd_id);
7752   else
7753     mp->bd_id = ~0;
7754
7755   S (mp);
7756
7757   /* Use a control ping for synchronization */
7758   MPING (CONTROL_PING, mp_ping);
7759   S (mp_ping);
7760
7761   W (ret);
7762   return ret;
7763 }
7764
7765 static int
7766 api_tap_connect (vat_main_t * vam)
7767 {
7768   unformat_input_t *i = vam->input;
7769   vl_api_tap_connect_t *mp;
7770   u8 mac_address[6];
7771   u8 random_mac = 1;
7772   u8 name_set = 0;
7773   u8 *tap_name;
7774   u8 *tag = 0;
7775   ip4_address_t ip4_address;
7776   u32 ip4_mask_width;
7777   int ip4_address_set = 0;
7778   ip6_address_t ip6_address;
7779   u32 ip6_mask_width;
7780   int ip6_address_set = 0;
7781   int ret;
7782
7783   memset (mac_address, 0, sizeof (mac_address));
7784
7785   /* Parse args required to build the message */
7786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7787     {
7788       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7789         {
7790           random_mac = 0;
7791         }
7792       else if (unformat (i, "random-mac"))
7793         random_mac = 1;
7794       else if (unformat (i, "tapname %s", &tap_name))
7795         name_set = 1;
7796       else if (unformat (i, "tag %s", &tag))
7797         ;
7798       else if (unformat (i, "address %U/%d",
7799                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7800         ip4_address_set = 1;
7801       else if (unformat (i, "address %U/%d",
7802                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7803         ip6_address_set = 1;
7804       else
7805         break;
7806     }
7807
7808   if (name_set == 0)
7809     {
7810       errmsg ("missing tap name");
7811       return -99;
7812     }
7813   if (vec_len (tap_name) > 63)
7814     {
7815       errmsg ("tap name too long");
7816       return -99;
7817     }
7818   vec_add1 (tap_name, 0);
7819
7820   if (vec_len (tag) > 63)
7821     {
7822       errmsg ("tag too long");
7823       return -99;
7824     }
7825
7826   /* Construct the API message */
7827   M (TAP_CONNECT, mp);
7828
7829   mp->use_random_mac = random_mac;
7830   clib_memcpy (mp->mac_address, mac_address, 6);
7831   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7832   if (tag)
7833     clib_memcpy (mp->tag, tag, vec_len (tag));
7834
7835   if (ip4_address_set)
7836     {
7837       mp->ip4_address_set = 1;
7838       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7839       mp->ip4_mask_width = ip4_mask_width;
7840     }
7841   if (ip6_address_set)
7842     {
7843       mp->ip6_address_set = 1;
7844       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7845       mp->ip6_mask_width = ip6_mask_width;
7846     }
7847
7848   vec_free (tap_name);
7849   vec_free (tag);
7850
7851   /* send it... */
7852   S (mp);
7853
7854   /* Wait for a reply... */
7855   W (ret);
7856   return ret;
7857 }
7858
7859 static int
7860 api_tap_modify (vat_main_t * vam)
7861 {
7862   unformat_input_t *i = vam->input;
7863   vl_api_tap_modify_t *mp;
7864   u8 mac_address[6];
7865   u8 random_mac = 1;
7866   u8 name_set = 0;
7867   u8 *tap_name;
7868   u32 sw_if_index = ~0;
7869   u8 sw_if_index_set = 0;
7870   int ret;
7871
7872   memset (mac_address, 0, sizeof (mac_address));
7873
7874   /* Parse args required to build the message */
7875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7876     {
7877       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7878         sw_if_index_set = 1;
7879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7880         sw_if_index_set = 1;
7881       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7882         {
7883           random_mac = 0;
7884         }
7885       else if (unformat (i, "random-mac"))
7886         random_mac = 1;
7887       else if (unformat (i, "tapname %s", &tap_name))
7888         name_set = 1;
7889       else
7890         break;
7891     }
7892
7893   if (sw_if_index_set == 0)
7894     {
7895       errmsg ("missing vpp interface name");
7896       return -99;
7897     }
7898   if (name_set == 0)
7899     {
7900       errmsg ("missing tap name");
7901       return -99;
7902     }
7903   if (vec_len (tap_name) > 63)
7904     {
7905       errmsg ("tap name too long");
7906     }
7907   vec_add1 (tap_name, 0);
7908
7909   /* Construct the API message */
7910   M (TAP_MODIFY, mp);
7911
7912   mp->use_random_mac = random_mac;
7913   mp->sw_if_index = ntohl (sw_if_index);
7914   clib_memcpy (mp->mac_address, mac_address, 6);
7915   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7916   vec_free (tap_name);
7917
7918   /* send it... */
7919   S (mp);
7920
7921   /* Wait for a reply... */
7922   W (ret);
7923   return ret;
7924 }
7925
7926 static int
7927 api_tap_delete (vat_main_t * vam)
7928 {
7929   unformat_input_t *i = vam->input;
7930   vl_api_tap_delete_t *mp;
7931   u32 sw_if_index = ~0;
7932   u8 sw_if_index_set = 0;
7933   int ret;
7934
7935   /* Parse args required to build the message */
7936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7937     {
7938       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7939         sw_if_index_set = 1;
7940       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7941         sw_if_index_set = 1;
7942       else
7943         break;
7944     }
7945
7946   if (sw_if_index_set == 0)
7947     {
7948       errmsg ("missing vpp interface name");
7949       return -99;
7950     }
7951
7952   /* Construct the API message */
7953   M (TAP_DELETE, mp);
7954
7955   mp->sw_if_index = ntohl (sw_if_index);
7956
7957   /* send it... */
7958   S (mp);
7959
7960   /* Wait for a reply... */
7961   W (ret);
7962   return ret;
7963 }
7964
7965 static int
7966 api_tap_create_v2 (vat_main_t * vam)
7967 {
7968   unformat_input_t *i = vam->input;
7969   vl_api_tap_create_v2_t *mp;
7970   u8 mac_address[6];
7971   u8 random_mac = 1;
7972   u32 id = ~0;
7973   u8 *host_if_name = 0;
7974   u8 *host_ns = 0;
7975   u8 host_mac_addr[6];
7976   u8 host_mac_addr_set = 0;
7977   u8 *host_bridge = 0;
7978   ip4_address_t host_ip4_addr;
7979   ip4_address_t host_ip4_gw;
7980   u8 host_ip4_gw_set = 0;
7981   u32 host_ip4_prefix_len = 0;
7982   ip6_address_t host_ip6_addr;
7983   ip6_address_t host_ip6_gw;
7984   u8 host_ip6_gw_set = 0;
7985   u32 host_ip6_prefix_len = 0;
7986   int ret;
7987   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7988
7989   memset (mac_address, 0, sizeof (mac_address));
7990
7991   /* Parse args required to build the message */
7992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7993     {
7994       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7995         {
7996           random_mac = 0;
7997         }
7998       else if (unformat (i, "id %u", &id))
7999         ;
8000       else if (unformat (i, "host-if-name %s", &host_if_name))
8001         ;
8002       else if (unformat (i, "host-ns %s", &host_ns))
8003         ;
8004       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8005                          host_mac_addr))
8006         host_mac_addr_set = 1;
8007       else if (unformat (i, "host-bridge %s", &host_bridge))
8008         ;
8009       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8010                          &host_ip4_addr, &host_ip4_prefix_len))
8011         ;
8012       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8013                          &host_ip6_addr, &host_ip6_prefix_len))
8014         ;
8015       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8016                          &host_ip4_gw))
8017         host_ip4_gw_set = 1;
8018       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8019                          &host_ip6_gw))
8020         host_ip6_gw_set = 1;
8021       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8022         ;
8023       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8024         ;
8025       else
8026         break;
8027     }
8028
8029   if (vec_len (host_if_name) > 63)
8030     {
8031       errmsg ("tap name too long. ");
8032       return -99;
8033     }
8034   if (vec_len (host_ns) > 63)
8035     {
8036       errmsg ("host name space too long. ");
8037       return -99;
8038     }
8039   if (vec_len (host_bridge) > 63)
8040     {
8041       errmsg ("host bridge name too long. ");
8042       return -99;
8043     }
8044   if (host_ip4_prefix_len > 32)
8045     {
8046       errmsg ("host ip4 prefix length not valid. ");
8047       return -99;
8048     }
8049   if (host_ip6_prefix_len > 128)
8050     {
8051       errmsg ("host ip6 prefix length not valid. ");
8052       return -99;
8053     }
8054   if (!is_pow2 (rx_ring_sz))
8055     {
8056       errmsg ("rx ring size must be power of 2. ");
8057       return -99;
8058     }
8059   if (rx_ring_sz > 32768)
8060     {
8061       errmsg ("rx ring size must be 32768 or lower. ");
8062       return -99;
8063     }
8064   if (!is_pow2 (tx_ring_sz))
8065     {
8066       errmsg ("tx ring size must be power of 2. ");
8067       return -99;
8068     }
8069   if (tx_ring_sz > 32768)
8070     {
8071       errmsg ("tx ring size must be 32768 or lower. ");
8072       return -99;
8073     }
8074
8075   /* Construct the API message */
8076   M (TAP_CREATE_V2, mp);
8077
8078   mp->use_random_mac = random_mac;
8079
8080   mp->id = ntohl (id);
8081   mp->host_namespace_set = host_ns != 0;
8082   mp->host_bridge_set = host_bridge != 0;
8083   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8084   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8085   mp->rx_ring_sz = ntohs (rx_ring_sz);
8086   mp->tx_ring_sz = ntohs (tx_ring_sz);
8087
8088   if (random_mac == 0)
8089     clib_memcpy (mp->mac_address, mac_address, 6);
8090   if (host_mac_addr_set)
8091     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8092   if (host_if_name)
8093     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8094   if (host_ns)
8095     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8096   if (host_bridge)
8097     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8098   if (host_ip4_prefix_len)
8099     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8100   if (host_ip4_prefix_len)
8101     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8102   if (host_ip4_gw_set)
8103     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8104   if (host_ip6_gw_set)
8105     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8106
8107   vec_free (host_ns);
8108   vec_free (host_if_name);
8109   vec_free (host_bridge);
8110
8111   /* send it... */
8112   S (mp);
8113
8114   /* Wait for a reply... */
8115   W (ret);
8116   return ret;
8117 }
8118
8119 static int
8120 api_tap_delete_v2 (vat_main_t * vam)
8121 {
8122   unformat_input_t *i = vam->input;
8123   vl_api_tap_delete_v2_t *mp;
8124   u32 sw_if_index = ~0;
8125   u8 sw_if_index_set = 0;
8126   int ret;
8127
8128   /* Parse args required to build the message */
8129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8130     {
8131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8132         sw_if_index_set = 1;
8133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8134         sw_if_index_set = 1;
8135       else
8136         break;
8137     }
8138
8139   if (sw_if_index_set == 0)
8140     {
8141       errmsg ("missing vpp interface name. ");
8142       return -99;
8143     }
8144
8145   /* Construct the API message */
8146   M (TAP_DELETE_V2, mp);
8147
8148   mp->sw_if_index = ntohl (sw_if_index);
8149
8150   /* send it... */
8151   S (mp);
8152
8153   /* Wait for a reply... */
8154   W (ret);
8155   return ret;
8156 }
8157
8158 static int
8159 api_bond_create (vat_main_t * vam)
8160 {
8161   unformat_input_t *i = vam->input;
8162   vl_api_bond_create_t *mp;
8163   u8 mac_address[6];
8164   u8 custom_mac = 0;
8165   int ret;
8166   u8 mode;
8167   u8 lb;
8168   u8 mode_is_set = 0;
8169
8170   memset (mac_address, 0, sizeof (mac_address));
8171   lb = BOND_LB_L2;
8172
8173   /* Parse args required to build the message */
8174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8175     {
8176       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8177         mode_is_set = 1;
8178       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8179                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8180         ;
8181       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8182                          mac_address))
8183         custom_mac = 1;
8184       else
8185         break;
8186     }
8187
8188   if (mode_is_set == 0)
8189     {
8190       errmsg ("Missing bond mode. ");
8191       return -99;
8192     }
8193
8194   /* Construct the API message */
8195   M (BOND_CREATE, mp);
8196
8197   mp->use_custom_mac = custom_mac;
8198
8199   mp->mode = mode;
8200   mp->lb = lb;
8201
8202   if (custom_mac)
8203     clib_memcpy (mp->mac_address, mac_address, 6);
8204
8205   /* send it... */
8206   S (mp);
8207
8208   /* Wait for a reply... */
8209   W (ret);
8210   return ret;
8211 }
8212
8213 static int
8214 api_bond_delete (vat_main_t * vam)
8215 {
8216   unformat_input_t *i = vam->input;
8217   vl_api_bond_delete_t *mp;
8218   u32 sw_if_index = ~0;
8219   u8 sw_if_index_set = 0;
8220   int ret;
8221
8222   /* Parse args required to build the message */
8223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8224     {
8225       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8226         sw_if_index_set = 1;
8227       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8228         sw_if_index_set = 1;
8229       else
8230         break;
8231     }
8232
8233   if (sw_if_index_set == 0)
8234     {
8235       errmsg ("missing vpp interface name. ");
8236       return -99;
8237     }
8238
8239   /* Construct the API message */
8240   M (BOND_DELETE, mp);
8241
8242   mp->sw_if_index = ntohl (sw_if_index);
8243
8244   /* send it... */
8245   S (mp);
8246
8247   /* Wait for a reply... */
8248   W (ret);
8249   return ret;
8250 }
8251
8252 static int
8253 api_bond_enslave (vat_main_t * vam)
8254 {
8255   unformat_input_t *i = vam->input;
8256   vl_api_bond_enslave_t *mp;
8257   u32 bond_sw_if_index;
8258   int ret;
8259   u8 is_passive;
8260   u8 is_long_timeout;
8261   u32 bond_sw_if_index_is_set = 0;
8262   u32 sw_if_index;
8263   u8 sw_if_index_is_set = 0;
8264
8265   /* Parse args required to build the message */
8266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8267     {
8268       if (unformat (i, "sw_if_index %d", &sw_if_index))
8269         sw_if_index_is_set = 1;
8270       else if (unformat (i, "bond %u", &bond_sw_if_index))
8271         bond_sw_if_index_is_set = 1;
8272       else if (unformat (i, "passive %d", &is_passive))
8273         ;
8274       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8275         ;
8276       else
8277         break;
8278     }
8279
8280   if (bond_sw_if_index_is_set == 0)
8281     {
8282       errmsg ("Missing bond sw_if_index. ");
8283       return -99;
8284     }
8285   if (sw_if_index_is_set == 0)
8286     {
8287       errmsg ("Missing slave sw_if_index. ");
8288       return -99;
8289     }
8290
8291   /* Construct the API message */
8292   M (BOND_ENSLAVE, mp);
8293
8294   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8295   mp->sw_if_index = ntohl (sw_if_index);
8296   mp->is_long_timeout = is_long_timeout;
8297   mp->is_passive = is_passive;
8298
8299   /* send it... */
8300   S (mp);
8301
8302   /* Wait for a reply... */
8303   W (ret);
8304   return ret;
8305 }
8306
8307 static int
8308 api_bond_detach_slave (vat_main_t * vam)
8309 {
8310   unformat_input_t *i = vam->input;
8311   vl_api_bond_detach_slave_t *mp;
8312   u32 sw_if_index = ~0;
8313   u8 sw_if_index_set = 0;
8314   int ret;
8315
8316   /* Parse args required to build the message */
8317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8318     {
8319       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8320         sw_if_index_set = 1;
8321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8322         sw_if_index_set = 1;
8323       else
8324         break;
8325     }
8326
8327   if (sw_if_index_set == 0)
8328     {
8329       errmsg ("missing vpp interface name. ");
8330       return -99;
8331     }
8332
8333   /* Construct the API message */
8334   M (BOND_DETACH_SLAVE, mp);
8335
8336   mp->sw_if_index = ntohl (sw_if_index);
8337
8338   /* send it... */
8339   S (mp);
8340
8341   /* Wait for a reply... */
8342   W (ret);
8343   return ret;
8344 }
8345
8346 static int
8347 api_ip_table_add_del (vat_main_t * vam)
8348 {
8349   unformat_input_t *i = vam->input;
8350   vl_api_ip_table_add_del_t *mp;
8351   u32 table_id = ~0;
8352   u8 is_ipv6 = 0;
8353   u8 is_add = 1;
8354   int ret = 0;
8355
8356   /* Parse args required to build the message */
8357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8358     {
8359       if (unformat (i, "ipv6"))
8360         is_ipv6 = 1;
8361       else if (unformat (i, "del"))
8362         is_add = 0;
8363       else if (unformat (i, "add"))
8364         is_add = 1;
8365       else if (unformat (i, "table %d", &table_id))
8366         ;
8367       else
8368         {
8369           clib_warning ("parse error '%U'", format_unformat_error, i);
8370           return -99;
8371         }
8372     }
8373
8374   if (~0 == table_id)
8375     {
8376       errmsg ("missing table-ID");
8377       return -99;
8378     }
8379
8380   /* Construct the API message */
8381   M (IP_TABLE_ADD_DEL, mp);
8382
8383   mp->table_id = ntohl (table_id);
8384   mp->is_ipv6 = is_ipv6;
8385   mp->is_add = is_add;
8386
8387   /* send it... */
8388   S (mp);
8389
8390   /* Wait for a reply... */
8391   W (ret);
8392
8393   return ret;
8394 }
8395
8396 static int
8397 api_ip_add_del_route (vat_main_t * vam)
8398 {
8399   unformat_input_t *i = vam->input;
8400   vl_api_ip_add_del_route_t *mp;
8401   u32 sw_if_index = ~0, vrf_id = 0;
8402   u8 is_ipv6 = 0;
8403   u8 is_local = 0, is_drop = 0;
8404   u8 is_unreach = 0, is_prohibit = 0;
8405   u8 is_add = 1;
8406   u32 next_hop_weight = 1;
8407   u8 is_multipath = 0;
8408   u8 address_set = 0;
8409   u8 address_length_set = 0;
8410   u32 next_hop_table_id = 0;
8411   u32 resolve_attempts = 0;
8412   u32 dst_address_length = 0;
8413   u8 next_hop_set = 0;
8414   ip4_address_t v4_dst_address, v4_next_hop_address;
8415   ip6_address_t v6_dst_address, v6_next_hop_address;
8416   int count = 1;
8417   int j;
8418   f64 before = 0;
8419   u32 random_add_del = 0;
8420   u32 *random_vector = 0;
8421   uword *random_hash;
8422   u32 random_seed = 0xdeaddabe;
8423   u32 classify_table_index = ~0;
8424   u8 is_classify = 0;
8425   u8 resolve_host = 0, resolve_attached = 0;
8426   mpls_label_t *next_hop_out_label_stack = NULL;
8427   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8428   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8429
8430   /* Parse args required to build the message */
8431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8432     {
8433       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8434         ;
8435       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8436         ;
8437       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8438         {
8439           address_set = 1;
8440           is_ipv6 = 0;
8441         }
8442       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8443         {
8444           address_set = 1;
8445           is_ipv6 = 1;
8446         }
8447       else if (unformat (i, "/%d", &dst_address_length))
8448         {
8449           address_length_set = 1;
8450         }
8451
8452       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8453                                          &v4_next_hop_address))
8454         {
8455           next_hop_set = 1;
8456         }
8457       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8458                                          &v6_next_hop_address))
8459         {
8460           next_hop_set = 1;
8461         }
8462       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8463         ;
8464       else if (unformat (i, "weight %d", &next_hop_weight))
8465         ;
8466       else if (unformat (i, "drop"))
8467         {
8468           is_drop = 1;
8469         }
8470       else if (unformat (i, "null-send-unreach"))
8471         {
8472           is_unreach = 1;
8473         }
8474       else if (unformat (i, "null-send-prohibit"))
8475         {
8476           is_prohibit = 1;
8477         }
8478       else if (unformat (i, "local"))
8479         {
8480           is_local = 1;
8481         }
8482       else if (unformat (i, "classify %d", &classify_table_index))
8483         {
8484           is_classify = 1;
8485         }
8486       else if (unformat (i, "del"))
8487         is_add = 0;
8488       else if (unformat (i, "add"))
8489         is_add = 1;
8490       else if (unformat (i, "resolve-via-host"))
8491         resolve_host = 1;
8492       else if (unformat (i, "resolve-via-attached"))
8493         resolve_attached = 1;
8494       else if (unformat (i, "multipath"))
8495         is_multipath = 1;
8496       else if (unformat (i, "vrf %d", &vrf_id))
8497         ;
8498       else if (unformat (i, "count %d", &count))
8499         ;
8500       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8501         ;
8502       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8503         ;
8504       else if (unformat (i, "out-label %d", &next_hop_out_label))
8505         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8506       else if (unformat (i, "via-label %d", &next_hop_via_label))
8507         ;
8508       else if (unformat (i, "random"))
8509         random_add_del = 1;
8510       else if (unformat (i, "seed %d", &random_seed))
8511         ;
8512       else
8513         {
8514           clib_warning ("parse error '%U'", format_unformat_error, i);
8515           return -99;
8516         }
8517     }
8518
8519   if (!next_hop_set && !is_drop && !is_local &&
8520       !is_classify && !is_unreach && !is_prohibit &&
8521       MPLS_LABEL_INVALID == next_hop_via_label)
8522     {
8523       errmsg
8524         ("next hop / local / drop / unreach / prohibit / classify not set");
8525       return -99;
8526     }
8527
8528   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8529     {
8530       errmsg ("next hop and next-hop via label set");
8531       return -99;
8532     }
8533   if (address_set == 0)
8534     {
8535       errmsg ("missing addresses");
8536       return -99;
8537     }
8538
8539   if (address_length_set == 0)
8540     {
8541       errmsg ("missing address length");
8542       return -99;
8543     }
8544
8545   /* Generate a pile of unique, random routes */
8546   if (random_add_del)
8547     {
8548       u32 this_random_address;
8549       random_hash = hash_create (count, sizeof (uword));
8550
8551       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8552       for (j = 0; j <= count; j++)
8553         {
8554           do
8555             {
8556               this_random_address = random_u32 (&random_seed);
8557               this_random_address =
8558                 clib_host_to_net_u32 (this_random_address);
8559             }
8560           while (hash_get (random_hash, this_random_address));
8561           vec_add1 (random_vector, this_random_address);
8562           hash_set (random_hash, this_random_address, 1);
8563         }
8564       hash_free (random_hash);
8565       v4_dst_address.as_u32 = random_vector[0];
8566     }
8567
8568   if (count > 1)
8569     {
8570       /* Turn on async mode */
8571       vam->async_mode = 1;
8572       vam->async_errors = 0;
8573       before = vat_time_now (vam);
8574     }
8575
8576   for (j = 0; j < count; j++)
8577     {
8578       /* Construct the API message */
8579       M2 (IP_ADD_DEL_ROUTE, mp,
8580           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8581
8582       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8583       mp->table_id = ntohl (vrf_id);
8584
8585       mp->is_add = is_add;
8586       mp->is_drop = is_drop;
8587       mp->is_unreach = is_unreach;
8588       mp->is_prohibit = is_prohibit;
8589       mp->is_ipv6 = is_ipv6;
8590       mp->is_local = is_local;
8591       mp->is_classify = is_classify;
8592       mp->is_multipath = is_multipath;
8593       mp->is_resolve_host = resolve_host;
8594       mp->is_resolve_attached = resolve_attached;
8595       mp->next_hop_weight = next_hop_weight;
8596       mp->dst_address_length = dst_address_length;
8597       mp->next_hop_table_id = ntohl (next_hop_table_id);
8598       mp->classify_table_index = ntohl (classify_table_index);
8599       mp->next_hop_via_label = ntohl (next_hop_via_label);
8600       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8601       if (0 != mp->next_hop_n_out_labels)
8602         {
8603           memcpy (mp->next_hop_out_label_stack,
8604                   next_hop_out_label_stack,
8605                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8606           vec_free (next_hop_out_label_stack);
8607         }
8608
8609       if (is_ipv6)
8610         {
8611           clib_memcpy (mp->dst_address, &v6_dst_address,
8612                        sizeof (v6_dst_address));
8613           if (next_hop_set)
8614             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8615                          sizeof (v6_next_hop_address));
8616           increment_v6_address (&v6_dst_address);
8617         }
8618       else
8619         {
8620           clib_memcpy (mp->dst_address, &v4_dst_address,
8621                        sizeof (v4_dst_address));
8622           if (next_hop_set)
8623             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8624                          sizeof (v4_next_hop_address));
8625           if (random_add_del)
8626             v4_dst_address.as_u32 = random_vector[j + 1];
8627           else
8628             increment_v4_address (&v4_dst_address);
8629         }
8630       /* send it... */
8631       S (mp);
8632       /* If we receive SIGTERM, stop now... */
8633       if (vam->do_exit)
8634         break;
8635     }
8636
8637   /* When testing multiple add/del ops, use a control-ping to sync */
8638   if (count > 1)
8639     {
8640       vl_api_control_ping_t *mp_ping;
8641       f64 after;
8642       f64 timeout;
8643
8644       /* Shut off async mode */
8645       vam->async_mode = 0;
8646
8647       MPING (CONTROL_PING, mp_ping);
8648       S (mp_ping);
8649
8650       timeout = vat_time_now (vam) + 1.0;
8651       while (vat_time_now (vam) < timeout)
8652         if (vam->result_ready == 1)
8653           goto out;
8654       vam->retval = -99;
8655
8656     out:
8657       if (vam->retval == -99)
8658         errmsg ("timeout");
8659
8660       if (vam->async_errors > 0)
8661         {
8662           errmsg ("%d asynchronous errors", vam->async_errors);
8663           vam->retval = -98;
8664         }
8665       vam->async_errors = 0;
8666       after = vat_time_now (vam);
8667
8668       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8669       if (j > 0)
8670         count = j;
8671
8672       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8673              count, after - before, count / (after - before));
8674     }
8675   else
8676     {
8677       int ret;
8678
8679       /* Wait for a reply... */
8680       W (ret);
8681       return ret;
8682     }
8683
8684   /* Return the good/bad news */
8685   return (vam->retval);
8686 }
8687
8688 static int
8689 api_ip_mroute_add_del (vat_main_t * vam)
8690 {
8691   unformat_input_t *i = vam->input;
8692   vl_api_ip_mroute_add_del_t *mp;
8693   u32 sw_if_index = ~0, vrf_id = 0;
8694   u8 is_ipv6 = 0;
8695   u8 is_local = 0;
8696   u8 is_add = 1;
8697   u8 address_set = 0;
8698   u32 grp_address_length = 0;
8699   ip4_address_t v4_grp_address, v4_src_address;
8700   ip6_address_t v6_grp_address, v6_src_address;
8701   mfib_itf_flags_t iflags = 0;
8702   mfib_entry_flags_t eflags = 0;
8703   int ret;
8704
8705   /* Parse args required to build the message */
8706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8707     {
8708       if (unformat (i, "sw_if_index %d", &sw_if_index))
8709         ;
8710       else if (unformat (i, "%U %U",
8711                          unformat_ip4_address, &v4_src_address,
8712                          unformat_ip4_address, &v4_grp_address))
8713         {
8714           grp_address_length = 64;
8715           address_set = 1;
8716           is_ipv6 = 0;
8717         }
8718       else if (unformat (i, "%U %U",
8719                          unformat_ip6_address, &v6_src_address,
8720                          unformat_ip6_address, &v6_grp_address))
8721         {
8722           grp_address_length = 256;
8723           address_set = 1;
8724           is_ipv6 = 1;
8725         }
8726       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8727         {
8728           memset (&v4_src_address, 0, sizeof (v4_src_address));
8729           grp_address_length = 32;
8730           address_set = 1;
8731           is_ipv6 = 0;
8732         }
8733       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8734         {
8735           memset (&v6_src_address, 0, sizeof (v6_src_address));
8736           grp_address_length = 128;
8737           address_set = 1;
8738           is_ipv6 = 1;
8739         }
8740       else if (unformat (i, "/%d", &grp_address_length))
8741         ;
8742       else if (unformat (i, "local"))
8743         {
8744           is_local = 1;
8745         }
8746       else if (unformat (i, "del"))
8747         is_add = 0;
8748       else if (unformat (i, "add"))
8749         is_add = 1;
8750       else if (unformat (i, "vrf %d", &vrf_id))
8751         ;
8752       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8753         ;
8754       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8755         ;
8756       else
8757         {
8758           clib_warning ("parse error '%U'", format_unformat_error, i);
8759           return -99;
8760         }
8761     }
8762
8763   if (address_set == 0)
8764     {
8765       errmsg ("missing addresses\n");
8766       return -99;
8767     }
8768
8769   /* Construct the API message */
8770   M (IP_MROUTE_ADD_DEL, mp);
8771
8772   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8773   mp->table_id = ntohl (vrf_id);
8774
8775   mp->is_add = is_add;
8776   mp->is_ipv6 = is_ipv6;
8777   mp->is_local = is_local;
8778   mp->itf_flags = ntohl (iflags);
8779   mp->entry_flags = ntohl (eflags);
8780   mp->grp_address_length = grp_address_length;
8781   mp->grp_address_length = ntohs (mp->grp_address_length);
8782
8783   if (is_ipv6)
8784     {
8785       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8786       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8787     }
8788   else
8789     {
8790       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8791       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8792
8793     }
8794
8795   /* send it... */
8796   S (mp);
8797   /* Wait for a reply... */
8798   W (ret);
8799   return ret;
8800 }
8801
8802 static int
8803 api_mpls_table_add_del (vat_main_t * vam)
8804 {
8805   unformat_input_t *i = vam->input;
8806   vl_api_mpls_table_add_del_t *mp;
8807   u32 table_id = ~0;
8808   u8 is_add = 1;
8809   int ret = 0;
8810
8811   /* Parse args required to build the message */
8812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8813     {
8814       if (unformat (i, "table %d", &table_id))
8815         ;
8816       else if (unformat (i, "del"))
8817         is_add = 0;
8818       else if (unformat (i, "add"))
8819         is_add = 1;
8820       else
8821         {
8822           clib_warning ("parse error '%U'", format_unformat_error, i);
8823           return -99;
8824         }
8825     }
8826
8827   if (~0 == table_id)
8828     {
8829       errmsg ("missing table-ID");
8830       return -99;
8831     }
8832
8833   /* Construct the API message */
8834   M (MPLS_TABLE_ADD_DEL, mp);
8835
8836   mp->mt_table_id = ntohl (table_id);
8837   mp->mt_is_add = is_add;
8838
8839   /* send it... */
8840   S (mp);
8841
8842   /* Wait for a reply... */
8843   W (ret);
8844
8845   return ret;
8846 }
8847
8848 static int
8849 api_mpls_route_add_del (vat_main_t * vam)
8850 {
8851   unformat_input_t *i = vam->input;
8852   vl_api_mpls_route_add_del_t *mp;
8853   u32 sw_if_index = ~0, table_id = 0;
8854   u8 is_add = 1;
8855   u32 next_hop_weight = 1;
8856   u8 is_multipath = 0;
8857   u32 next_hop_table_id = 0;
8858   u8 next_hop_set = 0;
8859   ip4_address_t v4_next_hop_address = {
8860     .as_u32 = 0,
8861   };
8862   ip6_address_t v6_next_hop_address = { {0} };
8863   int count = 1;
8864   int j;
8865   f64 before = 0;
8866   u32 classify_table_index = ~0;
8867   u8 is_classify = 0;
8868   u8 resolve_host = 0, resolve_attached = 0;
8869   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8870   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8871   mpls_label_t *next_hop_out_label_stack = NULL;
8872   mpls_label_t local_label = MPLS_LABEL_INVALID;
8873   u8 is_eos = 0;
8874   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8875
8876   /* Parse args required to build the message */
8877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8878     {
8879       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8880         ;
8881       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8882         ;
8883       else if (unformat (i, "%d", &local_label))
8884         ;
8885       else if (unformat (i, "eos"))
8886         is_eos = 1;
8887       else if (unformat (i, "non-eos"))
8888         is_eos = 0;
8889       else if (unformat (i, "via %U", unformat_ip4_address,
8890                          &v4_next_hop_address))
8891         {
8892           next_hop_set = 1;
8893           next_hop_proto = DPO_PROTO_IP4;
8894         }
8895       else if (unformat (i, "via %U", unformat_ip6_address,
8896                          &v6_next_hop_address))
8897         {
8898           next_hop_set = 1;
8899           next_hop_proto = DPO_PROTO_IP6;
8900         }
8901       else if (unformat (i, "weight %d", &next_hop_weight))
8902         ;
8903       else if (unformat (i, "classify %d", &classify_table_index))
8904         {
8905           is_classify = 1;
8906         }
8907       else if (unformat (i, "del"))
8908         is_add = 0;
8909       else if (unformat (i, "add"))
8910         is_add = 1;
8911       else if (unformat (i, "resolve-via-host"))
8912         resolve_host = 1;
8913       else if (unformat (i, "resolve-via-attached"))
8914         resolve_attached = 1;
8915       else if (unformat (i, "multipath"))
8916         is_multipath = 1;
8917       else if (unformat (i, "count %d", &count))
8918         ;
8919       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8920         {
8921           next_hop_set = 1;
8922           next_hop_proto = DPO_PROTO_IP4;
8923         }
8924       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8925         {
8926           next_hop_set = 1;
8927           next_hop_proto = DPO_PROTO_IP6;
8928         }
8929       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8930         ;
8931       else if (unformat (i, "via-label %d", &next_hop_via_label))
8932         ;
8933       else if (unformat (i, "out-label %d", &next_hop_out_label))
8934         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8935       else
8936         {
8937           clib_warning ("parse error '%U'", format_unformat_error, i);
8938           return -99;
8939         }
8940     }
8941
8942   if (!next_hop_set && !is_classify)
8943     {
8944       errmsg ("next hop / classify not set");
8945       return -99;
8946     }
8947
8948   if (MPLS_LABEL_INVALID == local_label)
8949     {
8950       errmsg ("missing label");
8951       return -99;
8952     }
8953
8954   if (count > 1)
8955     {
8956       /* Turn on async mode */
8957       vam->async_mode = 1;
8958       vam->async_errors = 0;
8959       before = vat_time_now (vam);
8960     }
8961
8962   for (j = 0; j < count; j++)
8963     {
8964       /* Construct the API message */
8965       M2 (MPLS_ROUTE_ADD_DEL, mp,
8966           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8967
8968       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8969       mp->mr_table_id = ntohl (table_id);
8970
8971       mp->mr_is_add = is_add;
8972       mp->mr_next_hop_proto = next_hop_proto;
8973       mp->mr_is_classify = is_classify;
8974       mp->mr_is_multipath = is_multipath;
8975       mp->mr_is_resolve_host = resolve_host;
8976       mp->mr_is_resolve_attached = resolve_attached;
8977       mp->mr_next_hop_weight = next_hop_weight;
8978       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8979       mp->mr_classify_table_index = ntohl (classify_table_index);
8980       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8981       mp->mr_label = ntohl (local_label);
8982       mp->mr_eos = is_eos;
8983
8984       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8985       if (0 != mp->mr_next_hop_n_out_labels)
8986         {
8987           memcpy (mp->mr_next_hop_out_label_stack,
8988                   next_hop_out_label_stack,
8989                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8990           vec_free (next_hop_out_label_stack);
8991         }
8992
8993       if (next_hop_set)
8994         {
8995           if (DPO_PROTO_IP4 == next_hop_proto)
8996             {
8997               clib_memcpy (mp->mr_next_hop,
8998                            &v4_next_hop_address,
8999                            sizeof (v4_next_hop_address));
9000             }
9001           else if (DPO_PROTO_IP6 == next_hop_proto)
9002
9003             {
9004               clib_memcpy (mp->mr_next_hop,
9005                            &v6_next_hop_address,
9006                            sizeof (v6_next_hop_address));
9007             }
9008         }
9009       local_label++;
9010
9011       /* send it... */
9012       S (mp);
9013       /* If we receive SIGTERM, stop now... */
9014       if (vam->do_exit)
9015         break;
9016     }
9017
9018   /* When testing multiple add/del ops, use a control-ping to sync */
9019   if (count > 1)
9020     {
9021       vl_api_control_ping_t *mp_ping;
9022       f64 after;
9023       f64 timeout;
9024
9025       /* Shut off async mode */
9026       vam->async_mode = 0;
9027
9028       MPING (CONTROL_PING, mp_ping);
9029       S (mp_ping);
9030
9031       timeout = vat_time_now (vam) + 1.0;
9032       while (vat_time_now (vam) < timeout)
9033         if (vam->result_ready == 1)
9034           goto out;
9035       vam->retval = -99;
9036
9037     out:
9038       if (vam->retval == -99)
9039         errmsg ("timeout");
9040
9041       if (vam->async_errors > 0)
9042         {
9043           errmsg ("%d asynchronous errors", vam->async_errors);
9044           vam->retval = -98;
9045         }
9046       vam->async_errors = 0;
9047       after = vat_time_now (vam);
9048
9049       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9050       if (j > 0)
9051         count = j;
9052
9053       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9054              count, after - before, count / (after - before));
9055     }
9056   else
9057     {
9058       int ret;
9059
9060       /* Wait for a reply... */
9061       W (ret);
9062       return ret;
9063     }
9064
9065   /* Return the good/bad news */
9066   return (vam->retval);
9067 }
9068
9069 static int
9070 api_mpls_ip_bind_unbind (vat_main_t * vam)
9071 {
9072   unformat_input_t *i = vam->input;
9073   vl_api_mpls_ip_bind_unbind_t *mp;
9074   u32 ip_table_id = 0;
9075   u8 is_bind = 1;
9076   u8 is_ip4 = 1;
9077   ip4_address_t v4_address;
9078   ip6_address_t v6_address;
9079   u32 address_length;
9080   u8 address_set = 0;
9081   mpls_label_t local_label = MPLS_LABEL_INVALID;
9082   int ret;
9083
9084   /* Parse args required to build the message */
9085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9086     {
9087       if (unformat (i, "%U/%d", unformat_ip4_address,
9088                     &v4_address, &address_length))
9089         {
9090           is_ip4 = 1;
9091           address_set = 1;
9092         }
9093       else if (unformat (i, "%U/%d", unformat_ip6_address,
9094                          &v6_address, &address_length))
9095         {
9096           is_ip4 = 0;
9097           address_set = 1;
9098         }
9099       else if (unformat (i, "%d", &local_label))
9100         ;
9101       else if (unformat (i, "table-id %d", &ip_table_id))
9102         ;
9103       else if (unformat (i, "unbind"))
9104         is_bind = 0;
9105       else if (unformat (i, "bind"))
9106         is_bind = 1;
9107       else
9108         {
9109           clib_warning ("parse error '%U'", format_unformat_error, i);
9110           return -99;
9111         }
9112     }
9113
9114   if (!address_set)
9115     {
9116       errmsg ("IP addres not set");
9117       return -99;
9118     }
9119
9120   if (MPLS_LABEL_INVALID == local_label)
9121     {
9122       errmsg ("missing label");
9123       return -99;
9124     }
9125
9126   /* Construct the API message */
9127   M (MPLS_IP_BIND_UNBIND, mp);
9128
9129   mp->mb_is_bind = is_bind;
9130   mp->mb_is_ip4 = is_ip4;
9131   mp->mb_ip_table_id = ntohl (ip_table_id);
9132   mp->mb_mpls_table_id = 0;
9133   mp->mb_label = ntohl (local_label);
9134   mp->mb_address_length = address_length;
9135
9136   if (is_ip4)
9137     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9138   else
9139     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9140
9141   /* send it... */
9142   S (mp);
9143
9144   /* Wait for a reply... */
9145   W (ret);
9146   return ret;
9147 }
9148
9149 static int
9150 api_bier_table_add_del (vat_main_t * vam)
9151 {
9152   unformat_input_t *i = vam->input;
9153   vl_api_bier_table_add_del_t *mp;
9154   u8 is_add = 1;
9155   u32 set = 0, sub_domain = 0, hdr_len = 3;
9156   mpls_label_t local_label = MPLS_LABEL_INVALID;
9157   int ret;
9158
9159   /* Parse args required to build the message */
9160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9161     {
9162       if (unformat (i, "sub-domain %d", &sub_domain))
9163         ;
9164       else if (unformat (i, "set %d", &set))
9165         ;
9166       else if (unformat (i, "label %d", &local_label))
9167         ;
9168       else if (unformat (i, "hdr-len %d", &hdr_len))
9169         ;
9170       else if (unformat (i, "add"))
9171         is_add = 1;
9172       else if (unformat (i, "del"))
9173         is_add = 0;
9174       else
9175         {
9176           clib_warning ("parse error '%U'", format_unformat_error, i);
9177           return -99;
9178         }
9179     }
9180
9181   if (MPLS_LABEL_INVALID == local_label)
9182     {
9183       errmsg ("missing label\n");
9184       return -99;
9185     }
9186
9187   /* Construct the API message */
9188   M (BIER_TABLE_ADD_DEL, mp);
9189
9190   mp->bt_is_add = is_add;
9191   mp->bt_label = ntohl (local_label);
9192   mp->bt_tbl_id.bt_set = set;
9193   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9194   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9195
9196   /* send it... */
9197   S (mp);
9198
9199   /* Wait for a reply... */
9200   W (ret);
9201
9202   return (ret);
9203 }
9204
9205 static int
9206 api_bier_route_add_del (vat_main_t * vam)
9207 {
9208   unformat_input_t *i = vam->input;
9209   vl_api_bier_route_add_del_t *mp;
9210   u8 is_add = 1;
9211   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9212   ip4_address_t v4_next_hop_address;
9213   ip6_address_t v6_next_hop_address;
9214   u8 next_hop_set = 0;
9215   u8 next_hop_proto_is_ip4 = 1;
9216   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9217   int ret;
9218
9219   /* Parse args required to build the message */
9220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9221     {
9222       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9223         {
9224           next_hop_proto_is_ip4 = 1;
9225           next_hop_set = 1;
9226         }
9227       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9228         {
9229           next_hop_proto_is_ip4 = 0;
9230           next_hop_set = 1;
9231         }
9232       if (unformat (i, "sub-domain %d", &sub_domain))
9233         ;
9234       else if (unformat (i, "set %d", &set))
9235         ;
9236       else if (unformat (i, "hdr-len %d", &hdr_len))
9237         ;
9238       else if (unformat (i, "bp %d", &bp))
9239         ;
9240       else if (unformat (i, "add"))
9241         is_add = 1;
9242       else if (unformat (i, "del"))
9243         is_add = 0;
9244       else if (unformat (i, "out-label %d", &next_hop_out_label))
9245         ;
9246       else
9247         {
9248           clib_warning ("parse error '%U'", format_unformat_error, i);
9249           return -99;
9250         }
9251     }
9252
9253   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9254     {
9255       errmsg ("next hop / label set\n");
9256       return -99;
9257     }
9258   if (0 == bp)
9259     {
9260       errmsg ("bit=position not set\n");
9261       return -99;
9262     }
9263
9264   /* Construct the API message */
9265   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9266
9267   mp->br_is_add = is_add;
9268   mp->br_tbl_id.bt_set = set;
9269   mp->br_tbl_id.bt_sub_domain = sub_domain;
9270   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9271   mp->br_bp = ntohs (bp);
9272   mp->br_n_paths = 1;
9273   mp->br_paths[0].n_labels = 1;
9274   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9275   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9276
9277   if (next_hop_proto_is_ip4)
9278     {
9279       clib_memcpy (mp->br_paths[0].next_hop,
9280                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9281     }
9282   else
9283     {
9284       clib_memcpy (mp->br_paths[0].next_hop,
9285                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9286     }
9287
9288   /* send it... */
9289   S (mp);
9290
9291   /* Wait for a reply... */
9292   W (ret);
9293
9294   return (ret);
9295 }
9296
9297 static int
9298 api_proxy_arp_add_del (vat_main_t * vam)
9299 {
9300   unformat_input_t *i = vam->input;
9301   vl_api_proxy_arp_add_del_t *mp;
9302   u32 vrf_id = 0;
9303   u8 is_add = 1;
9304   ip4_address_t lo, hi;
9305   u8 range_set = 0;
9306   int ret;
9307
9308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9309     {
9310       if (unformat (i, "vrf %d", &vrf_id))
9311         ;
9312       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9313                          unformat_ip4_address, &hi))
9314         range_set = 1;
9315       else if (unformat (i, "del"))
9316         is_add = 0;
9317       else
9318         {
9319           clib_warning ("parse error '%U'", format_unformat_error, i);
9320           return -99;
9321         }
9322     }
9323
9324   if (range_set == 0)
9325     {
9326       errmsg ("address range not set");
9327       return -99;
9328     }
9329
9330   M (PROXY_ARP_ADD_DEL, mp);
9331
9332   mp->proxy.vrf_id = ntohl (vrf_id);
9333   mp->is_add = is_add;
9334   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9335   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9336
9337   S (mp);
9338   W (ret);
9339   return ret;
9340 }
9341
9342 static int
9343 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9344 {
9345   unformat_input_t *i = vam->input;
9346   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9347   u32 sw_if_index;
9348   u8 enable = 1;
9349   u8 sw_if_index_set = 0;
9350   int ret;
9351
9352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9353     {
9354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9355         sw_if_index_set = 1;
9356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9357         sw_if_index_set = 1;
9358       else if (unformat (i, "enable"))
9359         enable = 1;
9360       else if (unformat (i, "disable"))
9361         enable = 0;
9362       else
9363         {
9364           clib_warning ("parse error '%U'", format_unformat_error, i);
9365           return -99;
9366         }
9367     }
9368
9369   if (sw_if_index_set == 0)
9370     {
9371       errmsg ("missing interface name or sw_if_index");
9372       return -99;
9373     }
9374
9375   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9376
9377   mp->sw_if_index = ntohl (sw_if_index);
9378   mp->enable_disable = enable;
9379
9380   S (mp);
9381   W (ret);
9382   return ret;
9383 }
9384
9385 static int
9386 api_mpls_tunnel_add_del (vat_main_t * vam)
9387 {
9388   unformat_input_t *i = vam->input;
9389   vl_api_mpls_tunnel_add_del_t *mp;
9390
9391   u8 is_add = 1;
9392   u8 l2_only = 0;
9393   u32 sw_if_index = ~0;
9394   u32 next_hop_sw_if_index = ~0;
9395   u32 next_hop_proto_is_ip4 = 1;
9396
9397   u32 next_hop_table_id = 0;
9398   ip4_address_t v4_next_hop_address = {
9399     .as_u32 = 0,
9400   };
9401   ip6_address_t v6_next_hop_address = { {0} };
9402   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9403   int ret;
9404
9405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9406     {
9407       if (unformat (i, "add"))
9408         is_add = 1;
9409       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9410         is_add = 0;
9411       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9412         ;
9413       else if (unformat (i, "via %U",
9414                          unformat_ip4_address, &v4_next_hop_address))
9415         {
9416           next_hop_proto_is_ip4 = 1;
9417         }
9418       else if (unformat (i, "via %U",
9419                          unformat_ip6_address, &v6_next_hop_address))
9420         {
9421           next_hop_proto_is_ip4 = 0;
9422         }
9423       else if (unformat (i, "l2-only"))
9424         l2_only = 1;
9425       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9426         ;
9427       else if (unformat (i, "out-label %d", &next_hop_out_label))
9428         vec_add1 (labels, ntohl (next_hop_out_label));
9429       else
9430         {
9431           clib_warning ("parse error '%U'", format_unformat_error, i);
9432           return -99;
9433         }
9434     }
9435
9436   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9437
9438   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9439   mp->mt_sw_if_index = ntohl (sw_if_index);
9440   mp->mt_is_add = is_add;
9441   mp->mt_l2_only = l2_only;
9442   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9443   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9444
9445   mp->mt_next_hop_n_out_labels = vec_len (labels);
9446
9447   if (0 != mp->mt_next_hop_n_out_labels)
9448     {
9449       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9450                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9451       vec_free (labels);
9452     }
9453
9454   if (next_hop_proto_is_ip4)
9455     {
9456       clib_memcpy (mp->mt_next_hop,
9457                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9458     }
9459   else
9460     {
9461       clib_memcpy (mp->mt_next_hop,
9462                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9463     }
9464
9465   S (mp);
9466   W (ret);
9467   return ret;
9468 }
9469
9470 static int
9471 api_sw_interface_set_unnumbered (vat_main_t * vam)
9472 {
9473   unformat_input_t *i = vam->input;
9474   vl_api_sw_interface_set_unnumbered_t *mp;
9475   u32 sw_if_index;
9476   u32 unnum_sw_index = ~0;
9477   u8 is_add = 1;
9478   u8 sw_if_index_set = 0;
9479   int ret;
9480
9481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9482     {
9483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9484         sw_if_index_set = 1;
9485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9486         sw_if_index_set = 1;
9487       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9488         ;
9489       else if (unformat (i, "del"))
9490         is_add = 0;
9491       else
9492         {
9493           clib_warning ("parse error '%U'", format_unformat_error, i);
9494           return -99;
9495         }
9496     }
9497
9498   if (sw_if_index_set == 0)
9499     {
9500       errmsg ("missing interface name or sw_if_index");
9501       return -99;
9502     }
9503
9504   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9505
9506   mp->sw_if_index = ntohl (sw_if_index);
9507   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9508   mp->is_add = is_add;
9509
9510   S (mp);
9511   W (ret);
9512   return ret;
9513 }
9514
9515 static int
9516 api_ip_neighbor_add_del (vat_main_t * vam)
9517 {
9518   unformat_input_t *i = vam->input;
9519   vl_api_ip_neighbor_add_del_t *mp;
9520   u32 sw_if_index;
9521   u8 sw_if_index_set = 0;
9522   u8 is_add = 1;
9523   u8 is_static = 0;
9524   u8 is_no_fib_entry = 0;
9525   u8 mac_address[6];
9526   u8 mac_set = 0;
9527   u8 v4_address_set = 0;
9528   u8 v6_address_set = 0;
9529   ip4_address_t v4address;
9530   ip6_address_t v6address;
9531   int ret;
9532
9533   memset (mac_address, 0, sizeof (mac_address));
9534
9535   /* Parse args required to build the message */
9536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9537     {
9538       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9539         {
9540           mac_set = 1;
9541         }
9542       else if (unformat (i, "del"))
9543         is_add = 0;
9544       else
9545         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9546         sw_if_index_set = 1;
9547       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9548         sw_if_index_set = 1;
9549       else if (unformat (i, "is_static"))
9550         is_static = 1;
9551       else if (unformat (i, "no-fib-entry"))
9552         is_no_fib_entry = 1;
9553       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9554         v4_address_set = 1;
9555       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9556         v6_address_set = 1;
9557       else
9558         {
9559           clib_warning ("parse error '%U'", format_unformat_error, i);
9560           return -99;
9561         }
9562     }
9563
9564   if (sw_if_index_set == 0)
9565     {
9566       errmsg ("missing interface name or sw_if_index");
9567       return -99;
9568     }
9569   if (v4_address_set && v6_address_set)
9570     {
9571       errmsg ("both v4 and v6 addresses set");
9572       return -99;
9573     }
9574   if (!v4_address_set && !v6_address_set)
9575     {
9576       errmsg ("no address set");
9577       return -99;
9578     }
9579
9580   /* Construct the API message */
9581   M (IP_NEIGHBOR_ADD_DEL, mp);
9582
9583   mp->sw_if_index = ntohl (sw_if_index);
9584   mp->is_add = is_add;
9585   mp->is_static = is_static;
9586   mp->is_no_adj_fib = is_no_fib_entry;
9587   if (mac_set)
9588     clib_memcpy (mp->mac_address, mac_address, 6);
9589   if (v6_address_set)
9590     {
9591       mp->is_ipv6 = 1;
9592       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9593     }
9594   else
9595     {
9596       /* mp->is_ipv6 = 0; via memset in M macro above */
9597       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9598     }
9599
9600   /* send it... */
9601   S (mp);
9602
9603   /* Wait for a reply, return good/bad news  */
9604   W (ret);
9605   return ret;
9606 }
9607
9608 static int
9609 api_create_vlan_subif (vat_main_t * vam)
9610 {
9611   unformat_input_t *i = vam->input;
9612   vl_api_create_vlan_subif_t *mp;
9613   u32 sw_if_index;
9614   u8 sw_if_index_set = 0;
9615   u32 vlan_id;
9616   u8 vlan_id_set = 0;
9617   int ret;
9618
9619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9620     {
9621       if (unformat (i, "sw_if_index %d", &sw_if_index))
9622         sw_if_index_set = 1;
9623       else
9624         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9625         sw_if_index_set = 1;
9626       else if (unformat (i, "vlan %d", &vlan_id))
9627         vlan_id_set = 1;
9628       else
9629         {
9630           clib_warning ("parse error '%U'", format_unformat_error, i);
9631           return -99;
9632         }
9633     }
9634
9635   if (sw_if_index_set == 0)
9636     {
9637       errmsg ("missing interface name or sw_if_index");
9638       return -99;
9639     }
9640
9641   if (vlan_id_set == 0)
9642     {
9643       errmsg ("missing vlan_id");
9644       return -99;
9645     }
9646   M (CREATE_VLAN_SUBIF, mp);
9647
9648   mp->sw_if_index = ntohl (sw_if_index);
9649   mp->vlan_id = ntohl (vlan_id);
9650
9651   S (mp);
9652   W (ret);
9653   return ret;
9654 }
9655
9656 #define foreach_create_subif_bit                \
9657 _(no_tags)                                      \
9658 _(one_tag)                                      \
9659 _(two_tags)                                     \
9660 _(dot1ad)                                       \
9661 _(exact_match)                                  \
9662 _(default_sub)                                  \
9663 _(outer_vlan_id_any)                            \
9664 _(inner_vlan_id_any)
9665
9666 static int
9667 api_create_subif (vat_main_t * vam)
9668 {
9669   unformat_input_t *i = vam->input;
9670   vl_api_create_subif_t *mp;
9671   u32 sw_if_index;
9672   u8 sw_if_index_set = 0;
9673   u32 sub_id;
9674   u8 sub_id_set = 0;
9675   u32 no_tags = 0;
9676   u32 one_tag = 0;
9677   u32 two_tags = 0;
9678   u32 dot1ad = 0;
9679   u32 exact_match = 0;
9680   u32 default_sub = 0;
9681   u32 outer_vlan_id_any = 0;
9682   u32 inner_vlan_id_any = 0;
9683   u32 tmp;
9684   u16 outer_vlan_id = 0;
9685   u16 inner_vlan_id = 0;
9686   int ret;
9687
9688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9689     {
9690       if (unformat (i, "sw_if_index %d", &sw_if_index))
9691         sw_if_index_set = 1;
9692       else
9693         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9694         sw_if_index_set = 1;
9695       else if (unformat (i, "sub_id %d", &sub_id))
9696         sub_id_set = 1;
9697       else if (unformat (i, "outer_vlan_id %d", &tmp))
9698         outer_vlan_id = tmp;
9699       else if (unformat (i, "inner_vlan_id %d", &tmp))
9700         inner_vlan_id = tmp;
9701
9702 #define _(a) else if (unformat (i, #a)) a = 1 ;
9703       foreach_create_subif_bit
9704 #undef _
9705         else
9706         {
9707           clib_warning ("parse error '%U'", format_unformat_error, i);
9708           return -99;
9709         }
9710     }
9711
9712   if (sw_if_index_set == 0)
9713     {
9714       errmsg ("missing interface name or sw_if_index");
9715       return -99;
9716     }
9717
9718   if (sub_id_set == 0)
9719     {
9720       errmsg ("missing sub_id");
9721       return -99;
9722     }
9723   M (CREATE_SUBIF, mp);
9724
9725   mp->sw_if_index = ntohl (sw_if_index);
9726   mp->sub_id = ntohl (sub_id);
9727
9728 #define _(a) mp->a = a;
9729   foreach_create_subif_bit;
9730 #undef _
9731
9732   mp->outer_vlan_id = ntohs (outer_vlan_id);
9733   mp->inner_vlan_id = ntohs (inner_vlan_id);
9734
9735   S (mp);
9736   W (ret);
9737   return ret;
9738 }
9739
9740 static int
9741 api_oam_add_del (vat_main_t * vam)
9742 {
9743   unformat_input_t *i = vam->input;
9744   vl_api_oam_add_del_t *mp;
9745   u32 vrf_id = 0;
9746   u8 is_add = 1;
9747   ip4_address_t src, dst;
9748   u8 src_set = 0;
9749   u8 dst_set = 0;
9750   int ret;
9751
9752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9753     {
9754       if (unformat (i, "vrf %d", &vrf_id))
9755         ;
9756       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9757         src_set = 1;
9758       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9759         dst_set = 1;
9760       else if (unformat (i, "del"))
9761         is_add = 0;
9762       else
9763         {
9764           clib_warning ("parse error '%U'", format_unformat_error, i);
9765           return -99;
9766         }
9767     }
9768
9769   if (src_set == 0)
9770     {
9771       errmsg ("missing src addr");
9772       return -99;
9773     }
9774
9775   if (dst_set == 0)
9776     {
9777       errmsg ("missing dst addr");
9778       return -99;
9779     }
9780
9781   M (OAM_ADD_DEL, mp);
9782
9783   mp->vrf_id = ntohl (vrf_id);
9784   mp->is_add = is_add;
9785   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9786   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9787
9788   S (mp);
9789   W (ret);
9790   return ret;
9791 }
9792
9793 static int
9794 api_reset_fib (vat_main_t * vam)
9795 {
9796   unformat_input_t *i = vam->input;
9797   vl_api_reset_fib_t *mp;
9798   u32 vrf_id = 0;
9799   u8 is_ipv6 = 0;
9800   u8 vrf_id_set = 0;
9801
9802   int ret;
9803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9804     {
9805       if (unformat (i, "vrf %d", &vrf_id))
9806         vrf_id_set = 1;
9807       else if (unformat (i, "ipv6"))
9808         is_ipv6 = 1;
9809       else
9810         {
9811           clib_warning ("parse error '%U'", format_unformat_error, i);
9812           return -99;
9813         }
9814     }
9815
9816   if (vrf_id_set == 0)
9817     {
9818       errmsg ("missing vrf id");
9819       return -99;
9820     }
9821
9822   M (RESET_FIB, mp);
9823
9824   mp->vrf_id = ntohl (vrf_id);
9825   mp->is_ipv6 = is_ipv6;
9826
9827   S (mp);
9828   W (ret);
9829   return ret;
9830 }
9831
9832 static int
9833 api_dhcp_proxy_config (vat_main_t * vam)
9834 {
9835   unformat_input_t *i = vam->input;
9836   vl_api_dhcp_proxy_config_t *mp;
9837   u32 rx_vrf_id = 0;
9838   u32 server_vrf_id = 0;
9839   u8 is_add = 1;
9840   u8 v4_address_set = 0;
9841   u8 v6_address_set = 0;
9842   ip4_address_t v4address;
9843   ip6_address_t v6address;
9844   u8 v4_src_address_set = 0;
9845   u8 v6_src_address_set = 0;
9846   ip4_address_t v4srcaddress;
9847   ip6_address_t v6srcaddress;
9848   int ret;
9849
9850   /* Parse args required to build the message */
9851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9852     {
9853       if (unformat (i, "del"))
9854         is_add = 0;
9855       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9856         ;
9857       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9858         ;
9859       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9860         v4_address_set = 1;
9861       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9862         v6_address_set = 1;
9863       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9864         v4_src_address_set = 1;
9865       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9866         v6_src_address_set = 1;
9867       else
9868         break;
9869     }
9870
9871   if (v4_address_set && v6_address_set)
9872     {
9873       errmsg ("both v4 and v6 server addresses set");
9874       return -99;
9875     }
9876   if (!v4_address_set && !v6_address_set)
9877     {
9878       errmsg ("no server addresses set");
9879       return -99;
9880     }
9881
9882   if (v4_src_address_set && v6_src_address_set)
9883     {
9884       errmsg ("both v4 and v6  src addresses set");
9885       return -99;
9886     }
9887   if (!v4_src_address_set && !v6_src_address_set)
9888     {
9889       errmsg ("no src addresses set");
9890       return -99;
9891     }
9892
9893   if (!(v4_src_address_set && v4_address_set) &&
9894       !(v6_src_address_set && v6_address_set))
9895     {
9896       errmsg ("no matching server and src addresses set");
9897       return -99;
9898     }
9899
9900   /* Construct the API message */
9901   M (DHCP_PROXY_CONFIG, mp);
9902
9903   mp->is_add = is_add;
9904   mp->rx_vrf_id = ntohl (rx_vrf_id);
9905   mp->server_vrf_id = ntohl (server_vrf_id);
9906   if (v6_address_set)
9907     {
9908       mp->is_ipv6 = 1;
9909       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9910       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9911     }
9912   else
9913     {
9914       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9915       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9916     }
9917
9918   /* send it... */
9919   S (mp);
9920
9921   /* Wait for a reply, return good/bad news  */
9922   W (ret);
9923   return ret;
9924 }
9925
9926 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9927 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9928
9929 static void
9930 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9931 {
9932   vat_main_t *vam = &vat_main;
9933   u32 i, count = mp->count;
9934   vl_api_dhcp_server_t *s;
9935
9936   if (mp->is_ipv6)
9937     print (vam->ofp,
9938            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9939            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9940            ntohl (mp->rx_vrf_id),
9941            format_ip6_address, mp->dhcp_src_address,
9942            mp->vss_type, mp->vss_vpn_ascii_id,
9943            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9944   else
9945     print (vam->ofp,
9946            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9947            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9948            ntohl (mp->rx_vrf_id),
9949            format_ip4_address, mp->dhcp_src_address,
9950            mp->vss_type, mp->vss_vpn_ascii_id,
9951            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9952
9953   for (i = 0; i < count; i++)
9954     {
9955       s = &mp->servers[i];
9956
9957       if (mp->is_ipv6)
9958         print (vam->ofp,
9959                " Server Table-ID %d, Server Address %U",
9960                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9961       else
9962         print (vam->ofp,
9963                " Server Table-ID %d, Server Address %U",
9964                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9965     }
9966 }
9967
9968 static void vl_api_dhcp_proxy_details_t_handler_json
9969   (vl_api_dhcp_proxy_details_t * mp)
9970 {
9971   vat_main_t *vam = &vat_main;
9972   vat_json_node_t *node = NULL;
9973   u32 i, count = mp->count;
9974   struct in_addr ip4;
9975   struct in6_addr ip6;
9976   vl_api_dhcp_server_t *s;
9977
9978   if (VAT_JSON_ARRAY != vam->json_tree.type)
9979     {
9980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9981       vat_json_init_array (&vam->json_tree);
9982     }
9983   node = vat_json_array_add (&vam->json_tree);
9984
9985   vat_json_init_object (node);
9986   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9987   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9988                              sizeof (mp->vss_type));
9989   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9990                                    mp->vss_vpn_ascii_id);
9991   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9992   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9993
9994   if (mp->is_ipv6)
9995     {
9996       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9997       vat_json_object_add_ip6 (node, "src_address", ip6);
9998     }
9999   else
10000     {
10001       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10002       vat_json_object_add_ip4 (node, "src_address", ip4);
10003     }
10004
10005   for (i = 0; i < count; i++)
10006     {
10007       s = &mp->servers[i];
10008
10009       vat_json_object_add_uint (node, "server-table-id",
10010                                 ntohl (s->server_vrf_id));
10011
10012       if (mp->is_ipv6)
10013         {
10014           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10015           vat_json_object_add_ip4 (node, "src_address", ip4);
10016         }
10017       else
10018         {
10019           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10020           vat_json_object_add_ip6 (node, "server_address", ip6);
10021         }
10022     }
10023 }
10024
10025 static int
10026 api_dhcp_proxy_dump (vat_main_t * vam)
10027 {
10028   unformat_input_t *i = vam->input;
10029   vl_api_control_ping_t *mp_ping;
10030   vl_api_dhcp_proxy_dump_t *mp;
10031   u8 is_ipv6 = 0;
10032   int ret;
10033
10034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10035     {
10036       if (unformat (i, "ipv6"))
10037         is_ipv6 = 1;
10038       else
10039         {
10040           clib_warning ("parse error '%U'", format_unformat_error, i);
10041           return -99;
10042         }
10043     }
10044
10045   M (DHCP_PROXY_DUMP, mp);
10046
10047   mp->is_ip6 = is_ipv6;
10048   S (mp);
10049
10050   /* Use a control ping for synchronization */
10051   MPING (CONTROL_PING, mp_ping);
10052   S (mp_ping);
10053
10054   W (ret);
10055   return ret;
10056 }
10057
10058 static int
10059 api_dhcp_proxy_set_vss (vat_main_t * vam)
10060 {
10061   unformat_input_t *i = vam->input;
10062   vl_api_dhcp_proxy_set_vss_t *mp;
10063   u8 is_ipv6 = 0;
10064   u8 is_add = 1;
10065   u32 tbl_id = ~0;
10066   u8 vss_type = VSS_TYPE_DEFAULT;
10067   u8 *vpn_ascii_id = 0;
10068   u32 oui = 0;
10069   u32 fib_id = 0;
10070   int ret;
10071
10072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10073     {
10074       if (unformat (i, "tbl_id %d", &tbl_id))
10075         ;
10076       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10077         vss_type = VSS_TYPE_ASCII;
10078       else if (unformat (i, "fib_id %d", &fib_id))
10079         vss_type = VSS_TYPE_VPN_ID;
10080       else if (unformat (i, "oui %d", &oui))
10081         vss_type = VSS_TYPE_VPN_ID;
10082       else if (unformat (i, "ipv6"))
10083         is_ipv6 = 1;
10084       else if (unformat (i, "del"))
10085         is_add = 0;
10086       else
10087         break;
10088     }
10089
10090   if (tbl_id == ~0)
10091     {
10092       errmsg ("missing tbl_id ");
10093       vec_free (vpn_ascii_id);
10094       return -99;
10095     }
10096
10097   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10098     {
10099       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10100       vec_free (vpn_ascii_id);
10101       return -99;
10102     }
10103
10104   M (DHCP_PROXY_SET_VSS, mp);
10105   mp->tbl_id = ntohl (tbl_id);
10106   mp->vss_type = vss_type;
10107   if (vpn_ascii_id)
10108     {
10109       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10110       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10111     }
10112   mp->vpn_index = ntohl (fib_id);
10113   mp->oui = ntohl (oui);
10114   mp->is_ipv6 = is_ipv6;
10115   mp->is_add = is_add;
10116
10117   S (mp);
10118   W (ret);
10119
10120   vec_free (vpn_ascii_id);
10121   return ret;
10122 }
10123
10124 static int
10125 api_dhcp_client_config (vat_main_t * vam)
10126 {
10127   unformat_input_t *i = vam->input;
10128   vl_api_dhcp_client_config_t *mp;
10129   u32 sw_if_index;
10130   u8 sw_if_index_set = 0;
10131   u8 is_add = 1;
10132   u8 *hostname = 0;
10133   u8 disable_event = 0;
10134   int ret;
10135
10136   /* Parse args required to build the message */
10137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10138     {
10139       if (unformat (i, "del"))
10140         is_add = 0;
10141       else
10142         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10143         sw_if_index_set = 1;
10144       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10145         sw_if_index_set = 1;
10146       else if (unformat (i, "hostname %s", &hostname))
10147         ;
10148       else if (unformat (i, "disable_event"))
10149         disable_event = 1;
10150       else
10151         break;
10152     }
10153
10154   if (sw_if_index_set == 0)
10155     {
10156       errmsg ("missing interface name or sw_if_index");
10157       return -99;
10158     }
10159
10160   if (vec_len (hostname) > 63)
10161     {
10162       errmsg ("hostname too long");
10163     }
10164   vec_add1 (hostname, 0);
10165
10166   /* Construct the API message */
10167   M (DHCP_CLIENT_CONFIG, mp);
10168
10169   mp->is_add = is_add;
10170   mp->client.sw_if_index = htonl (sw_if_index);
10171   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10172   vec_free (hostname);
10173   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10174   mp->client.pid = htonl (getpid ());
10175
10176   /* send it... */
10177   S (mp);
10178
10179   /* Wait for a reply, return good/bad news  */
10180   W (ret);
10181   return ret;
10182 }
10183
10184 static int
10185 api_set_ip_flow_hash (vat_main_t * vam)
10186 {
10187   unformat_input_t *i = vam->input;
10188   vl_api_set_ip_flow_hash_t *mp;
10189   u32 vrf_id = 0;
10190   u8 is_ipv6 = 0;
10191   u8 vrf_id_set = 0;
10192   u8 src = 0;
10193   u8 dst = 0;
10194   u8 sport = 0;
10195   u8 dport = 0;
10196   u8 proto = 0;
10197   u8 reverse = 0;
10198   int ret;
10199
10200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10201     {
10202       if (unformat (i, "vrf %d", &vrf_id))
10203         vrf_id_set = 1;
10204       else if (unformat (i, "ipv6"))
10205         is_ipv6 = 1;
10206       else if (unformat (i, "src"))
10207         src = 1;
10208       else if (unformat (i, "dst"))
10209         dst = 1;
10210       else if (unformat (i, "sport"))
10211         sport = 1;
10212       else if (unformat (i, "dport"))
10213         dport = 1;
10214       else if (unformat (i, "proto"))
10215         proto = 1;
10216       else if (unformat (i, "reverse"))
10217         reverse = 1;
10218
10219       else
10220         {
10221           clib_warning ("parse error '%U'", format_unformat_error, i);
10222           return -99;
10223         }
10224     }
10225
10226   if (vrf_id_set == 0)
10227     {
10228       errmsg ("missing vrf id");
10229       return -99;
10230     }
10231
10232   M (SET_IP_FLOW_HASH, mp);
10233   mp->src = src;
10234   mp->dst = dst;
10235   mp->sport = sport;
10236   mp->dport = dport;
10237   mp->proto = proto;
10238   mp->reverse = reverse;
10239   mp->vrf_id = ntohl (vrf_id);
10240   mp->is_ipv6 = is_ipv6;
10241
10242   S (mp);
10243   W (ret);
10244   return ret;
10245 }
10246
10247 static int
10248 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10249 {
10250   unformat_input_t *i = vam->input;
10251   vl_api_sw_interface_ip6_enable_disable_t *mp;
10252   u32 sw_if_index;
10253   u8 sw_if_index_set = 0;
10254   u8 enable = 0;
10255   int ret;
10256
10257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10258     {
10259       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10260         sw_if_index_set = 1;
10261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10262         sw_if_index_set = 1;
10263       else if (unformat (i, "enable"))
10264         enable = 1;
10265       else if (unformat (i, "disable"))
10266         enable = 0;
10267       else
10268         {
10269           clib_warning ("parse error '%U'", format_unformat_error, i);
10270           return -99;
10271         }
10272     }
10273
10274   if (sw_if_index_set == 0)
10275     {
10276       errmsg ("missing interface name or sw_if_index");
10277       return -99;
10278     }
10279
10280   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10281
10282   mp->sw_if_index = ntohl (sw_if_index);
10283   mp->enable = enable;
10284
10285   S (mp);
10286   W (ret);
10287   return ret;
10288 }
10289
10290 static int
10291 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10292 {
10293   unformat_input_t *i = vam->input;
10294   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10295   u32 sw_if_index;
10296   u8 sw_if_index_set = 0;
10297   u8 v6_address_set = 0;
10298   ip6_address_t v6address;
10299   int ret;
10300
10301   /* Parse args required to build the message */
10302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10303     {
10304       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10305         sw_if_index_set = 1;
10306       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10307         sw_if_index_set = 1;
10308       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10309         v6_address_set = 1;
10310       else
10311         break;
10312     }
10313
10314   if (sw_if_index_set == 0)
10315     {
10316       errmsg ("missing interface name or sw_if_index");
10317       return -99;
10318     }
10319   if (!v6_address_set)
10320     {
10321       errmsg ("no address set");
10322       return -99;
10323     }
10324
10325   /* Construct the API message */
10326   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10327
10328   mp->sw_if_index = ntohl (sw_if_index);
10329   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10330
10331   /* send it... */
10332   S (mp);
10333
10334   /* Wait for a reply, return good/bad news  */
10335   W (ret);
10336   return ret;
10337 }
10338
10339 static int
10340 api_ip6nd_proxy_add_del (vat_main_t * vam)
10341 {
10342   unformat_input_t *i = vam->input;
10343   vl_api_ip6nd_proxy_add_del_t *mp;
10344   u32 sw_if_index = ~0;
10345   u8 v6_address_set = 0;
10346   ip6_address_t v6address;
10347   u8 is_del = 0;
10348   int ret;
10349
10350   /* Parse args required to build the message */
10351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10352     {
10353       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10354         ;
10355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10356         ;
10357       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10358         v6_address_set = 1;
10359       if (unformat (i, "del"))
10360         is_del = 1;
10361       else
10362         {
10363           clib_warning ("parse error '%U'", format_unformat_error, i);
10364           return -99;
10365         }
10366     }
10367
10368   if (sw_if_index == ~0)
10369     {
10370       errmsg ("missing interface name or sw_if_index");
10371       return -99;
10372     }
10373   if (!v6_address_set)
10374     {
10375       errmsg ("no address set");
10376       return -99;
10377     }
10378
10379   /* Construct the API message */
10380   M (IP6ND_PROXY_ADD_DEL, mp);
10381
10382   mp->is_del = is_del;
10383   mp->sw_if_index = ntohl (sw_if_index);
10384   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10385
10386   /* send it... */
10387   S (mp);
10388
10389   /* Wait for a reply, return good/bad news  */
10390   W (ret);
10391   return ret;
10392 }
10393
10394 static int
10395 api_ip6nd_proxy_dump (vat_main_t * vam)
10396 {
10397   vl_api_ip6nd_proxy_dump_t *mp;
10398   vl_api_control_ping_t *mp_ping;
10399   int ret;
10400
10401   M (IP6ND_PROXY_DUMP, mp);
10402
10403   S (mp);
10404
10405   /* Use a control ping for synchronization */
10406   MPING (CONTROL_PING, mp_ping);
10407   S (mp_ping);
10408
10409   W (ret);
10410   return ret;
10411 }
10412
10413 static void vl_api_ip6nd_proxy_details_t_handler
10414   (vl_api_ip6nd_proxy_details_t * mp)
10415 {
10416   vat_main_t *vam = &vat_main;
10417
10418   print (vam->ofp, "host %U sw_if_index %d",
10419          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10420 }
10421
10422 static void vl_api_ip6nd_proxy_details_t_handler_json
10423   (vl_api_ip6nd_proxy_details_t * mp)
10424 {
10425   vat_main_t *vam = &vat_main;
10426   struct in6_addr ip6;
10427   vat_json_node_t *node = NULL;
10428
10429   if (VAT_JSON_ARRAY != vam->json_tree.type)
10430     {
10431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10432       vat_json_init_array (&vam->json_tree);
10433     }
10434   node = vat_json_array_add (&vam->json_tree);
10435
10436   vat_json_init_object (node);
10437   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10438
10439   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10440   vat_json_object_add_ip6 (node, "host", ip6);
10441 }
10442
10443 static int
10444 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10445 {
10446   unformat_input_t *i = vam->input;
10447   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10448   u32 sw_if_index;
10449   u8 sw_if_index_set = 0;
10450   u32 address_length = 0;
10451   u8 v6_address_set = 0;
10452   ip6_address_t v6address;
10453   u8 use_default = 0;
10454   u8 no_advertise = 0;
10455   u8 off_link = 0;
10456   u8 no_autoconfig = 0;
10457   u8 no_onlink = 0;
10458   u8 is_no = 0;
10459   u32 val_lifetime = 0;
10460   u32 pref_lifetime = 0;
10461   int ret;
10462
10463   /* Parse args required to build the message */
10464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10465     {
10466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10467         sw_if_index_set = 1;
10468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10469         sw_if_index_set = 1;
10470       else if (unformat (i, "%U/%d",
10471                          unformat_ip6_address, &v6address, &address_length))
10472         v6_address_set = 1;
10473       else if (unformat (i, "val_life %d", &val_lifetime))
10474         ;
10475       else if (unformat (i, "pref_life %d", &pref_lifetime))
10476         ;
10477       else if (unformat (i, "def"))
10478         use_default = 1;
10479       else if (unformat (i, "noadv"))
10480         no_advertise = 1;
10481       else if (unformat (i, "offl"))
10482         off_link = 1;
10483       else if (unformat (i, "noauto"))
10484         no_autoconfig = 1;
10485       else if (unformat (i, "nolink"))
10486         no_onlink = 1;
10487       else if (unformat (i, "isno"))
10488         is_no = 1;
10489       else
10490         {
10491           clib_warning ("parse error '%U'", format_unformat_error, i);
10492           return -99;
10493         }
10494     }
10495
10496   if (sw_if_index_set == 0)
10497     {
10498       errmsg ("missing interface name or sw_if_index");
10499       return -99;
10500     }
10501   if (!v6_address_set)
10502     {
10503       errmsg ("no address set");
10504       return -99;
10505     }
10506
10507   /* Construct the API message */
10508   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10509
10510   mp->sw_if_index = ntohl (sw_if_index);
10511   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10512   mp->address_length = address_length;
10513   mp->use_default = use_default;
10514   mp->no_advertise = no_advertise;
10515   mp->off_link = off_link;
10516   mp->no_autoconfig = no_autoconfig;
10517   mp->no_onlink = no_onlink;
10518   mp->is_no = is_no;
10519   mp->val_lifetime = ntohl (val_lifetime);
10520   mp->pref_lifetime = ntohl (pref_lifetime);
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_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10532 {
10533   unformat_input_t *i = vam->input;
10534   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10535   u32 sw_if_index;
10536   u8 sw_if_index_set = 0;
10537   u8 suppress = 0;
10538   u8 managed = 0;
10539   u8 other = 0;
10540   u8 ll_option = 0;
10541   u8 send_unicast = 0;
10542   u8 cease = 0;
10543   u8 is_no = 0;
10544   u8 default_router = 0;
10545   u32 max_interval = 0;
10546   u32 min_interval = 0;
10547   u32 lifetime = 0;
10548   u32 initial_count = 0;
10549   u32 initial_interval = 0;
10550   int ret;
10551
10552
10553   /* Parse args required to build the message */
10554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10555     {
10556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10557         sw_if_index_set = 1;
10558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10559         sw_if_index_set = 1;
10560       else if (unformat (i, "maxint %d", &max_interval))
10561         ;
10562       else if (unformat (i, "minint %d", &min_interval))
10563         ;
10564       else if (unformat (i, "life %d", &lifetime))
10565         ;
10566       else if (unformat (i, "count %d", &initial_count))
10567         ;
10568       else if (unformat (i, "interval %d", &initial_interval))
10569         ;
10570       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10571         suppress = 1;
10572       else if (unformat (i, "managed"))
10573         managed = 1;
10574       else if (unformat (i, "other"))
10575         other = 1;
10576       else if (unformat (i, "ll"))
10577         ll_option = 1;
10578       else if (unformat (i, "send"))
10579         send_unicast = 1;
10580       else if (unformat (i, "cease"))
10581         cease = 1;
10582       else if (unformat (i, "isno"))
10583         is_no = 1;
10584       else if (unformat (i, "def"))
10585         default_router = 1;
10586       else
10587         {
10588           clib_warning ("parse error '%U'", format_unformat_error, i);
10589           return -99;
10590         }
10591     }
10592
10593   if (sw_if_index_set == 0)
10594     {
10595       errmsg ("missing interface name or sw_if_index");
10596       return -99;
10597     }
10598
10599   /* Construct the API message */
10600   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10601
10602   mp->sw_if_index = ntohl (sw_if_index);
10603   mp->max_interval = ntohl (max_interval);
10604   mp->min_interval = ntohl (min_interval);
10605   mp->lifetime = ntohl (lifetime);
10606   mp->initial_count = ntohl (initial_count);
10607   mp->initial_interval = ntohl (initial_interval);
10608   mp->suppress = suppress;
10609   mp->managed = managed;
10610   mp->other = other;
10611   mp->ll_option = ll_option;
10612   mp->send_unicast = send_unicast;
10613   mp->cease = cease;
10614   mp->is_no = is_no;
10615   mp->default_router = default_router;
10616
10617   /* send it... */
10618   S (mp);
10619
10620   /* Wait for a reply, return good/bad news  */
10621   W (ret);
10622   return ret;
10623 }
10624
10625 static int
10626 api_set_arp_neighbor_limit (vat_main_t * vam)
10627 {
10628   unformat_input_t *i = vam->input;
10629   vl_api_set_arp_neighbor_limit_t *mp;
10630   u32 arp_nbr_limit;
10631   u8 limit_set = 0;
10632   u8 is_ipv6 = 0;
10633   int ret;
10634
10635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10636     {
10637       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10638         limit_set = 1;
10639       else if (unformat (i, "ipv6"))
10640         is_ipv6 = 1;
10641       else
10642         {
10643           clib_warning ("parse error '%U'", format_unformat_error, i);
10644           return -99;
10645         }
10646     }
10647
10648   if (limit_set == 0)
10649     {
10650       errmsg ("missing limit value");
10651       return -99;
10652     }
10653
10654   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10655
10656   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10657   mp->is_ipv6 = is_ipv6;
10658
10659   S (mp);
10660   W (ret);
10661   return ret;
10662 }
10663
10664 static int
10665 api_l2_patch_add_del (vat_main_t * vam)
10666 {
10667   unformat_input_t *i = vam->input;
10668   vl_api_l2_patch_add_del_t *mp;
10669   u32 rx_sw_if_index;
10670   u8 rx_sw_if_index_set = 0;
10671   u32 tx_sw_if_index;
10672   u8 tx_sw_if_index_set = 0;
10673   u8 is_add = 1;
10674   int ret;
10675
10676   /* Parse args required to build the message */
10677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10678     {
10679       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10680         rx_sw_if_index_set = 1;
10681       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10682         tx_sw_if_index_set = 1;
10683       else if (unformat (i, "rx"))
10684         {
10685           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10686             {
10687               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10688                             &rx_sw_if_index))
10689                 rx_sw_if_index_set = 1;
10690             }
10691           else
10692             break;
10693         }
10694       else if (unformat (i, "tx"))
10695         {
10696           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10697             {
10698               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10699                             &tx_sw_if_index))
10700                 tx_sw_if_index_set = 1;
10701             }
10702           else
10703             break;
10704         }
10705       else if (unformat (i, "del"))
10706         is_add = 0;
10707       else
10708         break;
10709     }
10710
10711   if (rx_sw_if_index_set == 0)
10712     {
10713       errmsg ("missing rx interface name or rx_sw_if_index");
10714       return -99;
10715     }
10716
10717   if (tx_sw_if_index_set == 0)
10718     {
10719       errmsg ("missing tx interface name or tx_sw_if_index");
10720       return -99;
10721     }
10722
10723   M (L2_PATCH_ADD_DEL, mp);
10724
10725   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10726   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10727   mp->is_add = is_add;
10728
10729   S (mp);
10730   W (ret);
10731   return ret;
10732 }
10733
10734 u8 is_del;
10735 u8 localsid_addr[16];
10736 u8 end_psp;
10737 u8 behavior;
10738 u32 sw_if_index;
10739 u32 vlan_index;
10740 u32 fib_table;
10741 u8 nh_addr[16];
10742
10743 static int
10744 api_sr_localsid_add_del (vat_main_t * vam)
10745 {
10746   unformat_input_t *i = vam->input;
10747   vl_api_sr_localsid_add_del_t *mp;
10748
10749   u8 is_del;
10750   ip6_address_t localsid;
10751   u8 end_psp = 0;
10752   u8 behavior = ~0;
10753   u32 sw_if_index;
10754   u32 fib_table = ~(u32) 0;
10755   ip6_address_t nh_addr6;
10756   ip4_address_t nh_addr4;
10757   memset (&nh_addr6, 0, sizeof (ip6_address_t));
10758   memset (&nh_addr4, 0, sizeof (ip4_address_t));
10759
10760   bool nexthop_set = 0;
10761
10762   int ret;
10763
10764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10765     {
10766       if (unformat (i, "del"))
10767         is_del = 1;
10768       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10769       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10770         nexthop_set = 1;
10771       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10772         nexthop_set = 1;
10773       else if (unformat (i, "behavior %u", &behavior));
10774       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10775       else if (unformat (i, "fib-table %u", &fib_table));
10776       else if (unformat (i, "end.psp %u", &behavior));
10777       else
10778         break;
10779     }
10780
10781   M (SR_LOCALSID_ADD_DEL, mp);
10782
10783   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10784   if (nexthop_set)
10785     {
10786       clib_memcpy (mp->nh_addr6, &nh_addr4, sizeof (mp->nh_addr6));
10787       clib_memcpy (mp->nh_addr4, &nh_addr6, sizeof (mp->nh_addr4));
10788     }
10789   mp->behavior = behavior;
10790   mp->sw_if_index = ntohl (sw_if_index);
10791   mp->fib_table = ntohl (fib_table);
10792   mp->end_psp = end_psp;
10793   mp->is_del = is_del;
10794
10795   S (mp);
10796   W (ret);
10797   return ret;
10798 }
10799
10800 static int
10801 api_ioam_enable (vat_main_t * vam)
10802 {
10803   unformat_input_t *input = vam->input;
10804   vl_api_ioam_enable_t *mp;
10805   u32 id = 0;
10806   int has_trace_option = 0;
10807   int has_pot_option = 0;
10808   int has_seqno_option = 0;
10809   int has_analyse_option = 0;
10810   int ret;
10811
10812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10813     {
10814       if (unformat (input, "trace"))
10815         has_trace_option = 1;
10816       else if (unformat (input, "pot"))
10817         has_pot_option = 1;
10818       else if (unformat (input, "seqno"))
10819         has_seqno_option = 1;
10820       else if (unformat (input, "analyse"))
10821         has_analyse_option = 1;
10822       else
10823         break;
10824     }
10825   M (IOAM_ENABLE, mp);
10826   mp->id = htons (id);
10827   mp->seqno = has_seqno_option;
10828   mp->analyse = has_analyse_option;
10829   mp->pot_enable = has_pot_option;
10830   mp->trace_enable = has_trace_option;
10831
10832   S (mp);
10833   W (ret);
10834   return ret;
10835 }
10836
10837
10838 static int
10839 api_ioam_disable (vat_main_t * vam)
10840 {
10841   vl_api_ioam_disable_t *mp;
10842   int ret;
10843
10844   M (IOAM_DISABLE, mp);
10845   S (mp);
10846   W (ret);
10847   return ret;
10848 }
10849
10850 #define foreach_tcp_proto_field                 \
10851 _(src_port)                                     \
10852 _(dst_port)
10853
10854 #define foreach_udp_proto_field                 \
10855 _(src_port)                                     \
10856 _(dst_port)
10857
10858 #define foreach_ip4_proto_field                 \
10859 _(src_address)                                  \
10860 _(dst_address)                                  \
10861 _(tos)                                          \
10862 _(length)                                       \
10863 _(fragment_id)                                  \
10864 _(ttl)                                          \
10865 _(protocol)                                     \
10866 _(checksum)
10867
10868 typedef struct
10869 {
10870   u16 src_port, dst_port;
10871 } tcpudp_header_t;
10872
10873 #if VPP_API_TEST_BUILTIN == 0
10874 uword
10875 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10876 {
10877   u8 **maskp = va_arg (*args, u8 **);
10878   u8 *mask = 0;
10879   u8 found_something = 0;
10880   tcp_header_t *tcp;
10881
10882 #define _(a) u8 a=0;
10883   foreach_tcp_proto_field;
10884 #undef _
10885
10886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10887     {
10888       if (0);
10889 #define _(a) else if (unformat (input, #a)) a=1;
10890       foreach_tcp_proto_field
10891 #undef _
10892         else
10893         break;
10894     }
10895
10896 #define _(a) found_something += a;
10897   foreach_tcp_proto_field;
10898 #undef _
10899
10900   if (found_something == 0)
10901     return 0;
10902
10903   vec_validate (mask, sizeof (*tcp) - 1);
10904
10905   tcp = (tcp_header_t *) mask;
10906
10907 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10908   foreach_tcp_proto_field;
10909 #undef _
10910
10911   *maskp = mask;
10912   return 1;
10913 }
10914
10915 uword
10916 unformat_udp_mask (unformat_input_t * input, va_list * args)
10917 {
10918   u8 **maskp = va_arg (*args, u8 **);
10919   u8 *mask = 0;
10920   u8 found_something = 0;
10921   udp_header_t *udp;
10922
10923 #define _(a) u8 a=0;
10924   foreach_udp_proto_field;
10925 #undef _
10926
10927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10928     {
10929       if (0);
10930 #define _(a) else if (unformat (input, #a)) a=1;
10931       foreach_udp_proto_field
10932 #undef _
10933         else
10934         break;
10935     }
10936
10937 #define _(a) found_something += a;
10938   foreach_udp_proto_field;
10939 #undef _
10940
10941   if (found_something == 0)
10942     return 0;
10943
10944   vec_validate (mask, sizeof (*udp) - 1);
10945
10946   udp = (udp_header_t *) mask;
10947
10948 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10949   foreach_udp_proto_field;
10950 #undef _
10951
10952   *maskp = mask;
10953   return 1;
10954 }
10955
10956 uword
10957 unformat_l4_mask (unformat_input_t * input, va_list * args)
10958 {
10959   u8 **maskp = va_arg (*args, u8 **);
10960   u16 src_port = 0, dst_port = 0;
10961   tcpudp_header_t *tcpudp;
10962
10963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10964     {
10965       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10966         return 1;
10967       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10968         return 1;
10969       else if (unformat (input, "src_port"))
10970         src_port = 0xFFFF;
10971       else if (unformat (input, "dst_port"))
10972         dst_port = 0xFFFF;
10973       else
10974         return 0;
10975     }
10976
10977   if (!src_port && !dst_port)
10978     return 0;
10979
10980   u8 *mask = 0;
10981   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10982
10983   tcpudp = (tcpudp_header_t *) mask;
10984   tcpudp->src_port = src_port;
10985   tcpudp->dst_port = dst_port;
10986
10987   *maskp = mask;
10988
10989   return 1;
10990 }
10991
10992 uword
10993 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10994 {
10995   u8 **maskp = va_arg (*args, u8 **);
10996   u8 *mask = 0;
10997   u8 found_something = 0;
10998   ip4_header_t *ip;
10999
11000 #define _(a) u8 a=0;
11001   foreach_ip4_proto_field;
11002 #undef _
11003   u8 version = 0;
11004   u8 hdr_length = 0;
11005
11006
11007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11008     {
11009       if (unformat (input, "version"))
11010         version = 1;
11011       else if (unformat (input, "hdr_length"))
11012         hdr_length = 1;
11013       else if (unformat (input, "src"))
11014         src_address = 1;
11015       else if (unformat (input, "dst"))
11016         dst_address = 1;
11017       else if (unformat (input, "proto"))
11018         protocol = 1;
11019
11020 #define _(a) else if (unformat (input, #a)) a=1;
11021       foreach_ip4_proto_field
11022 #undef _
11023         else
11024         break;
11025     }
11026
11027 #define _(a) found_something += a;
11028   foreach_ip4_proto_field;
11029 #undef _
11030
11031   if (found_something == 0)
11032     return 0;
11033
11034   vec_validate (mask, sizeof (*ip) - 1);
11035
11036   ip = (ip4_header_t *) mask;
11037
11038 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11039   foreach_ip4_proto_field;
11040 #undef _
11041
11042   ip->ip_version_and_header_length = 0;
11043
11044   if (version)
11045     ip->ip_version_and_header_length |= 0xF0;
11046
11047   if (hdr_length)
11048     ip->ip_version_and_header_length |= 0x0F;
11049
11050   *maskp = mask;
11051   return 1;
11052 }
11053
11054 #define foreach_ip6_proto_field                 \
11055 _(src_address)                                  \
11056 _(dst_address)                                  \
11057 _(payload_length)                               \
11058 _(hop_limit)                                    \
11059 _(protocol)
11060
11061 uword
11062 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11063 {
11064   u8 **maskp = va_arg (*args, u8 **);
11065   u8 *mask = 0;
11066   u8 found_something = 0;
11067   ip6_header_t *ip;
11068   u32 ip_version_traffic_class_and_flow_label;
11069
11070 #define _(a) u8 a=0;
11071   foreach_ip6_proto_field;
11072 #undef _
11073   u8 version = 0;
11074   u8 traffic_class = 0;
11075   u8 flow_label = 0;
11076
11077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11078     {
11079       if (unformat (input, "version"))
11080         version = 1;
11081       else if (unformat (input, "traffic-class"))
11082         traffic_class = 1;
11083       else if (unformat (input, "flow-label"))
11084         flow_label = 1;
11085       else if (unformat (input, "src"))
11086         src_address = 1;
11087       else if (unformat (input, "dst"))
11088         dst_address = 1;
11089       else if (unformat (input, "proto"))
11090         protocol = 1;
11091
11092 #define _(a) else if (unformat (input, #a)) a=1;
11093       foreach_ip6_proto_field
11094 #undef _
11095         else
11096         break;
11097     }
11098
11099 #define _(a) found_something += a;
11100   foreach_ip6_proto_field;
11101 #undef _
11102
11103   if (found_something == 0)
11104     return 0;
11105
11106   vec_validate (mask, sizeof (*ip) - 1);
11107
11108   ip = (ip6_header_t *) mask;
11109
11110 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11111   foreach_ip6_proto_field;
11112 #undef _
11113
11114   ip_version_traffic_class_and_flow_label = 0;
11115
11116   if (version)
11117     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11118
11119   if (traffic_class)
11120     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11121
11122   if (flow_label)
11123     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11124
11125   ip->ip_version_traffic_class_and_flow_label =
11126     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11127
11128   *maskp = mask;
11129   return 1;
11130 }
11131
11132 uword
11133 unformat_l3_mask (unformat_input_t * input, va_list * args)
11134 {
11135   u8 **maskp = va_arg (*args, u8 **);
11136
11137   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11138     {
11139       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11140         return 1;
11141       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11142         return 1;
11143       else
11144         break;
11145     }
11146   return 0;
11147 }
11148
11149 uword
11150 unformat_l2_mask (unformat_input_t * input, va_list * args)
11151 {
11152   u8 **maskp = va_arg (*args, u8 **);
11153   u8 *mask = 0;
11154   u8 src = 0;
11155   u8 dst = 0;
11156   u8 proto = 0;
11157   u8 tag1 = 0;
11158   u8 tag2 = 0;
11159   u8 ignore_tag1 = 0;
11160   u8 ignore_tag2 = 0;
11161   u8 cos1 = 0;
11162   u8 cos2 = 0;
11163   u8 dot1q = 0;
11164   u8 dot1ad = 0;
11165   int len = 14;
11166
11167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11168     {
11169       if (unformat (input, "src"))
11170         src = 1;
11171       else if (unformat (input, "dst"))
11172         dst = 1;
11173       else if (unformat (input, "proto"))
11174         proto = 1;
11175       else if (unformat (input, "tag1"))
11176         tag1 = 1;
11177       else if (unformat (input, "tag2"))
11178         tag2 = 1;
11179       else if (unformat (input, "ignore-tag1"))
11180         ignore_tag1 = 1;
11181       else if (unformat (input, "ignore-tag2"))
11182         ignore_tag2 = 1;
11183       else if (unformat (input, "cos1"))
11184         cos1 = 1;
11185       else if (unformat (input, "cos2"))
11186         cos2 = 1;
11187       else if (unformat (input, "dot1q"))
11188         dot1q = 1;
11189       else if (unformat (input, "dot1ad"))
11190         dot1ad = 1;
11191       else
11192         break;
11193     }
11194   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11195        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11196     return 0;
11197
11198   if (tag1 || ignore_tag1 || cos1 || dot1q)
11199     len = 18;
11200   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11201     len = 22;
11202
11203   vec_validate (mask, len - 1);
11204
11205   if (dst)
11206     memset (mask, 0xff, 6);
11207
11208   if (src)
11209     memset (mask + 6, 0xff, 6);
11210
11211   if (tag2 || dot1ad)
11212     {
11213       /* inner vlan tag */
11214       if (tag2)
11215         {
11216           mask[19] = 0xff;
11217           mask[18] = 0x0f;
11218         }
11219       if (cos2)
11220         mask[18] |= 0xe0;
11221       if (proto)
11222         mask[21] = mask[20] = 0xff;
11223       if (tag1)
11224         {
11225           mask[15] = 0xff;
11226           mask[14] = 0x0f;
11227         }
11228       if (cos1)
11229         mask[14] |= 0xe0;
11230       *maskp = mask;
11231       return 1;
11232     }
11233   if (tag1 | dot1q)
11234     {
11235       if (tag1)
11236         {
11237           mask[15] = 0xff;
11238           mask[14] = 0x0f;
11239         }
11240       if (cos1)
11241         mask[14] |= 0xe0;
11242       if (proto)
11243         mask[16] = mask[17] = 0xff;
11244
11245       *maskp = mask;
11246       return 1;
11247     }
11248   if (cos2)
11249     mask[18] |= 0xe0;
11250   if (cos1)
11251     mask[14] |= 0xe0;
11252   if (proto)
11253     mask[12] = mask[13] = 0xff;
11254
11255   *maskp = mask;
11256   return 1;
11257 }
11258
11259 uword
11260 unformat_classify_mask (unformat_input_t * input, va_list * args)
11261 {
11262   u8 **maskp = va_arg (*args, u8 **);
11263   u32 *skipp = va_arg (*args, u32 *);
11264   u32 *matchp = va_arg (*args, u32 *);
11265   u32 match;
11266   u8 *mask = 0;
11267   u8 *l2 = 0;
11268   u8 *l3 = 0;
11269   u8 *l4 = 0;
11270   int i;
11271
11272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11273     {
11274       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11275         ;
11276       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11277         ;
11278       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11279         ;
11280       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11281         ;
11282       else
11283         break;
11284     }
11285
11286   if (l4 && !l3)
11287     {
11288       vec_free (mask);
11289       vec_free (l2);
11290       vec_free (l4);
11291       return 0;
11292     }
11293
11294   if (mask || l2 || l3 || l4)
11295     {
11296       if (l2 || l3 || l4)
11297         {
11298           /* "With a free Ethernet header in every package" */
11299           if (l2 == 0)
11300             vec_validate (l2, 13);
11301           mask = l2;
11302           if (vec_len (l3))
11303             {
11304               vec_append (mask, l3);
11305               vec_free (l3);
11306             }
11307           if (vec_len (l4))
11308             {
11309               vec_append (mask, l4);
11310               vec_free (l4);
11311             }
11312         }
11313
11314       /* Scan forward looking for the first significant mask octet */
11315       for (i = 0; i < vec_len (mask); i++)
11316         if (mask[i])
11317           break;
11318
11319       /* compute (skip, match) params */
11320       *skipp = i / sizeof (u32x4);
11321       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11322
11323       /* Pad mask to an even multiple of the vector size */
11324       while (vec_len (mask) % sizeof (u32x4))
11325         vec_add1 (mask, 0);
11326
11327       match = vec_len (mask) / sizeof (u32x4);
11328
11329       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11330         {
11331           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11332           if (*tmp || *(tmp + 1))
11333             break;
11334           match--;
11335         }
11336       if (match == 0)
11337         clib_warning ("BUG: match 0");
11338
11339       _vec_len (mask) = match * sizeof (u32x4);
11340
11341       *matchp = match;
11342       *maskp = mask;
11343
11344       return 1;
11345     }
11346
11347   return 0;
11348 }
11349 #endif /* VPP_API_TEST_BUILTIN */
11350
11351 #define foreach_l2_next                         \
11352 _(drop, DROP)                                   \
11353 _(ethernet, ETHERNET_INPUT)                     \
11354 _(ip4, IP4_INPUT)                               \
11355 _(ip6, IP6_INPUT)
11356
11357 uword
11358 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11359 {
11360   u32 *miss_next_indexp = va_arg (*args, u32 *);
11361   u32 next_index = 0;
11362   u32 tmp;
11363
11364 #define _(n,N) \
11365   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11366   foreach_l2_next;
11367 #undef _
11368
11369   if (unformat (input, "%d", &tmp))
11370     {
11371       next_index = tmp;
11372       goto out;
11373     }
11374
11375   return 0;
11376
11377 out:
11378   *miss_next_indexp = next_index;
11379   return 1;
11380 }
11381
11382 #define foreach_ip_next                         \
11383 _(drop, DROP)                                   \
11384 _(local, LOCAL)                                 \
11385 _(rewrite, REWRITE)
11386
11387 uword
11388 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11389 {
11390   u32 *miss_next_indexp = va_arg (*args, u32 *);
11391   u32 next_index = 0;
11392   u32 tmp;
11393
11394 #define _(n,N) \
11395   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11396   foreach_ip_next;
11397 #undef _
11398
11399   if (unformat (input, "%d", &tmp))
11400     {
11401       next_index = tmp;
11402       goto out;
11403     }
11404
11405   return 0;
11406
11407 out:
11408   *miss_next_indexp = next_index;
11409   return 1;
11410 }
11411
11412 #define foreach_acl_next                        \
11413 _(deny, DENY)
11414
11415 uword
11416 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11417 {
11418   u32 *miss_next_indexp = va_arg (*args, u32 *);
11419   u32 next_index = 0;
11420   u32 tmp;
11421
11422 #define _(n,N) \
11423   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11424   foreach_acl_next;
11425 #undef _
11426
11427   if (unformat (input, "permit"))
11428     {
11429       next_index = ~0;
11430       goto out;
11431     }
11432   else if (unformat (input, "%d", &tmp))
11433     {
11434       next_index = tmp;
11435       goto out;
11436     }
11437
11438   return 0;
11439
11440 out:
11441   *miss_next_indexp = next_index;
11442   return 1;
11443 }
11444
11445 uword
11446 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11447 {
11448   u32 *r = va_arg (*args, u32 *);
11449
11450   if (unformat (input, "conform-color"))
11451     *r = POLICE_CONFORM;
11452   else if (unformat (input, "exceed-color"))
11453     *r = POLICE_EXCEED;
11454   else
11455     return 0;
11456
11457   return 1;
11458 }
11459
11460 static int
11461 api_classify_add_del_table (vat_main_t * vam)
11462 {
11463   unformat_input_t *i = vam->input;
11464   vl_api_classify_add_del_table_t *mp;
11465
11466   u32 nbuckets = 2;
11467   u32 skip = ~0;
11468   u32 match = ~0;
11469   int is_add = 1;
11470   int del_chain = 0;
11471   u32 table_index = ~0;
11472   u32 next_table_index = ~0;
11473   u32 miss_next_index = ~0;
11474   u32 memory_size = 32 << 20;
11475   u8 *mask = 0;
11476   u32 current_data_flag = 0;
11477   int current_data_offset = 0;
11478   int ret;
11479
11480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11481     {
11482       if (unformat (i, "del"))
11483         is_add = 0;
11484       else if (unformat (i, "del-chain"))
11485         {
11486           is_add = 0;
11487           del_chain = 1;
11488         }
11489       else if (unformat (i, "buckets %d", &nbuckets))
11490         ;
11491       else if (unformat (i, "memory_size %d", &memory_size))
11492         ;
11493       else if (unformat (i, "skip %d", &skip))
11494         ;
11495       else if (unformat (i, "match %d", &match))
11496         ;
11497       else if (unformat (i, "table %d", &table_index))
11498         ;
11499       else if (unformat (i, "mask %U", unformat_classify_mask,
11500                          &mask, &skip, &match))
11501         ;
11502       else if (unformat (i, "next-table %d", &next_table_index))
11503         ;
11504       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11505                          &miss_next_index))
11506         ;
11507       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11508                          &miss_next_index))
11509         ;
11510       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11511                          &miss_next_index))
11512         ;
11513       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11514         ;
11515       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11516         ;
11517       else
11518         break;
11519     }
11520
11521   if (is_add && mask == 0)
11522     {
11523       errmsg ("Mask required");
11524       return -99;
11525     }
11526
11527   if (is_add && skip == ~0)
11528     {
11529       errmsg ("skip count required");
11530       return -99;
11531     }
11532
11533   if (is_add && match == ~0)
11534     {
11535       errmsg ("match count required");
11536       return -99;
11537     }
11538
11539   if (!is_add && table_index == ~0)
11540     {
11541       errmsg ("table index required for delete");
11542       return -99;
11543     }
11544
11545   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11546
11547   mp->is_add = is_add;
11548   mp->del_chain = del_chain;
11549   mp->table_index = ntohl (table_index);
11550   mp->nbuckets = ntohl (nbuckets);
11551   mp->memory_size = ntohl (memory_size);
11552   mp->skip_n_vectors = ntohl (skip);
11553   mp->match_n_vectors = ntohl (match);
11554   mp->next_table_index = ntohl (next_table_index);
11555   mp->miss_next_index = ntohl (miss_next_index);
11556   mp->current_data_flag = ntohl (current_data_flag);
11557   mp->current_data_offset = ntohl (current_data_offset);
11558   mp->mask_len = ntohl (vec_len (mask));
11559   clib_memcpy (mp->mask, mask, vec_len (mask));
11560
11561   vec_free (mask);
11562
11563   S (mp);
11564   W (ret);
11565   return ret;
11566 }
11567
11568 #if VPP_API_TEST_BUILTIN == 0
11569 uword
11570 unformat_l4_match (unformat_input_t * input, va_list * args)
11571 {
11572   u8 **matchp = va_arg (*args, u8 **);
11573
11574   u8 *proto_header = 0;
11575   int src_port = 0;
11576   int dst_port = 0;
11577
11578   tcpudp_header_t h;
11579
11580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11581     {
11582       if (unformat (input, "src_port %d", &src_port))
11583         ;
11584       else if (unformat (input, "dst_port %d", &dst_port))
11585         ;
11586       else
11587         return 0;
11588     }
11589
11590   h.src_port = clib_host_to_net_u16 (src_port);
11591   h.dst_port = clib_host_to_net_u16 (dst_port);
11592   vec_validate (proto_header, sizeof (h) - 1);
11593   memcpy (proto_header, &h, sizeof (h));
11594
11595   *matchp = proto_header;
11596
11597   return 1;
11598 }
11599
11600 uword
11601 unformat_ip4_match (unformat_input_t * input, va_list * args)
11602 {
11603   u8 **matchp = va_arg (*args, u8 **);
11604   u8 *match = 0;
11605   ip4_header_t *ip;
11606   int version = 0;
11607   u32 version_val;
11608   int hdr_length = 0;
11609   u32 hdr_length_val;
11610   int src = 0, dst = 0;
11611   ip4_address_t src_val, dst_val;
11612   int proto = 0;
11613   u32 proto_val;
11614   int tos = 0;
11615   u32 tos_val;
11616   int length = 0;
11617   u32 length_val;
11618   int fragment_id = 0;
11619   u32 fragment_id_val;
11620   int ttl = 0;
11621   int ttl_val;
11622   int checksum = 0;
11623   u32 checksum_val;
11624
11625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11626     {
11627       if (unformat (input, "version %d", &version_val))
11628         version = 1;
11629       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11630         hdr_length = 1;
11631       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11632         src = 1;
11633       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11634         dst = 1;
11635       else if (unformat (input, "proto %d", &proto_val))
11636         proto = 1;
11637       else if (unformat (input, "tos %d", &tos_val))
11638         tos = 1;
11639       else if (unformat (input, "length %d", &length_val))
11640         length = 1;
11641       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11642         fragment_id = 1;
11643       else if (unformat (input, "ttl %d", &ttl_val))
11644         ttl = 1;
11645       else if (unformat (input, "checksum %d", &checksum_val))
11646         checksum = 1;
11647       else
11648         break;
11649     }
11650
11651   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11652       + ttl + checksum == 0)
11653     return 0;
11654
11655   /*
11656    * Aligned because we use the real comparison functions
11657    */
11658   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11659
11660   ip = (ip4_header_t *) match;
11661
11662   /* These are realistically matched in practice */
11663   if (src)
11664     ip->src_address.as_u32 = src_val.as_u32;
11665
11666   if (dst)
11667     ip->dst_address.as_u32 = dst_val.as_u32;
11668
11669   if (proto)
11670     ip->protocol = proto_val;
11671
11672
11673   /* These are not, but they're included for completeness */
11674   if (version)
11675     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11676
11677   if (hdr_length)
11678     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11679
11680   if (tos)
11681     ip->tos = tos_val;
11682
11683   if (length)
11684     ip->length = clib_host_to_net_u16 (length_val);
11685
11686   if (ttl)
11687     ip->ttl = ttl_val;
11688
11689   if (checksum)
11690     ip->checksum = clib_host_to_net_u16 (checksum_val);
11691
11692   *matchp = match;
11693   return 1;
11694 }
11695
11696 uword
11697 unformat_ip6_match (unformat_input_t * input, va_list * args)
11698 {
11699   u8 **matchp = va_arg (*args, u8 **);
11700   u8 *match = 0;
11701   ip6_header_t *ip;
11702   int version = 0;
11703   u32 version_val;
11704   u8 traffic_class = 0;
11705   u32 traffic_class_val = 0;
11706   u8 flow_label = 0;
11707   u8 flow_label_val;
11708   int src = 0, dst = 0;
11709   ip6_address_t src_val, dst_val;
11710   int proto = 0;
11711   u32 proto_val;
11712   int payload_length = 0;
11713   u32 payload_length_val;
11714   int hop_limit = 0;
11715   int hop_limit_val;
11716   u32 ip_version_traffic_class_and_flow_label;
11717
11718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11719     {
11720       if (unformat (input, "version %d", &version_val))
11721         version = 1;
11722       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11723         traffic_class = 1;
11724       else if (unformat (input, "flow_label %d", &flow_label_val))
11725         flow_label = 1;
11726       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11727         src = 1;
11728       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11729         dst = 1;
11730       else if (unformat (input, "proto %d", &proto_val))
11731         proto = 1;
11732       else if (unformat (input, "payload_length %d", &payload_length_val))
11733         payload_length = 1;
11734       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11735         hop_limit = 1;
11736       else
11737         break;
11738     }
11739
11740   if (version + traffic_class + flow_label + src + dst + proto +
11741       payload_length + hop_limit == 0)
11742     return 0;
11743
11744   /*
11745    * Aligned because we use the real comparison functions
11746    */
11747   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11748
11749   ip = (ip6_header_t *) match;
11750
11751   if (src)
11752     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11753
11754   if (dst)
11755     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11756
11757   if (proto)
11758     ip->protocol = proto_val;
11759
11760   ip_version_traffic_class_and_flow_label = 0;
11761
11762   if (version)
11763     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11764
11765   if (traffic_class)
11766     ip_version_traffic_class_and_flow_label |=
11767       (traffic_class_val & 0xFF) << 20;
11768
11769   if (flow_label)
11770     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11771
11772   ip->ip_version_traffic_class_and_flow_label =
11773     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11774
11775   if (payload_length)
11776     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11777
11778   if (hop_limit)
11779     ip->hop_limit = hop_limit_val;
11780
11781   *matchp = match;
11782   return 1;
11783 }
11784
11785 uword
11786 unformat_l3_match (unformat_input_t * input, va_list * args)
11787 {
11788   u8 **matchp = va_arg (*args, u8 **);
11789
11790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11791     {
11792       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11793         return 1;
11794       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11795         return 1;
11796       else
11797         break;
11798     }
11799   return 0;
11800 }
11801
11802 uword
11803 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11804 {
11805   u8 *tagp = va_arg (*args, u8 *);
11806   u32 tag;
11807
11808   if (unformat (input, "%d", &tag))
11809     {
11810       tagp[0] = (tag >> 8) & 0x0F;
11811       tagp[1] = tag & 0xFF;
11812       return 1;
11813     }
11814
11815   return 0;
11816 }
11817
11818 uword
11819 unformat_l2_match (unformat_input_t * input, va_list * args)
11820 {
11821   u8 **matchp = va_arg (*args, u8 **);
11822   u8 *match = 0;
11823   u8 src = 0;
11824   u8 src_val[6];
11825   u8 dst = 0;
11826   u8 dst_val[6];
11827   u8 proto = 0;
11828   u16 proto_val;
11829   u8 tag1 = 0;
11830   u8 tag1_val[2];
11831   u8 tag2 = 0;
11832   u8 tag2_val[2];
11833   int len = 14;
11834   u8 ignore_tag1 = 0;
11835   u8 ignore_tag2 = 0;
11836   u8 cos1 = 0;
11837   u8 cos2 = 0;
11838   u32 cos1_val = 0;
11839   u32 cos2_val = 0;
11840
11841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11842     {
11843       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11844         src = 1;
11845       else
11846         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11847         dst = 1;
11848       else if (unformat (input, "proto %U",
11849                          unformat_ethernet_type_host_byte_order, &proto_val))
11850         proto = 1;
11851       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11852         tag1 = 1;
11853       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11854         tag2 = 1;
11855       else if (unformat (input, "ignore-tag1"))
11856         ignore_tag1 = 1;
11857       else if (unformat (input, "ignore-tag2"))
11858         ignore_tag2 = 1;
11859       else if (unformat (input, "cos1 %d", &cos1_val))
11860         cos1 = 1;
11861       else if (unformat (input, "cos2 %d", &cos2_val))
11862         cos2 = 1;
11863       else
11864         break;
11865     }
11866   if ((src + dst + proto + tag1 + tag2 +
11867        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11868     return 0;
11869
11870   if (tag1 || ignore_tag1 || cos1)
11871     len = 18;
11872   if (tag2 || ignore_tag2 || cos2)
11873     len = 22;
11874
11875   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11876
11877   if (dst)
11878     clib_memcpy (match, dst_val, 6);
11879
11880   if (src)
11881     clib_memcpy (match + 6, src_val, 6);
11882
11883   if (tag2)
11884     {
11885       /* inner vlan tag */
11886       match[19] = tag2_val[1];
11887       match[18] = tag2_val[0];
11888       if (cos2)
11889         match[18] |= (cos2_val & 0x7) << 5;
11890       if (proto)
11891         {
11892           match[21] = proto_val & 0xff;
11893           match[20] = proto_val >> 8;
11894         }
11895       if (tag1)
11896         {
11897           match[15] = tag1_val[1];
11898           match[14] = tag1_val[0];
11899         }
11900       if (cos1)
11901         match[14] |= (cos1_val & 0x7) << 5;
11902       *matchp = match;
11903       return 1;
11904     }
11905   if (tag1)
11906     {
11907       match[15] = tag1_val[1];
11908       match[14] = tag1_val[0];
11909       if (proto)
11910         {
11911           match[17] = proto_val & 0xff;
11912           match[16] = proto_val >> 8;
11913         }
11914       if (cos1)
11915         match[14] |= (cos1_val & 0x7) << 5;
11916
11917       *matchp = match;
11918       return 1;
11919     }
11920   if (cos2)
11921     match[18] |= (cos2_val & 0x7) << 5;
11922   if (cos1)
11923     match[14] |= (cos1_val & 0x7) << 5;
11924   if (proto)
11925     {
11926       match[13] = proto_val & 0xff;
11927       match[12] = proto_val >> 8;
11928     }
11929
11930   *matchp = match;
11931   return 1;
11932 }
11933
11934 uword
11935 unformat_qos_source (unformat_input_t * input, va_list * args)
11936 {
11937   int *qs = va_arg (*args, int *);
11938
11939   if (unformat (input, "ip"))
11940     *qs = QOS_SOURCE_IP;
11941   else if (unformat (input, "mpls"))
11942     *qs = QOS_SOURCE_MPLS;
11943   else if (unformat (input, "ext"))
11944     *qs = QOS_SOURCE_EXT;
11945   else if (unformat (input, "vlan"))
11946     *qs = QOS_SOURCE_VLAN;
11947   else
11948     return 0;
11949
11950   return 1;
11951 }
11952 #endif
11953
11954 uword
11955 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11956 {
11957   u8 **matchp = va_arg (*args, u8 **);
11958   u32 skip_n_vectors = va_arg (*args, u32);
11959   u32 match_n_vectors = va_arg (*args, u32);
11960
11961   u8 *match = 0;
11962   u8 *l2 = 0;
11963   u8 *l3 = 0;
11964   u8 *l4 = 0;
11965
11966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11967     {
11968       if (unformat (input, "hex %U", unformat_hex_string, &match))
11969         ;
11970       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11971         ;
11972       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11973         ;
11974       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11975         ;
11976       else
11977         break;
11978     }
11979
11980   if (l4 && !l3)
11981     {
11982       vec_free (match);
11983       vec_free (l2);
11984       vec_free (l4);
11985       return 0;
11986     }
11987
11988   if (match || l2 || l3 || l4)
11989     {
11990       if (l2 || l3 || l4)
11991         {
11992           /* "Win a free Ethernet header in every packet" */
11993           if (l2 == 0)
11994             vec_validate_aligned (l2, 13, sizeof (u32x4));
11995           match = l2;
11996           if (vec_len (l3))
11997             {
11998               vec_append_aligned (match, l3, sizeof (u32x4));
11999               vec_free (l3);
12000             }
12001           if (vec_len (l4))
12002             {
12003               vec_append_aligned (match, l4, sizeof (u32x4));
12004               vec_free (l4);
12005             }
12006         }
12007
12008       /* Make sure the vector is big enough even if key is all 0's */
12009       vec_validate_aligned
12010         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12011          sizeof (u32x4));
12012
12013       /* Set size, include skipped vectors */
12014       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12015
12016       *matchp = match;
12017
12018       return 1;
12019     }
12020
12021   return 0;
12022 }
12023
12024 static int
12025 api_classify_add_del_session (vat_main_t * vam)
12026 {
12027   unformat_input_t *i = vam->input;
12028   vl_api_classify_add_del_session_t *mp;
12029   int is_add = 1;
12030   u32 table_index = ~0;
12031   u32 hit_next_index = ~0;
12032   u32 opaque_index = ~0;
12033   u8 *match = 0;
12034   i32 advance = 0;
12035   u32 skip_n_vectors = 0;
12036   u32 match_n_vectors = 0;
12037   u32 action = 0;
12038   u32 metadata = 0;
12039   int ret;
12040
12041   /*
12042    * Warning: you have to supply skip_n and match_n
12043    * because the API client cant simply look at the classify
12044    * table object.
12045    */
12046
12047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12048     {
12049       if (unformat (i, "del"))
12050         is_add = 0;
12051       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12052                          &hit_next_index))
12053         ;
12054       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12055                          &hit_next_index))
12056         ;
12057       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12058                          &hit_next_index))
12059         ;
12060       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12061         ;
12062       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12063         ;
12064       else if (unformat (i, "opaque-index %d", &opaque_index))
12065         ;
12066       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12067         ;
12068       else if (unformat (i, "match_n %d", &match_n_vectors))
12069         ;
12070       else if (unformat (i, "match %U", api_unformat_classify_match,
12071                          &match, skip_n_vectors, match_n_vectors))
12072         ;
12073       else if (unformat (i, "advance %d", &advance))
12074         ;
12075       else if (unformat (i, "table-index %d", &table_index))
12076         ;
12077       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12078         action = 1;
12079       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12080         action = 2;
12081       else if (unformat (i, "action %d", &action))
12082         ;
12083       else if (unformat (i, "metadata %d", &metadata))
12084         ;
12085       else
12086         break;
12087     }
12088
12089   if (table_index == ~0)
12090     {
12091       errmsg ("Table index required");
12092       return -99;
12093     }
12094
12095   if (is_add && match == 0)
12096     {
12097       errmsg ("Match value required");
12098       return -99;
12099     }
12100
12101   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12102
12103   mp->is_add = is_add;
12104   mp->table_index = ntohl (table_index);
12105   mp->hit_next_index = ntohl (hit_next_index);
12106   mp->opaque_index = ntohl (opaque_index);
12107   mp->advance = ntohl (advance);
12108   mp->action = action;
12109   mp->metadata = ntohl (metadata);
12110   mp->match_len = ntohl (vec_len (match));
12111   clib_memcpy (mp->match, match, vec_len (match));
12112   vec_free (match);
12113
12114   S (mp);
12115   W (ret);
12116   return ret;
12117 }
12118
12119 static int
12120 api_classify_set_interface_ip_table (vat_main_t * vam)
12121 {
12122   unformat_input_t *i = vam->input;
12123   vl_api_classify_set_interface_ip_table_t *mp;
12124   u32 sw_if_index;
12125   int sw_if_index_set;
12126   u32 table_index = ~0;
12127   u8 is_ipv6 = 0;
12128   int ret;
12129
12130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12131     {
12132       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12133         sw_if_index_set = 1;
12134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12135         sw_if_index_set = 1;
12136       else if (unformat (i, "table %d", &table_index))
12137         ;
12138       else
12139         {
12140           clib_warning ("parse error '%U'", format_unformat_error, i);
12141           return -99;
12142         }
12143     }
12144
12145   if (sw_if_index_set == 0)
12146     {
12147       errmsg ("missing interface name or sw_if_index");
12148       return -99;
12149     }
12150
12151
12152   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12153
12154   mp->sw_if_index = ntohl (sw_if_index);
12155   mp->table_index = ntohl (table_index);
12156   mp->is_ipv6 = is_ipv6;
12157
12158   S (mp);
12159   W (ret);
12160   return ret;
12161 }
12162
12163 static int
12164 api_classify_set_interface_l2_tables (vat_main_t * vam)
12165 {
12166   unformat_input_t *i = vam->input;
12167   vl_api_classify_set_interface_l2_tables_t *mp;
12168   u32 sw_if_index;
12169   int sw_if_index_set;
12170   u32 ip4_table_index = ~0;
12171   u32 ip6_table_index = ~0;
12172   u32 other_table_index = ~0;
12173   u32 is_input = 1;
12174   int ret;
12175
12176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12177     {
12178       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12179         sw_if_index_set = 1;
12180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12181         sw_if_index_set = 1;
12182       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12183         ;
12184       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12185         ;
12186       else if (unformat (i, "other-table %d", &other_table_index))
12187         ;
12188       else if (unformat (i, "is-input %d", &is_input))
12189         ;
12190       else
12191         {
12192           clib_warning ("parse error '%U'", format_unformat_error, i);
12193           return -99;
12194         }
12195     }
12196
12197   if (sw_if_index_set == 0)
12198     {
12199       errmsg ("missing interface name or sw_if_index");
12200       return -99;
12201     }
12202
12203
12204   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12205
12206   mp->sw_if_index = ntohl (sw_if_index);
12207   mp->ip4_table_index = ntohl (ip4_table_index);
12208   mp->ip6_table_index = ntohl (ip6_table_index);
12209   mp->other_table_index = ntohl (other_table_index);
12210   mp->is_input = (u8) is_input;
12211
12212   S (mp);
12213   W (ret);
12214   return ret;
12215 }
12216
12217 static int
12218 api_set_ipfix_exporter (vat_main_t * vam)
12219 {
12220   unformat_input_t *i = vam->input;
12221   vl_api_set_ipfix_exporter_t *mp;
12222   ip4_address_t collector_address;
12223   u8 collector_address_set = 0;
12224   u32 collector_port = ~0;
12225   ip4_address_t src_address;
12226   u8 src_address_set = 0;
12227   u32 vrf_id = ~0;
12228   u32 path_mtu = ~0;
12229   u32 template_interval = ~0;
12230   u8 udp_checksum = 0;
12231   int ret;
12232
12233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12234     {
12235       if (unformat (i, "collector_address %U", unformat_ip4_address,
12236                     &collector_address))
12237         collector_address_set = 1;
12238       else if (unformat (i, "collector_port %d", &collector_port))
12239         ;
12240       else if (unformat (i, "src_address %U", unformat_ip4_address,
12241                          &src_address))
12242         src_address_set = 1;
12243       else if (unformat (i, "vrf_id %d", &vrf_id))
12244         ;
12245       else if (unformat (i, "path_mtu %d", &path_mtu))
12246         ;
12247       else if (unformat (i, "template_interval %d", &template_interval))
12248         ;
12249       else if (unformat (i, "udp_checksum"))
12250         udp_checksum = 1;
12251       else
12252         break;
12253     }
12254
12255   if (collector_address_set == 0)
12256     {
12257       errmsg ("collector_address required");
12258       return -99;
12259     }
12260
12261   if (src_address_set == 0)
12262     {
12263       errmsg ("src_address required");
12264       return -99;
12265     }
12266
12267   M (SET_IPFIX_EXPORTER, mp);
12268
12269   memcpy (mp->collector_address, collector_address.data,
12270           sizeof (collector_address.data));
12271   mp->collector_port = htons ((u16) collector_port);
12272   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12273   mp->vrf_id = htonl (vrf_id);
12274   mp->path_mtu = htonl (path_mtu);
12275   mp->template_interval = htonl (template_interval);
12276   mp->udp_checksum = udp_checksum;
12277
12278   S (mp);
12279   W (ret);
12280   return ret;
12281 }
12282
12283 static int
12284 api_set_ipfix_classify_stream (vat_main_t * vam)
12285 {
12286   unformat_input_t *i = vam->input;
12287   vl_api_set_ipfix_classify_stream_t *mp;
12288   u32 domain_id = 0;
12289   u32 src_port = UDP_DST_PORT_ipfix;
12290   int ret;
12291
12292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12293     {
12294       if (unformat (i, "domain %d", &domain_id))
12295         ;
12296       else if (unformat (i, "src_port %d", &src_port))
12297         ;
12298       else
12299         {
12300           errmsg ("unknown input `%U'", format_unformat_error, i);
12301           return -99;
12302         }
12303     }
12304
12305   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12306
12307   mp->domain_id = htonl (domain_id);
12308   mp->src_port = htons ((u16) src_port);
12309
12310   S (mp);
12311   W (ret);
12312   return ret;
12313 }
12314
12315 static int
12316 api_ipfix_classify_table_add_del (vat_main_t * vam)
12317 {
12318   unformat_input_t *i = vam->input;
12319   vl_api_ipfix_classify_table_add_del_t *mp;
12320   int is_add = -1;
12321   u32 classify_table_index = ~0;
12322   u8 ip_version = 0;
12323   u8 transport_protocol = 255;
12324   int ret;
12325
12326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12327     {
12328       if (unformat (i, "add"))
12329         is_add = 1;
12330       else if (unformat (i, "del"))
12331         is_add = 0;
12332       else if (unformat (i, "table %d", &classify_table_index))
12333         ;
12334       else if (unformat (i, "ip4"))
12335         ip_version = 4;
12336       else if (unformat (i, "ip6"))
12337         ip_version = 6;
12338       else if (unformat (i, "tcp"))
12339         transport_protocol = 6;
12340       else if (unformat (i, "udp"))
12341         transport_protocol = 17;
12342       else
12343         {
12344           errmsg ("unknown input `%U'", format_unformat_error, i);
12345           return -99;
12346         }
12347     }
12348
12349   if (is_add == -1)
12350     {
12351       errmsg ("expecting: add|del");
12352       return -99;
12353     }
12354   if (classify_table_index == ~0)
12355     {
12356       errmsg ("classifier table not specified");
12357       return -99;
12358     }
12359   if (ip_version == 0)
12360     {
12361       errmsg ("IP version not specified");
12362       return -99;
12363     }
12364
12365   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12366
12367   mp->is_add = is_add;
12368   mp->table_id = htonl (classify_table_index);
12369   mp->ip_version = ip_version;
12370   mp->transport_protocol = transport_protocol;
12371
12372   S (mp);
12373   W (ret);
12374   return ret;
12375 }
12376
12377 static int
12378 api_get_node_index (vat_main_t * vam)
12379 {
12380   unformat_input_t *i = vam->input;
12381   vl_api_get_node_index_t *mp;
12382   u8 *name = 0;
12383   int ret;
12384
12385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12386     {
12387       if (unformat (i, "node %s", &name))
12388         ;
12389       else
12390         break;
12391     }
12392   if (name == 0)
12393     {
12394       errmsg ("node name required");
12395       return -99;
12396     }
12397   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12398     {
12399       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12400       return -99;
12401     }
12402
12403   M (GET_NODE_INDEX, mp);
12404   clib_memcpy (mp->node_name, name, vec_len (name));
12405   vec_free (name);
12406
12407   S (mp);
12408   W (ret);
12409   return ret;
12410 }
12411
12412 static int
12413 api_get_next_index (vat_main_t * vam)
12414 {
12415   unformat_input_t *i = vam->input;
12416   vl_api_get_next_index_t *mp;
12417   u8 *node_name = 0, *next_node_name = 0;
12418   int ret;
12419
12420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12421     {
12422       if (unformat (i, "node-name %s", &node_name))
12423         ;
12424       else if (unformat (i, "next-node-name %s", &next_node_name))
12425         break;
12426     }
12427
12428   if (node_name == 0)
12429     {
12430       errmsg ("node name required");
12431       return -99;
12432     }
12433   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12434     {
12435       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12436       return -99;
12437     }
12438
12439   if (next_node_name == 0)
12440     {
12441       errmsg ("next node name required");
12442       return -99;
12443     }
12444   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12445     {
12446       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12447       return -99;
12448     }
12449
12450   M (GET_NEXT_INDEX, mp);
12451   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12452   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12453   vec_free (node_name);
12454   vec_free (next_node_name);
12455
12456   S (mp);
12457   W (ret);
12458   return ret;
12459 }
12460
12461 static int
12462 api_add_node_next (vat_main_t * vam)
12463 {
12464   unformat_input_t *i = vam->input;
12465   vl_api_add_node_next_t *mp;
12466   u8 *name = 0;
12467   u8 *next = 0;
12468   int ret;
12469
12470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12471     {
12472       if (unformat (i, "node %s", &name))
12473         ;
12474       else if (unformat (i, "next %s", &next))
12475         ;
12476       else
12477         break;
12478     }
12479   if (name == 0)
12480     {
12481       errmsg ("node name required");
12482       return -99;
12483     }
12484   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12485     {
12486       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12487       return -99;
12488     }
12489   if (next == 0)
12490     {
12491       errmsg ("next node required");
12492       return -99;
12493     }
12494   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12495     {
12496       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12497       return -99;
12498     }
12499
12500   M (ADD_NODE_NEXT, mp);
12501   clib_memcpy (mp->node_name, name, vec_len (name));
12502   clib_memcpy (mp->next_name, next, vec_len (next));
12503   vec_free (name);
12504   vec_free (next);
12505
12506   S (mp);
12507   W (ret);
12508   return ret;
12509 }
12510
12511 static int
12512 api_l2tpv3_create_tunnel (vat_main_t * vam)
12513 {
12514   unformat_input_t *i = vam->input;
12515   ip6_address_t client_address, our_address;
12516   int client_address_set = 0;
12517   int our_address_set = 0;
12518   u32 local_session_id = 0;
12519   u32 remote_session_id = 0;
12520   u64 local_cookie = 0;
12521   u64 remote_cookie = 0;
12522   u8 l2_sublayer_present = 0;
12523   vl_api_l2tpv3_create_tunnel_t *mp;
12524   int ret;
12525
12526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12527     {
12528       if (unformat (i, "client_address %U", unformat_ip6_address,
12529                     &client_address))
12530         client_address_set = 1;
12531       else if (unformat (i, "our_address %U", unformat_ip6_address,
12532                          &our_address))
12533         our_address_set = 1;
12534       else if (unformat (i, "local_session_id %d", &local_session_id))
12535         ;
12536       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12537         ;
12538       else if (unformat (i, "local_cookie %lld", &local_cookie))
12539         ;
12540       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12541         ;
12542       else if (unformat (i, "l2-sublayer-present"))
12543         l2_sublayer_present = 1;
12544       else
12545         break;
12546     }
12547
12548   if (client_address_set == 0)
12549     {
12550       errmsg ("client_address required");
12551       return -99;
12552     }
12553
12554   if (our_address_set == 0)
12555     {
12556       errmsg ("our_address required");
12557       return -99;
12558     }
12559
12560   M (L2TPV3_CREATE_TUNNEL, mp);
12561
12562   clib_memcpy (mp->client_address, client_address.as_u8,
12563                sizeof (mp->client_address));
12564
12565   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12566
12567   mp->local_session_id = ntohl (local_session_id);
12568   mp->remote_session_id = ntohl (remote_session_id);
12569   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12570   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12571   mp->l2_sublayer_present = l2_sublayer_present;
12572   mp->is_ipv6 = 1;
12573
12574   S (mp);
12575   W (ret);
12576   return ret;
12577 }
12578
12579 static int
12580 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12581 {
12582   unformat_input_t *i = vam->input;
12583   u32 sw_if_index;
12584   u8 sw_if_index_set = 0;
12585   u64 new_local_cookie = 0;
12586   u64 new_remote_cookie = 0;
12587   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12588   int ret;
12589
12590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12591     {
12592       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12593         sw_if_index_set = 1;
12594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12595         sw_if_index_set = 1;
12596       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12597         ;
12598       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12599         ;
12600       else
12601         break;
12602     }
12603
12604   if (sw_if_index_set == 0)
12605     {
12606       errmsg ("missing interface name or sw_if_index");
12607       return -99;
12608     }
12609
12610   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12611
12612   mp->sw_if_index = ntohl (sw_if_index);
12613   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12614   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12615
12616   S (mp);
12617   W (ret);
12618   return ret;
12619 }
12620
12621 static int
12622 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12623 {
12624   unformat_input_t *i = vam->input;
12625   vl_api_l2tpv3_interface_enable_disable_t *mp;
12626   u32 sw_if_index;
12627   u8 sw_if_index_set = 0;
12628   u8 enable_disable = 1;
12629   int ret;
12630
12631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12632     {
12633       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12634         sw_if_index_set = 1;
12635       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12636         sw_if_index_set = 1;
12637       else if (unformat (i, "enable"))
12638         enable_disable = 1;
12639       else if (unformat (i, "disable"))
12640         enable_disable = 0;
12641       else
12642         break;
12643     }
12644
12645   if (sw_if_index_set == 0)
12646     {
12647       errmsg ("missing interface name or sw_if_index");
12648       return -99;
12649     }
12650
12651   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12652
12653   mp->sw_if_index = ntohl (sw_if_index);
12654   mp->enable_disable = enable_disable;
12655
12656   S (mp);
12657   W (ret);
12658   return ret;
12659 }
12660
12661 static int
12662 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12663 {
12664   unformat_input_t *i = vam->input;
12665   vl_api_l2tpv3_set_lookup_key_t *mp;
12666   u8 key = ~0;
12667   int ret;
12668
12669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12670     {
12671       if (unformat (i, "lookup_v6_src"))
12672         key = L2T_LOOKUP_SRC_ADDRESS;
12673       else if (unformat (i, "lookup_v6_dst"))
12674         key = L2T_LOOKUP_DST_ADDRESS;
12675       else if (unformat (i, "lookup_session_id"))
12676         key = L2T_LOOKUP_SESSION_ID;
12677       else
12678         break;
12679     }
12680
12681   if (key == (u8) ~ 0)
12682     {
12683       errmsg ("l2tp session lookup key unset");
12684       return -99;
12685     }
12686
12687   M (L2TPV3_SET_LOOKUP_KEY, mp);
12688
12689   mp->key = key;
12690
12691   S (mp);
12692   W (ret);
12693   return ret;
12694 }
12695
12696 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12697   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12698 {
12699   vat_main_t *vam = &vat_main;
12700
12701   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12702          format_ip6_address, mp->our_address,
12703          format_ip6_address, mp->client_address,
12704          clib_net_to_host_u32 (mp->sw_if_index));
12705
12706   print (vam->ofp,
12707          "   local cookies %016llx %016llx remote cookie %016llx",
12708          clib_net_to_host_u64 (mp->local_cookie[0]),
12709          clib_net_to_host_u64 (mp->local_cookie[1]),
12710          clib_net_to_host_u64 (mp->remote_cookie));
12711
12712   print (vam->ofp, "   local session-id %d remote session-id %d",
12713          clib_net_to_host_u32 (mp->local_session_id),
12714          clib_net_to_host_u32 (mp->remote_session_id));
12715
12716   print (vam->ofp, "   l2 specific sublayer %s\n",
12717          mp->l2_sublayer_present ? "preset" : "absent");
12718
12719 }
12720
12721 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12722   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12723 {
12724   vat_main_t *vam = &vat_main;
12725   vat_json_node_t *node = NULL;
12726   struct in6_addr addr;
12727
12728   if (VAT_JSON_ARRAY != vam->json_tree.type)
12729     {
12730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12731       vat_json_init_array (&vam->json_tree);
12732     }
12733   node = vat_json_array_add (&vam->json_tree);
12734
12735   vat_json_init_object (node);
12736
12737   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12738   vat_json_object_add_ip6 (node, "our_address", addr);
12739   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12740   vat_json_object_add_ip6 (node, "client_address", addr);
12741
12742   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12743   vat_json_init_array (lc);
12744   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12745   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12746   vat_json_object_add_uint (node, "remote_cookie",
12747                             clib_net_to_host_u64 (mp->remote_cookie));
12748
12749   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12750   vat_json_object_add_uint (node, "local_session_id",
12751                             clib_net_to_host_u32 (mp->local_session_id));
12752   vat_json_object_add_uint (node, "remote_session_id",
12753                             clib_net_to_host_u32 (mp->remote_session_id));
12754   vat_json_object_add_string_copy (node, "l2_sublayer",
12755                                    mp->l2_sublayer_present ? (u8 *) "present"
12756                                    : (u8 *) "absent");
12757 }
12758
12759 static int
12760 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12761 {
12762   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12763   vl_api_control_ping_t *mp_ping;
12764   int ret;
12765
12766   /* Get list of l2tpv3-tunnel interfaces */
12767   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12768   S (mp);
12769
12770   /* Use a control ping for synchronization */
12771   MPING (CONTROL_PING, mp_ping);
12772   S (mp_ping);
12773
12774   W (ret);
12775   return ret;
12776 }
12777
12778
12779 static void vl_api_sw_interface_tap_details_t_handler
12780   (vl_api_sw_interface_tap_details_t * mp)
12781 {
12782   vat_main_t *vam = &vat_main;
12783
12784   print (vam->ofp, "%-16s %d",
12785          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12786 }
12787
12788 static void vl_api_sw_interface_tap_details_t_handler_json
12789   (vl_api_sw_interface_tap_details_t * mp)
12790 {
12791   vat_main_t *vam = &vat_main;
12792   vat_json_node_t *node = NULL;
12793
12794   if (VAT_JSON_ARRAY != vam->json_tree.type)
12795     {
12796       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12797       vat_json_init_array (&vam->json_tree);
12798     }
12799   node = vat_json_array_add (&vam->json_tree);
12800
12801   vat_json_init_object (node);
12802   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12803   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12804 }
12805
12806 static int
12807 api_sw_interface_tap_dump (vat_main_t * vam)
12808 {
12809   vl_api_sw_interface_tap_dump_t *mp;
12810   vl_api_control_ping_t *mp_ping;
12811   int ret;
12812
12813   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12814   /* Get list of tap interfaces */
12815   M (SW_INTERFACE_TAP_DUMP, mp);
12816   S (mp);
12817
12818   /* Use a control ping for synchronization */
12819   MPING (CONTROL_PING, mp_ping);
12820   S (mp_ping);
12821
12822   W (ret);
12823   return ret;
12824 }
12825
12826 static void vl_api_sw_interface_tap_v2_details_t_handler
12827   (vl_api_sw_interface_tap_v2_details_t * mp)
12828 {
12829   vat_main_t *vam = &vat_main;
12830
12831   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12832                     mp->host_ip4_prefix_len);
12833   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12834                     mp->host_ip6_prefix_len);
12835
12836   print (vam->ofp,
12837          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12838          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12839          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12840          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12841          mp->host_bridge, ip4, ip6);
12842
12843   vec_free (ip4);
12844   vec_free (ip6);
12845 }
12846
12847 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12848   (vl_api_sw_interface_tap_v2_details_t * mp)
12849 {
12850   vat_main_t *vam = &vat_main;
12851   vat_json_node_t *node = NULL;
12852
12853   if (VAT_JSON_ARRAY != vam->json_tree.type)
12854     {
12855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12856       vat_json_init_array (&vam->json_tree);
12857     }
12858   node = vat_json_array_add (&vam->json_tree);
12859
12860   vat_json_init_object (node);
12861   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12862   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12863   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12864   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12865   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12866   vat_json_object_add_string_copy (node, "host_mac_addr",
12867                                    format (0, "%U", format_ethernet_address,
12868                                            &mp->host_mac_addr));
12869   vat_json_object_add_string_copy (node, "host_namespace",
12870                                    mp->host_namespace);
12871   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12872   vat_json_object_add_string_copy (node, "host_ip4_addr",
12873                                    format (0, "%U/%d", format_ip4_address,
12874                                            mp->host_ip4_addr,
12875                                            mp->host_ip4_prefix_len));
12876   vat_json_object_add_string_copy (node, "host_ip6_addr",
12877                                    format (0, "%U/%d", format_ip6_address,
12878                                            mp->host_ip6_addr,
12879                                            mp->host_ip6_prefix_len));
12880
12881 }
12882
12883 static int
12884 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12885 {
12886   vl_api_sw_interface_tap_v2_dump_t *mp;
12887   vl_api_control_ping_t *mp_ping;
12888   int ret;
12889
12890   print (vam->ofp,
12891          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12892          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12893          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12894          "host_ip6_addr");
12895
12896   /* Get list of tap interfaces */
12897   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12898   S (mp);
12899
12900   /* Use a control ping for synchronization */
12901   MPING (CONTROL_PING, mp_ping);
12902   S (mp_ping);
12903
12904   W (ret);
12905   return ret;
12906 }
12907
12908 static int
12909 api_vxlan_offload_rx (vat_main_t * vam)
12910 {
12911   unformat_input_t *line_input = vam->input;
12912   vl_api_vxlan_offload_rx_t *mp;
12913   u32 hw_if_index = ~0, rx_if_index = ~0;
12914   u8 is_add = 1;
12915   int ret;
12916
12917   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12918     {
12919       if (unformat (line_input, "del"))
12920         is_add = 0;
12921       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12922                          &hw_if_index))
12923         ;
12924       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12925         ;
12926       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12927                          &rx_if_index))
12928         ;
12929       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12930         ;
12931       else
12932         {
12933           errmsg ("parse error '%U'", format_unformat_error, line_input);
12934           return -99;
12935         }
12936     }
12937
12938   if (hw_if_index == ~0)
12939     {
12940       errmsg ("no hw interface");
12941       return -99;
12942     }
12943
12944   if (rx_if_index == ~0)
12945     {
12946       errmsg ("no rx tunnel");
12947       return -99;
12948     }
12949
12950   M (VXLAN_OFFLOAD_RX, mp);
12951
12952   mp->hw_if_index = ntohl (hw_if_index);
12953   mp->sw_if_index = ntohl (rx_if_index);
12954   mp->enable = is_add;
12955
12956   S (mp);
12957   W (ret);
12958   return ret;
12959 }
12960
12961 static uword unformat_vxlan_decap_next
12962   (unformat_input_t * input, va_list * args)
12963 {
12964   u32 *result = va_arg (*args, u32 *);
12965   u32 tmp;
12966
12967   if (unformat (input, "l2"))
12968     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12969   else if (unformat (input, "%d", &tmp))
12970     *result = tmp;
12971   else
12972     return 0;
12973   return 1;
12974 }
12975
12976 static int
12977 api_vxlan_add_del_tunnel (vat_main_t * vam)
12978 {
12979   unformat_input_t *line_input = vam->input;
12980   vl_api_vxlan_add_del_tunnel_t *mp;
12981   ip46_address_t src, dst;
12982   u8 is_add = 1;
12983   u8 ipv4_set = 0, ipv6_set = 0;
12984   u8 src_set = 0;
12985   u8 dst_set = 0;
12986   u8 grp_set = 0;
12987   u32 instance = ~0;
12988   u32 mcast_sw_if_index = ~0;
12989   u32 encap_vrf_id = 0;
12990   u32 decap_next_index = ~0;
12991   u32 vni = 0;
12992   int ret;
12993
12994   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12995   memset (&src, 0, sizeof src);
12996   memset (&dst, 0, sizeof dst);
12997
12998   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12999     {
13000       if (unformat (line_input, "del"))
13001         is_add = 0;
13002       else if (unformat (line_input, "instance %d", &instance))
13003         ;
13004       else
13005         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13006         {
13007           ipv4_set = 1;
13008           src_set = 1;
13009         }
13010       else
13011         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13012         {
13013           ipv4_set = 1;
13014           dst_set = 1;
13015         }
13016       else
13017         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13018         {
13019           ipv6_set = 1;
13020           src_set = 1;
13021         }
13022       else
13023         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13024         {
13025           ipv6_set = 1;
13026           dst_set = 1;
13027         }
13028       else if (unformat (line_input, "group %U %U",
13029                          unformat_ip4_address, &dst.ip4,
13030                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13031         {
13032           grp_set = dst_set = 1;
13033           ipv4_set = 1;
13034         }
13035       else if (unformat (line_input, "group %U",
13036                          unformat_ip4_address, &dst.ip4))
13037         {
13038           grp_set = dst_set = 1;
13039           ipv4_set = 1;
13040         }
13041       else if (unformat (line_input, "group %U %U",
13042                          unformat_ip6_address, &dst.ip6,
13043                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13044         {
13045           grp_set = dst_set = 1;
13046           ipv6_set = 1;
13047         }
13048       else if (unformat (line_input, "group %U",
13049                          unformat_ip6_address, &dst.ip6))
13050         {
13051           grp_set = dst_set = 1;
13052           ipv6_set = 1;
13053         }
13054       else
13055         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13056         ;
13057       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13058         ;
13059       else if (unformat (line_input, "decap-next %U",
13060                          unformat_vxlan_decap_next, &decap_next_index))
13061         ;
13062       else if (unformat (line_input, "vni %d", &vni))
13063         ;
13064       else
13065         {
13066           errmsg ("parse error '%U'", format_unformat_error, line_input);
13067           return -99;
13068         }
13069     }
13070
13071   if (src_set == 0)
13072     {
13073       errmsg ("tunnel src address not specified");
13074       return -99;
13075     }
13076   if (dst_set == 0)
13077     {
13078       errmsg ("tunnel dst address not specified");
13079       return -99;
13080     }
13081
13082   if (grp_set && !ip46_address_is_multicast (&dst))
13083     {
13084       errmsg ("tunnel group address not multicast");
13085       return -99;
13086     }
13087   if (grp_set && mcast_sw_if_index == ~0)
13088     {
13089       errmsg ("tunnel nonexistent multicast device");
13090       return -99;
13091     }
13092   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13093     {
13094       errmsg ("tunnel dst address must be unicast");
13095       return -99;
13096     }
13097
13098
13099   if (ipv4_set && ipv6_set)
13100     {
13101       errmsg ("both IPv4 and IPv6 addresses specified");
13102       return -99;
13103     }
13104
13105   if ((vni == 0) || (vni >> 24))
13106     {
13107       errmsg ("vni not specified or out of range");
13108       return -99;
13109     }
13110
13111   M (VXLAN_ADD_DEL_TUNNEL, mp);
13112
13113   if (ipv6_set)
13114     {
13115       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13116       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13117     }
13118   else
13119     {
13120       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13121       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13122     }
13123
13124   mp->instance = htonl (instance);
13125   mp->encap_vrf_id = ntohl (encap_vrf_id);
13126   mp->decap_next_index = ntohl (decap_next_index);
13127   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13128   mp->vni = ntohl (vni);
13129   mp->is_add = is_add;
13130   mp->is_ipv6 = ipv6_set;
13131
13132   S (mp);
13133   W (ret);
13134   return ret;
13135 }
13136
13137 static void vl_api_vxlan_tunnel_details_t_handler
13138   (vl_api_vxlan_tunnel_details_t * mp)
13139 {
13140   vat_main_t *vam = &vat_main;
13141   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13142   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13143
13144   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13145          ntohl (mp->sw_if_index),
13146          ntohl (mp->instance),
13147          format_ip46_address, &src, IP46_TYPE_ANY,
13148          format_ip46_address, &dst, IP46_TYPE_ANY,
13149          ntohl (mp->encap_vrf_id),
13150          ntohl (mp->decap_next_index), ntohl (mp->vni),
13151          ntohl (mp->mcast_sw_if_index));
13152 }
13153
13154 static void vl_api_vxlan_tunnel_details_t_handler_json
13155   (vl_api_vxlan_tunnel_details_t * mp)
13156 {
13157   vat_main_t *vam = &vat_main;
13158   vat_json_node_t *node = NULL;
13159
13160   if (VAT_JSON_ARRAY != vam->json_tree.type)
13161     {
13162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13163       vat_json_init_array (&vam->json_tree);
13164     }
13165   node = vat_json_array_add (&vam->json_tree);
13166
13167   vat_json_init_object (node);
13168   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13169
13170   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13171
13172   if (mp->is_ipv6)
13173     {
13174       struct in6_addr ip6;
13175
13176       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13177       vat_json_object_add_ip6 (node, "src_address", ip6);
13178       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13179       vat_json_object_add_ip6 (node, "dst_address", ip6);
13180     }
13181   else
13182     {
13183       struct in_addr ip4;
13184
13185       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13186       vat_json_object_add_ip4 (node, "src_address", ip4);
13187       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13188       vat_json_object_add_ip4 (node, "dst_address", ip4);
13189     }
13190   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13191   vat_json_object_add_uint (node, "decap_next_index",
13192                             ntohl (mp->decap_next_index));
13193   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13194   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13195   vat_json_object_add_uint (node, "mcast_sw_if_index",
13196                             ntohl (mp->mcast_sw_if_index));
13197 }
13198
13199 static int
13200 api_vxlan_tunnel_dump (vat_main_t * vam)
13201 {
13202   unformat_input_t *i = vam->input;
13203   vl_api_vxlan_tunnel_dump_t *mp;
13204   vl_api_control_ping_t *mp_ping;
13205   u32 sw_if_index;
13206   u8 sw_if_index_set = 0;
13207   int ret;
13208
13209   /* Parse args required to build the message */
13210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13211     {
13212       if (unformat (i, "sw_if_index %d", &sw_if_index))
13213         sw_if_index_set = 1;
13214       else
13215         break;
13216     }
13217
13218   if (sw_if_index_set == 0)
13219     {
13220       sw_if_index = ~0;
13221     }
13222
13223   if (!vam->json_output)
13224     {
13225       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13226              "sw_if_index", "instance", "src_address", "dst_address",
13227              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13228     }
13229
13230   /* Get list of vxlan-tunnel interfaces */
13231   M (VXLAN_TUNNEL_DUMP, mp);
13232
13233   mp->sw_if_index = htonl (sw_if_index);
13234
13235   S (mp);
13236
13237   /* Use a control ping for synchronization */
13238   MPING (CONTROL_PING, mp_ping);
13239   S (mp_ping);
13240
13241   W (ret);
13242   return ret;
13243 }
13244
13245 static uword unformat_geneve_decap_next
13246   (unformat_input_t * input, va_list * args)
13247 {
13248   u32 *result = va_arg (*args, u32 *);
13249   u32 tmp;
13250
13251   if (unformat (input, "l2"))
13252     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13253   else if (unformat (input, "%d", &tmp))
13254     *result = tmp;
13255   else
13256     return 0;
13257   return 1;
13258 }
13259
13260 static int
13261 api_geneve_add_del_tunnel (vat_main_t * vam)
13262 {
13263   unformat_input_t *line_input = vam->input;
13264   vl_api_geneve_add_del_tunnel_t *mp;
13265   ip46_address_t src, dst;
13266   u8 is_add = 1;
13267   u8 ipv4_set = 0, ipv6_set = 0;
13268   u8 src_set = 0;
13269   u8 dst_set = 0;
13270   u8 grp_set = 0;
13271   u32 mcast_sw_if_index = ~0;
13272   u32 encap_vrf_id = 0;
13273   u32 decap_next_index = ~0;
13274   u32 vni = 0;
13275   int ret;
13276
13277   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13278   memset (&src, 0, sizeof src);
13279   memset (&dst, 0, sizeof dst);
13280
13281   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13282     {
13283       if (unformat (line_input, "del"))
13284         is_add = 0;
13285       else
13286         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13287         {
13288           ipv4_set = 1;
13289           src_set = 1;
13290         }
13291       else
13292         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13293         {
13294           ipv4_set = 1;
13295           dst_set = 1;
13296         }
13297       else
13298         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13299         {
13300           ipv6_set = 1;
13301           src_set = 1;
13302         }
13303       else
13304         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13305         {
13306           ipv6_set = 1;
13307           dst_set = 1;
13308         }
13309       else if (unformat (line_input, "group %U %U",
13310                          unformat_ip4_address, &dst.ip4,
13311                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13312         {
13313           grp_set = dst_set = 1;
13314           ipv4_set = 1;
13315         }
13316       else if (unformat (line_input, "group %U",
13317                          unformat_ip4_address, &dst.ip4))
13318         {
13319           grp_set = dst_set = 1;
13320           ipv4_set = 1;
13321         }
13322       else if (unformat (line_input, "group %U %U",
13323                          unformat_ip6_address, &dst.ip6,
13324                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13325         {
13326           grp_set = dst_set = 1;
13327           ipv6_set = 1;
13328         }
13329       else if (unformat (line_input, "group %U",
13330                          unformat_ip6_address, &dst.ip6))
13331         {
13332           grp_set = dst_set = 1;
13333           ipv6_set = 1;
13334         }
13335       else
13336         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13337         ;
13338       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13339         ;
13340       else if (unformat (line_input, "decap-next %U",
13341                          unformat_geneve_decap_next, &decap_next_index))
13342         ;
13343       else if (unformat (line_input, "vni %d", &vni))
13344         ;
13345       else
13346         {
13347           errmsg ("parse error '%U'", format_unformat_error, line_input);
13348           return -99;
13349         }
13350     }
13351
13352   if (src_set == 0)
13353     {
13354       errmsg ("tunnel src address not specified");
13355       return -99;
13356     }
13357   if (dst_set == 0)
13358     {
13359       errmsg ("tunnel dst address not specified");
13360       return -99;
13361     }
13362
13363   if (grp_set && !ip46_address_is_multicast (&dst))
13364     {
13365       errmsg ("tunnel group address not multicast");
13366       return -99;
13367     }
13368   if (grp_set && mcast_sw_if_index == ~0)
13369     {
13370       errmsg ("tunnel nonexistent multicast device");
13371       return -99;
13372     }
13373   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13374     {
13375       errmsg ("tunnel dst address must be unicast");
13376       return -99;
13377     }
13378
13379
13380   if (ipv4_set && ipv6_set)
13381     {
13382       errmsg ("both IPv4 and IPv6 addresses specified");
13383       return -99;
13384     }
13385
13386   if ((vni == 0) || (vni >> 24))
13387     {
13388       errmsg ("vni not specified or out of range");
13389       return -99;
13390     }
13391
13392   M (GENEVE_ADD_DEL_TUNNEL, mp);
13393
13394   if (ipv6_set)
13395     {
13396       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13397       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13398     }
13399   else
13400     {
13401       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13402       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13403     }
13404   mp->encap_vrf_id = ntohl (encap_vrf_id);
13405   mp->decap_next_index = ntohl (decap_next_index);
13406   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13407   mp->vni = ntohl (vni);
13408   mp->is_add = is_add;
13409   mp->is_ipv6 = ipv6_set;
13410
13411   S (mp);
13412   W (ret);
13413   return ret;
13414 }
13415
13416 static void vl_api_geneve_tunnel_details_t_handler
13417   (vl_api_geneve_tunnel_details_t * mp)
13418 {
13419   vat_main_t *vam = &vat_main;
13420   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13421   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13422
13423   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13424          ntohl (mp->sw_if_index),
13425          format_ip46_address, &src, IP46_TYPE_ANY,
13426          format_ip46_address, &dst, IP46_TYPE_ANY,
13427          ntohl (mp->encap_vrf_id),
13428          ntohl (mp->decap_next_index), ntohl (mp->vni),
13429          ntohl (mp->mcast_sw_if_index));
13430 }
13431
13432 static void vl_api_geneve_tunnel_details_t_handler_json
13433   (vl_api_geneve_tunnel_details_t * mp)
13434 {
13435   vat_main_t *vam = &vat_main;
13436   vat_json_node_t *node = NULL;
13437
13438   if (VAT_JSON_ARRAY != vam->json_tree.type)
13439     {
13440       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13441       vat_json_init_array (&vam->json_tree);
13442     }
13443   node = vat_json_array_add (&vam->json_tree);
13444
13445   vat_json_init_object (node);
13446   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13447   if (mp->is_ipv6)
13448     {
13449       struct in6_addr ip6;
13450
13451       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13452       vat_json_object_add_ip6 (node, "src_address", ip6);
13453       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13454       vat_json_object_add_ip6 (node, "dst_address", ip6);
13455     }
13456   else
13457     {
13458       struct in_addr ip4;
13459
13460       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13461       vat_json_object_add_ip4 (node, "src_address", ip4);
13462       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13463       vat_json_object_add_ip4 (node, "dst_address", ip4);
13464     }
13465   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13466   vat_json_object_add_uint (node, "decap_next_index",
13467                             ntohl (mp->decap_next_index));
13468   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13469   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13470   vat_json_object_add_uint (node, "mcast_sw_if_index",
13471                             ntohl (mp->mcast_sw_if_index));
13472 }
13473
13474 static int
13475 api_geneve_tunnel_dump (vat_main_t * vam)
13476 {
13477   unformat_input_t *i = vam->input;
13478   vl_api_geneve_tunnel_dump_t *mp;
13479   vl_api_control_ping_t *mp_ping;
13480   u32 sw_if_index;
13481   u8 sw_if_index_set = 0;
13482   int ret;
13483
13484   /* Parse args required to build the message */
13485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13486     {
13487       if (unformat (i, "sw_if_index %d", &sw_if_index))
13488         sw_if_index_set = 1;
13489       else
13490         break;
13491     }
13492
13493   if (sw_if_index_set == 0)
13494     {
13495       sw_if_index = ~0;
13496     }
13497
13498   if (!vam->json_output)
13499     {
13500       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13501              "sw_if_index", "local_address", "remote_address",
13502              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13503     }
13504
13505   /* Get list of geneve-tunnel interfaces */
13506   M (GENEVE_TUNNEL_DUMP, mp);
13507
13508   mp->sw_if_index = htonl (sw_if_index);
13509
13510   S (mp);
13511
13512   /* Use a control ping for synchronization */
13513   M (CONTROL_PING, mp_ping);
13514   S (mp_ping);
13515
13516   W (ret);
13517   return ret;
13518 }
13519
13520 static int
13521 api_gre_add_del_tunnel (vat_main_t * vam)
13522 {
13523   unformat_input_t *line_input = vam->input;
13524   vl_api_gre_add_del_tunnel_t *mp;
13525   ip4_address_t src4, dst4;
13526   ip6_address_t src6, dst6;
13527   u8 is_add = 1;
13528   u8 ipv4_set = 0;
13529   u8 ipv6_set = 0;
13530   u8 t_type = GRE_TUNNEL_TYPE_L3;
13531   u8 src_set = 0;
13532   u8 dst_set = 0;
13533   u32 outer_fib_id = 0;
13534   u32 session_id = 0;
13535   u32 instance = ~0;
13536   int ret;
13537
13538   memset (&src4, 0, sizeof src4);
13539   memset (&dst4, 0, sizeof dst4);
13540   memset (&src6, 0, sizeof src6);
13541   memset (&dst6, 0, sizeof dst6);
13542
13543   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13544     {
13545       if (unformat (line_input, "del"))
13546         is_add = 0;
13547       else if (unformat (line_input, "instance %d", &instance))
13548         ;
13549       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13550         {
13551           src_set = 1;
13552           ipv4_set = 1;
13553         }
13554       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13555         {
13556           dst_set = 1;
13557           ipv4_set = 1;
13558         }
13559       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13560         {
13561           src_set = 1;
13562           ipv6_set = 1;
13563         }
13564       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13565         {
13566           dst_set = 1;
13567           ipv6_set = 1;
13568         }
13569       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13570         ;
13571       else if (unformat (line_input, "teb"))
13572         t_type = GRE_TUNNEL_TYPE_TEB;
13573       else if (unformat (line_input, "erspan %d", &session_id))
13574         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13575       else
13576         {
13577           errmsg ("parse error '%U'", format_unformat_error, line_input);
13578           return -99;
13579         }
13580     }
13581
13582   if (src_set == 0)
13583     {
13584       errmsg ("tunnel src address not specified");
13585       return -99;
13586     }
13587   if (dst_set == 0)
13588     {
13589       errmsg ("tunnel dst address not specified");
13590       return -99;
13591     }
13592   if (ipv4_set && ipv6_set)
13593     {
13594       errmsg ("both IPv4 and IPv6 addresses specified");
13595       return -99;
13596     }
13597
13598
13599   M (GRE_ADD_DEL_TUNNEL, mp);
13600
13601   if (ipv4_set)
13602     {
13603       clib_memcpy (&mp->src_address, &src4, 4);
13604       clib_memcpy (&mp->dst_address, &dst4, 4);
13605     }
13606   else
13607     {
13608       clib_memcpy (&mp->src_address, &src6, 16);
13609       clib_memcpy (&mp->dst_address, &dst6, 16);
13610     }
13611   mp->instance = htonl (instance);
13612   mp->outer_fib_id = htonl (outer_fib_id);
13613   mp->is_add = is_add;
13614   mp->session_id = htons ((u16) session_id);
13615   mp->tunnel_type = t_type;
13616   mp->is_ipv6 = ipv6_set;
13617
13618   S (mp);
13619   W (ret);
13620   return ret;
13621 }
13622
13623 static void vl_api_gre_tunnel_details_t_handler
13624   (vl_api_gre_tunnel_details_t * mp)
13625 {
13626   vat_main_t *vam = &vat_main;
13627   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13628   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13629
13630   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13631          ntohl (mp->sw_if_index),
13632          ntohl (mp->instance),
13633          format_ip46_address, &src, IP46_TYPE_ANY,
13634          format_ip46_address, &dst, IP46_TYPE_ANY,
13635          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13636 }
13637
13638 static void vl_api_gre_tunnel_details_t_handler_json
13639   (vl_api_gre_tunnel_details_t * mp)
13640 {
13641   vat_main_t *vam = &vat_main;
13642   vat_json_node_t *node = NULL;
13643   struct in_addr ip4;
13644   struct in6_addr ip6;
13645
13646   if (VAT_JSON_ARRAY != vam->json_tree.type)
13647     {
13648       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13649       vat_json_init_array (&vam->json_tree);
13650     }
13651   node = vat_json_array_add (&vam->json_tree);
13652
13653   vat_json_init_object (node);
13654   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13655   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13656   if (!mp->is_ipv6)
13657     {
13658       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13659       vat_json_object_add_ip4 (node, "src_address", ip4);
13660       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13661       vat_json_object_add_ip4 (node, "dst_address", ip4);
13662     }
13663   else
13664     {
13665       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13666       vat_json_object_add_ip6 (node, "src_address", ip6);
13667       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13668       vat_json_object_add_ip6 (node, "dst_address", ip6);
13669     }
13670   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13671   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13672   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13673   vat_json_object_add_uint (node, "session_id", mp->session_id);
13674 }
13675
13676 static int
13677 api_gre_tunnel_dump (vat_main_t * vam)
13678 {
13679   unformat_input_t *i = vam->input;
13680   vl_api_gre_tunnel_dump_t *mp;
13681   vl_api_control_ping_t *mp_ping;
13682   u32 sw_if_index;
13683   u8 sw_if_index_set = 0;
13684   int ret;
13685
13686   /* Parse args required to build the message */
13687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13688     {
13689       if (unformat (i, "sw_if_index %d", &sw_if_index))
13690         sw_if_index_set = 1;
13691       else
13692         break;
13693     }
13694
13695   if (sw_if_index_set == 0)
13696     {
13697       sw_if_index = ~0;
13698     }
13699
13700   if (!vam->json_output)
13701     {
13702       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13703              "sw_if_index", "instance", "src_address", "dst_address",
13704              "tunnel_type", "outer_fib_id", "session_id");
13705     }
13706
13707   /* Get list of gre-tunnel interfaces */
13708   M (GRE_TUNNEL_DUMP, mp);
13709
13710   mp->sw_if_index = htonl (sw_if_index);
13711
13712   S (mp);
13713
13714   /* Use a control ping for synchronization */
13715   MPING (CONTROL_PING, mp_ping);
13716   S (mp_ping);
13717
13718   W (ret);
13719   return ret;
13720 }
13721
13722 static int
13723 api_l2_fib_clear_table (vat_main_t * vam)
13724 {
13725 //  unformat_input_t * i = vam->input;
13726   vl_api_l2_fib_clear_table_t *mp;
13727   int ret;
13728
13729   M (L2_FIB_CLEAR_TABLE, mp);
13730
13731   S (mp);
13732   W (ret);
13733   return ret;
13734 }
13735
13736 static int
13737 api_l2_interface_efp_filter (vat_main_t * vam)
13738 {
13739   unformat_input_t *i = vam->input;
13740   vl_api_l2_interface_efp_filter_t *mp;
13741   u32 sw_if_index;
13742   u8 enable = 1;
13743   u8 sw_if_index_set = 0;
13744   int ret;
13745
13746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13747     {
13748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13749         sw_if_index_set = 1;
13750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13751         sw_if_index_set = 1;
13752       else if (unformat (i, "enable"))
13753         enable = 1;
13754       else if (unformat (i, "disable"))
13755         enable = 0;
13756       else
13757         {
13758           clib_warning ("parse error '%U'", format_unformat_error, i);
13759           return -99;
13760         }
13761     }
13762
13763   if (sw_if_index_set == 0)
13764     {
13765       errmsg ("missing sw_if_index");
13766       return -99;
13767     }
13768
13769   M (L2_INTERFACE_EFP_FILTER, mp);
13770
13771   mp->sw_if_index = ntohl (sw_if_index);
13772   mp->enable_disable = enable;
13773
13774   S (mp);
13775   W (ret);
13776   return ret;
13777 }
13778
13779 #define foreach_vtr_op                          \
13780 _("disable",  L2_VTR_DISABLED)                  \
13781 _("push-1",  L2_VTR_PUSH_1)                     \
13782 _("push-2",  L2_VTR_PUSH_2)                     \
13783 _("pop-1",  L2_VTR_POP_1)                       \
13784 _("pop-2",  L2_VTR_POP_2)                       \
13785 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13786 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13787 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13788 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13789
13790 static int
13791 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13792 {
13793   unformat_input_t *i = vam->input;
13794   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13795   u32 sw_if_index;
13796   u8 sw_if_index_set = 0;
13797   u8 vtr_op_set = 0;
13798   u32 vtr_op = 0;
13799   u32 push_dot1q = 1;
13800   u32 tag1 = ~0;
13801   u32 tag2 = ~0;
13802   int ret;
13803
13804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13805     {
13806       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13807         sw_if_index_set = 1;
13808       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13809         sw_if_index_set = 1;
13810       else if (unformat (i, "vtr_op %d", &vtr_op))
13811         vtr_op_set = 1;
13812 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13813       foreach_vtr_op
13814 #undef _
13815         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13816         ;
13817       else if (unformat (i, "tag1 %d", &tag1))
13818         ;
13819       else if (unformat (i, "tag2 %d", &tag2))
13820         ;
13821       else
13822         {
13823           clib_warning ("parse error '%U'", format_unformat_error, i);
13824           return -99;
13825         }
13826     }
13827
13828   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13829     {
13830       errmsg ("missing vtr operation or sw_if_index");
13831       return -99;
13832     }
13833
13834   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13835   mp->sw_if_index = ntohl (sw_if_index);
13836   mp->vtr_op = ntohl (vtr_op);
13837   mp->push_dot1q = ntohl (push_dot1q);
13838   mp->tag1 = ntohl (tag1);
13839   mp->tag2 = ntohl (tag2);
13840
13841   S (mp);
13842   W (ret);
13843   return ret;
13844 }
13845
13846 static int
13847 api_create_vhost_user_if (vat_main_t * vam)
13848 {
13849   unformat_input_t *i = vam->input;
13850   vl_api_create_vhost_user_if_t *mp;
13851   u8 *file_name;
13852   u8 is_server = 0;
13853   u8 file_name_set = 0;
13854   u32 custom_dev_instance = ~0;
13855   u8 hwaddr[6];
13856   u8 use_custom_mac = 0;
13857   u8 *tag = 0;
13858   int ret;
13859
13860   /* Shut up coverity */
13861   memset (hwaddr, 0, sizeof (hwaddr));
13862
13863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13864     {
13865       if (unformat (i, "socket %s", &file_name))
13866         {
13867           file_name_set = 1;
13868         }
13869       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13870         ;
13871       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13872         use_custom_mac = 1;
13873       else if (unformat (i, "server"))
13874         is_server = 1;
13875       else if (unformat (i, "tag %s", &tag))
13876         ;
13877       else
13878         break;
13879     }
13880
13881   if (file_name_set == 0)
13882     {
13883       errmsg ("missing socket file name");
13884       return -99;
13885     }
13886
13887   if (vec_len (file_name) > 255)
13888     {
13889       errmsg ("socket file name too long");
13890       return -99;
13891     }
13892   vec_add1 (file_name, 0);
13893
13894   M (CREATE_VHOST_USER_IF, mp);
13895
13896   mp->is_server = is_server;
13897   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13898   vec_free (file_name);
13899   if (custom_dev_instance != ~0)
13900     {
13901       mp->renumber = 1;
13902       mp->custom_dev_instance = ntohl (custom_dev_instance);
13903     }
13904   mp->use_custom_mac = use_custom_mac;
13905   clib_memcpy (mp->mac_address, hwaddr, 6);
13906   if (tag)
13907     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13908   vec_free (tag);
13909
13910   S (mp);
13911   W (ret);
13912   return ret;
13913 }
13914
13915 static int
13916 api_modify_vhost_user_if (vat_main_t * vam)
13917 {
13918   unformat_input_t *i = vam->input;
13919   vl_api_modify_vhost_user_if_t *mp;
13920   u8 *file_name;
13921   u8 is_server = 0;
13922   u8 file_name_set = 0;
13923   u32 custom_dev_instance = ~0;
13924   u8 sw_if_index_set = 0;
13925   u32 sw_if_index = (u32) ~ 0;
13926   int ret;
13927
13928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13929     {
13930       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13931         sw_if_index_set = 1;
13932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13933         sw_if_index_set = 1;
13934       else if (unformat (i, "socket %s", &file_name))
13935         {
13936           file_name_set = 1;
13937         }
13938       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13939         ;
13940       else if (unformat (i, "server"))
13941         is_server = 1;
13942       else
13943         break;
13944     }
13945
13946   if (sw_if_index_set == 0)
13947     {
13948       errmsg ("missing sw_if_index or interface name");
13949       return -99;
13950     }
13951
13952   if (file_name_set == 0)
13953     {
13954       errmsg ("missing socket file name");
13955       return -99;
13956     }
13957
13958   if (vec_len (file_name) > 255)
13959     {
13960       errmsg ("socket file name too long");
13961       return -99;
13962     }
13963   vec_add1 (file_name, 0);
13964
13965   M (MODIFY_VHOST_USER_IF, mp);
13966
13967   mp->sw_if_index = ntohl (sw_if_index);
13968   mp->is_server = is_server;
13969   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13970   vec_free (file_name);
13971   if (custom_dev_instance != ~0)
13972     {
13973       mp->renumber = 1;
13974       mp->custom_dev_instance = ntohl (custom_dev_instance);
13975     }
13976
13977   S (mp);
13978   W (ret);
13979   return ret;
13980 }
13981
13982 static int
13983 api_delete_vhost_user_if (vat_main_t * vam)
13984 {
13985   unformat_input_t *i = vam->input;
13986   vl_api_delete_vhost_user_if_t *mp;
13987   u32 sw_if_index = ~0;
13988   u8 sw_if_index_set = 0;
13989   int ret;
13990
13991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13992     {
13993       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13994         sw_if_index_set = 1;
13995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13996         sw_if_index_set = 1;
13997       else
13998         break;
13999     }
14000
14001   if (sw_if_index_set == 0)
14002     {
14003       errmsg ("missing sw_if_index or interface name");
14004       return -99;
14005     }
14006
14007
14008   M (DELETE_VHOST_USER_IF, mp);
14009
14010   mp->sw_if_index = ntohl (sw_if_index);
14011
14012   S (mp);
14013   W (ret);
14014   return ret;
14015 }
14016
14017 static void vl_api_sw_interface_vhost_user_details_t_handler
14018   (vl_api_sw_interface_vhost_user_details_t * mp)
14019 {
14020   vat_main_t *vam = &vat_main;
14021
14022   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14023          (char *) mp->interface_name,
14024          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14025          clib_net_to_host_u64 (mp->features), mp->is_server,
14026          ntohl (mp->num_regions), (char *) mp->sock_filename);
14027   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14028 }
14029
14030 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14031   (vl_api_sw_interface_vhost_user_details_t * mp)
14032 {
14033   vat_main_t *vam = &vat_main;
14034   vat_json_node_t *node = NULL;
14035
14036   if (VAT_JSON_ARRAY != vam->json_tree.type)
14037     {
14038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14039       vat_json_init_array (&vam->json_tree);
14040     }
14041   node = vat_json_array_add (&vam->json_tree);
14042
14043   vat_json_init_object (node);
14044   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14045   vat_json_object_add_string_copy (node, "interface_name",
14046                                    mp->interface_name);
14047   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14048                             ntohl (mp->virtio_net_hdr_sz));
14049   vat_json_object_add_uint (node, "features",
14050                             clib_net_to_host_u64 (mp->features));
14051   vat_json_object_add_uint (node, "is_server", mp->is_server);
14052   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14053   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14054   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14055 }
14056
14057 static int
14058 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14059 {
14060   vl_api_sw_interface_vhost_user_dump_t *mp;
14061   vl_api_control_ping_t *mp_ping;
14062   int ret;
14063   print (vam->ofp,
14064          "Interface name            idx hdr_sz features server regions filename");
14065
14066   /* Get list of vhost-user interfaces */
14067   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14068   S (mp);
14069
14070   /* Use a control ping for synchronization */
14071   MPING (CONTROL_PING, mp_ping);
14072   S (mp_ping);
14073
14074   W (ret);
14075   return ret;
14076 }
14077
14078 static int
14079 api_show_version (vat_main_t * vam)
14080 {
14081   vl_api_show_version_t *mp;
14082   int ret;
14083
14084   M (SHOW_VERSION, mp);
14085
14086   S (mp);
14087   W (ret);
14088   return ret;
14089 }
14090
14091
14092 static int
14093 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14094 {
14095   unformat_input_t *line_input = vam->input;
14096   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14097   ip4_address_t local4, remote4;
14098   ip6_address_t local6, remote6;
14099   u8 is_add = 1;
14100   u8 ipv4_set = 0, ipv6_set = 0;
14101   u8 local_set = 0;
14102   u8 remote_set = 0;
14103   u8 grp_set = 0;
14104   u32 mcast_sw_if_index = ~0;
14105   u32 encap_vrf_id = 0;
14106   u32 decap_vrf_id = 0;
14107   u8 protocol = ~0;
14108   u32 vni;
14109   u8 vni_set = 0;
14110   int ret;
14111
14112   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14113   memset (&local4, 0, sizeof local4);
14114   memset (&remote4, 0, sizeof remote4);
14115   memset (&local6, 0, sizeof local6);
14116   memset (&remote6, 0, sizeof remote6);
14117
14118   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14119     {
14120       if (unformat (line_input, "del"))
14121         is_add = 0;
14122       else if (unformat (line_input, "local %U",
14123                          unformat_ip4_address, &local4))
14124         {
14125           local_set = 1;
14126           ipv4_set = 1;
14127         }
14128       else if (unformat (line_input, "remote %U",
14129                          unformat_ip4_address, &remote4))
14130         {
14131           remote_set = 1;
14132           ipv4_set = 1;
14133         }
14134       else if (unformat (line_input, "local %U",
14135                          unformat_ip6_address, &local6))
14136         {
14137           local_set = 1;
14138           ipv6_set = 1;
14139         }
14140       else if (unformat (line_input, "remote %U",
14141                          unformat_ip6_address, &remote6))
14142         {
14143           remote_set = 1;
14144           ipv6_set = 1;
14145         }
14146       else if (unformat (line_input, "group %U %U",
14147                          unformat_ip4_address, &remote4,
14148                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14149         {
14150           grp_set = remote_set = 1;
14151           ipv4_set = 1;
14152         }
14153       else if (unformat (line_input, "group %U",
14154                          unformat_ip4_address, &remote4))
14155         {
14156           grp_set = remote_set = 1;
14157           ipv4_set = 1;
14158         }
14159       else if (unformat (line_input, "group %U %U",
14160                          unformat_ip6_address, &remote6,
14161                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14162         {
14163           grp_set = remote_set = 1;
14164           ipv6_set = 1;
14165         }
14166       else if (unformat (line_input, "group %U",
14167                          unformat_ip6_address, &remote6))
14168         {
14169           grp_set = remote_set = 1;
14170           ipv6_set = 1;
14171         }
14172       else
14173         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14174         ;
14175       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14176         ;
14177       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14178         ;
14179       else if (unformat (line_input, "vni %d", &vni))
14180         vni_set = 1;
14181       else if (unformat (line_input, "next-ip4"))
14182         protocol = 1;
14183       else if (unformat (line_input, "next-ip6"))
14184         protocol = 2;
14185       else if (unformat (line_input, "next-ethernet"))
14186         protocol = 3;
14187       else if (unformat (line_input, "next-nsh"))
14188         protocol = 4;
14189       else
14190         {
14191           errmsg ("parse error '%U'", format_unformat_error, line_input);
14192           return -99;
14193         }
14194     }
14195
14196   if (local_set == 0)
14197     {
14198       errmsg ("tunnel local address not specified");
14199       return -99;
14200     }
14201   if (remote_set == 0)
14202     {
14203       errmsg ("tunnel remote address not specified");
14204       return -99;
14205     }
14206   if (grp_set && mcast_sw_if_index == ~0)
14207     {
14208       errmsg ("tunnel nonexistent multicast device");
14209       return -99;
14210     }
14211   if (ipv4_set && ipv6_set)
14212     {
14213       errmsg ("both IPv4 and IPv6 addresses specified");
14214       return -99;
14215     }
14216
14217   if (vni_set == 0)
14218     {
14219       errmsg ("vni not specified");
14220       return -99;
14221     }
14222
14223   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14224
14225
14226   if (ipv6_set)
14227     {
14228       clib_memcpy (&mp->local, &local6, sizeof (local6));
14229       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14230     }
14231   else
14232     {
14233       clib_memcpy (&mp->local, &local4, sizeof (local4));
14234       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14235     }
14236
14237   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14238   mp->encap_vrf_id = ntohl (encap_vrf_id);
14239   mp->decap_vrf_id = ntohl (decap_vrf_id);
14240   mp->protocol = protocol;
14241   mp->vni = ntohl (vni);
14242   mp->is_add = is_add;
14243   mp->is_ipv6 = ipv6_set;
14244
14245   S (mp);
14246   W (ret);
14247   return ret;
14248 }
14249
14250 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14251   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14252 {
14253   vat_main_t *vam = &vat_main;
14254   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14255   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14256
14257   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14258          ntohl (mp->sw_if_index),
14259          format_ip46_address, &local, IP46_TYPE_ANY,
14260          format_ip46_address, &remote, IP46_TYPE_ANY,
14261          ntohl (mp->vni), mp->protocol,
14262          ntohl (mp->mcast_sw_if_index),
14263          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14264 }
14265
14266
14267 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14268   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14269 {
14270   vat_main_t *vam = &vat_main;
14271   vat_json_node_t *node = NULL;
14272   struct in_addr ip4;
14273   struct in6_addr ip6;
14274
14275   if (VAT_JSON_ARRAY != vam->json_tree.type)
14276     {
14277       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14278       vat_json_init_array (&vam->json_tree);
14279     }
14280   node = vat_json_array_add (&vam->json_tree);
14281
14282   vat_json_init_object (node);
14283   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14284   if (mp->is_ipv6)
14285     {
14286       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14287       vat_json_object_add_ip6 (node, "local", ip6);
14288       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14289       vat_json_object_add_ip6 (node, "remote", ip6);
14290     }
14291   else
14292     {
14293       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14294       vat_json_object_add_ip4 (node, "local", ip4);
14295       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14296       vat_json_object_add_ip4 (node, "remote", ip4);
14297     }
14298   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14299   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14300   vat_json_object_add_uint (node, "mcast_sw_if_index",
14301                             ntohl (mp->mcast_sw_if_index));
14302   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14303   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14304   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14305 }
14306
14307 static int
14308 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14309 {
14310   unformat_input_t *i = vam->input;
14311   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14312   vl_api_control_ping_t *mp_ping;
14313   u32 sw_if_index;
14314   u8 sw_if_index_set = 0;
14315   int ret;
14316
14317   /* Parse args required to build the message */
14318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14319     {
14320       if (unformat (i, "sw_if_index %d", &sw_if_index))
14321         sw_if_index_set = 1;
14322       else
14323         break;
14324     }
14325
14326   if (sw_if_index_set == 0)
14327     {
14328       sw_if_index = ~0;
14329     }
14330
14331   if (!vam->json_output)
14332     {
14333       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14334              "sw_if_index", "local", "remote", "vni",
14335              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14336     }
14337
14338   /* Get list of vxlan-tunnel interfaces */
14339   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14340
14341   mp->sw_if_index = htonl (sw_if_index);
14342
14343   S (mp);
14344
14345   /* Use a control ping for synchronization */
14346   MPING (CONTROL_PING, mp_ping);
14347   S (mp_ping);
14348
14349   W (ret);
14350   return ret;
14351 }
14352
14353 static void vl_api_l2_fib_table_details_t_handler
14354   (vl_api_l2_fib_table_details_t * mp)
14355 {
14356   vat_main_t *vam = &vat_main;
14357
14358   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14359          "       %d       %d     %d",
14360          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14361          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14362          mp->bvi_mac);
14363 }
14364
14365 static void vl_api_l2_fib_table_details_t_handler_json
14366   (vl_api_l2_fib_table_details_t * mp)
14367 {
14368   vat_main_t *vam = &vat_main;
14369   vat_json_node_t *node = NULL;
14370
14371   if (VAT_JSON_ARRAY != vam->json_tree.type)
14372     {
14373       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14374       vat_json_init_array (&vam->json_tree);
14375     }
14376   node = vat_json_array_add (&vam->json_tree);
14377
14378   vat_json_init_object (node);
14379   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14380   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14381   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14382   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14383   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14384   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14385 }
14386
14387 static int
14388 api_l2_fib_table_dump (vat_main_t * vam)
14389 {
14390   unformat_input_t *i = vam->input;
14391   vl_api_l2_fib_table_dump_t *mp;
14392   vl_api_control_ping_t *mp_ping;
14393   u32 bd_id;
14394   u8 bd_id_set = 0;
14395   int ret;
14396
14397   /* Parse args required to build the message */
14398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14399     {
14400       if (unformat (i, "bd_id %d", &bd_id))
14401         bd_id_set = 1;
14402       else
14403         break;
14404     }
14405
14406   if (bd_id_set == 0)
14407     {
14408       errmsg ("missing bridge domain");
14409       return -99;
14410     }
14411
14412   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14413
14414   /* Get list of l2 fib entries */
14415   M (L2_FIB_TABLE_DUMP, mp);
14416
14417   mp->bd_id = ntohl (bd_id);
14418   S (mp);
14419
14420   /* Use a control ping for synchronization */
14421   MPING (CONTROL_PING, mp_ping);
14422   S (mp_ping);
14423
14424   W (ret);
14425   return ret;
14426 }
14427
14428
14429 static int
14430 api_interface_name_renumber (vat_main_t * vam)
14431 {
14432   unformat_input_t *line_input = vam->input;
14433   vl_api_interface_name_renumber_t *mp;
14434   u32 sw_if_index = ~0;
14435   u32 new_show_dev_instance = ~0;
14436   int ret;
14437
14438   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14439     {
14440       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14441                     &sw_if_index))
14442         ;
14443       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14444         ;
14445       else if (unformat (line_input, "new_show_dev_instance %d",
14446                          &new_show_dev_instance))
14447         ;
14448       else
14449         break;
14450     }
14451
14452   if (sw_if_index == ~0)
14453     {
14454       errmsg ("missing interface name or sw_if_index");
14455       return -99;
14456     }
14457
14458   if (new_show_dev_instance == ~0)
14459     {
14460       errmsg ("missing new_show_dev_instance");
14461       return -99;
14462     }
14463
14464   M (INTERFACE_NAME_RENUMBER, mp);
14465
14466   mp->sw_if_index = ntohl (sw_if_index);
14467   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14468
14469   S (mp);
14470   W (ret);
14471   return ret;
14472 }
14473
14474 static int
14475 api_ip_probe_neighbor (vat_main_t * vam)
14476 {
14477   unformat_input_t *i = vam->input;
14478   vl_api_ip_probe_neighbor_t *mp;
14479   u8 int_set = 0;
14480   u8 adr_set = 0;
14481   u8 is_ipv6 = 0;
14482   u8 dst_adr[16];
14483   u32 sw_if_index;
14484   int ret;
14485
14486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14487     {
14488       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14489         int_set = 1;
14490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14491         int_set = 1;
14492       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14493         adr_set = 1;
14494       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14495         {
14496           adr_set = 1;
14497           is_ipv6 = 1;
14498         }
14499       else
14500         break;
14501     }
14502
14503   if (int_set == 0)
14504     {
14505       errmsg ("missing interface");
14506       return -99;
14507     }
14508
14509   if (adr_set == 0)
14510     {
14511       errmsg ("missing addresses");
14512       return -99;
14513     }
14514
14515   M (IP_PROBE_NEIGHBOR, mp);
14516
14517   mp->sw_if_index = ntohl (sw_if_index);
14518   mp->is_ipv6 = is_ipv6;
14519   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14520
14521   S (mp);
14522   W (ret);
14523   return ret;
14524 }
14525
14526 static int
14527 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14528 {
14529   unformat_input_t *i = vam->input;
14530   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14531   u8 mode = IP_SCAN_V46_NEIGHBORS;
14532   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14533   int ret;
14534
14535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14536     {
14537       if (unformat (i, "ip4"))
14538         mode = IP_SCAN_V4_NEIGHBORS;
14539       else if (unformat (i, "ip6"))
14540         mode = IP_SCAN_V6_NEIGHBORS;
14541       if (unformat (i, "both"))
14542         mode = IP_SCAN_V46_NEIGHBORS;
14543       else if (unformat (i, "disable"))
14544         mode = IP_SCAN_DISABLED;
14545       else if (unformat (i, "interval %d", &interval))
14546         ;
14547       else if (unformat (i, "max-time %d", &time))
14548         ;
14549       else if (unformat (i, "max-update %d", &update))
14550         ;
14551       else if (unformat (i, "delay %d", &delay))
14552         ;
14553       else if (unformat (i, "stale %d", &stale))
14554         ;
14555       else
14556         break;
14557     }
14558
14559   if (interval > 255)
14560     {
14561       errmsg ("interval cannot exceed 255 minutes.");
14562       return -99;
14563     }
14564   if (time > 255)
14565     {
14566       errmsg ("max-time cannot exceed 255 usec.");
14567       return -99;
14568     }
14569   if (update > 255)
14570     {
14571       errmsg ("max-update cannot exceed 255.");
14572       return -99;
14573     }
14574   if (delay > 255)
14575     {
14576       errmsg ("delay cannot exceed 255 msec.");
14577       return -99;
14578     }
14579   if (stale > 255)
14580     {
14581       errmsg ("stale cannot exceed 255 minutes.");
14582       return -99;
14583     }
14584
14585   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14586   mp->mode = mode;
14587   mp->scan_interval = interval;
14588   mp->max_proc_time = time;
14589   mp->max_update = update;
14590   mp->scan_int_delay = delay;
14591   mp->stale_threshold = stale;
14592
14593   S (mp);
14594   W (ret);
14595   return ret;
14596 }
14597
14598 static int
14599 api_want_ip4_arp_events (vat_main_t * vam)
14600 {
14601   unformat_input_t *line_input = vam->input;
14602   vl_api_want_ip4_arp_events_t *mp;
14603   ip4_address_t address;
14604   int address_set = 0;
14605   u32 enable_disable = 1;
14606   int ret;
14607
14608   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14609     {
14610       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14611         address_set = 1;
14612       else if (unformat (line_input, "del"))
14613         enable_disable = 0;
14614       else
14615         break;
14616     }
14617
14618   if (address_set == 0)
14619     {
14620       errmsg ("missing addresses");
14621       return -99;
14622     }
14623
14624   M (WANT_IP4_ARP_EVENTS, mp);
14625   mp->enable_disable = enable_disable;
14626   mp->pid = htonl (getpid ());
14627   mp->address = address.as_u32;
14628
14629   S (mp);
14630   W (ret);
14631   return ret;
14632 }
14633
14634 static int
14635 api_want_ip6_nd_events (vat_main_t * vam)
14636 {
14637   unformat_input_t *line_input = vam->input;
14638   vl_api_want_ip6_nd_events_t *mp;
14639   ip6_address_t address;
14640   int address_set = 0;
14641   u32 enable_disable = 1;
14642   int ret;
14643
14644   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14645     {
14646       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14647         address_set = 1;
14648       else if (unformat (line_input, "del"))
14649         enable_disable = 0;
14650       else
14651         break;
14652     }
14653
14654   if (address_set == 0)
14655     {
14656       errmsg ("missing addresses");
14657       return -99;
14658     }
14659
14660   M (WANT_IP6_ND_EVENTS, mp);
14661   mp->enable_disable = enable_disable;
14662   mp->pid = htonl (getpid ());
14663   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14664
14665   S (mp);
14666   W (ret);
14667   return ret;
14668 }
14669
14670 static int
14671 api_want_l2_macs_events (vat_main_t * vam)
14672 {
14673   unformat_input_t *line_input = vam->input;
14674   vl_api_want_l2_macs_events_t *mp;
14675   u8 enable_disable = 1;
14676   u32 scan_delay = 0;
14677   u32 max_macs_in_event = 0;
14678   u32 learn_limit = 0;
14679   int ret;
14680
14681   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14682     {
14683       if (unformat (line_input, "learn-limit %d", &learn_limit))
14684         ;
14685       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14686         ;
14687       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14688         ;
14689       else if (unformat (line_input, "disable"))
14690         enable_disable = 0;
14691       else
14692         break;
14693     }
14694
14695   M (WANT_L2_MACS_EVENTS, mp);
14696   mp->enable_disable = enable_disable;
14697   mp->pid = htonl (getpid ());
14698   mp->learn_limit = htonl (learn_limit);
14699   mp->scan_delay = (u8) scan_delay;
14700   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14701   S (mp);
14702   W (ret);
14703   return ret;
14704 }
14705
14706 static int
14707 api_input_acl_set_interface (vat_main_t * vam)
14708 {
14709   unformat_input_t *i = vam->input;
14710   vl_api_input_acl_set_interface_t *mp;
14711   u32 sw_if_index;
14712   int sw_if_index_set;
14713   u32 ip4_table_index = ~0;
14714   u32 ip6_table_index = ~0;
14715   u32 l2_table_index = ~0;
14716   u8 is_add = 1;
14717   int ret;
14718
14719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14720     {
14721       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14722         sw_if_index_set = 1;
14723       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14724         sw_if_index_set = 1;
14725       else if (unformat (i, "del"))
14726         is_add = 0;
14727       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14728         ;
14729       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14730         ;
14731       else if (unformat (i, "l2-table %d", &l2_table_index))
14732         ;
14733       else
14734         {
14735           clib_warning ("parse error '%U'", format_unformat_error, i);
14736           return -99;
14737         }
14738     }
14739
14740   if (sw_if_index_set == 0)
14741     {
14742       errmsg ("missing interface name or sw_if_index");
14743       return -99;
14744     }
14745
14746   M (INPUT_ACL_SET_INTERFACE, mp);
14747
14748   mp->sw_if_index = ntohl (sw_if_index);
14749   mp->ip4_table_index = ntohl (ip4_table_index);
14750   mp->ip6_table_index = ntohl (ip6_table_index);
14751   mp->l2_table_index = ntohl (l2_table_index);
14752   mp->is_add = is_add;
14753
14754   S (mp);
14755   W (ret);
14756   return ret;
14757 }
14758
14759 static int
14760 api_output_acl_set_interface (vat_main_t * vam)
14761 {
14762   unformat_input_t *i = vam->input;
14763   vl_api_output_acl_set_interface_t *mp;
14764   u32 sw_if_index;
14765   int sw_if_index_set;
14766   u32 ip4_table_index = ~0;
14767   u32 ip6_table_index = ~0;
14768   u32 l2_table_index = ~0;
14769   u8 is_add = 1;
14770   int ret;
14771
14772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14773     {
14774       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14775         sw_if_index_set = 1;
14776       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14777         sw_if_index_set = 1;
14778       else if (unformat (i, "del"))
14779         is_add = 0;
14780       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14781         ;
14782       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14783         ;
14784       else if (unformat (i, "l2-table %d", &l2_table_index))
14785         ;
14786       else
14787         {
14788           clib_warning ("parse error '%U'", format_unformat_error, i);
14789           return -99;
14790         }
14791     }
14792
14793   if (sw_if_index_set == 0)
14794     {
14795       errmsg ("missing interface name or sw_if_index");
14796       return -99;
14797     }
14798
14799   M (OUTPUT_ACL_SET_INTERFACE, mp);
14800
14801   mp->sw_if_index = ntohl (sw_if_index);
14802   mp->ip4_table_index = ntohl (ip4_table_index);
14803   mp->ip6_table_index = ntohl (ip6_table_index);
14804   mp->l2_table_index = ntohl (l2_table_index);
14805   mp->is_add = is_add;
14806
14807   S (mp);
14808   W (ret);
14809   return ret;
14810 }
14811
14812 static int
14813 api_ip_address_dump (vat_main_t * vam)
14814 {
14815   unformat_input_t *i = vam->input;
14816   vl_api_ip_address_dump_t *mp;
14817   vl_api_control_ping_t *mp_ping;
14818   u32 sw_if_index = ~0;
14819   u8 sw_if_index_set = 0;
14820   u8 ipv4_set = 0;
14821   u8 ipv6_set = 0;
14822   int ret;
14823
14824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14825     {
14826       if (unformat (i, "sw_if_index %d", &sw_if_index))
14827         sw_if_index_set = 1;
14828       else
14829         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14830         sw_if_index_set = 1;
14831       else if (unformat (i, "ipv4"))
14832         ipv4_set = 1;
14833       else if (unformat (i, "ipv6"))
14834         ipv6_set = 1;
14835       else
14836         break;
14837     }
14838
14839   if (ipv4_set && ipv6_set)
14840     {
14841       errmsg ("ipv4 and ipv6 flags cannot be both set");
14842       return -99;
14843     }
14844
14845   if ((!ipv4_set) && (!ipv6_set))
14846     {
14847       errmsg ("no ipv4 nor ipv6 flag set");
14848       return -99;
14849     }
14850
14851   if (sw_if_index_set == 0)
14852     {
14853       errmsg ("missing interface name or sw_if_index");
14854       return -99;
14855     }
14856
14857   vam->current_sw_if_index = sw_if_index;
14858   vam->is_ipv6 = ipv6_set;
14859
14860   M (IP_ADDRESS_DUMP, mp);
14861   mp->sw_if_index = ntohl (sw_if_index);
14862   mp->is_ipv6 = ipv6_set;
14863   S (mp);
14864
14865   /* Use a control ping for synchronization */
14866   MPING (CONTROL_PING, mp_ping);
14867   S (mp_ping);
14868
14869   W (ret);
14870   return ret;
14871 }
14872
14873 static int
14874 api_ip_dump (vat_main_t * vam)
14875 {
14876   vl_api_ip_dump_t *mp;
14877   vl_api_control_ping_t *mp_ping;
14878   unformat_input_t *in = vam->input;
14879   int ipv4_set = 0;
14880   int ipv6_set = 0;
14881   int is_ipv6;
14882   int i;
14883   int ret;
14884
14885   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14886     {
14887       if (unformat (in, "ipv4"))
14888         ipv4_set = 1;
14889       else if (unformat (in, "ipv6"))
14890         ipv6_set = 1;
14891       else
14892         break;
14893     }
14894
14895   if (ipv4_set && ipv6_set)
14896     {
14897       errmsg ("ipv4 and ipv6 flags cannot be both set");
14898       return -99;
14899     }
14900
14901   if ((!ipv4_set) && (!ipv6_set))
14902     {
14903       errmsg ("no ipv4 nor ipv6 flag set");
14904       return -99;
14905     }
14906
14907   is_ipv6 = ipv6_set;
14908   vam->is_ipv6 = is_ipv6;
14909
14910   /* free old data */
14911   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14912     {
14913       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14914     }
14915   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14916
14917   M (IP_DUMP, mp);
14918   mp->is_ipv6 = ipv6_set;
14919   S (mp);
14920
14921   /* Use a control ping for synchronization */
14922   MPING (CONTROL_PING, mp_ping);
14923   S (mp_ping);
14924
14925   W (ret);
14926   return ret;
14927 }
14928
14929 static int
14930 api_ipsec_spd_add_del (vat_main_t * vam)
14931 {
14932   unformat_input_t *i = vam->input;
14933   vl_api_ipsec_spd_add_del_t *mp;
14934   u32 spd_id = ~0;
14935   u8 is_add = 1;
14936   int ret;
14937
14938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14939     {
14940       if (unformat (i, "spd_id %d", &spd_id))
14941         ;
14942       else if (unformat (i, "del"))
14943         is_add = 0;
14944       else
14945         {
14946           clib_warning ("parse error '%U'", format_unformat_error, i);
14947           return -99;
14948         }
14949     }
14950   if (spd_id == ~0)
14951     {
14952       errmsg ("spd_id must be set");
14953       return -99;
14954     }
14955
14956   M (IPSEC_SPD_ADD_DEL, mp);
14957
14958   mp->spd_id = ntohl (spd_id);
14959   mp->is_add = is_add;
14960
14961   S (mp);
14962   W (ret);
14963   return ret;
14964 }
14965
14966 static int
14967 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14968 {
14969   unformat_input_t *i = vam->input;
14970   vl_api_ipsec_interface_add_del_spd_t *mp;
14971   u32 sw_if_index;
14972   u8 sw_if_index_set = 0;
14973   u32 spd_id = (u32) ~ 0;
14974   u8 is_add = 1;
14975   int ret;
14976
14977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14978     {
14979       if (unformat (i, "del"))
14980         is_add = 0;
14981       else if (unformat (i, "spd_id %d", &spd_id))
14982         ;
14983       else
14984         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14985         sw_if_index_set = 1;
14986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14987         sw_if_index_set = 1;
14988       else
14989         {
14990           clib_warning ("parse error '%U'", format_unformat_error, i);
14991           return -99;
14992         }
14993
14994     }
14995
14996   if (spd_id == (u32) ~ 0)
14997     {
14998       errmsg ("spd_id must be set");
14999       return -99;
15000     }
15001
15002   if (sw_if_index_set == 0)
15003     {
15004       errmsg ("missing interface name or sw_if_index");
15005       return -99;
15006     }
15007
15008   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15009
15010   mp->spd_id = ntohl (spd_id);
15011   mp->sw_if_index = ntohl (sw_if_index);
15012   mp->is_add = is_add;
15013
15014   S (mp);
15015   W (ret);
15016   return ret;
15017 }
15018
15019 static int
15020 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15021 {
15022   unformat_input_t *i = vam->input;
15023   vl_api_ipsec_spd_add_del_entry_t *mp;
15024   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15025   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15026   i32 priority = 0;
15027   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15028   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15029   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15030   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15031   int ret;
15032
15033   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15034   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15035   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15036   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15037   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15038   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15039
15040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15041     {
15042       if (unformat (i, "del"))
15043         is_add = 0;
15044       if (unformat (i, "outbound"))
15045         is_outbound = 1;
15046       if (unformat (i, "inbound"))
15047         is_outbound = 0;
15048       else if (unformat (i, "spd_id %d", &spd_id))
15049         ;
15050       else if (unformat (i, "sa_id %d", &sa_id))
15051         ;
15052       else if (unformat (i, "priority %d", &priority))
15053         ;
15054       else if (unformat (i, "protocol %d", &protocol))
15055         ;
15056       else if (unformat (i, "lport_start %d", &lport_start))
15057         ;
15058       else if (unformat (i, "lport_stop %d", &lport_stop))
15059         ;
15060       else if (unformat (i, "rport_start %d", &rport_start))
15061         ;
15062       else if (unformat (i, "rport_stop %d", &rport_stop))
15063         ;
15064       else
15065         if (unformat
15066             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15067         {
15068           is_ipv6 = 0;
15069           is_ip_any = 0;
15070         }
15071       else
15072         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15073         {
15074           is_ipv6 = 0;
15075           is_ip_any = 0;
15076         }
15077       else
15078         if (unformat
15079             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15080         {
15081           is_ipv6 = 0;
15082           is_ip_any = 0;
15083         }
15084       else
15085         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15086         {
15087           is_ipv6 = 0;
15088           is_ip_any = 0;
15089         }
15090       else
15091         if (unformat
15092             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15093         {
15094           is_ipv6 = 1;
15095           is_ip_any = 0;
15096         }
15097       else
15098         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15099         {
15100           is_ipv6 = 1;
15101           is_ip_any = 0;
15102         }
15103       else
15104         if (unformat
15105             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15106         {
15107           is_ipv6 = 1;
15108           is_ip_any = 0;
15109         }
15110       else
15111         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15112         {
15113           is_ipv6 = 1;
15114           is_ip_any = 0;
15115         }
15116       else
15117         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15118         {
15119           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15120             {
15121               clib_warning ("unsupported action: 'resolve'");
15122               return -99;
15123             }
15124         }
15125       else
15126         {
15127           clib_warning ("parse error '%U'", format_unformat_error, i);
15128           return -99;
15129         }
15130
15131     }
15132
15133   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15134
15135   mp->spd_id = ntohl (spd_id);
15136   mp->priority = ntohl (priority);
15137   mp->is_outbound = is_outbound;
15138
15139   mp->is_ipv6 = is_ipv6;
15140   if (is_ipv6 || is_ip_any)
15141     {
15142       clib_memcpy (mp->remote_address_start, &raddr6_start,
15143                    sizeof (ip6_address_t));
15144       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15145                    sizeof (ip6_address_t));
15146       clib_memcpy (mp->local_address_start, &laddr6_start,
15147                    sizeof (ip6_address_t));
15148       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15149                    sizeof (ip6_address_t));
15150     }
15151   else
15152     {
15153       clib_memcpy (mp->remote_address_start, &raddr4_start,
15154                    sizeof (ip4_address_t));
15155       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15156                    sizeof (ip4_address_t));
15157       clib_memcpy (mp->local_address_start, &laddr4_start,
15158                    sizeof (ip4_address_t));
15159       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15160                    sizeof (ip4_address_t));
15161     }
15162   mp->protocol = (u8) protocol;
15163   mp->local_port_start = ntohs ((u16) lport_start);
15164   mp->local_port_stop = ntohs ((u16) lport_stop);
15165   mp->remote_port_start = ntohs ((u16) rport_start);
15166   mp->remote_port_stop = ntohs ((u16) rport_stop);
15167   mp->policy = (u8) policy;
15168   mp->sa_id = ntohl (sa_id);
15169   mp->is_add = is_add;
15170   mp->is_ip_any = is_ip_any;
15171   S (mp);
15172   W (ret);
15173   return ret;
15174 }
15175
15176 static int
15177 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15178 {
15179   unformat_input_t *i = vam->input;
15180   vl_api_ipsec_sad_add_del_entry_t *mp;
15181   u32 sad_id = 0, spi = 0;
15182   u8 *ck = 0, *ik = 0;
15183   u8 is_add = 1;
15184
15185   u8 protocol = IPSEC_PROTOCOL_AH;
15186   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15187   u32 crypto_alg = 0, integ_alg = 0;
15188   ip4_address_t tun_src4;
15189   ip4_address_t tun_dst4;
15190   ip6_address_t tun_src6;
15191   ip6_address_t tun_dst6;
15192   int ret;
15193
15194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15195     {
15196       if (unformat (i, "del"))
15197         is_add = 0;
15198       else if (unformat (i, "sad_id %d", &sad_id))
15199         ;
15200       else if (unformat (i, "spi %d", &spi))
15201         ;
15202       else if (unformat (i, "esp"))
15203         protocol = IPSEC_PROTOCOL_ESP;
15204       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15205         {
15206           is_tunnel = 1;
15207           is_tunnel_ipv6 = 0;
15208         }
15209       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15210         {
15211           is_tunnel = 1;
15212           is_tunnel_ipv6 = 0;
15213         }
15214       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15215         {
15216           is_tunnel = 1;
15217           is_tunnel_ipv6 = 1;
15218         }
15219       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15220         {
15221           is_tunnel = 1;
15222           is_tunnel_ipv6 = 1;
15223         }
15224       else
15225         if (unformat
15226             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15227         {
15228           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15229             {
15230               clib_warning ("unsupported crypto-alg: '%U'",
15231                             format_ipsec_crypto_alg, crypto_alg);
15232               return -99;
15233             }
15234         }
15235       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15236         ;
15237       else
15238         if (unformat
15239             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15240         {
15241           if (integ_alg >= IPSEC_INTEG_N_ALG)
15242             {
15243               clib_warning ("unsupported integ-alg: '%U'",
15244                             format_ipsec_integ_alg, integ_alg);
15245               return -99;
15246             }
15247         }
15248       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15249         ;
15250       else
15251         {
15252           clib_warning ("parse error '%U'", format_unformat_error, i);
15253           return -99;
15254         }
15255
15256     }
15257
15258   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15259
15260   mp->sad_id = ntohl (sad_id);
15261   mp->is_add = is_add;
15262   mp->protocol = protocol;
15263   mp->spi = ntohl (spi);
15264   mp->is_tunnel = is_tunnel;
15265   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15266   mp->crypto_algorithm = crypto_alg;
15267   mp->integrity_algorithm = integ_alg;
15268   mp->crypto_key_length = vec_len (ck);
15269   mp->integrity_key_length = vec_len (ik);
15270
15271   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15272     mp->crypto_key_length = sizeof (mp->crypto_key);
15273
15274   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15275     mp->integrity_key_length = sizeof (mp->integrity_key);
15276
15277   if (ck)
15278     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15279   if (ik)
15280     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15281
15282   if (is_tunnel)
15283     {
15284       if (is_tunnel_ipv6)
15285         {
15286           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15287                        sizeof (ip6_address_t));
15288           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15289                        sizeof (ip6_address_t));
15290         }
15291       else
15292         {
15293           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15294                        sizeof (ip4_address_t));
15295           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15296                        sizeof (ip4_address_t));
15297         }
15298     }
15299
15300   S (mp);
15301   W (ret);
15302   return ret;
15303 }
15304
15305 static int
15306 api_ipsec_sa_set_key (vat_main_t * vam)
15307 {
15308   unformat_input_t *i = vam->input;
15309   vl_api_ipsec_sa_set_key_t *mp;
15310   u32 sa_id;
15311   u8 *ck = 0, *ik = 0;
15312   int ret;
15313
15314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15315     {
15316       if (unformat (i, "sa_id %d", &sa_id))
15317         ;
15318       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15319         ;
15320       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15321         ;
15322       else
15323         {
15324           clib_warning ("parse error '%U'", format_unformat_error, i);
15325           return -99;
15326         }
15327     }
15328
15329   M (IPSEC_SA_SET_KEY, mp);
15330
15331   mp->sa_id = ntohl (sa_id);
15332   mp->crypto_key_length = vec_len (ck);
15333   mp->integrity_key_length = vec_len (ik);
15334
15335   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15336     mp->crypto_key_length = sizeof (mp->crypto_key);
15337
15338   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15339     mp->integrity_key_length = sizeof (mp->integrity_key);
15340
15341   if (ck)
15342     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15343   if (ik)
15344     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15345
15346   S (mp);
15347   W (ret);
15348   return ret;
15349 }
15350
15351 static int
15352 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15353 {
15354   unformat_input_t *i = vam->input;
15355   vl_api_ipsec_tunnel_if_add_del_t *mp;
15356   u32 local_spi = 0, remote_spi = 0;
15357   u32 crypto_alg = 0, integ_alg = 0;
15358   u8 *lck = NULL, *rck = NULL;
15359   u8 *lik = NULL, *rik = NULL;
15360   ip4_address_t local_ip = { {0} };
15361   ip4_address_t remote_ip = { {0} };
15362   u8 is_add = 1;
15363   u8 esn = 0;
15364   u8 anti_replay = 0;
15365   u8 renumber = 0;
15366   u32 instance = ~0;
15367   int ret;
15368
15369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15370     {
15371       if (unformat (i, "del"))
15372         is_add = 0;
15373       else if (unformat (i, "esn"))
15374         esn = 1;
15375       else if (unformat (i, "anti_replay"))
15376         anti_replay = 1;
15377       else if (unformat (i, "local_spi %d", &local_spi))
15378         ;
15379       else if (unformat (i, "remote_spi %d", &remote_spi))
15380         ;
15381       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15382         ;
15383       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15384         ;
15385       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15386         ;
15387       else
15388         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15389         ;
15390       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15391         ;
15392       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15393         ;
15394       else
15395         if (unformat
15396             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15397         {
15398           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15399             {
15400               errmsg ("unsupported crypto-alg: '%U'\n",
15401                       format_ipsec_crypto_alg, crypto_alg);
15402               return -99;
15403             }
15404         }
15405       else
15406         if (unformat
15407             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15408         {
15409           if (integ_alg >= IPSEC_INTEG_N_ALG)
15410             {
15411               errmsg ("unsupported integ-alg: '%U'\n",
15412                       format_ipsec_integ_alg, integ_alg);
15413               return -99;
15414             }
15415         }
15416       else if (unformat (i, "instance %u", &instance))
15417         renumber = 1;
15418       else
15419         {
15420           errmsg ("parse error '%U'\n", format_unformat_error, i);
15421           return -99;
15422         }
15423     }
15424
15425   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15426
15427   mp->is_add = is_add;
15428   mp->esn = esn;
15429   mp->anti_replay = anti_replay;
15430
15431   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15432   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15433
15434   mp->local_spi = htonl (local_spi);
15435   mp->remote_spi = htonl (remote_spi);
15436   mp->crypto_alg = (u8) crypto_alg;
15437
15438   mp->local_crypto_key_len = 0;
15439   if (lck)
15440     {
15441       mp->local_crypto_key_len = vec_len (lck);
15442       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15443         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15444       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15445     }
15446
15447   mp->remote_crypto_key_len = 0;
15448   if (rck)
15449     {
15450       mp->remote_crypto_key_len = vec_len (rck);
15451       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15452         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15453       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15454     }
15455
15456   mp->integ_alg = (u8) integ_alg;
15457
15458   mp->local_integ_key_len = 0;
15459   if (lik)
15460     {
15461       mp->local_integ_key_len = vec_len (lik);
15462       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15463         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15464       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15465     }
15466
15467   mp->remote_integ_key_len = 0;
15468   if (rik)
15469     {
15470       mp->remote_integ_key_len = vec_len (rik);
15471       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15472         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15473       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15474     }
15475
15476   if (renumber)
15477     {
15478       mp->renumber = renumber;
15479       mp->show_instance = ntohl (instance);
15480     }
15481
15482   S (mp);
15483   W (ret);
15484   return ret;
15485 }
15486
15487 static void
15488 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15489 {
15490   vat_main_t *vam = &vat_main;
15491
15492   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15493          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15494          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15495          "tunnel_src_addr %U tunnel_dst_addr %U "
15496          "salt %u seq_outbound %lu last_seq_inbound %lu "
15497          "replay_window %lu total_data_size %lu\n",
15498          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15499          mp->protocol,
15500          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15501          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15502          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15503          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15504          mp->tunnel_src_addr,
15505          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15506          mp->tunnel_dst_addr,
15507          ntohl (mp->salt),
15508          clib_net_to_host_u64 (mp->seq_outbound),
15509          clib_net_to_host_u64 (mp->last_seq_inbound),
15510          clib_net_to_host_u64 (mp->replay_window),
15511          clib_net_to_host_u64 (mp->total_data_size));
15512 }
15513
15514 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15515 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15516
15517 static void vl_api_ipsec_sa_details_t_handler_json
15518   (vl_api_ipsec_sa_details_t * mp)
15519 {
15520   vat_main_t *vam = &vat_main;
15521   vat_json_node_t *node = NULL;
15522   struct in_addr src_ip4, dst_ip4;
15523   struct in6_addr src_ip6, dst_ip6;
15524
15525   if (VAT_JSON_ARRAY != vam->json_tree.type)
15526     {
15527       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15528       vat_json_init_array (&vam->json_tree);
15529     }
15530   node = vat_json_array_add (&vam->json_tree);
15531
15532   vat_json_init_object (node);
15533   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15534   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15535   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15536   vat_json_object_add_uint (node, "proto", mp->protocol);
15537   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15538   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15539   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15540   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15541   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15542   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15543   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15544                              mp->crypto_key_len);
15545   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15546                              mp->integ_key_len);
15547   if (mp->is_tunnel_ip6)
15548     {
15549       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15550       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15551       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15552       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15553     }
15554   else
15555     {
15556       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15557       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15558       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15559       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15560     }
15561   vat_json_object_add_uint (node, "replay_window",
15562                             clib_net_to_host_u64 (mp->replay_window));
15563   vat_json_object_add_uint (node, "total_data_size",
15564                             clib_net_to_host_u64 (mp->total_data_size));
15565
15566 }
15567
15568 static int
15569 api_ipsec_sa_dump (vat_main_t * vam)
15570 {
15571   unformat_input_t *i = vam->input;
15572   vl_api_ipsec_sa_dump_t *mp;
15573   vl_api_control_ping_t *mp_ping;
15574   u32 sa_id = ~0;
15575   int ret;
15576
15577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15578     {
15579       if (unformat (i, "sa_id %d", &sa_id))
15580         ;
15581       else
15582         {
15583           clib_warning ("parse error '%U'", format_unformat_error, i);
15584           return -99;
15585         }
15586     }
15587
15588   M (IPSEC_SA_DUMP, mp);
15589
15590   mp->sa_id = ntohl (sa_id);
15591
15592   S (mp);
15593
15594   /* Use a control ping for synchronization */
15595   M (CONTROL_PING, mp_ping);
15596   S (mp_ping);
15597
15598   W (ret);
15599   return ret;
15600 }
15601
15602 static int
15603 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15604 {
15605   unformat_input_t *i = vam->input;
15606   vl_api_ipsec_tunnel_if_set_key_t *mp;
15607   u32 sw_if_index = ~0;
15608   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15609   u8 *key = 0;
15610   u32 alg = ~0;
15611   int ret;
15612
15613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15614     {
15615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15616         ;
15617       else
15618         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15619         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15620       else
15621         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15622         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15623       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15624         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15625       else
15626         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15627         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15628       else if (unformat (i, "%U", unformat_hex_string, &key))
15629         ;
15630       else
15631         {
15632           clib_warning ("parse error '%U'", format_unformat_error, i);
15633           return -99;
15634         }
15635     }
15636
15637   if (sw_if_index == ~0)
15638     {
15639       errmsg ("interface must be specified");
15640       return -99;
15641     }
15642
15643   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15644     {
15645       errmsg ("key type must be specified");
15646       return -99;
15647     }
15648
15649   if (alg == ~0)
15650     {
15651       errmsg ("algorithm must be specified");
15652       return -99;
15653     }
15654
15655   if (vec_len (key) == 0)
15656     {
15657       errmsg ("key must be specified");
15658       return -99;
15659     }
15660
15661   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15662
15663   mp->sw_if_index = htonl (sw_if_index);
15664   mp->alg = alg;
15665   mp->key_type = key_type;
15666   mp->key_len = vec_len (key);
15667   clib_memcpy (mp->key, key, vec_len (key));
15668
15669   S (mp);
15670   W (ret);
15671
15672   return ret;
15673 }
15674
15675 static int
15676 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15677 {
15678   unformat_input_t *i = vam->input;
15679   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15680   u32 sw_if_index = ~0;
15681   u32 sa_id = ~0;
15682   u8 is_outbound = (u8) ~ 0;
15683   int ret;
15684
15685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15686     {
15687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15688         ;
15689       else if (unformat (i, "sa_id %d", &sa_id))
15690         ;
15691       else if (unformat (i, "outbound"))
15692         is_outbound = 1;
15693       else if (unformat (i, "inbound"))
15694         is_outbound = 0;
15695       else
15696         {
15697           clib_warning ("parse error '%U'", format_unformat_error, i);
15698           return -99;
15699         }
15700     }
15701
15702   if (sw_if_index == ~0)
15703     {
15704       errmsg ("interface must be specified");
15705       return -99;
15706     }
15707
15708   if (sa_id == ~0)
15709     {
15710       errmsg ("SA ID must be specified");
15711       return -99;
15712     }
15713
15714   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15715
15716   mp->sw_if_index = htonl (sw_if_index);
15717   mp->sa_id = htonl (sa_id);
15718   mp->is_outbound = is_outbound;
15719
15720   S (mp);
15721   W (ret);
15722
15723   return ret;
15724 }
15725
15726 static int
15727 api_ikev2_profile_add_del (vat_main_t * vam)
15728 {
15729   unformat_input_t *i = vam->input;
15730   vl_api_ikev2_profile_add_del_t *mp;
15731   u8 is_add = 1;
15732   u8 *name = 0;
15733   int ret;
15734
15735   const char *valid_chars = "a-zA-Z0-9_";
15736
15737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15738     {
15739       if (unformat (i, "del"))
15740         is_add = 0;
15741       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15742         vec_add1 (name, 0);
15743       else
15744         {
15745           errmsg ("parse error '%U'", format_unformat_error, i);
15746           return -99;
15747         }
15748     }
15749
15750   if (!vec_len (name))
15751     {
15752       errmsg ("profile name must be specified");
15753       return -99;
15754     }
15755
15756   if (vec_len (name) > 64)
15757     {
15758       errmsg ("profile name too long");
15759       return -99;
15760     }
15761
15762   M (IKEV2_PROFILE_ADD_DEL, mp);
15763
15764   clib_memcpy (mp->name, name, vec_len (name));
15765   mp->is_add = is_add;
15766   vec_free (name);
15767
15768   S (mp);
15769   W (ret);
15770   return ret;
15771 }
15772
15773 static int
15774 api_ikev2_profile_set_auth (vat_main_t * vam)
15775 {
15776   unformat_input_t *i = vam->input;
15777   vl_api_ikev2_profile_set_auth_t *mp;
15778   u8 *name = 0;
15779   u8 *data = 0;
15780   u32 auth_method = 0;
15781   u8 is_hex = 0;
15782   int ret;
15783
15784   const char *valid_chars = "a-zA-Z0-9_";
15785
15786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15787     {
15788       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15789         vec_add1 (name, 0);
15790       else if (unformat (i, "auth_method %U",
15791                          unformat_ikev2_auth_method, &auth_method))
15792         ;
15793       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15794         is_hex = 1;
15795       else if (unformat (i, "auth_data %v", &data))
15796         ;
15797       else
15798         {
15799           errmsg ("parse error '%U'", format_unformat_error, i);
15800           return -99;
15801         }
15802     }
15803
15804   if (!vec_len (name))
15805     {
15806       errmsg ("profile name must be specified");
15807       return -99;
15808     }
15809
15810   if (vec_len (name) > 64)
15811     {
15812       errmsg ("profile name too long");
15813       return -99;
15814     }
15815
15816   if (!vec_len (data))
15817     {
15818       errmsg ("auth_data must be specified");
15819       return -99;
15820     }
15821
15822   if (!auth_method)
15823     {
15824       errmsg ("auth_method must be specified");
15825       return -99;
15826     }
15827
15828   M (IKEV2_PROFILE_SET_AUTH, mp);
15829
15830   mp->is_hex = is_hex;
15831   mp->auth_method = (u8) auth_method;
15832   mp->data_len = vec_len (data);
15833   clib_memcpy (mp->name, name, vec_len (name));
15834   clib_memcpy (mp->data, data, vec_len (data));
15835   vec_free (name);
15836   vec_free (data);
15837
15838   S (mp);
15839   W (ret);
15840   return ret;
15841 }
15842
15843 static int
15844 api_ikev2_profile_set_id (vat_main_t * vam)
15845 {
15846   unformat_input_t *i = vam->input;
15847   vl_api_ikev2_profile_set_id_t *mp;
15848   u8 *name = 0;
15849   u8 *data = 0;
15850   u8 is_local = 0;
15851   u32 id_type = 0;
15852   ip4_address_t ip4;
15853   int ret;
15854
15855   const char *valid_chars = "a-zA-Z0-9_";
15856
15857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15858     {
15859       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15860         vec_add1 (name, 0);
15861       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15862         ;
15863       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15864         {
15865           data = vec_new (u8, 4);
15866           clib_memcpy (data, ip4.as_u8, 4);
15867         }
15868       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15869         ;
15870       else if (unformat (i, "id_data %v", &data))
15871         ;
15872       else if (unformat (i, "local"))
15873         is_local = 1;
15874       else if (unformat (i, "remote"))
15875         is_local = 0;
15876       else
15877         {
15878           errmsg ("parse error '%U'", format_unformat_error, i);
15879           return -99;
15880         }
15881     }
15882
15883   if (!vec_len (name))
15884     {
15885       errmsg ("profile name must be specified");
15886       return -99;
15887     }
15888
15889   if (vec_len (name) > 64)
15890     {
15891       errmsg ("profile name too long");
15892       return -99;
15893     }
15894
15895   if (!vec_len (data))
15896     {
15897       errmsg ("id_data must be specified");
15898       return -99;
15899     }
15900
15901   if (!id_type)
15902     {
15903       errmsg ("id_type must be specified");
15904       return -99;
15905     }
15906
15907   M (IKEV2_PROFILE_SET_ID, mp);
15908
15909   mp->is_local = is_local;
15910   mp->id_type = (u8) id_type;
15911   mp->data_len = vec_len (data);
15912   clib_memcpy (mp->name, name, vec_len (name));
15913   clib_memcpy (mp->data, data, vec_len (data));
15914   vec_free (name);
15915   vec_free (data);
15916
15917   S (mp);
15918   W (ret);
15919   return ret;
15920 }
15921
15922 static int
15923 api_ikev2_profile_set_ts (vat_main_t * vam)
15924 {
15925   unformat_input_t *i = vam->input;
15926   vl_api_ikev2_profile_set_ts_t *mp;
15927   u8 *name = 0;
15928   u8 is_local = 0;
15929   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15930   ip4_address_t start_addr, end_addr;
15931
15932   const char *valid_chars = "a-zA-Z0-9_";
15933   int ret;
15934
15935   start_addr.as_u32 = 0;
15936   end_addr.as_u32 = (u32) ~ 0;
15937
15938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15939     {
15940       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15941         vec_add1 (name, 0);
15942       else if (unformat (i, "protocol %d", &proto))
15943         ;
15944       else if (unformat (i, "start_port %d", &start_port))
15945         ;
15946       else if (unformat (i, "end_port %d", &end_port))
15947         ;
15948       else
15949         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15950         ;
15951       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15952         ;
15953       else if (unformat (i, "local"))
15954         is_local = 1;
15955       else if (unformat (i, "remote"))
15956         is_local = 0;
15957       else
15958         {
15959           errmsg ("parse error '%U'", format_unformat_error, i);
15960           return -99;
15961         }
15962     }
15963
15964   if (!vec_len (name))
15965     {
15966       errmsg ("profile name must be specified");
15967       return -99;
15968     }
15969
15970   if (vec_len (name) > 64)
15971     {
15972       errmsg ("profile name too long");
15973       return -99;
15974     }
15975
15976   M (IKEV2_PROFILE_SET_TS, mp);
15977
15978   mp->is_local = is_local;
15979   mp->proto = (u8) proto;
15980   mp->start_port = (u16) start_port;
15981   mp->end_port = (u16) end_port;
15982   mp->start_addr = start_addr.as_u32;
15983   mp->end_addr = end_addr.as_u32;
15984   clib_memcpy (mp->name, name, vec_len (name));
15985   vec_free (name);
15986
15987   S (mp);
15988   W (ret);
15989   return ret;
15990 }
15991
15992 static int
15993 api_ikev2_set_local_key (vat_main_t * vam)
15994 {
15995   unformat_input_t *i = vam->input;
15996   vl_api_ikev2_set_local_key_t *mp;
15997   u8 *file = 0;
15998   int ret;
15999
16000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16001     {
16002       if (unformat (i, "file %v", &file))
16003         vec_add1 (file, 0);
16004       else
16005         {
16006           errmsg ("parse error '%U'", format_unformat_error, i);
16007           return -99;
16008         }
16009     }
16010
16011   if (!vec_len (file))
16012     {
16013       errmsg ("RSA key file must be specified");
16014       return -99;
16015     }
16016
16017   if (vec_len (file) > 256)
16018     {
16019       errmsg ("file name too long");
16020       return -99;
16021     }
16022
16023   M (IKEV2_SET_LOCAL_KEY, mp);
16024
16025   clib_memcpy (mp->key_file, file, vec_len (file));
16026   vec_free (file);
16027
16028   S (mp);
16029   W (ret);
16030   return ret;
16031 }
16032
16033 static int
16034 api_ikev2_set_responder (vat_main_t * vam)
16035 {
16036   unformat_input_t *i = vam->input;
16037   vl_api_ikev2_set_responder_t *mp;
16038   int ret;
16039   u8 *name = 0;
16040   u32 sw_if_index = ~0;
16041   ip4_address_t address;
16042
16043   const char *valid_chars = "a-zA-Z0-9_";
16044
16045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16046     {
16047       if (unformat
16048           (i, "%U interface %d address %U", unformat_token, valid_chars,
16049            &name, &sw_if_index, unformat_ip4_address, &address))
16050         vec_add1 (name, 0);
16051       else
16052         {
16053           errmsg ("parse error '%U'", format_unformat_error, i);
16054           return -99;
16055         }
16056     }
16057
16058   if (!vec_len (name))
16059     {
16060       errmsg ("profile name must be specified");
16061       return -99;
16062     }
16063
16064   if (vec_len (name) > 64)
16065     {
16066       errmsg ("profile name too long");
16067       return -99;
16068     }
16069
16070   M (IKEV2_SET_RESPONDER, mp);
16071
16072   clib_memcpy (mp->name, name, vec_len (name));
16073   vec_free (name);
16074
16075   mp->sw_if_index = sw_if_index;
16076   clib_memcpy (mp->address, &address, sizeof (address));
16077
16078   S (mp);
16079   W (ret);
16080   return ret;
16081 }
16082
16083 static int
16084 api_ikev2_set_ike_transforms (vat_main_t * vam)
16085 {
16086   unformat_input_t *i = vam->input;
16087   vl_api_ikev2_set_ike_transforms_t *mp;
16088   int ret;
16089   u8 *name = 0;
16090   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16091
16092   const char *valid_chars = "a-zA-Z0-9_";
16093
16094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16095     {
16096       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16097                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16098         vec_add1 (name, 0);
16099       else
16100         {
16101           errmsg ("parse error '%U'", format_unformat_error, i);
16102           return -99;
16103         }
16104     }
16105
16106   if (!vec_len (name))
16107     {
16108       errmsg ("profile name must be specified");
16109       return -99;
16110     }
16111
16112   if (vec_len (name) > 64)
16113     {
16114       errmsg ("profile name too long");
16115       return -99;
16116     }
16117
16118   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16119
16120   clib_memcpy (mp->name, name, vec_len (name));
16121   vec_free (name);
16122   mp->crypto_alg = crypto_alg;
16123   mp->crypto_key_size = crypto_key_size;
16124   mp->integ_alg = integ_alg;
16125   mp->dh_group = dh_group;
16126
16127   S (mp);
16128   W (ret);
16129   return ret;
16130 }
16131
16132
16133 static int
16134 api_ikev2_set_esp_transforms (vat_main_t * vam)
16135 {
16136   unformat_input_t *i = vam->input;
16137   vl_api_ikev2_set_esp_transforms_t *mp;
16138   int ret;
16139   u8 *name = 0;
16140   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16141
16142   const char *valid_chars = "a-zA-Z0-9_";
16143
16144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16147                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16148         vec_add1 (name, 0);
16149       else
16150         {
16151           errmsg ("parse error '%U'", format_unformat_error, i);
16152           return -99;
16153         }
16154     }
16155
16156   if (!vec_len (name))
16157     {
16158       errmsg ("profile name must be specified");
16159       return -99;
16160     }
16161
16162   if (vec_len (name) > 64)
16163     {
16164       errmsg ("profile name too long");
16165       return -99;
16166     }
16167
16168   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16169
16170   clib_memcpy (mp->name, name, vec_len (name));
16171   vec_free (name);
16172   mp->crypto_alg = crypto_alg;
16173   mp->crypto_key_size = crypto_key_size;
16174   mp->integ_alg = integ_alg;
16175   mp->dh_group = dh_group;
16176
16177   S (mp);
16178   W (ret);
16179   return ret;
16180 }
16181
16182 static int
16183 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16184 {
16185   unformat_input_t *i = vam->input;
16186   vl_api_ikev2_set_sa_lifetime_t *mp;
16187   int ret;
16188   u8 *name = 0;
16189   u64 lifetime, lifetime_maxdata;
16190   u32 lifetime_jitter, handover;
16191
16192   const char *valid_chars = "a-zA-Z0-9_";
16193
16194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16195     {
16196       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16197                     &lifetime, &lifetime_jitter, &handover,
16198                     &lifetime_maxdata))
16199         vec_add1 (name, 0);
16200       else
16201         {
16202           errmsg ("parse error '%U'", format_unformat_error, i);
16203           return -99;
16204         }
16205     }
16206
16207   if (!vec_len (name))
16208     {
16209       errmsg ("profile name must be specified");
16210       return -99;
16211     }
16212
16213   if (vec_len (name) > 64)
16214     {
16215       errmsg ("profile name too long");
16216       return -99;
16217     }
16218
16219   M (IKEV2_SET_SA_LIFETIME, mp);
16220
16221   clib_memcpy (mp->name, name, vec_len (name));
16222   vec_free (name);
16223   mp->lifetime = lifetime;
16224   mp->lifetime_jitter = lifetime_jitter;
16225   mp->handover = handover;
16226   mp->lifetime_maxdata = lifetime_maxdata;
16227
16228   S (mp);
16229   W (ret);
16230   return ret;
16231 }
16232
16233 static int
16234 api_ikev2_initiate_sa_init (vat_main_t * vam)
16235 {
16236   unformat_input_t *i = vam->input;
16237   vl_api_ikev2_initiate_sa_init_t *mp;
16238   int ret;
16239   u8 *name = 0;
16240
16241   const char *valid_chars = "a-zA-Z0-9_";
16242
16243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16244     {
16245       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16246         vec_add1 (name, 0);
16247       else
16248         {
16249           errmsg ("parse error '%U'", format_unformat_error, i);
16250           return -99;
16251         }
16252     }
16253
16254   if (!vec_len (name))
16255     {
16256       errmsg ("profile name must be specified");
16257       return -99;
16258     }
16259
16260   if (vec_len (name) > 64)
16261     {
16262       errmsg ("profile name too long");
16263       return -99;
16264     }
16265
16266   M (IKEV2_INITIATE_SA_INIT, mp);
16267
16268   clib_memcpy (mp->name, name, vec_len (name));
16269   vec_free (name);
16270
16271   S (mp);
16272   W (ret);
16273   return ret;
16274 }
16275
16276 static int
16277 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16278 {
16279   unformat_input_t *i = vam->input;
16280   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16281   int ret;
16282   u64 ispi;
16283
16284
16285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16286     {
16287       if (unformat (i, "%lx", &ispi))
16288         ;
16289       else
16290         {
16291           errmsg ("parse error '%U'", format_unformat_error, i);
16292           return -99;
16293         }
16294     }
16295
16296   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16297
16298   mp->ispi = ispi;
16299
16300   S (mp);
16301   W (ret);
16302   return ret;
16303 }
16304
16305 static int
16306 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16307 {
16308   unformat_input_t *i = vam->input;
16309   vl_api_ikev2_initiate_del_child_sa_t *mp;
16310   int ret;
16311   u32 ispi;
16312
16313
16314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16315     {
16316       if (unformat (i, "%x", &ispi))
16317         ;
16318       else
16319         {
16320           errmsg ("parse error '%U'", format_unformat_error, i);
16321           return -99;
16322         }
16323     }
16324
16325   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16326
16327   mp->ispi = ispi;
16328
16329   S (mp);
16330   W (ret);
16331   return ret;
16332 }
16333
16334 static int
16335 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16336 {
16337   unformat_input_t *i = vam->input;
16338   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16339   int ret;
16340   u32 ispi;
16341
16342
16343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16344     {
16345       if (unformat (i, "%x", &ispi))
16346         ;
16347       else
16348         {
16349           errmsg ("parse error '%U'", format_unformat_error, i);
16350           return -99;
16351         }
16352     }
16353
16354   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16355
16356   mp->ispi = ispi;
16357
16358   S (mp);
16359   W (ret);
16360   return ret;
16361 }
16362
16363 static int
16364 api_get_first_msg_id (vat_main_t * vam)
16365 {
16366   vl_api_get_first_msg_id_t *mp;
16367   unformat_input_t *i = vam->input;
16368   u8 *name;
16369   u8 name_set = 0;
16370   int ret;
16371
16372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16373     {
16374       if (unformat (i, "client %s", &name))
16375         name_set = 1;
16376       else
16377         break;
16378     }
16379
16380   if (name_set == 0)
16381     {
16382       errmsg ("missing client name");
16383       return -99;
16384     }
16385   vec_add1 (name, 0);
16386
16387   if (vec_len (name) > 63)
16388     {
16389       errmsg ("client name too long");
16390       return -99;
16391     }
16392
16393   M (GET_FIRST_MSG_ID, mp);
16394   clib_memcpy (mp->name, name, vec_len (name));
16395   S (mp);
16396   W (ret);
16397   return ret;
16398 }
16399
16400 static int
16401 api_cop_interface_enable_disable (vat_main_t * vam)
16402 {
16403   unformat_input_t *line_input = vam->input;
16404   vl_api_cop_interface_enable_disable_t *mp;
16405   u32 sw_if_index = ~0;
16406   u8 enable_disable = 1;
16407   int ret;
16408
16409   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16410     {
16411       if (unformat (line_input, "disable"))
16412         enable_disable = 0;
16413       if (unformat (line_input, "enable"))
16414         enable_disable = 1;
16415       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16416                          vam, &sw_if_index))
16417         ;
16418       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16419         ;
16420       else
16421         break;
16422     }
16423
16424   if (sw_if_index == ~0)
16425     {
16426       errmsg ("missing interface name or sw_if_index");
16427       return -99;
16428     }
16429
16430   /* Construct the API message */
16431   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16432   mp->sw_if_index = ntohl (sw_if_index);
16433   mp->enable_disable = enable_disable;
16434
16435   /* send it... */
16436   S (mp);
16437   /* Wait for the reply */
16438   W (ret);
16439   return ret;
16440 }
16441
16442 static int
16443 api_cop_whitelist_enable_disable (vat_main_t * vam)
16444 {
16445   unformat_input_t *line_input = vam->input;
16446   vl_api_cop_whitelist_enable_disable_t *mp;
16447   u32 sw_if_index = ~0;
16448   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16449   u32 fib_id = 0;
16450   int ret;
16451
16452   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16453     {
16454       if (unformat (line_input, "ip4"))
16455         ip4 = 1;
16456       else if (unformat (line_input, "ip6"))
16457         ip6 = 1;
16458       else if (unformat (line_input, "default"))
16459         default_cop = 1;
16460       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16461                          vam, &sw_if_index))
16462         ;
16463       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16464         ;
16465       else if (unformat (line_input, "fib-id %d", &fib_id))
16466         ;
16467       else
16468         break;
16469     }
16470
16471   if (sw_if_index == ~0)
16472     {
16473       errmsg ("missing interface name or sw_if_index");
16474       return -99;
16475     }
16476
16477   /* Construct the API message */
16478   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16479   mp->sw_if_index = ntohl (sw_if_index);
16480   mp->fib_id = ntohl (fib_id);
16481   mp->ip4 = ip4;
16482   mp->ip6 = ip6;
16483   mp->default_cop = default_cop;
16484
16485   /* send it... */
16486   S (mp);
16487   /* Wait for the reply */
16488   W (ret);
16489   return ret;
16490 }
16491
16492 static int
16493 api_get_node_graph (vat_main_t * vam)
16494 {
16495   vl_api_get_node_graph_t *mp;
16496   int ret;
16497
16498   M (GET_NODE_GRAPH, mp);
16499
16500   /* send it... */
16501   S (mp);
16502   /* Wait for the reply */
16503   W (ret);
16504   return ret;
16505 }
16506
16507 /* *INDENT-OFF* */
16508 /** Used for parsing LISP eids */
16509 typedef CLIB_PACKED(struct{
16510   u8 addr[16];   /**< eid address */
16511   u32 len;       /**< prefix length if IP */
16512   u8 type;      /**< type of eid */
16513 }) lisp_eid_vat_t;
16514 /* *INDENT-ON* */
16515
16516 static uword
16517 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16518 {
16519   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16520
16521   memset (a, 0, sizeof (a[0]));
16522
16523   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16524     {
16525       a->type = 0;              /* ipv4 type */
16526     }
16527   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16528     {
16529       a->type = 1;              /* ipv6 type */
16530     }
16531   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16532     {
16533       a->type = 2;              /* mac type */
16534     }
16535   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16536     {
16537       a->type = 3;              /* NSH type */
16538       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16539       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16540     }
16541   else
16542     {
16543       return 0;
16544     }
16545
16546   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16547     {
16548       return 0;
16549     }
16550
16551   return 1;
16552 }
16553
16554 static int
16555 lisp_eid_size_vat (u8 type)
16556 {
16557   switch (type)
16558     {
16559     case 0:
16560       return 4;
16561     case 1:
16562       return 16;
16563     case 2:
16564       return 6;
16565     case 3:
16566       return 5;
16567     }
16568   return 0;
16569 }
16570
16571 static void
16572 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16573 {
16574   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16575 }
16576
16577 static int
16578 api_one_add_del_locator_set (vat_main_t * vam)
16579 {
16580   unformat_input_t *input = vam->input;
16581   vl_api_one_add_del_locator_set_t *mp;
16582   u8 is_add = 1;
16583   u8 *locator_set_name = NULL;
16584   u8 locator_set_name_set = 0;
16585   vl_api_local_locator_t locator, *locators = 0;
16586   u32 sw_if_index, priority, weight;
16587   u32 data_len = 0;
16588
16589   int ret;
16590   /* Parse args required to build the message */
16591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16592     {
16593       if (unformat (input, "del"))
16594         {
16595           is_add = 0;
16596         }
16597       else if (unformat (input, "locator-set %s", &locator_set_name))
16598         {
16599           locator_set_name_set = 1;
16600         }
16601       else if (unformat (input, "sw_if_index %u p %u w %u",
16602                          &sw_if_index, &priority, &weight))
16603         {
16604           locator.sw_if_index = htonl (sw_if_index);
16605           locator.priority = priority;
16606           locator.weight = weight;
16607           vec_add1 (locators, locator);
16608         }
16609       else
16610         if (unformat
16611             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16612              &sw_if_index, &priority, &weight))
16613         {
16614           locator.sw_if_index = htonl (sw_if_index);
16615           locator.priority = priority;
16616           locator.weight = weight;
16617           vec_add1 (locators, locator);
16618         }
16619       else
16620         break;
16621     }
16622
16623   if (locator_set_name_set == 0)
16624     {
16625       errmsg ("missing locator-set name");
16626       vec_free (locators);
16627       return -99;
16628     }
16629
16630   if (vec_len (locator_set_name) > 64)
16631     {
16632       errmsg ("locator-set name too long");
16633       vec_free (locator_set_name);
16634       vec_free (locators);
16635       return -99;
16636     }
16637   vec_add1 (locator_set_name, 0);
16638
16639   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16640
16641   /* Construct the API message */
16642   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16643
16644   mp->is_add = is_add;
16645   clib_memcpy (mp->locator_set_name, locator_set_name,
16646                vec_len (locator_set_name));
16647   vec_free (locator_set_name);
16648
16649   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16650   if (locators)
16651     clib_memcpy (mp->locators, locators, data_len);
16652   vec_free (locators);
16653
16654   /* send it... */
16655   S (mp);
16656
16657   /* Wait for a reply... */
16658   W (ret);
16659   return ret;
16660 }
16661
16662 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16663
16664 static int
16665 api_one_add_del_locator (vat_main_t * vam)
16666 {
16667   unformat_input_t *input = vam->input;
16668   vl_api_one_add_del_locator_t *mp;
16669   u32 tmp_if_index = ~0;
16670   u32 sw_if_index = ~0;
16671   u8 sw_if_index_set = 0;
16672   u8 sw_if_index_if_name_set = 0;
16673   u32 priority = ~0;
16674   u8 priority_set = 0;
16675   u32 weight = ~0;
16676   u8 weight_set = 0;
16677   u8 is_add = 1;
16678   u8 *locator_set_name = NULL;
16679   u8 locator_set_name_set = 0;
16680   int ret;
16681
16682   /* Parse args required to build the message */
16683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16684     {
16685       if (unformat (input, "del"))
16686         {
16687           is_add = 0;
16688         }
16689       else if (unformat (input, "locator-set %s", &locator_set_name))
16690         {
16691           locator_set_name_set = 1;
16692         }
16693       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16694                          &tmp_if_index))
16695         {
16696           sw_if_index_if_name_set = 1;
16697           sw_if_index = tmp_if_index;
16698         }
16699       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16700         {
16701           sw_if_index_set = 1;
16702           sw_if_index = tmp_if_index;
16703         }
16704       else if (unformat (input, "p %d", &priority))
16705         {
16706           priority_set = 1;
16707         }
16708       else if (unformat (input, "w %d", &weight))
16709         {
16710           weight_set = 1;
16711         }
16712       else
16713         break;
16714     }
16715
16716   if (locator_set_name_set == 0)
16717     {
16718       errmsg ("missing locator-set name");
16719       return -99;
16720     }
16721
16722   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16723     {
16724       errmsg ("missing sw_if_index");
16725       vec_free (locator_set_name);
16726       return -99;
16727     }
16728
16729   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16730     {
16731       errmsg ("cannot use both params interface name and sw_if_index");
16732       vec_free (locator_set_name);
16733       return -99;
16734     }
16735
16736   if (priority_set == 0)
16737     {
16738       errmsg ("missing locator-set priority");
16739       vec_free (locator_set_name);
16740       return -99;
16741     }
16742
16743   if (weight_set == 0)
16744     {
16745       errmsg ("missing locator-set weight");
16746       vec_free (locator_set_name);
16747       return -99;
16748     }
16749
16750   if (vec_len (locator_set_name) > 64)
16751     {
16752       errmsg ("locator-set name too long");
16753       vec_free (locator_set_name);
16754       return -99;
16755     }
16756   vec_add1 (locator_set_name, 0);
16757
16758   /* Construct the API message */
16759   M (ONE_ADD_DEL_LOCATOR, mp);
16760
16761   mp->is_add = is_add;
16762   mp->sw_if_index = ntohl (sw_if_index);
16763   mp->priority = priority;
16764   mp->weight = weight;
16765   clib_memcpy (mp->locator_set_name, locator_set_name,
16766                vec_len (locator_set_name));
16767   vec_free (locator_set_name);
16768
16769   /* send it... */
16770   S (mp);
16771
16772   /* Wait for a reply... */
16773   W (ret);
16774   return ret;
16775 }
16776
16777 #define api_lisp_add_del_locator api_one_add_del_locator
16778
16779 uword
16780 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16781 {
16782   u32 *key_id = va_arg (*args, u32 *);
16783   u8 *s = 0;
16784
16785   if (unformat (input, "%s", &s))
16786     {
16787       if (!strcmp ((char *) s, "sha1"))
16788         key_id[0] = HMAC_SHA_1_96;
16789       else if (!strcmp ((char *) s, "sha256"))
16790         key_id[0] = HMAC_SHA_256_128;
16791       else
16792         {
16793           clib_warning ("invalid key_id: '%s'", s);
16794           key_id[0] = HMAC_NO_KEY;
16795         }
16796     }
16797   else
16798     return 0;
16799
16800   vec_free (s);
16801   return 1;
16802 }
16803
16804 static int
16805 api_one_add_del_local_eid (vat_main_t * vam)
16806 {
16807   unformat_input_t *input = vam->input;
16808   vl_api_one_add_del_local_eid_t *mp;
16809   u8 is_add = 1;
16810   u8 eid_set = 0;
16811   lisp_eid_vat_t _eid, *eid = &_eid;
16812   u8 *locator_set_name = 0;
16813   u8 locator_set_name_set = 0;
16814   u32 vni = 0;
16815   u16 key_id = 0;
16816   u8 *key = 0;
16817   int ret;
16818
16819   /* Parse args required to build the message */
16820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16821     {
16822       if (unformat (input, "del"))
16823         {
16824           is_add = 0;
16825         }
16826       else if (unformat (input, "vni %d", &vni))
16827         {
16828           ;
16829         }
16830       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16831         {
16832           eid_set = 1;
16833         }
16834       else if (unformat (input, "locator-set %s", &locator_set_name))
16835         {
16836           locator_set_name_set = 1;
16837         }
16838       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16839         ;
16840       else if (unformat (input, "secret-key %_%v%_", &key))
16841         ;
16842       else
16843         break;
16844     }
16845
16846   if (locator_set_name_set == 0)
16847     {
16848       errmsg ("missing locator-set name");
16849       return -99;
16850     }
16851
16852   if (0 == eid_set)
16853     {
16854       errmsg ("EID address not set!");
16855       vec_free (locator_set_name);
16856       return -99;
16857     }
16858
16859   if (key && (0 == key_id))
16860     {
16861       errmsg ("invalid key_id!");
16862       return -99;
16863     }
16864
16865   if (vec_len (key) > 64)
16866     {
16867       errmsg ("key too long");
16868       vec_free (key);
16869       return -99;
16870     }
16871
16872   if (vec_len (locator_set_name) > 64)
16873     {
16874       errmsg ("locator-set name too long");
16875       vec_free (locator_set_name);
16876       return -99;
16877     }
16878   vec_add1 (locator_set_name, 0);
16879
16880   /* Construct the API message */
16881   M (ONE_ADD_DEL_LOCAL_EID, mp);
16882
16883   mp->is_add = is_add;
16884   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16885   mp->eid_type = eid->type;
16886   mp->prefix_len = eid->len;
16887   mp->vni = clib_host_to_net_u32 (vni);
16888   mp->key_id = clib_host_to_net_u16 (key_id);
16889   clib_memcpy (mp->locator_set_name, locator_set_name,
16890                vec_len (locator_set_name));
16891   clib_memcpy (mp->key, key, vec_len (key));
16892
16893   vec_free (locator_set_name);
16894   vec_free (key);
16895
16896   /* send it... */
16897   S (mp);
16898
16899   /* Wait for a reply... */
16900   W (ret);
16901   return ret;
16902 }
16903
16904 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16905
16906 static int
16907 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16908 {
16909   u32 dp_table = 0, vni = 0;;
16910   unformat_input_t *input = vam->input;
16911   vl_api_gpe_add_del_fwd_entry_t *mp;
16912   u8 is_add = 1;
16913   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16914   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16915   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16916   u32 action = ~0, w;
16917   ip4_address_t rmt_rloc4, lcl_rloc4;
16918   ip6_address_t rmt_rloc6, lcl_rloc6;
16919   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16920   int ret;
16921
16922   memset (&rloc, 0, sizeof (rloc));
16923
16924   /* Parse args required to build the message */
16925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16926     {
16927       if (unformat (input, "del"))
16928         is_add = 0;
16929       else if (unformat (input, "add"))
16930         is_add = 1;
16931       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16932         {
16933           rmt_eid_set = 1;
16934         }
16935       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16936         {
16937           lcl_eid_set = 1;
16938         }
16939       else if (unformat (input, "vrf %d", &dp_table))
16940         ;
16941       else if (unformat (input, "bd %d", &dp_table))
16942         ;
16943       else if (unformat (input, "vni %d", &vni))
16944         ;
16945       else if (unformat (input, "w %d", &w))
16946         {
16947           if (!curr_rloc)
16948             {
16949               errmsg ("No RLOC configured for setting priority/weight!");
16950               return -99;
16951             }
16952           curr_rloc->weight = w;
16953         }
16954       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16955                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16956         {
16957           rloc.is_ip4 = 1;
16958
16959           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16960           rloc.weight = 0;
16961           vec_add1 (lcl_locs, rloc);
16962
16963           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16964           vec_add1 (rmt_locs, rloc);
16965           /* weight saved in rmt loc */
16966           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16967         }
16968       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16969                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16970         {
16971           rloc.is_ip4 = 0;
16972           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16973           rloc.weight = 0;
16974           vec_add1 (lcl_locs, rloc);
16975
16976           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16977           vec_add1 (rmt_locs, rloc);
16978           /* weight saved in rmt loc */
16979           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16980         }
16981       else if (unformat (input, "action %d", &action))
16982         {
16983           ;
16984         }
16985       else
16986         {
16987           clib_warning ("parse error '%U'", format_unformat_error, input);
16988           return -99;
16989         }
16990     }
16991
16992   if (!rmt_eid_set)
16993     {
16994       errmsg ("remote eid addresses not set");
16995       return -99;
16996     }
16997
16998   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16999     {
17000       errmsg ("eid types don't match");
17001       return -99;
17002     }
17003
17004   if (0 == rmt_locs && (u32) ~ 0 == action)
17005     {
17006       errmsg ("action not set for negative mapping");
17007       return -99;
17008     }
17009
17010   /* Construct the API message */
17011   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17012       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17013
17014   mp->is_add = is_add;
17015   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17016   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17017   mp->eid_type = rmt_eid->type;
17018   mp->dp_table = clib_host_to_net_u32 (dp_table);
17019   mp->vni = clib_host_to_net_u32 (vni);
17020   mp->rmt_len = rmt_eid->len;
17021   mp->lcl_len = lcl_eid->len;
17022   mp->action = action;
17023
17024   if (0 != rmt_locs && 0 != lcl_locs)
17025     {
17026       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17027       clib_memcpy (mp->locs, lcl_locs,
17028                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17029
17030       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17031       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17032                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17033     }
17034   vec_free (lcl_locs);
17035   vec_free (rmt_locs);
17036
17037   /* send it... */
17038   S (mp);
17039
17040   /* Wait for a reply... */
17041   W (ret);
17042   return ret;
17043 }
17044
17045 static int
17046 api_one_add_del_map_server (vat_main_t * vam)
17047 {
17048   unformat_input_t *input = vam->input;
17049   vl_api_one_add_del_map_server_t *mp;
17050   u8 is_add = 1;
17051   u8 ipv4_set = 0;
17052   u8 ipv6_set = 0;
17053   ip4_address_t ipv4;
17054   ip6_address_t ipv6;
17055   int ret;
17056
17057   /* Parse args required to build the message */
17058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17059     {
17060       if (unformat (input, "del"))
17061         {
17062           is_add = 0;
17063         }
17064       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17065         {
17066           ipv4_set = 1;
17067         }
17068       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17069         {
17070           ipv6_set = 1;
17071         }
17072       else
17073         break;
17074     }
17075
17076   if (ipv4_set && ipv6_set)
17077     {
17078       errmsg ("both eid v4 and v6 addresses set");
17079       return -99;
17080     }
17081
17082   if (!ipv4_set && !ipv6_set)
17083     {
17084       errmsg ("eid addresses not set");
17085       return -99;
17086     }
17087
17088   /* Construct the API message */
17089   M (ONE_ADD_DEL_MAP_SERVER, mp);
17090
17091   mp->is_add = is_add;
17092   if (ipv6_set)
17093     {
17094       mp->is_ipv6 = 1;
17095       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17096     }
17097   else
17098     {
17099       mp->is_ipv6 = 0;
17100       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17101     }
17102
17103   /* send it... */
17104   S (mp);
17105
17106   /* Wait for a reply... */
17107   W (ret);
17108   return ret;
17109 }
17110
17111 #define api_lisp_add_del_map_server api_one_add_del_map_server
17112
17113 static int
17114 api_one_add_del_map_resolver (vat_main_t * vam)
17115 {
17116   unformat_input_t *input = vam->input;
17117   vl_api_one_add_del_map_resolver_t *mp;
17118   u8 is_add = 1;
17119   u8 ipv4_set = 0;
17120   u8 ipv6_set = 0;
17121   ip4_address_t ipv4;
17122   ip6_address_t ipv6;
17123   int ret;
17124
17125   /* Parse args required to build the message */
17126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17127     {
17128       if (unformat (input, "del"))
17129         {
17130           is_add = 0;
17131         }
17132       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17133         {
17134           ipv4_set = 1;
17135         }
17136       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17137         {
17138           ipv6_set = 1;
17139         }
17140       else
17141         break;
17142     }
17143
17144   if (ipv4_set && ipv6_set)
17145     {
17146       errmsg ("both eid v4 and v6 addresses set");
17147       return -99;
17148     }
17149
17150   if (!ipv4_set && !ipv6_set)
17151     {
17152       errmsg ("eid addresses not set");
17153       return -99;
17154     }
17155
17156   /* Construct the API message */
17157   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17158
17159   mp->is_add = is_add;
17160   if (ipv6_set)
17161     {
17162       mp->is_ipv6 = 1;
17163       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17164     }
17165   else
17166     {
17167       mp->is_ipv6 = 0;
17168       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17169     }
17170
17171   /* send it... */
17172   S (mp);
17173
17174   /* Wait for a reply... */
17175   W (ret);
17176   return ret;
17177 }
17178
17179 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17180
17181 static int
17182 api_lisp_gpe_enable_disable (vat_main_t * vam)
17183 {
17184   unformat_input_t *input = vam->input;
17185   vl_api_gpe_enable_disable_t *mp;
17186   u8 is_set = 0;
17187   u8 is_en = 1;
17188   int ret;
17189
17190   /* Parse args required to build the message */
17191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17192     {
17193       if (unformat (input, "enable"))
17194         {
17195           is_set = 1;
17196           is_en = 1;
17197         }
17198       else if (unformat (input, "disable"))
17199         {
17200           is_set = 1;
17201           is_en = 0;
17202         }
17203       else
17204         break;
17205     }
17206
17207   if (is_set == 0)
17208     {
17209       errmsg ("Value not set");
17210       return -99;
17211     }
17212
17213   /* Construct the API message */
17214   M (GPE_ENABLE_DISABLE, mp);
17215
17216   mp->is_en = is_en;
17217
17218   /* send it... */
17219   S (mp);
17220
17221   /* Wait for a reply... */
17222   W (ret);
17223   return ret;
17224 }
17225
17226 static int
17227 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17228 {
17229   unformat_input_t *input = vam->input;
17230   vl_api_one_rloc_probe_enable_disable_t *mp;
17231   u8 is_set = 0;
17232   u8 is_en = 0;
17233   int ret;
17234
17235   /* Parse args required to build the message */
17236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17237     {
17238       if (unformat (input, "enable"))
17239         {
17240           is_set = 1;
17241           is_en = 1;
17242         }
17243       else if (unformat (input, "disable"))
17244         is_set = 1;
17245       else
17246         break;
17247     }
17248
17249   if (!is_set)
17250     {
17251       errmsg ("Value not set");
17252       return -99;
17253     }
17254
17255   /* Construct the API message */
17256   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17257
17258   mp->is_enabled = is_en;
17259
17260   /* send it... */
17261   S (mp);
17262
17263   /* Wait for a reply... */
17264   W (ret);
17265   return ret;
17266 }
17267
17268 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17269
17270 static int
17271 api_one_map_register_enable_disable (vat_main_t * vam)
17272 {
17273   unformat_input_t *input = vam->input;
17274   vl_api_one_map_register_enable_disable_t *mp;
17275   u8 is_set = 0;
17276   u8 is_en = 0;
17277   int ret;
17278
17279   /* Parse args required to build the message */
17280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17281     {
17282       if (unformat (input, "enable"))
17283         {
17284           is_set = 1;
17285           is_en = 1;
17286         }
17287       else if (unformat (input, "disable"))
17288         is_set = 1;
17289       else
17290         break;
17291     }
17292
17293   if (!is_set)
17294     {
17295       errmsg ("Value not set");
17296       return -99;
17297     }
17298
17299   /* Construct the API message */
17300   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17301
17302   mp->is_enabled = is_en;
17303
17304   /* send it... */
17305   S (mp);
17306
17307   /* Wait for a reply... */
17308   W (ret);
17309   return ret;
17310 }
17311
17312 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17313
17314 static int
17315 api_one_enable_disable (vat_main_t * vam)
17316 {
17317   unformat_input_t *input = vam->input;
17318   vl_api_one_enable_disable_t *mp;
17319   u8 is_set = 0;
17320   u8 is_en = 0;
17321   int ret;
17322
17323   /* Parse args required to build the message */
17324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17325     {
17326       if (unformat (input, "enable"))
17327         {
17328           is_set = 1;
17329           is_en = 1;
17330         }
17331       else if (unformat (input, "disable"))
17332         {
17333           is_set = 1;
17334         }
17335       else
17336         break;
17337     }
17338
17339   if (!is_set)
17340     {
17341       errmsg ("Value not set");
17342       return -99;
17343     }
17344
17345   /* Construct the API message */
17346   M (ONE_ENABLE_DISABLE, mp);
17347
17348   mp->is_en = is_en;
17349
17350   /* send it... */
17351   S (mp);
17352
17353   /* Wait for a reply... */
17354   W (ret);
17355   return ret;
17356 }
17357
17358 #define api_lisp_enable_disable api_one_enable_disable
17359
17360 static int
17361 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17362 {
17363   unformat_input_t *input = vam->input;
17364   vl_api_one_enable_disable_xtr_mode_t *mp;
17365   u8 is_set = 0;
17366   u8 is_en = 0;
17367   int ret;
17368
17369   /* Parse args required to build the message */
17370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17371     {
17372       if (unformat (input, "enable"))
17373         {
17374           is_set = 1;
17375           is_en = 1;
17376         }
17377       else if (unformat (input, "disable"))
17378         {
17379           is_set = 1;
17380         }
17381       else
17382         break;
17383     }
17384
17385   if (!is_set)
17386     {
17387       errmsg ("Value not set");
17388       return -99;
17389     }
17390
17391   /* Construct the API message */
17392   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17393
17394   mp->is_en = is_en;
17395
17396   /* send it... */
17397   S (mp);
17398
17399   /* Wait for a reply... */
17400   W (ret);
17401   return ret;
17402 }
17403
17404 static int
17405 api_one_show_xtr_mode (vat_main_t * vam)
17406 {
17407   vl_api_one_show_xtr_mode_t *mp;
17408   int ret;
17409
17410   /* Construct the API message */
17411   M (ONE_SHOW_XTR_MODE, mp);
17412
17413   /* send it... */
17414   S (mp);
17415
17416   /* Wait for a reply... */
17417   W (ret);
17418   return ret;
17419 }
17420
17421 static int
17422 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17423 {
17424   unformat_input_t *input = vam->input;
17425   vl_api_one_enable_disable_pitr_mode_t *mp;
17426   u8 is_set = 0;
17427   u8 is_en = 0;
17428   int ret;
17429
17430   /* Parse args required to build the message */
17431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17432     {
17433       if (unformat (input, "enable"))
17434         {
17435           is_set = 1;
17436           is_en = 1;
17437         }
17438       else if (unformat (input, "disable"))
17439         {
17440           is_set = 1;
17441         }
17442       else
17443         break;
17444     }
17445
17446   if (!is_set)
17447     {
17448       errmsg ("Value not set");
17449       return -99;
17450     }
17451
17452   /* Construct the API message */
17453   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17454
17455   mp->is_en = is_en;
17456
17457   /* send it... */
17458   S (mp);
17459
17460   /* Wait for a reply... */
17461   W (ret);
17462   return ret;
17463 }
17464
17465 static int
17466 api_one_show_pitr_mode (vat_main_t * vam)
17467 {
17468   vl_api_one_show_pitr_mode_t *mp;
17469   int ret;
17470
17471   /* Construct the API message */
17472   M (ONE_SHOW_PITR_MODE, mp);
17473
17474   /* send it... */
17475   S (mp);
17476
17477   /* Wait for a reply... */
17478   W (ret);
17479   return ret;
17480 }
17481
17482 static int
17483 api_one_enable_disable_petr_mode (vat_main_t * vam)
17484 {
17485   unformat_input_t *input = vam->input;
17486   vl_api_one_enable_disable_petr_mode_t *mp;
17487   u8 is_set = 0;
17488   u8 is_en = 0;
17489   int ret;
17490
17491   /* Parse args required to build the message */
17492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17493     {
17494       if (unformat (input, "enable"))
17495         {
17496           is_set = 1;
17497           is_en = 1;
17498         }
17499       else if (unformat (input, "disable"))
17500         {
17501           is_set = 1;
17502         }
17503       else
17504         break;
17505     }
17506
17507   if (!is_set)
17508     {
17509       errmsg ("Value not set");
17510       return -99;
17511     }
17512
17513   /* Construct the API message */
17514   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17515
17516   mp->is_en = is_en;
17517
17518   /* send it... */
17519   S (mp);
17520
17521   /* Wait for a reply... */
17522   W (ret);
17523   return ret;
17524 }
17525
17526 static int
17527 api_one_show_petr_mode (vat_main_t * vam)
17528 {
17529   vl_api_one_show_petr_mode_t *mp;
17530   int ret;
17531
17532   /* Construct the API message */
17533   M (ONE_SHOW_PETR_MODE, mp);
17534
17535   /* send it... */
17536   S (mp);
17537
17538   /* Wait for a reply... */
17539   W (ret);
17540   return ret;
17541 }
17542
17543 static int
17544 api_show_one_map_register_state (vat_main_t * vam)
17545 {
17546   vl_api_show_one_map_register_state_t *mp;
17547   int ret;
17548
17549   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17550
17551   /* send */
17552   S (mp);
17553
17554   /* wait for reply */
17555   W (ret);
17556   return ret;
17557 }
17558
17559 #define api_show_lisp_map_register_state api_show_one_map_register_state
17560
17561 static int
17562 api_show_one_rloc_probe_state (vat_main_t * vam)
17563 {
17564   vl_api_show_one_rloc_probe_state_t *mp;
17565   int ret;
17566
17567   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17568
17569   /* send */
17570   S (mp);
17571
17572   /* wait for reply */
17573   W (ret);
17574   return ret;
17575 }
17576
17577 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17578
17579 static int
17580 api_one_add_del_ndp_entry (vat_main_t * vam)
17581 {
17582   vl_api_one_add_del_ndp_entry_t *mp;
17583   unformat_input_t *input = vam->input;
17584   u8 is_add = 1;
17585   u8 mac_set = 0;
17586   u8 bd_set = 0;
17587   u8 ip_set = 0;
17588   u8 mac[6] = { 0, };
17589   u8 ip6[16] = { 0, };
17590   u32 bd = ~0;
17591   int ret;
17592
17593   /* Parse args required to build the message */
17594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17595     {
17596       if (unformat (input, "del"))
17597         is_add = 0;
17598       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17599         mac_set = 1;
17600       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17601         ip_set = 1;
17602       else if (unformat (input, "bd %d", &bd))
17603         bd_set = 1;
17604       else
17605         {
17606           errmsg ("parse error '%U'", format_unformat_error, input);
17607           return -99;
17608         }
17609     }
17610
17611   if (!bd_set || !ip_set || (!mac_set && is_add))
17612     {
17613       errmsg ("Missing BD, IP or MAC!");
17614       return -99;
17615     }
17616
17617   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17618   mp->is_add = is_add;
17619   clib_memcpy (mp->mac, mac, 6);
17620   mp->bd = clib_host_to_net_u32 (bd);
17621   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17622
17623   /* send */
17624   S (mp);
17625
17626   /* wait for reply */
17627   W (ret);
17628   return ret;
17629 }
17630
17631 static int
17632 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17633 {
17634   vl_api_one_add_del_l2_arp_entry_t *mp;
17635   unformat_input_t *input = vam->input;
17636   u8 is_add = 1;
17637   u8 mac_set = 0;
17638   u8 bd_set = 0;
17639   u8 ip_set = 0;
17640   u8 mac[6] = { 0, };
17641   u32 ip4 = 0, bd = ~0;
17642   int ret;
17643
17644   /* Parse args required to build the message */
17645   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17646     {
17647       if (unformat (input, "del"))
17648         is_add = 0;
17649       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17650         mac_set = 1;
17651       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17652         ip_set = 1;
17653       else if (unformat (input, "bd %d", &bd))
17654         bd_set = 1;
17655       else
17656         {
17657           errmsg ("parse error '%U'", format_unformat_error, input);
17658           return -99;
17659         }
17660     }
17661
17662   if (!bd_set || !ip_set || (!mac_set && is_add))
17663     {
17664       errmsg ("Missing BD, IP or MAC!");
17665       return -99;
17666     }
17667
17668   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17669   mp->is_add = is_add;
17670   clib_memcpy (mp->mac, mac, 6);
17671   mp->bd = clib_host_to_net_u32 (bd);
17672   mp->ip4 = ip4;
17673
17674   /* send */
17675   S (mp);
17676
17677   /* wait for reply */
17678   W (ret);
17679   return ret;
17680 }
17681
17682 static int
17683 api_one_ndp_bd_get (vat_main_t * vam)
17684 {
17685   vl_api_one_ndp_bd_get_t *mp;
17686   int ret;
17687
17688   M (ONE_NDP_BD_GET, mp);
17689
17690   /* send */
17691   S (mp);
17692
17693   /* wait for reply */
17694   W (ret);
17695   return ret;
17696 }
17697
17698 static int
17699 api_one_ndp_entries_get (vat_main_t * vam)
17700 {
17701   vl_api_one_ndp_entries_get_t *mp;
17702   unformat_input_t *input = vam->input;
17703   u8 bd_set = 0;
17704   u32 bd = ~0;
17705   int ret;
17706
17707   /* Parse args required to build the message */
17708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17709     {
17710       if (unformat (input, "bd %d", &bd))
17711         bd_set = 1;
17712       else
17713         {
17714           errmsg ("parse error '%U'", format_unformat_error, input);
17715           return -99;
17716         }
17717     }
17718
17719   if (!bd_set)
17720     {
17721       errmsg ("Expected bridge domain!");
17722       return -99;
17723     }
17724
17725   M (ONE_NDP_ENTRIES_GET, mp);
17726   mp->bd = clib_host_to_net_u32 (bd);
17727
17728   /* send */
17729   S (mp);
17730
17731   /* wait for reply */
17732   W (ret);
17733   return ret;
17734 }
17735
17736 static int
17737 api_one_l2_arp_bd_get (vat_main_t * vam)
17738 {
17739   vl_api_one_l2_arp_bd_get_t *mp;
17740   int ret;
17741
17742   M (ONE_L2_ARP_BD_GET, mp);
17743
17744   /* send */
17745   S (mp);
17746
17747   /* wait for reply */
17748   W (ret);
17749   return ret;
17750 }
17751
17752 static int
17753 api_one_l2_arp_entries_get (vat_main_t * vam)
17754 {
17755   vl_api_one_l2_arp_entries_get_t *mp;
17756   unformat_input_t *input = vam->input;
17757   u8 bd_set = 0;
17758   u32 bd = ~0;
17759   int ret;
17760
17761   /* Parse args required to build the message */
17762   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17763     {
17764       if (unformat (input, "bd %d", &bd))
17765         bd_set = 1;
17766       else
17767         {
17768           errmsg ("parse error '%U'", format_unformat_error, input);
17769           return -99;
17770         }
17771     }
17772
17773   if (!bd_set)
17774     {
17775       errmsg ("Expected bridge domain!");
17776       return -99;
17777     }
17778
17779   M (ONE_L2_ARP_ENTRIES_GET, mp);
17780   mp->bd = clib_host_to_net_u32 (bd);
17781
17782   /* send */
17783   S (mp);
17784
17785   /* wait for reply */
17786   W (ret);
17787   return ret;
17788 }
17789
17790 static int
17791 api_one_stats_enable_disable (vat_main_t * vam)
17792 {
17793   vl_api_one_stats_enable_disable_t *mp;
17794   unformat_input_t *input = vam->input;
17795   u8 is_set = 0;
17796   u8 is_en = 0;
17797   int ret;
17798
17799   /* Parse args required to build the message */
17800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17801     {
17802       if (unformat (input, "enable"))
17803         {
17804           is_set = 1;
17805           is_en = 1;
17806         }
17807       else if (unformat (input, "disable"))
17808         {
17809           is_set = 1;
17810         }
17811       else
17812         break;
17813     }
17814
17815   if (!is_set)
17816     {
17817       errmsg ("Value not set");
17818       return -99;
17819     }
17820
17821   M (ONE_STATS_ENABLE_DISABLE, mp);
17822   mp->is_en = is_en;
17823
17824   /* send */
17825   S (mp);
17826
17827   /* wait for reply */
17828   W (ret);
17829   return ret;
17830 }
17831
17832 static int
17833 api_show_one_stats_enable_disable (vat_main_t * vam)
17834 {
17835   vl_api_show_one_stats_enable_disable_t *mp;
17836   int ret;
17837
17838   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17839
17840   /* send */
17841   S (mp);
17842
17843   /* wait for reply */
17844   W (ret);
17845   return ret;
17846 }
17847
17848 static int
17849 api_show_one_map_request_mode (vat_main_t * vam)
17850 {
17851   vl_api_show_one_map_request_mode_t *mp;
17852   int ret;
17853
17854   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17855
17856   /* send */
17857   S (mp);
17858
17859   /* wait for reply */
17860   W (ret);
17861   return ret;
17862 }
17863
17864 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17865
17866 static int
17867 api_one_map_request_mode (vat_main_t * vam)
17868 {
17869   unformat_input_t *input = vam->input;
17870   vl_api_one_map_request_mode_t *mp;
17871   u8 mode = 0;
17872   int ret;
17873
17874   /* Parse args required to build the message */
17875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17876     {
17877       if (unformat (input, "dst-only"))
17878         mode = 0;
17879       else if (unformat (input, "src-dst"))
17880         mode = 1;
17881       else
17882         {
17883           errmsg ("parse error '%U'", format_unformat_error, input);
17884           return -99;
17885         }
17886     }
17887
17888   M (ONE_MAP_REQUEST_MODE, mp);
17889
17890   mp->mode = mode;
17891
17892   /* send */
17893   S (mp);
17894
17895   /* wait for reply */
17896   W (ret);
17897   return ret;
17898 }
17899
17900 #define api_lisp_map_request_mode api_one_map_request_mode
17901
17902 /**
17903  * Enable/disable ONE proxy ITR.
17904  *
17905  * @param vam vpp API test context
17906  * @return return code
17907  */
17908 static int
17909 api_one_pitr_set_locator_set (vat_main_t * vam)
17910 {
17911   u8 ls_name_set = 0;
17912   unformat_input_t *input = vam->input;
17913   vl_api_one_pitr_set_locator_set_t *mp;
17914   u8 is_add = 1;
17915   u8 *ls_name = 0;
17916   int ret;
17917
17918   /* Parse args required to build the message */
17919   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17920     {
17921       if (unformat (input, "del"))
17922         is_add = 0;
17923       else if (unformat (input, "locator-set %s", &ls_name))
17924         ls_name_set = 1;
17925       else
17926         {
17927           errmsg ("parse error '%U'", format_unformat_error, input);
17928           return -99;
17929         }
17930     }
17931
17932   if (!ls_name_set)
17933     {
17934       errmsg ("locator-set name not set!");
17935       return -99;
17936     }
17937
17938   M (ONE_PITR_SET_LOCATOR_SET, mp);
17939
17940   mp->is_add = is_add;
17941   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17942   vec_free (ls_name);
17943
17944   /* send */
17945   S (mp);
17946
17947   /* wait for reply */
17948   W (ret);
17949   return ret;
17950 }
17951
17952 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17953
17954 static int
17955 api_one_nsh_set_locator_set (vat_main_t * vam)
17956 {
17957   u8 ls_name_set = 0;
17958   unformat_input_t *input = vam->input;
17959   vl_api_one_nsh_set_locator_set_t *mp;
17960   u8 is_add = 1;
17961   u8 *ls_name = 0;
17962   int ret;
17963
17964   /* Parse args required to build the message */
17965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17966     {
17967       if (unformat (input, "del"))
17968         is_add = 0;
17969       else if (unformat (input, "ls %s", &ls_name))
17970         ls_name_set = 1;
17971       else
17972         {
17973           errmsg ("parse error '%U'", format_unformat_error, input);
17974           return -99;
17975         }
17976     }
17977
17978   if (!ls_name_set && is_add)
17979     {
17980       errmsg ("locator-set name not set!");
17981       return -99;
17982     }
17983
17984   M (ONE_NSH_SET_LOCATOR_SET, mp);
17985
17986   mp->is_add = is_add;
17987   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17988   vec_free (ls_name);
17989
17990   /* send */
17991   S (mp);
17992
17993   /* wait for reply */
17994   W (ret);
17995   return ret;
17996 }
17997
17998 static int
17999 api_show_one_pitr (vat_main_t * vam)
18000 {
18001   vl_api_show_one_pitr_t *mp;
18002   int ret;
18003
18004   if (!vam->json_output)
18005     {
18006       print (vam->ofp, "%=20s", "lisp status:");
18007     }
18008
18009   M (SHOW_ONE_PITR, mp);
18010   /* send it... */
18011   S (mp);
18012
18013   /* Wait for a reply... */
18014   W (ret);
18015   return ret;
18016 }
18017
18018 #define api_show_lisp_pitr api_show_one_pitr
18019
18020 static int
18021 api_one_use_petr (vat_main_t * vam)
18022 {
18023   unformat_input_t *input = vam->input;
18024   vl_api_one_use_petr_t *mp;
18025   u8 is_add = 0;
18026   ip_address_t ip;
18027   int ret;
18028
18029   memset (&ip, 0, sizeof (ip));
18030
18031   /* Parse args required to build the message */
18032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18033     {
18034       if (unformat (input, "disable"))
18035         is_add = 0;
18036       else
18037         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18038         {
18039           is_add = 1;
18040           ip_addr_version (&ip) = IP4;
18041         }
18042       else
18043         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18044         {
18045           is_add = 1;
18046           ip_addr_version (&ip) = IP6;
18047         }
18048       else
18049         {
18050           errmsg ("parse error '%U'", format_unformat_error, input);
18051           return -99;
18052         }
18053     }
18054
18055   M (ONE_USE_PETR, mp);
18056
18057   mp->is_add = is_add;
18058   if (is_add)
18059     {
18060       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18061       if (mp->is_ip4)
18062         clib_memcpy (mp->address, &ip, 4);
18063       else
18064         clib_memcpy (mp->address, &ip, 16);
18065     }
18066
18067   /* send */
18068   S (mp);
18069
18070   /* wait for reply */
18071   W (ret);
18072   return ret;
18073 }
18074
18075 #define api_lisp_use_petr api_one_use_petr
18076
18077 static int
18078 api_show_one_nsh_mapping (vat_main_t * vam)
18079 {
18080   vl_api_show_one_use_petr_t *mp;
18081   int ret;
18082
18083   if (!vam->json_output)
18084     {
18085       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18086     }
18087
18088   M (SHOW_ONE_NSH_MAPPING, mp);
18089   /* send it... */
18090   S (mp);
18091
18092   /* Wait for a reply... */
18093   W (ret);
18094   return ret;
18095 }
18096
18097 static int
18098 api_show_one_use_petr (vat_main_t * vam)
18099 {
18100   vl_api_show_one_use_petr_t *mp;
18101   int ret;
18102
18103   if (!vam->json_output)
18104     {
18105       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18106     }
18107
18108   M (SHOW_ONE_USE_PETR, mp);
18109   /* send it... */
18110   S (mp);
18111
18112   /* Wait for a reply... */
18113   W (ret);
18114   return ret;
18115 }
18116
18117 #define api_show_lisp_use_petr api_show_one_use_petr
18118
18119 /**
18120  * Add/delete mapping between vni and vrf
18121  */
18122 static int
18123 api_one_eid_table_add_del_map (vat_main_t * vam)
18124 {
18125   unformat_input_t *input = vam->input;
18126   vl_api_one_eid_table_add_del_map_t *mp;
18127   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18128   u32 vni, vrf, bd_index;
18129   int ret;
18130
18131   /* Parse args required to build the message */
18132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18133     {
18134       if (unformat (input, "del"))
18135         is_add = 0;
18136       else if (unformat (input, "vrf %d", &vrf))
18137         vrf_set = 1;
18138       else if (unformat (input, "bd_index %d", &bd_index))
18139         bd_index_set = 1;
18140       else if (unformat (input, "vni %d", &vni))
18141         vni_set = 1;
18142       else
18143         break;
18144     }
18145
18146   if (!vni_set || (!vrf_set && !bd_index_set))
18147     {
18148       errmsg ("missing arguments!");
18149       return -99;
18150     }
18151
18152   if (vrf_set && bd_index_set)
18153     {
18154       errmsg ("error: both vrf and bd entered!");
18155       return -99;
18156     }
18157
18158   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18159
18160   mp->is_add = is_add;
18161   mp->vni = htonl (vni);
18162   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18163   mp->is_l2 = bd_index_set;
18164
18165   /* send */
18166   S (mp);
18167
18168   /* wait for reply */
18169   W (ret);
18170   return ret;
18171 }
18172
18173 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18174
18175 uword
18176 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18177 {
18178   u32 *action = va_arg (*args, u32 *);
18179   u8 *s = 0;
18180
18181   if (unformat (input, "%s", &s))
18182     {
18183       if (!strcmp ((char *) s, "no-action"))
18184         action[0] = 0;
18185       else if (!strcmp ((char *) s, "natively-forward"))
18186         action[0] = 1;
18187       else if (!strcmp ((char *) s, "send-map-request"))
18188         action[0] = 2;
18189       else if (!strcmp ((char *) s, "drop"))
18190         action[0] = 3;
18191       else
18192         {
18193           clib_warning ("invalid action: '%s'", s);
18194           action[0] = 3;
18195         }
18196     }
18197   else
18198     return 0;
18199
18200   vec_free (s);
18201   return 1;
18202 }
18203
18204 /**
18205  * Add/del remote mapping to/from ONE control plane
18206  *
18207  * @param vam vpp API test context
18208  * @return return code
18209  */
18210 static int
18211 api_one_add_del_remote_mapping (vat_main_t * vam)
18212 {
18213   unformat_input_t *input = vam->input;
18214   vl_api_one_add_del_remote_mapping_t *mp;
18215   u32 vni = 0;
18216   lisp_eid_vat_t _eid, *eid = &_eid;
18217   lisp_eid_vat_t _seid, *seid = &_seid;
18218   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18219   u32 action = ~0, p, w, data_len;
18220   ip4_address_t rloc4;
18221   ip6_address_t rloc6;
18222   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18223   int ret;
18224
18225   memset (&rloc, 0, sizeof (rloc));
18226
18227   /* Parse args required to build the message */
18228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18229     {
18230       if (unformat (input, "del-all"))
18231         {
18232           del_all = 1;
18233         }
18234       else if (unformat (input, "del"))
18235         {
18236           is_add = 0;
18237         }
18238       else if (unformat (input, "add"))
18239         {
18240           is_add = 1;
18241         }
18242       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18243         {
18244           eid_set = 1;
18245         }
18246       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18247         {
18248           seid_set = 1;
18249         }
18250       else if (unformat (input, "vni %d", &vni))
18251         {
18252           ;
18253         }
18254       else if (unformat (input, "p %d w %d", &p, &w))
18255         {
18256           if (!curr_rloc)
18257             {
18258               errmsg ("No RLOC configured for setting priority/weight!");
18259               return -99;
18260             }
18261           curr_rloc->priority = p;
18262           curr_rloc->weight = w;
18263         }
18264       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18265         {
18266           rloc.is_ip4 = 1;
18267           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18268           vec_add1 (rlocs, rloc);
18269           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18270         }
18271       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18272         {
18273           rloc.is_ip4 = 0;
18274           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18275           vec_add1 (rlocs, rloc);
18276           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18277         }
18278       else if (unformat (input, "action %U",
18279                          unformat_negative_mapping_action, &action))
18280         {
18281           ;
18282         }
18283       else
18284         {
18285           clib_warning ("parse error '%U'", format_unformat_error, input);
18286           return -99;
18287         }
18288     }
18289
18290   if (0 == eid_set)
18291     {
18292       errmsg ("missing params!");
18293       return -99;
18294     }
18295
18296   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18297     {
18298       errmsg ("no action set for negative map-reply!");
18299       return -99;
18300     }
18301
18302   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18303
18304   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18305   mp->is_add = is_add;
18306   mp->vni = htonl (vni);
18307   mp->action = (u8) action;
18308   mp->is_src_dst = seid_set;
18309   mp->eid_len = eid->len;
18310   mp->seid_len = seid->len;
18311   mp->del_all = del_all;
18312   mp->eid_type = eid->type;
18313   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18314   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18315
18316   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18317   clib_memcpy (mp->rlocs, rlocs, data_len);
18318   vec_free (rlocs);
18319
18320   /* send it... */
18321   S (mp);
18322
18323   /* Wait for a reply... */
18324   W (ret);
18325   return ret;
18326 }
18327
18328 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18329
18330 /**
18331  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18332  * forwarding entries in data-plane accordingly.
18333  *
18334  * @param vam vpp API test context
18335  * @return return code
18336  */
18337 static int
18338 api_one_add_del_adjacency (vat_main_t * vam)
18339 {
18340   unformat_input_t *input = vam->input;
18341   vl_api_one_add_del_adjacency_t *mp;
18342   u32 vni = 0;
18343   ip4_address_t leid4, reid4;
18344   ip6_address_t leid6, reid6;
18345   u8 reid_mac[6] = { 0 };
18346   u8 leid_mac[6] = { 0 };
18347   u8 reid_type, leid_type;
18348   u32 leid_len = 0, reid_len = 0, len;
18349   u8 is_add = 1;
18350   int ret;
18351
18352   leid_type = reid_type = (u8) ~ 0;
18353
18354   /* Parse args required to build the message */
18355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18356     {
18357       if (unformat (input, "del"))
18358         {
18359           is_add = 0;
18360         }
18361       else if (unformat (input, "add"))
18362         {
18363           is_add = 1;
18364         }
18365       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18366                          &reid4, &len))
18367         {
18368           reid_type = 0;        /* ipv4 */
18369           reid_len = len;
18370         }
18371       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18372                          &reid6, &len))
18373         {
18374           reid_type = 1;        /* ipv6 */
18375           reid_len = len;
18376         }
18377       else if (unformat (input, "reid %U", unformat_ethernet_address,
18378                          reid_mac))
18379         {
18380           reid_type = 2;        /* mac */
18381         }
18382       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18383                          &leid4, &len))
18384         {
18385           leid_type = 0;        /* ipv4 */
18386           leid_len = len;
18387         }
18388       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18389                          &leid6, &len))
18390         {
18391           leid_type = 1;        /* ipv6 */
18392           leid_len = len;
18393         }
18394       else if (unformat (input, "leid %U", unformat_ethernet_address,
18395                          leid_mac))
18396         {
18397           leid_type = 2;        /* mac */
18398         }
18399       else if (unformat (input, "vni %d", &vni))
18400         {
18401           ;
18402         }
18403       else
18404         {
18405           errmsg ("parse error '%U'", format_unformat_error, input);
18406           return -99;
18407         }
18408     }
18409
18410   if ((u8) ~ 0 == reid_type)
18411     {
18412       errmsg ("missing params!");
18413       return -99;
18414     }
18415
18416   if (leid_type != reid_type)
18417     {
18418       errmsg ("remote and local EIDs are of different types!");
18419       return -99;
18420     }
18421
18422   M (ONE_ADD_DEL_ADJACENCY, mp);
18423   mp->is_add = is_add;
18424   mp->vni = htonl (vni);
18425   mp->leid_len = leid_len;
18426   mp->reid_len = reid_len;
18427   mp->eid_type = reid_type;
18428
18429   switch (mp->eid_type)
18430     {
18431     case 0:
18432       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18433       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18434       break;
18435     case 1:
18436       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18437       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18438       break;
18439     case 2:
18440       clib_memcpy (mp->leid, leid_mac, 6);
18441       clib_memcpy (mp->reid, reid_mac, 6);
18442       break;
18443     default:
18444       errmsg ("unknown EID type %d!", mp->eid_type);
18445       return 0;
18446     }
18447
18448   /* send it... */
18449   S (mp);
18450
18451   /* Wait for a reply... */
18452   W (ret);
18453   return ret;
18454 }
18455
18456 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18457
18458 uword
18459 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18460 {
18461   u32 *mode = va_arg (*args, u32 *);
18462
18463   if (unformat (input, "lisp"))
18464     *mode = 0;
18465   else if (unformat (input, "vxlan"))
18466     *mode = 1;
18467   else
18468     return 0;
18469
18470   return 1;
18471 }
18472
18473 static int
18474 api_gpe_get_encap_mode (vat_main_t * vam)
18475 {
18476   vl_api_gpe_get_encap_mode_t *mp;
18477   int ret;
18478
18479   /* Construct the API message */
18480   M (GPE_GET_ENCAP_MODE, mp);
18481
18482   /* send it... */
18483   S (mp);
18484
18485   /* Wait for a reply... */
18486   W (ret);
18487   return ret;
18488 }
18489
18490 static int
18491 api_gpe_set_encap_mode (vat_main_t * vam)
18492 {
18493   unformat_input_t *input = vam->input;
18494   vl_api_gpe_set_encap_mode_t *mp;
18495   int ret;
18496   u32 mode = 0;
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", unformat_gpe_encap_mode, &mode))
18502         ;
18503       else
18504         break;
18505     }
18506
18507   /* Construct the API message */
18508   M (GPE_SET_ENCAP_MODE, mp);
18509
18510   mp->mode = mode;
18511
18512   /* send it... */
18513   S (mp);
18514
18515   /* Wait for a reply... */
18516   W (ret);
18517   return ret;
18518 }
18519
18520 static int
18521 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18522 {
18523   unformat_input_t *input = vam->input;
18524   vl_api_gpe_add_del_iface_t *mp;
18525   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18526   u32 dp_table = 0, vni = 0;
18527   int ret;
18528
18529   /* Parse args required to build the message */
18530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18531     {
18532       if (unformat (input, "up"))
18533         {
18534           action_set = 1;
18535           is_add = 1;
18536         }
18537       else if (unformat (input, "down"))
18538         {
18539           action_set = 1;
18540           is_add = 0;
18541         }
18542       else if (unformat (input, "table_id %d", &dp_table))
18543         {
18544           dp_table_set = 1;
18545         }
18546       else if (unformat (input, "bd_id %d", &dp_table))
18547         {
18548           dp_table_set = 1;
18549           is_l2 = 1;
18550         }
18551       else if (unformat (input, "vni %d", &vni))
18552         {
18553           vni_set = 1;
18554         }
18555       else
18556         break;
18557     }
18558
18559   if (action_set == 0)
18560     {
18561       errmsg ("Action not set");
18562       return -99;
18563     }
18564   if (dp_table_set == 0 || vni_set == 0)
18565     {
18566       errmsg ("vni and dp_table must be set");
18567       return -99;
18568     }
18569
18570   /* Construct the API message */
18571   M (GPE_ADD_DEL_IFACE, mp);
18572
18573   mp->is_add = is_add;
18574   mp->dp_table = clib_host_to_net_u32 (dp_table);
18575   mp->is_l2 = is_l2;
18576   mp->vni = clib_host_to_net_u32 (vni);
18577
18578   /* send it... */
18579   S (mp);
18580
18581   /* Wait for a reply... */
18582   W (ret);
18583   return ret;
18584 }
18585
18586 static int
18587 api_one_map_register_fallback_threshold (vat_main_t * vam)
18588 {
18589   unformat_input_t *input = vam->input;
18590   vl_api_one_map_register_fallback_threshold_t *mp;
18591   u32 value = 0;
18592   u8 is_set = 0;
18593   int ret;
18594
18595   /* Parse args required to build the message */
18596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18597     {
18598       if (unformat (input, "%u", &value))
18599         is_set = 1;
18600       else
18601         {
18602           clib_warning ("parse error '%U'", format_unformat_error, input);
18603           return -99;
18604         }
18605     }
18606
18607   if (!is_set)
18608     {
18609       errmsg ("fallback threshold value is missing!");
18610       return -99;
18611     }
18612
18613   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18614   mp->value = clib_host_to_net_u32 (value);
18615
18616   /* send it... */
18617   S (mp);
18618
18619   /* Wait for a reply... */
18620   W (ret);
18621   return ret;
18622 }
18623
18624 static int
18625 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18626 {
18627   vl_api_show_one_map_register_fallback_threshold_t *mp;
18628   int ret;
18629
18630   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18631
18632   /* send it... */
18633   S (mp);
18634
18635   /* Wait for a reply... */
18636   W (ret);
18637   return ret;
18638 }
18639
18640 uword
18641 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18642 {
18643   u32 *proto = va_arg (*args, u32 *);
18644
18645   if (unformat (input, "udp"))
18646     *proto = 1;
18647   else if (unformat (input, "api"))
18648     *proto = 2;
18649   else
18650     return 0;
18651
18652   return 1;
18653 }
18654
18655 static int
18656 api_one_set_transport_protocol (vat_main_t * vam)
18657 {
18658   unformat_input_t *input = vam->input;
18659   vl_api_one_set_transport_protocol_t *mp;
18660   u8 is_set = 0;
18661   u32 protocol = 0;
18662   int ret;
18663
18664   /* Parse args required to build the message */
18665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18666     {
18667       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18668         is_set = 1;
18669       else
18670         {
18671           clib_warning ("parse error '%U'", format_unformat_error, input);
18672           return -99;
18673         }
18674     }
18675
18676   if (!is_set)
18677     {
18678       errmsg ("Transport protocol missing!");
18679       return -99;
18680     }
18681
18682   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18683   mp->protocol = (u8) protocol;
18684
18685   /* send it... */
18686   S (mp);
18687
18688   /* Wait for a reply... */
18689   W (ret);
18690   return ret;
18691 }
18692
18693 static int
18694 api_one_get_transport_protocol (vat_main_t * vam)
18695 {
18696   vl_api_one_get_transport_protocol_t *mp;
18697   int ret;
18698
18699   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18700
18701   /* send it... */
18702   S (mp);
18703
18704   /* Wait for a reply... */
18705   W (ret);
18706   return ret;
18707 }
18708
18709 static int
18710 api_one_map_register_set_ttl (vat_main_t * vam)
18711 {
18712   unformat_input_t *input = vam->input;
18713   vl_api_one_map_register_set_ttl_t *mp;
18714   u32 ttl = 0;
18715   u8 is_set = 0;
18716   int ret;
18717
18718   /* Parse args required to build the message */
18719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18720     {
18721       if (unformat (input, "%u", &ttl))
18722         is_set = 1;
18723       else
18724         {
18725           clib_warning ("parse error '%U'", format_unformat_error, input);
18726           return -99;
18727         }
18728     }
18729
18730   if (!is_set)
18731     {
18732       errmsg ("TTL value missing!");
18733       return -99;
18734     }
18735
18736   M (ONE_MAP_REGISTER_SET_TTL, mp);
18737   mp->ttl = clib_host_to_net_u32 (ttl);
18738
18739   /* send it... */
18740   S (mp);
18741
18742   /* Wait for a reply... */
18743   W (ret);
18744   return ret;
18745 }
18746
18747 static int
18748 api_show_one_map_register_ttl (vat_main_t * vam)
18749 {
18750   vl_api_show_one_map_register_ttl_t *mp;
18751   int ret;
18752
18753   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18754
18755   /* send it... */
18756   S (mp);
18757
18758   /* Wait for a reply... */
18759   W (ret);
18760   return ret;
18761 }
18762
18763 /**
18764  * Add/del map request itr rlocs from ONE control plane and updates
18765  *
18766  * @param vam vpp API test context
18767  * @return return code
18768  */
18769 static int
18770 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18771 {
18772   unformat_input_t *input = vam->input;
18773   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18774   u8 *locator_set_name = 0;
18775   u8 locator_set_name_set = 0;
18776   u8 is_add = 1;
18777   int ret;
18778
18779   /* Parse args required to build the message */
18780   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18781     {
18782       if (unformat (input, "del"))
18783         {
18784           is_add = 0;
18785         }
18786       else if (unformat (input, "%_%v%_", &locator_set_name))
18787         {
18788           locator_set_name_set = 1;
18789         }
18790       else
18791         {
18792           clib_warning ("parse error '%U'", format_unformat_error, input);
18793           return -99;
18794         }
18795     }
18796
18797   if (is_add && !locator_set_name_set)
18798     {
18799       errmsg ("itr-rloc is not set!");
18800       return -99;
18801     }
18802
18803   if (is_add && vec_len (locator_set_name) > 64)
18804     {
18805       errmsg ("itr-rloc locator-set name too long");
18806       vec_free (locator_set_name);
18807       return -99;
18808     }
18809
18810   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18811   mp->is_add = is_add;
18812   if (is_add)
18813     {
18814       clib_memcpy (mp->locator_set_name, locator_set_name,
18815                    vec_len (locator_set_name));
18816     }
18817   else
18818     {
18819       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18820     }
18821   vec_free (locator_set_name);
18822
18823   /* send it... */
18824   S (mp);
18825
18826   /* Wait for a reply... */
18827   W (ret);
18828   return ret;
18829 }
18830
18831 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18832
18833 static int
18834 api_one_locator_dump (vat_main_t * vam)
18835 {
18836   unformat_input_t *input = vam->input;
18837   vl_api_one_locator_dump_t *mp;
18838   vl_api_control_ping_t *mp_ping;
18839   u8 is_index_set = 0, is_name_set = 0;
18840   u8 *ls_name = 0;
18841   u32 ls_index = ~0;
18842   int ret;
18843
18844   /* Parse args required to build the message */
18845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18846     {
18847       if (unformat (input, "ls_name %_%v%_", &ls_name))
18848         {
18849           is_name_set = 1;
18850         }
18851       else if (unformat (input, "ls_index %d", &ls_index))
18852         {
18853           is_index_set = 1;
18854         }
18855       else
18856         {
18857           errmsg ("parse error '%U'", format_unformat_error, input);
18858           return -99;
18859         }
18860     }
18861
18862   if (!is_index_set && !is_name_set)
18863     {
18864       errmsg ("error: expected one of index or name!");
18865       return -99;
18866     }
18867
18868   if (is_index_set && is_name_set)
18869     {
18870       errmsg ("error: only one param expected!");
18871       return -99;
18872     }
18873
18874   if (vec_len (ls_name) > 62)
18875     {
18876       errmsg ("error: locator set name too long!");
18877       return -99;
18878     }
18879
18880   if (!vam->json_output)
18881     {
18882       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18883     }
18884
18885   M (ONE_LOCATOR_DUMP, mp);
18886   mp->is_index_set = is_index_set;
18887
18888   if (is_index_set)
18889     mp->ls_index = clib_host_to_net_u32 (ls_index);
18890   else
18891     {
18892       vec_add1 (ls_name, 0);
18893       strncpy ((char *) mp->ls_name, (char *) ls_name,
18894                sizeof (mp->ls_name) - 1);
18895     }
18896
18897   /* send it... */
18898   S (mp);
18899
18900   /* Use a control ping for synchronization */
18901   MPING (CONTROL_PING, mp_ping);
18902   S (mp_ping);
18903
18904   /* Wait for a reply... */
18905   W (ret);
18906   return ret;
18907 }
18908
18909 #define api_lisp_locator_dump api_one_locator_dump
18910
18911 static int
18912 api_one_locator_set_dump (vat_main_t * vam)
18913 {
18914   vl_api_one_locator_set_dump_t *mp;
18915   vl_api_control_ping_t *mp_ping;
18916   unformat_input_t *input = vam->input;
18917   u8 filter = 0;
18918   int ret;
18919
18920   /* Parse args required to build the message */
18921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18922     {
18923       if (unformat (input, "local"))
18924         {
18925           filter = 1;
18926         }
18927       else if (unformat (input, "remote"))
18928         {
18929           filter = 2;
18930         }
18931       else
18932         {
18933           errmsg ("parse error '%U'", format_unformat_error, input);
18934           return -99;
18935         }
18936     }
18937
18938   if (!vam->json_output)
18939     {
18940       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18941     }
18942
18943   M (ONE_LOCATOR_SET_DUMP, mp);
18944
18945   mp->filter = filter;
18946
18947   /* send it... */
18948   S (mp);
18949
18950   /* Use a control ping for synchronization */
18951   MPING (CONTROL_PING, mp_ping);
18952   S (mp_ping);
18953
18954   /* Wait for a reply... */
18955   W (ret);
18956   return ret;
18957 }
18958
18959 #define api_lisp_locator_set_dump api_one_locator_set_dump
18960
18961 static int
18962 api_one_eid_table_map_dump (vat_main_t * vam)
18963 {
18964   u8 is_l2 = 0;
18965   u8 mode_set = 0;
18966   unformat_input_t *input = vam->input;
18967   vl_api_one_eid_table_map_dump_t *mp;
18968   vl_api_control_ping_t *mp_ping;
18969   int ret;
18970
18971   /* Parse args required to build the message */
18972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18973     {
18974       if (unformat (input, "l2"))
18975         {
18976           is_l2 = 1;
18977           mode_set = 1;
18978         }
18979       else if (unformat (input, "l3"))
18980         {
18981           is_l2 = 0;
18982           mode_set = 1;
18983         }
18984       else
18985         {
18986           errmsg ("parse error '%U'", format_unformat_error, input);
18987           return -99;
18988         }
18989     }
18990
18991   if (!mode_set)
18992     {
18993       errmsg ("expected one of 'l2' or 'l3' parameter!");
18994       return -99;
18995     }
18996
18997   if (!vam->json_output)
18998     {
18999       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19000     }
19001
19002   M (ONE_EID_TABLE_MAP_DUMP, mp);
19003   mp->is_l2 = is_l2;
19004
19005   /* send it... */
19006   S (mp);
19007
19008   /* Use a control ping for synchronization */
19009   MPING (CONTROL_PING, mp_ping);
19010   S (mp_ping);
19011
19012   /* Wait for a reply... */
19013   W (ret);
19014   return ret;
19015 }
19016
19017 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19018
19019 static int
19020 api_one_eid_table_vni_dump (vat_main_t * vam)
19021 {
19022   vl_api_one_eid_table_vni_dump_t *mp;
19023   vl_api_control_ping_t *mp_ping;
19024   int ret;
19025
19026   if (!vam->json_output)
19027     {
19028       print (vam->ofp, "VNI");
19029     }
19030
19031   M (ONE_EID_TABLE_VNI_DUMP, mp);
19032
19033   /* send it... */
19034   S (mp);
19035
19036   /* Use a control ping for synchronization */
19037   MPING (CONTROL_PING, mp_ping);
19038   S (mp_ping);
19039
19040   /* Wait for a reply... */
19041   W (ret);
19042   return ret;
19043 }
19044
19045 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19046
19047 static int
19048 api_one_eid_table_dump (vat_main_t * vam)
19049 {
19050   unformat_input_t *i = vam->input;
19051   vl_api_one_eid_table_dump_t *mp;
19052   vl_api_control_ping_t *mp_ping;
19053   struct in_addr ip4;
19054   struct in6_addr ip6;
19055   u8 mac[6];
19056   u8 eid_type = ~0, eid_set = 0;
19057   u32 prefix_length = ~0, t, vni = 0;
19058   u8 filter = 0;
19059   int ret;
19060   lisp_nsh_api_t nsh;
19061
19062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19063     {
19064       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19065         {
19066           eid_set = 1;
19067           eid_type = 0;
19068           prefix_length = t;
19069         }
19070       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19071         {
19072           eid_set = 1;
19073           eid_type = 1;
19074           prefix_length = t;
19075         }
19076       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19077         {
19078           eid_set = 1;
19079           eid_type = 2;
19080         }
19081       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19082         {
19083           eid_set = 1;
19084           eid_type = 3;
19085         }
19086       else if (unformat (i, "vni %d", &t))
19087         {
19088           vni = t;
19089         }
19090       else if (unformat (i, "local"))
19091         {
19092           filter = 1;
19093         }
19094       else if (unformat (i, "remote"))
19095         {
19096           filter = 2;
19097         }
19098       else
19099         {
19100           errmsg ("parse error '%U'", format_unformat_error, i);
19101           return -99;
19102         }
19103     }
19104
19105   if (!vam->json_output)
19106     {
19107       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19108              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19109     }
19110
19111   M (ONE_EID_TABLE_DUMP, mp);
19112
19113   mp->filter = filter;
19114   if (eid_set)
19115     {
19116       mp->eid_set = 1;
19117       mp->vni = htonl (vni);
19118       mp->eid_type = eid_type;
19119       switch (eid_type)
19120         {
19121         case 0:
19122           mp->prefix_length = prefix_length;
19123           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19124           break;
19125         case 1:
19126           mp->prefix_length = prefix_length;
19127           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19128           break;
19129         case 2:
19130           clib_memcpy (mp->eid, mac, sizeof (mac));
19131           break;
19132         case 3:
19133           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19134           break;
19135         default:
19136           errmsg ("unknown EID type %d!", eid_type);
19137           return -99;
19138         }
19139     }
19140
19141   /* send it... */
19142   S (mp);
19143
19144   /* Use a control ping for synchronization */
19145   MPING (CONTROL_PING, mp_ping);
19146   S (mp_ping);
19147
19148   /* Wait for a reply... */
19149   W (ret);
19150   return ret;
19151 }
19152
19153 #define api_lisp_eid_table_dump api_one_eid_table_dump
19154
19155 static int
19156 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19157 {
19158   unformat_input_t *i = vam->input;
19159   vl_api_gpe_fwd_entries_get_t *mp;
19160   u8 vni_set = 0;
19161   u32 vni = ~0;
19162   int ret;
19163
19164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19165     {
19166       if (unformat (i, "vni %d", &vni))
19167         {
19168           vni_set = 1;
19169         }
19170       else
19171         {
19172           errmsg ("parse error '%U'", format_unformat_error, i);
19173           return -99;
19174         }
19175     }
19176
19177   if (!vni_set)
19178     {
19179       errmsg ("vni not set!");
19180       return -99;
19181     }
19182
19183   if (!vam->json_output)
19184     {
19185       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19186              "leid", "reid");
19187     }
19188
19189   M (GPE_FWD_ENTRIES_GET, mp);
19190   mp->vni = clib_host_to_net_u32 (vni);
19191
19192   /* send it... */
19193   S (mp);
19194
19195   /* Wait for a reply... */
19196   W (ret);
19197   return ret;
19198 }
19199
19200 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19201 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19202 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19203 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19204 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19205 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19206 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19207 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19208
19209 static int
19210 api_one_adjacencies_get (vat_main_t * vam)
19211 {
19212   unformat_input_t *i = vam->input;
19213   vl_api_one_adjacencies_get_t *mp;
19214   u8 vni_set = 0;
19215   u32 vni = ~0;
19216   int ret;
19217
19218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19219     {
19220       if (unformat (i, "vni %d", &vni))
19221         {
19222           vni_set = 1;
19223         }
19224       else
19225         {
19226           errmsg ("parse error '%U'", format_unformat_error, i);
19227           return -99;
19228         }
19229     }
19230
19231   if (!vni_set)
19232     {
19233       errmsg ("vni not set!");
19234       return -99;
19235     }
19236
19237   if (!vam->json_output)
19238     {
19239       print (vam->ofp, "%s %40s", "leid", "reid");
19240     }
19241
19242   M (ONE_ADJACENCIES_GET, mp);
19243   mp->vni = clib_host_to_net_u32 (vni);
19244
19245   /* send it... */
19246   S (mp);
19247
19248   /* Wait for a reply... */
19249   W (ret);
19250   return ret;
19251 }
19252
19253 #define api_lisp_adjacencies_get api_one_adjacencies_get
19254
19255 static int
19256 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19257 {
19258   unformat_input_t *i = vam->input;
19259   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19260   int ret;
19261   u8 ip_family_set = 0, is_ip4 = 1;
19262
19263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19264     {
19265       if (unformat (i, "ip4"))
19266         {
19267           ip_family_set = 1;
19268           is_ip4 = 1;
19269         }
19270       else if (unformat (i, "ip6"))
19271         {
19272           ip_family_set = 1;
19273           is_ip4 = 0;
19274         }
19275       else
19276         {
19277           errmsg ("parse error '%U'", format_unformat_error, i);
19278           return -99;
19279         }
19280     }
19281
19282   if (!ip_family_set)
19283     {
19284       errmsg ("ip family not set!");
19285       return -99;
19286     }
19287
19288   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19289   mp->is_ip4 = is_ip4;
19290
19291   /* send it... */
19292   S (mp);
19293
19294   /* Wait for a reply... */
19295   W (ret);
19296   return ret;
19297 }
19298
19299 static int
19300 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19301 {
19302   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19303   int ret;
19304
19305   if (!vam->json_output)
19306     {
19307       print (vam->ofp, "VNIs");
19308     }
19309
19310   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19311
19312   /* send it... */
19313   S (mp);
19314
19315   /* Wait for a reply... */
19316   W (ret);
19317   return ret;
19318 }
19319
19320 static int
19321 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19322 {
19323   unformat_input_t *i = vam->input;
19324   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19325   int ret = 0;
19326   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19327   struct in_addr ip4;
19328   struct in6_addr ip6;
19329   u32 table_id = 0, nh_sw_if_index = ~0;
19330
19331   memset (&ip4, 0, sizeof (ip4));
19332   memset (&ip6, 0, sizeof (ip6));
19333
19334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19335     {
19336       if (unformat (i, "del"))
19337         is_add = 0;
19338       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19339                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19340         {
19341           ip_set = 1;
19342           is_ip4 = 1;
19343         }
19344       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19345                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19346         {
19347           ip_set = 1;
19348           is_ip4 = 0;
19349         }
19350       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19351         {
19352           ip_set = 1;
19353           is_ip4 = 1;
19354           nh_sw_if_index = ~0;
19355         }
19356       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19357         {
19358           ip_set = 1;
19359           is_ip4 = 0;
19360           nh_sw_if_index = ~0;
19361         }
19362       else if (unformat (i, "table %d", &table_id))
19363         ;
19364       else
19365         {
19366           errmsg ("parse error '%U'", format_unformat_error, i);
19367           return -99;
19368         }
19369     }
19370
19371   if (!ip_set)
19372     {
19373       errmsg ("nh addr not set!");
19374       return -99;
19375     }
19376
19377   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19378   mp->is_add = is_add;
19379   mp->table_id = clib_host_to_net_u32 (table_id);
19380   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19381   mp->is_ip4 = is_ip4;
19382   if (is_ip4)
19383     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19384   else
19385     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19386
19387   /* send it... */
19388   S (mp);
19389
19390   /* Wait for a reply... */
19391   W (ret);
19392   return ret;
19393 }
19394
19395 static int
19396 api_one_map_server_dump (vat_main_t * vam)
19397 {
19398   vl_api_one_map_server_dump_t *mp;
19399   vl_api_control_ping_t *mp_ping;
19400   int ret;
19401
19402   if (!vam->json_output)
19403     {
19404       print (vam->ofp, "%=20s", "Map server");
19405     }
19406
19407   M (ONE_MAP_SERVER_DUMP, mp);
19408   /* send it... */
19409   S (mp);
19410
19411   /* Use a control ping for synchronization */
19412   MPING (CONTROL_PING, mp_ping);
19413   S (mp_ping);
19414
19415   /* Wait for a reply... */
19416   W (ret);
19417   return ret;
19418 }
19419
19420 #define api_lisp_map_server_dump api_one_map_server_dump
19421
19422 static int
19423 api_one_map_resolver_dump (vat_main_t * vam)
19424 {
19425   vl_api_one_map_resolver_dump_t *mp;
19426   vl_api_control_ping_t *mp_ping;
19427   int ret;
19428
19429   if (!vam->json_output)
19430     {
19431       print (vam->ofp, "%=20s", "Map resolver");
19432     }
19433
19434   M (ONE_MAP_RESOLVER_DUMP, mp);
19435   /* send it... */
19436   S (mp);
19437
19438   /* Use a control ping for synchronization */
19439   MPING (CONTROL_PING, mp_ping);
19440   S (mp_ping);
19441
19442   /* Wait for a reply... */
19443   W (ret);
19444   return ret;
19445 }
19446
19447 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19448
19449 static int
19450 api_one_stats_flush (vat_main_t * vam)
19451 {
19452   vl_api_one_stats_flush_t *mp;
19453   int ret = 0;
19454
19455   M (ONE_STATS_FLUSH, mp);
19456   S (mp);
19457   W (ret);
19458   return ret;
19459 }
19460
19461 static int
19462 api_one_stats_dump (vat_main_t * vam)
19463 {
19464   vl_api_one_stats_dump_t *mp;
19465   vl_api_control_ping_t *mp_ping;
19466   int ret;
19467
19468   M (ONE_STATS_DUMP, mp);
19469   /* send it... */
19470   S (mp);
19471
19472   /* Use a control ping for synchronization */
19473   MPING (CONTROL_PING, mp_ping);
19474   S (mp_ping);
19475
19476   /* Wait for a reply... */
19477   W (ret);
19478   return ret;
19479 }
19480
19481 static int
19482 api_show_one_status (vat_main_t * vam)
19483 {
19484   vl_api_show_one_status_t *mp;
19485   int ret;
19486
19487   if (!vam->json_output)
19488     {
19489       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19490     }
19491
19492   M (SHOW_ONE_STATUS, mp);
19493   /* send it... */
19494   S (mp);
19495   /* Wait for a reply... */
19496   W (ret);
19497   return ret;
19498 }
19499
19500 #define api_show_lisp_status api_show_one_status
19501
19502 static int
19503 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19504 {
19505   vl_api_gpe_fwd_entry_path_dump_t *mp;
19506   vl_api_control_ping_t *mp_ping;
19507   unformat_input_t *i = vam->input;
19508   u32 fwd_entry_index = ~0;
19509   int ret;
19510
19511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19512     {
19513       if (unformat (i, "index %d", &fwd_entry_index))
19514         ;
19515       else
19516         break;
19517     }
19518
19519   if (~0 == fwd_entry_index)
19520     {
19521       errmsg ("no index specified!");
19522       return -99;
19523     }
19524
19525   if (!vam->json_output)
19526     {
19527       print (vam->ofp, "first line");
19528     }
19529
19530   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19531
19532   /* send it... */
19533   S (mp);
19534   /* Use a control ping for synchronization */
19535   MPING (CONTROL_PING, mp_ping);
19536   S (mp_ping);
19537
19538   /* Wait for a reply... */
19539   W (ret);
19540   return ret;
19541 }
19542
19543 static int
19544 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19545 {
19546   vl_api_one_get_map_request_itr_rlocs_t *mp;
19547   int ret;
19548
19549   if (!vam->json_output)
19550     {
19551       print (vam->ofp, "%=20s", "itr-rlocs:");
19552     }
19553
19554   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19555   /* send it... */
19556   S (mp);
19557   /* Wait for a reply... */
19558   W (ret);
19559   return ret;
19560 }
19561
19562 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19563
19564 static int
19565 api_af_packet_create (vat_main_t * vam)
19566 {
19567   unformat_input_t *i = vam->input;
19568   vl_api_af_packet_create_t *mp;
19569   u8 *host_if_name = 0;
19570   u8 hw_addr[6];
19571   u8 random_hw_addr = 1;
19572   int ret;
19573
19574   memset (hw_addr, 0, sizeof (hw_addr));
19575
19576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19577     {
19578       if (unformat (i, "name %s", &host_if_name))
19579         vec_add1 (host_if_name, 0);
19580       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19581         random_hw_addr = 0;
19582       else
19583         break;
19584     }
19585
19586   if (!vec_len (host_if_name))
19587     {
19588       errmsg ("host-interface name must be specified");
19589       return -99;
19590     }
19591
19592   if (vec_len (host_if_name) > 64)
19593     {
19594       errmsg ("host-interface name too long");
19595       return -99;
19596     }
19597
19598   M (AF_PACKET_CREATE, mp);
19599
19600   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19601   clib_memcpy (mp->hw_addr, hw_addr, 6);
19602   mp->use_random_hw_addr = random_hw_addr;
19603   vec_free (host_if_name);
19604
19605   S (mp);
19606
19607   /* *INDENT-OFF* */
19608   W2 (ret,
19609       ({
19610         if (ret == 0)
19611           fprintf (vam->ofp ? vam->ofp : stderr,
19612                    " new sw_if_index = %d\n", vam->sw_if_index);
19613       }));
19614   /* *INDENT-ON* */
19615   return ret;
19616 }
19617
19618 static int
19619 api_af_packet_delete (vat_main_t * vam)
19620 {
19621   unformat_input_t *i = vam->input;
19622   vl_api_af_packet_delete_t *mp;
19623   u8 *host_if_name = 0;
19624   int ret;
19625
19626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19627     {
19628       if (unformat (i, "name %s", &host_if_name))
19629         vec_add1 (host_if_name, 0);
19630       else
19631         break;
19632     }
19633
19634   if (!vec_len (host_if_name))
19635     {
19636       errmsg ("host-interface name must be specified");
19637       return -99;
19638     }
19639
19640   if (vec_len (host_if_name) > 64)
19641     {
19642       errmsg ("host-interface name too long");
19643       return -99;
19644     }
19645
19646   M (AF_PACKET_DELETE, mp);
19647
19648   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19649   vec_free (host_if_name);
19650
19651   S (mp);
19652   W (ret);
19653   return ret;
19654 }
19655
19656 static void vl_api_af_packet_details_t_handler
19657   (vl_api_af_packet_details_t * mp)
19658 {
19659   vat_main_t *vam = &vat_main;
19660
19661   print (vam->ofp, "%-16s %d",
19662          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19663 }
19664
19665 static void vl_api_af_packet_details_t_handler_json
19666   (vl_api_af_packet_details_t * mp)
19667 {
19668   vat_main_t *vam = &vat_main;
19669   vat_json_node_t *node = NULL;
19670
19671   if (VAT_JSON_ARRAY != vam->json_tree.type)
19672     {
19673       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19674       vat_json_init_array (&vam->json_tree);
19675     }
19676   node = vat_json_array_add (&vam->json_tree);
19677
19678   vat_json_init_object (node);
19679   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19680   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19681 }
19682
19683 static int
19684 api_af_packet_dump (vat_main_t * vam)
19685 {
19686   vl_api_af_packet_dump_t *mp;
19687   vl_api_control_ping_t *mp_ping;
19688   int ret;
19689
19690   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19691   /* Get list of tap interfaces */
19692   M (AF_PACKET_DUMP, mp);
19693   S (mp);
19694
19695   /* Use a control ping for synchronization */
19696   MPING (CONTROL_PING, mp_ping);
19697   S (mp_ping);
19698
19699   W (ret);
19700   return ret;
19701 }
19702
19703 static int
19704 api_policer_add_del (vat_main_t * vam)
19705 {
19706   unformat_input_t *i = vam->input;
19707   vl_api_policer_add_del_t *mp;
19708   u8 is_add = 1;
19709   u8 *name = 0;
19710   u32 cir = 0;
19711   u32 eir = 0;
19712   u64 cb = 0;
19713   u64 eb = 0;
19714   u8 rate_type = 0;
19715   u8 round_type = 0;
19716   u8 type = 0;
19717   u8 color_aware = 0;
19718   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19719   int ret;
19720
19721   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19722   conform_action.dscp = 0;
19723   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19724   exceed_action.dscp = 0;
19725   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19726   violate_action.dscp = 0;
19727
19728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19729     {
19730       if (unformat (i, "del"))
19731         is_add = 0;
19732       else if (unformat (i, "name %s", &name))
19733         vec_add1 (name, 0);
19734       else if (unformat (i, "cir %u", &cir))
19735         ;
19736       else if (unformat (i, "eir %u", &eir))
19737         ;
19738       else if (unformat (i, "cb %u", &cb))
19739         ;
19740       else if (unformat (i, "eb %u", &eb))
19741         ;
19742       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19743                          &rate_type))
19744         ;
19745       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19746                          &round_type))
19747         ;
19748       else if (unformat (i, "type %U", unformat_policer_type, &type))
19749         ;
19750       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19751                          &conform_action))
19752         ;
19753       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19754                          &exceed_action))
19755         ;
19756       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19757                          &violate_action))
19758         ;
19759       else if (unformat (i, "color-aware"))
19760         color_aware = 1;
19761       else
19762         break;
19763     }
19764
19765   if (!vec_len (name))
19766     {
19767       errmsg ("policer name must be specified");
19768       return -99;
19769     }
19770
19771   if (vec_len (name) > 64)
19772     {
19773       errmsg ("policer name too long");
19774       return -99;
19775     }
19776
19777   M (POLICER_ADD_DEL, mp);
19778
19779   clib_memcpy (mp->name, name, vec_len (name));
19780   vec_free (name);
19781   mp->is_add = is_add;
19782   mp->cir = ntohl (cir);
19783   mp->eir = ntohl (eir);
19784   mp->cb = clib_net_to_host_u64 (cb);
19785   mp->eb = clib_net_to_host_u64 (eb);
19786   mp->rate_type = rate_type;
19787   mp->round_type = round_type;
19788   mp->type = type;
19789   mp->conform_action_type = conform_action.action_type;
19790   mp->conform_dscp = conform_action.dscp;
19791   mp->exceed_action_type = exceed_action.action_type;
19792   mp->exceed_dscp = exceed_action.dscp;
19793   mp->violate_action_type = violate_action.action_type;
19794   mp->violate_dscp = violate_action.dscp;
19795   mp->color_aware = color_aware;
19796
19797   S (mp);
19798   W (ret);
19799   return ret;
19800 }
19801
19802 static int
19803 api_policer_dump (vat_main_t * vam)
19804 {
19805   unformat_input_t *i = vam->input;
19806   vl_api_policer_dump_t *mp;
19807   vl_api_control_ping_t *mp_ping;
19808   u8 *match_name = 0;
19809   u8 match_name_valid = 0;
19810   int ret;
19811
19812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19813     {
19814       if (unformat (i, "name %s", &match_name))
19815         {
19816           vec_add1 (match_name, 0);
19817           match_name_valid = 1;
19818         }
19819       else
19820         break;
19821     }
19822
19823   M (POLICER_DUMP, mp);
19824   mp->match_name_valid = match_name_valid;
19825   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19826   vec_free (match_name);
19827   /* send it... */
19828   S (mp);
19829
19830   /* Use a control ping for synchronization */
19831   MPING (CONTROL_PING, mp_ping);
19832   S (mp_ping);
19833
19834   /* Wait for a reply... */
19835   W (ret);
19836   return ret;
19837 }
19838
19839 static int
19840 api_policer_classify_set_interface (vat_main_t * vam)
19841 {
19842   unformat_input_t *i = vam->input;
19843   vl_api_policer_classify_set_interface_t *mp;
19844   u32 sw_if_index;
19845   int sw_if_index_set;
19846   u32 ip4_table_index = ~0;
19847   u32 ip6_table_index = ~0;
19848   u32 l2_table_index = ~0;
19849   u8 is_add = 1;
19850   int ret;
19851
19852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19853     {
19854       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19855         sw_if_index_set = 1;
19856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19857         sw_if_index_set = 1;
19858       else if (unformat (i, "del"))
19859         is_add = 0;
19860       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19861         ;
19862       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19863         ;
19864       else if (unformat (i, "l2-table %d", &l2_table_index))
19865         ;
19866       else
19867         {
19868           clib_warning ("parse error '%U'", format_unformat_error, i);
19869           return -99;
19870         }
19871     }
19872
19873   if (sw_if_index_set == 0)
19874     {
19875       errmsg ("missing interface name or sw_if_index");
19876       return -99;
19877     }
19878
19879   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19880
19881   mp->sw_if_index = ntohl (sw_if_index);
19882   mp->ip4_table_index = ntohl (ip4_table_index);
19883   mp->ip6_table_index = ntohl (ip6_table_index);
19884   mp->l2_table_index = ntohl (l2_table_index);
19885   mp->is_add = is_add;
19886
19887   S (mp);
19888   W (ret);
19889   return ret;
19890 }
19891
19892 static int
19893 api_policer_classify_dump (vat_main_t * vam)
19894 {
19895   unformat_input_t *i = vam->input;
19896   vl_api_policer_classify_dump_t *mp;
19897   vl_api_control_ping_t *mp_ping;
19898   u8 type = POLICER_CLASSIFY_N_TABLES;
19899   int ret;
19900
19901   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19902     ;
19903   else
19904     {
19905       errmsg ("classify table type must be specified");
19906       return -99;
19907     }
19908
19909   if (!vam->json_output)
19910     {
19911       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19912     }
19913
19914   M (POLICER_CLASSIFY_DUMP, mp);
19915   mp->type = type;
19916   /* send it... */
19917   S (mp);
19918
19919   /* Use a control ping for synchronization */
19920   MPING (CONTROL_PING, mp_ping);
19921   S (mp_ping);
19922
19923   /* Wait for a reply... */
19924   W (ret);
19925   return ret;
19926 }
19927
19928 static int
19929 api_netmap_create (vat_main_t * vam)
19930 {
19931   unformat_input_t *i = vam->input;
19932   vl_api_netmap_create_t *mp;
19933   u8 *if_name = 0;
19934   u8 hw_addr[6];
19935   u8 random_hw_addr = 1;
19936   u8 is_pipe = 0;
19937   u8 is_master = 0;
19938   int ret;
19939
19940   memset (hw_addr, 0, sizeof (hw_addr));
19941
19942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19943     {
19944       if (unformat (i, "name %s", &if_name))
19945         vec_add1 (if_name, 0);
19946       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19947         random_hw_addr = 0;
19948       else if (unformat (i, "pipe"))
19949         is_pipe = 1;
19950       else if (unformat (i, "master"))
19951         is_master = 1;
19952       else if (unformat (i, "slave"))
19953         is_master = 0;
19954       else
19955         break;
19956     }
19957
19958   if (!vec_len (if_name))
19959     {
19960       errmsg ("interface name must be specified");
19961       return -99;
19962     }
19963
19964   if (vec_len (if_name) > 64)
19965     {
19966       errmsg ("interface name too long");
19967       return -99;
19968     }
19969
19970   M (NETMAP_CREATE, mp);
19971
19972   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19973   clib_memcpy (mp->hw_addr, hw_addr, 6);
19974   mp->use_random_hw_addr = random_hw_addr;
19975   mp->is_pipe = is_pipe;
19976   mp->is_master = is_master;
19977   vec_free (if_name);
19978
19979   S (mp);
19980   W (ret);
19981   return ret;
19982 }
19983
19984 static int
19985 api_netmap_delete (vat_main_t * vam)
19986 {
19987   unformat_input_t *i = vam->input;
19988   vl_api_netmap_delete_t *mp;
19989   u8 *if_name = 0;
19990   int ret;
19991
19992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19993     {
19994       if (unformat (i, "name %s", &if_name))
19995         vec_add1 (if_name, 0);
19996       else
19997         break;
19998     }
19999
20000   if (!vec_len (if_name))
20001     {
20002       errmsg ("interface name must be specified");
20003       return -99;
20004     }
20005
20006   if (vec_len (if_name) > 64)
20007     {
20008       errmsg ("interface name too long");
20009       return -99;
20010     }
20011
20012   M (NETMAP_DELETE, mp);
20013
20014   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20015   vec_free (if_name);
20016
20017   S (mp);
20018   W (ret);
20019   return ret;
20020 }
20021
20022 static void
20023 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20024 {
20025   if (fp->afi == IP46_TYPE_IP6)
20026     print (vam->ofp,
20027            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20028            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20029            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20030            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20031            format_ip6_address, fp->next_hop);
20032   else if (fp->afi == IP46_TYPE_IP4)
20033     print (vam->ofp,
20034            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20035            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20036            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20037            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20038            format_ip4_address, fp->next_hop);
20039 }
20040
20041 static void
20042 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20043                                  vl_api_fib_path_t * fp)
20044 {
20045   struct in_addr ip4;
20046   struct in6_addr ip6;
20047
20048   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20049   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20050   vat_json_object_add_uint (node, "is_local", fp->is_local);
20051   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20052   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20053   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20054   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20055   if (fp->afi == IP46_TYPE_IP4)
20056     {
20057       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20058       vat_json_object_add_ip4 (node, "next_hop", ip4);
20059     }
20060   else if (fp->afi == IP46_TYPE_IP6)
20061     {
20062       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20063       vat_json_object_add_ip6 (node, "next_hop", ip6);
20064     }
20065 }
20066
20067 static void
20068 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20069 {
20070   vat_main_t *vam = &vat_main;
20071   int count = ntohl (mp->mt_count);
20072   vl_api_fib_path_t *fp;
20073   i32 i;
20074
20075   print (vam->ofp, "[%d]: sw_if_index %d via:",
20076          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20077   fp = mp->mt_paths;
20078   for (i = 0; i < count; i++)
20079     {
20080       vl_api_mpls_fib_path_print (vam, fp);
20081       fp++;
20082     }
20083
20084   print (vam->ofp, "");
20085 }
20086
20087 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20088 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20089
20090 static void
20091 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20092 {
20093   vat_main_t *vam = &vat_main;
20094   vat_json_node_t *node = NULL;
20095   int count = ntohl (mp->mt_count);
20096   vl_api_fib_path_t *fp;
20097   i32 i;
20098
20099   if (VAT_JSON_ARRAY != vam->json_tree.type)
20100     {
20101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20102       vat_json_init_array (&vam->json_tree);
20103     }
20104   node = vat_json_array_add (&vam->json_tree);
20105
20106   vat_json_init_object (node);
20107   vat_json_object_add_uint (node, "tunnel_index",
20108                             ntohl (mp->mt_tunnel_index));
20109   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20110
20111   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20112
20113   fp = mp->mt_paths;
20114   for (i = 0; i < count; i++)
20115     {
20116       vl_api_mpls_fib_path_json_print (node, fp);
20117       fp++;
20118     }
20119 }
20120
20121 static int
20122 api_mpls_tunnel_dump (vat_main_t * vam)
20123 {
20124   vl_api_mpls_tunnel_dump_t *mp;
20125   vl_api_control_ping_t *mp_ping;
20126   i32 index = -1;
20127   int ret;
20128
20129   /* Parse args required to build the message */
20130   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20131     {
20132       if (!unformat (vam->input, "tunnel_index %d", &index))
20133         {
20134           index = -1;
20135           break;
20136         }
20137     }
20138
20139   print (vam->ofp, "  tunnel_index %d", index);
20140
20141   M (MPLS_TUNNEL_DUMP, mp);
20142   mp->tunnel_index = htonl (index);
20143   S (mp);
20144
20145   /* Use a control ping for synchronization */
20146   MPING (CONTROL_PING, mp_ping);
20147   S (mp_ping);
20148
20149   W (ret);
20150   return ret;
20151 }
20152
20153 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20154 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20155
20156
20157 static void
20158 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20159 {
20160   vat_main_t *vam = &vat_main;
20161   int count = ntohl (mp->count);
20162   vl_api_fib_path_t *fp;
20163   int i;
20164
20165   print (vam->ofp,
20166          "table-id %d, label %u, ess_bit %u",
20167          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20168   fp = mp->path;
20169   for (i = 0; i < count; i++)
20170     {
20171       vl_api_mpls_fib_path_print (vam, fp);
20172       fp++;
20173     }
20174 }
20175
20176 static void vl_api_mpls_fib_details_t_handler_json
20177   (vl_api_mpls_fib_details_t * mp)
20178 {
20179   vat_main_t *vam = &vat_main;
20180   int count = ntohl (mp->count);
20181   vat_json_node_t *node = NULL;
20182   vl_api_fib_path_t *fp;
20183   int i;
20184
20185   if (VAT_JSON_ARRAY != vam->json_tree.type)
20186     {
20187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20188       vat_json_init_array (&vam->json_tree);
20189     }
20190   node = vat_json_array_add (&vam->json_tree);
20191
20192   vat_json_init_object (node);
20193   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20194   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20195   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20196   vat_json_object_add_uint (node, "path_count", count);
20197   fp = mp->path;
20198   for (i = 0; i < count; i++)
20199     {
20200       vl_api_mpls_fib_path_json_print (node, fp);
20201       fp++;
20202     }
20203 }
20204
20205 static int
20206 api_mpls_fib_dump (vat_main_t * vam)
20207 {
20208   vl_api_mpls_fib_dump_t *mp;
20209   vl_api_control_ping_t *mp_ping;
20210   int ret;
20211
20212   M (MPLS_FIB_DUMP, mp);
20213   S (mp);
20214
20215   /* Use a control ping for synchronization */
20216   MPING (CONTROL_PING, mp_ping);
20217   S (mp_ping);
20218
20219   W (ret);
20220   return ret;
20221 }
20222
20223 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20224 #define vl_api_ip_fib_details_t_print vl_noop_handler
20225
20226 static void
20227 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20228 {
20229   vat_main_t *vam = &vat_main;
20230   int count = ntohl (mp->count);
20231   vl_api_fib_path_t *fp;
20232   int i;
20233
20234   print (vam->ofp,
20235          "table-id %d, prefix %U/%d",
20236          ntohl (mp->table_id), format_ip4_address, mp->address,
20237          mp->address_length);
20238   fp = mp->path;
20239   for (i = 0; i < count; i++)
20240     {
20241       if (fp->afi == IP46_TYPE_IP6)
20242         print (vam->ofp,
20243                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20244                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20245                "next_hop_table %d",
20246                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20247                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20248                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20249       else if (fp->afi == IP46_TYPE_IP4)
20250         print (vam->ofp,
20251                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20252                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20253                "next_hop_table %d",
20254                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20255                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20256                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20257       fp++;
20258     }
20259 }
20260
20261 static void vl_api_ip_fib_details_t_handler_json
20262   (vl_api_ip_fib_details_t * mp)
20263 {
20264   vat_main_t *vam = &vat_main;
20265   int count = ntohl (mp->count);
20266   vat_json_node_t *node = NULL;
20267   struct in_addr ip4;
20268   struct in6_addr ip6;
20269   vl_api_fib_path_t *fp;
20270   int i;
20271
20272   if (VAT_JSON_ARRAY != vam->json_tree.type)
20273     {
20274       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20275       vat_json_init_array (&vam->json_tree);
20276     }
20277   node = vat_json_array_add (&vam->json_tree);
20278
20279   vat_json_init_object (node);
20280   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20281   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20282   vat_json_object_add_ip4 (node, "prefix", ip4);
20283   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20284   vat_json_object_add_uint (node, "path_count", count);
20285   fp = mp->path;
20286   for (i = 0; i < count; i++)
20287     {
20288       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20289       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20290       vat_json_object_add_uint (node, "is_local", fp->is_local);
20291       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20292       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20293       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20294       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20295       if (fp->afi == IP46_TYPE_IP4)
20296         {
20297           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20298           vat_json_object_add_ip4 (node, "next_hop", ip4);
20299         }
20300       else if (fp->afi == IP46_TYPE_IP6)
20301         {
20302           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20303           vat_json_object_add_ip6 (node, "next_hop", ip6);
20304         }
20305     }
20306 }
20307
20308 static int
20309 api_ip_fib_dump (vat_main_t * vam)
20310 {
20311   vl_api_ip_fib_dump_t *mp;
20312   vl_api_control_ping_t *mp_ping;
20313   int ret;
20314
20315   M (IP_FIB_DUMP, mp);
20316   S (mp);
20317
20318   /* Use a control ping for synchronization */
20319   MPING (CONTROL_PING, mp_ping);
20320   S (mp_ping);
20321
20322   W (ret);
20323   return ret;
20324 }
20325
20326 static int
20327 api_ip_mfib_dump (vat_main_t * vam)
20328 {
20329   vl_api_ip_mfib_dump_t *mp;
20330   vl_api_control_ping_t *mp_ping;
20331   int ret;
20332
20333   M (IP_MFIB_DUMP, mp);
20334   S (mp);
20335
20336   /* Use a control ping for synchronization */
20337   MPING (CONTROL_PING, mp_ping);
20338   S (mp_ping);
20339
20340   W (ret);
20341   return ret;
20342 }
20343
20344 static void vl_api_ip_neighbor_details_t_handler
20345   (vl_api_ip_neighbor_details_t * mp)
20346 {
20347   vat_main_t *vam = &vat_main;
20348
20349   print (vam->ofp, "%c %U %U",
20350          (mp->is_static) ? 'S' : 'D',
20351          format_ethernet_address, &mp->mac_address,
20352          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20353          &mp->ip_address);
20354 }
20355
20356 static void vl_api_ip_neighbor_details_t_handler_json
20357   (vl_api_ip_neighbor_details_t * mp)
20358 {
20359
20360   vat_main_t *vam = &vat_main;
20361   vat_json_node_t *node;
20362   struct in_addr ip4;
20363   struct in6_addr ip6;
20364
20365   if (VAT_JSON_ARRAY != vam->json_tree.type)
20366     {
20367       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20368       vat_json_init_array (&vam->json_tree);
20369     }
20370   node = vat_json_array_add (&vam->json_tree);
20371
20372   vat_json_init_object (node);
20373   vat_json_object_add_string_copy (node, "flag",
20374                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20375                                    "dynamic");
20376
20377   vat_json_object_add_string_copy (node, "link_layer",
20378                                    format (0, "%U", format_ethernet_address,
20379                                            &mp->mac_address));
20380
20381   if (mp->is_ipv6)
20382     {
20383       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20384       vat_json_object_add_ip6 (node, "ip_address", ip6);
20385     }
20386   else
20387     {
20388       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20389       vat_json_object_add_ip4 (node, "ip_address", ip4);
20390     }
20391 }
20392
20393 static int
20394 api_ip_neighbor_dump (vat_main_t * vam)
20395 {
20396   unformat_input_t *i = vam->input;
20397   vl_api_ip_neighbor_dump_t *mp;
20398   vl_api_control_ping_t *mp_ping;
20399   u8 is_ipv6 = 0;
20400   u32 sw_if_index = ~0;
20401   int ret;
20402
20403   /* Parse args required to build the message */
20404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20405     {
20406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20407         ;
20408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20409         ;
20410       else if (unformat (i, "ip6"))
20411         is_ipv6 = 1;
20412       else
20413         break;
20414     }
20415
20416   if (sw_if_index == ~0)
20417     {
20418       errmsg ("missing interface name or sw_if_index");
20419       return -99;
20420     }
20421
20422   M (IP_NEIGHBOR_DUMP, mp);
20423   mp->is_ipv6 = (u8) is_ipv6;
20424   mp->sw_if_index = ntohl (sw_if_index);
20425   S (mp);
20426
20427   /* Use a control ping for synchronization */
20428   MPING (CONTROL_PING, mp_ping);
20429   S (mp_ping);
20430
20431   W (ret);
20432   return ret;
20433 }
20434
20435 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20436 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20437
20438 static void
20439 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20440 {
20441   vat_main_t *vam = &vat_main;
20442   int count = ntohl (mp->count);
20443   vl_api_fib_path_t *fp;
20444   int i;
20445
20446   print (vam->ofp,
20447          "table-id %d, prefix %U/%d",
20448          ntohl (mp->table_id), format_ip6_address, mp->address,
20449          mp->address_length);
20450   fp = mp->path;
20451   for (i = 0; i < count; i++)
20452     {
20453       if (fp->afi == IP46_TYPE_IP6)
20454         print (vam->ofp,
20455                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20456                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20457                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20458                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20459                format_ip6_address, fp->next_hop);
20460       else if (fp->afi == IP46_TYPE_IP4)
20461         print (vam->ofp,
20462                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20463                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20464                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20465                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20466                format_ip4_address, fp->next_hop);
20467       fp++;
20468     }
20469 }
20470
20471 static void vl_api_ip6_fib_details_t_handler_json
20472   (vl_api_ip6_fib_details_t * mp)
20473 {
20474   vat_main_t *vam = &vat_main;
20475   int count = ntohl (mp->count);
20476   vat_json_node_t *node = NULL;
20477   struct in_addr ip4;
20478   struct in6_addr ip6;
20479   vl_api_fib_path_t *fp;
20480   int i;
20481
20482   if (VAT_JSON_ARRAY != vam->json_tree.type)
20483     {
20484       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20485       vat_json_init_array (&vam->json_tree);
20486     }
20487   node = vat_json_array_add (&vam->json_tree);
20488
20489   vat_json_init_object (node);
20490   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20491   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20492   vat_json_object_add_ip6 (node, "prefix", ip6);
20493   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20494   vat_json_object_add_uint (node, "path_count", count);
20495   fp = mp->path;
20496   for (i = 0; i < count; i++)
20497     {
20498       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20499       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20500       vat_json_object_add_uint (node, "is_local", fp->is_local);
20501       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20502       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20503       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20504       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20505       if (fp->afi == IP46_TYPE_IP4)
20506         {
20507           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20508           vat_json_object_add_ip4 (node, "next_hop", ip4);
20509         }
20510       else if (fp->afi == IP46_TYPE_IP6)
20511         {
20512           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20513           vat_json_object_add_ip6 (node, "next_hop", ip6);
20514         }
20515     }
20516 }
20517
20518 static int
20519 api_ip6_fib_dump (vat_main_t * vam)
20520 {
20521   vl_api_ip6_fib_dump_t *mp;
20522   vl_api_control_ping_t *mp_ping;
20523   int ret;
20524
20525   M (IP6_FIB_DUMP, mp);
20526   S (mp);
20527
20528   /* Use a control ping for synchronization */
20529   MPING (CONTROL_PING, mp_ping);
20530   S (mp_ping);
20531
20532   W (ret);
20533   return ret;
20534 }
20535
20536 static int
20537 api_ip6_mfib_dump (vat_main_t * vam)
20538 {
20539   vl_api_ip6_mfib_dump_t *mp;
20540   vl_api_control_ping_t *mp_ping;
20541   int ret;
20542
20543   M (IP6_MFIB_DUMP, mp);
20544   S (mp);
20545
20546   /* Use a control ping for synchronization */
20547   MPING (CONTROL_PING, mp_ping);
20548   S (mp_ping);
20549
20550   W (ret);
20551   return ret;
20552 }
20553
20554 int
20555 api_classify_table_ids (vat_main_t * vam)
20556 {
20557   vl_api_classify_table_ids_t *mp;
20558   int ret;
20559
20560   /* Construct the API message */
20561   M (CLASSIFY_TABLE_IDS, mp);
20562   mp->context = 0;
20563
20564   S (mp);
20565   W (ret);
20566   return ret;
20567 }
20568
20569 int
20570 api_classify_table_by_interface (vat_main_t * vam)
20571 {
20572   unformat_input_t *input = vam->input;
20573   vl_api_classify_table_by_interface_t *mp;
20574
20575   u32 sw_if_index = ~0;
20576   int ret;
20577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20578     {
20579       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20580         ;
20581       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20582         ;
20583       else
20584         break;
20585     }
20586   if (sw_if_index == ~0)
20587     {
20588       errmsg ("missing interface name or sw_if_index");
20589       return -99;
20590     }
20591
20592   /* Construct the API message */
20593   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20594   mp->context = 0;
20595   mp->sw_if_index = ntohl (sw_if_index);
20596
20597   S (mp);
20598   W (ret);
20599   return ret;
20600 }
20601
20602 int
20603 api_classify_table_info (vat_main_t * vam)
20604 {
20605   unformat_input_t *input = vam->input;
20606   vl_api_classify_table_info_t *mp;
20607
20608   u32 table_id = ~0;
20609   int ret;
20610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20611     {
20612       if (unformat (input, "table_id %d", &table_id))
20613         ;
20614       else
20615         break;
20616     }
20617   if (table_id == ~0)
20618     {
20619       errmsg ("missing table id");
20620       return -99;
20621     }
20622
20623   /* Construct the API message */
20624   M (CLASSIFY_TABLE_INFO, mp);
20625   mp->context = 0;
20626   mp->table_id = ntohl (table_id);
20627
20628   S (mp);
20629   W (ret);
20630   return ret;
20631 }
20632
20633 int
20634 api_classify_session_dump (vat_main_t * vam)
20635 {
20636   unformat_input_t *input = vam->input;
20637   vl_api_classify_session_dump_t *mp;
20638   vl_api_control_ping_t *mp_ping;
20639
20640   u32 table_id = ~0;
20641   int ret;
20642   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20643     {
20644       if (unformat (input, "table_id %d", &table_id))
20645         ;
20646       else
20647         break;
20648     }
20649   if (table_id == ~0)
20650     {
20651       errmsg ("missing table id");
20652       return -99;
20653     }
20654
20655   /* Construct the API message */
20656   M (CLASSIFY_SESSION_DUMP, mp);
20657   mp->context = 0;
20658   mp->table_id = ntohl (table_id);
20659   S (mp);
20660
20661   /* Use a control ping for synchronization */
20662   MPING (CONTROL_PING, mp_ping);
20663   S (mp_ping);
20664
20665   W (ret);
20666   return ret;
20667 }
20668
20669 static void
20670 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20671 {
20672   vat_main_t *vam = &vat_main;
20673
20674   print (vam->ofp, "collector_address %U, collector_port %d, "
20675          "src_address %U, vrf_id %d, path_mtu %u, "
20676          "template_interval %u, udp_checksum %d",
20677          format_ip4_address, mp->collector_address,
20678          ntohs (mp->collector_port),
20679          format_ip4_address, mp->src_address,
20680          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20681          ntohl (mp->template_interval), mp->udp_checksum);
20682
20683   vam->retval = 0;
20684   vam->result_ready = 1;
20685 }
20686
20687 static void
20688   vl_api_ipfix_exporter_details_t_handler_json
20689   (vl_api_ipfix_exporter_details_t * mp)
20690 {
20691   vat_main_t *vam = &vat_main;
20692   vat_json_node_t node;
20693   struct in_addr collector_address;
20694   struct in_addr src_address;
20695
20696   vat_json_init_object (&node);
20697   clib_memcpy (&collector_address, &mp->collector_address,
20698                sizeof (collector_address));
20699   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20700   vat_json_object_add_uint (&node, "collector_port",
20701                             ntohs (mp->collector_port));
20702   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20703   vat_json_object_add_ip4 (&node, "src_address", src_address);
20704   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20705   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20706   vat_json_object_add_uint (&node, "template_interval",
20707                             ntohl (mp->template_interval));
20708   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20709
20710   vat_json_print (vam->ofp, &node);
20711   vat_json_free (&node);
20712   vam->retval = 0;
20713   vam->result_ready = 1;
20714 }
20715
20716 int
20717 api_ipfix_exporter_dump (vat_main_t * vam)
20718 {
20719   vl_api_ipfix_exporter_dump_t *mp;
20720   int ret;
20721
20722   /* Construct the API message */
20723   M (IPFIX_EXPORTER_DUMP, mp);
20724   mp->context = 0;
20725
20726   S (mp);
20727   W (ret);
20728   return ret;
20729 }
20730
20731 static int
20732 api_ipfix_classify_stream_dump (vat_main_t * vam)
20733 {
20734   vl_api_ipfix_classify_stream_dump_t *mp;
20735   int ret;
20736
20737   /* Construct the API message */
20738   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20739   mp->context = 0;
20740
20741   S (mp);
20742   W (ret);
20743   return ret;
20744   /* NOTREACHED */
20745   return 0;
20746 }
20747
20748 static void
20749   vl_api_ipfix_classify_stream_details_t_handler
20750   (vl_api_ipfix_classify_stream_details_t * mp)
20751 {
20752   vat_main_t *vam = &vat_main;
20753   print (vam->ofp, "domain_id %d, src_port %d",
20754          ntohl (mp->domain_id), ntohs (mp->src_port));
20755   vam->retval = 0;
20756   vam->result_ready = 1;
20757 }
20758
20759 static void
20760   vl_api_ipfix_classify_stream_details_t_handler_json
20761   (vl_api_ipfix_classify_stream_details_t * mp)
20762 {
20763   vat_main_t *vam = &vat_main;
20764   vat_json_node_t node;
20765
20766   vat_json_init_object (&node);
20767   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20768   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20769
20770   vat_json_print (vam->ofp, &node);
20771   vat_json_free (&node);
20772   vam->retval = 0;
20773   vam->result_ready = 1;
20774 }
20775
20776 static int
20777 api_ipfix_classify_table_dump (vat_main_t * vam)
20778 {
20779   vl_api_ipfix_classify_table_dump_t *mp;
20780   vl_api_control_ping_t *mp_ping;
20781   int ret;
20782
20783   if (!vam->json_output)
20784     {
20785       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20786              "transport_protocol");
20787     }
20788
20789   /* Construct the API message */
20790   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20791
20792   /* send it... */
20793   S (mp);
20794
20795   /* Use a control ping for synchronization */
20796   MPING (CONTROL_PING, mp_ping);
20797   S (mp_ping);
20798
20799   W (ret);
20800   return ret;
20801 }
20802
20803 static void
20804   vl_api_ipfix_classify_table_details_t_handler
20805   (vl_api_ipfix_classify_table_details_t * mp)
20806 {
20807   vat_main_t *vam = &vat_main;
20808   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20809          mp->transport_protocol);
20810 }
20811
20812 static void
20813   vl_api_ipfix_classify_table_details_t_handler_json
20814   (vl_api_ipfix_classify_table_details_t * mp)
20815 {
20816   vat_json_node_t *node = NULL;
20817   vat_main_t *vam = &vat_main;
20818
20819   if (VAT_JSON_ARRAY != vam->json_tree.type)
20820     {
20821       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20822       vat_json_init_array (&vam->json_tree);
20823     }
20824
20825   node = vat_json_array_add (&vam->json_tree);
20826   vat_json_init_object (node);
20827
20828   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20829   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20830   vat_json_object_add_uint (node, "transport_protocol",
20831                             mp->transport_protocol);
20832 }
20833
20834 static int
20835 api_sw_interface_span_enable_disable (vat_main_t * vam)
20836 {
20837   unformat_input_t *i = vam->input;
20838   vl_api_sw_interface_span_enable_disable_t *mp;
20839   u32 src_sw_if_index = ~0;
20840   u32 dst_sw_if_index = ~0;
20841   u8 state = 3;
20842   int ret;
20843   u8 is_l2 = 0;
20844
20845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20846     {
20847       if (unformat
20848           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20849         ;
20850       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20851         ;
20852       else
20853         if (unformat
20854             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20855         ;
20856       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20857         ;
20858       else if (unformat (i, "disable"))
20859         state = 0;
20860       else if (unformat (i, "rx"))
20861         state = 1;
20862       else if (unformat (i, "tx"))
20863         state = 2;
20864       else if (unformat (i, "both"))
20865         state = 3;
20866       else if (unformat (i, "l2"))
20867         is_l2 = 1;
20868       else
20869         break;
20870     }
20871
20872   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20873
20874   mp->sw_if_index_from = htonl (src_sw_if_index);
20875   mp->sw_if_index_to = htonl (dst_sw_if_index);
20876   mp->state = state;
20877   mp->is_l2 = is_l2;
20878
20879   S (mp);
20880   W (ret);
20881   return ret;
20882 }
20883
20884 static void
20885 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20886                                             * mp)
20887 {
20888   vat_main_t *vam = &vat_main;
20889   u8 *sw_if_from_name = 0;
20890   u8 *sw_if_to_name = 0;
20891   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20892   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20893   char *states[] = { "none", "rx", "tx", "both" };
20894   hash_pair_t *p;
20895
20896   /* *INDENT-OFF* */
20897   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20898   ({
20899     if ((u32) p->value[0] == sw_if_index_from)
20900       {
20901         sw_if_from_name = (u8 *)(p->key);
20902         if (sw_if_to_name)
20903           break;
20904       }
20905     if ((u32) p->value[0] == sw_if_index_to)
20906       {
20907         sw_if_to_name = (u8 *)(p->key);
20908         if (sw_if_from_name)
20909           break;
20910       }
20911   }));
20912   /* *INDENT-ON* */
20913   print (vam->ofp, "%20s => %20s (%s) %s",
20914          sw_if_from_name, sw_if_to_name, states[mp->state],
20915          mp->is_l2 ? "l2" : "device");
20916 }
20917
20918 static void
20919   vl_api_sw_interface_span_details_t_handler_json
20920   (vl_api_sw_interface_span_details_t * mp)
20921 {
20922   vat_main_t *vam = &vat_main;
20923   vat_json_node_t *node = NULL;
20924   u8 *sw_if_from_name = 0;
20925   u8 *sw_if_to_name = 0;
20926   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20927   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20928   hash_pair_t *p;
20929
20930   /* *INDENT-OFF* */
20931   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20932   ({
20933     if ((u32) p->value[0] == sw_if_index_from)
20934       {
20935         sw_if_from_name = (u8 *)(p->key);
20936         if (sw_if_to_name)
20937           break;
20938       }
20939     if ((u32) p->value[0] == sw_if_index_to)
20940       {
20941         sw_if_to_name = (u8 *)(p->key);
20942         if (sw_if_from_name)
20943           break;
20944       }
20945   }));
20946   /* *INDENT-ON* */
20947
20948   if (VAT_JSON_ARRAY != vam->json_tree.type)
20949     {
20950       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20951       vat_json_init_array (&vam->json_tree);
20952     }
20953   node = vat_json_array_add (&vam->json_tree);
20954
20955   vat_json_init_object (node);
20956   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20957   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20958   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20959   if (0 != sw_if_to_name)
20960     {
20961       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20962     }
20963   vat_json_object_add_uint (node, "state", mp->state);
20964   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20965 }
20966
20967 static int
20968 api_sw_interface_span_dump (vat_main_t * vam)
20969 {
20970   unformat_input_t *input = vam->input;
20971   vl_api_sw_interface_span_dump_t *mp;
20972   vl_api_control_ping_t *mp_ping;
20973   u8 is_l2 = 0;
20974   int ret;
20975
20976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20977     {
20978       if (unformat (input, "l2"))
20979         is_l2 = 1;
20980       else
20981         break;
20982     }
20983
20984   M (SW_INTERFACE_SPAN_DUMP, mp);
20985   mp->is_l2 = is_l2;
20986   S (mp);
20987
20988   /* Use a control ping for synchronization */
20989   MPING (CONTROL_PING, mp_ping);
20990   S (mp_ping);
20991
20992   W (ret);
20993   return ret;
20994 }
20995
20996 int
20997 api_pg_create_interface (vat_main_t * vam)
20998 {
20999   unformat_input_t *input = vam->input;
21000   vl_api_pg_create_interface_t *mp;
21001
21002   u32 if_id = ~0;
21003   int ret;
21004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21005     {
21006       if (unformat (input, "if_id %d", &if_id))
21007         ;
21008       else
21009         break;
21010     }
21011   if (if_id == ~0)
21012     {
21013       errmsg ("missing pg interface index");
21014       return -99;
21015     }
21016
21017   /* Construct the API message */
21018   M (PG_CREATE_INTERFACE, mp);
21019   mp->context = 0;
21020   mp->interface_id = ntohl (if_id);
21021
21022   S (mp);
21023   W (ret);
21024   return ret;
21025 }
21026
21027 int
21028 api_pg_capture (vat_main_t * vam)
21029 {
21030   unformat_input_t *input = vam->input;
21031   vl_api_pg_capture_t *mp;
21032
21033   u32 if_id = ~0;
21034   u8 enable = 1;
21035   u32 count = 1;
21036   u8 pcap_file_set = 0;
21037   u8 *pcap_file = 0;
21038   int ret;
21039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21040     {
21041       if (unformat (input, "if_id %d", &if_id))
21042         ;
21043       else if (unformat (input, "pcap %s", &pcap_file))
21044         pcap_file_set = 1;
21045       else if (unformat (input, "count %d", &count))
21046         ;
21047       else if (unformat (input, "disable"))
21048         enable = 0;
21049       else
21050         break;
21051     }
21052   if (if_id == ~0)
21053     {
21054       errmsg ("missing pg interface index");
21055       return -99;
21056     }
21057   if (pcap_file_set > 0)
21058     {
21059       if (vec_len (pcap_file) > 255)
21060         {
21061           errmsg ("pcap file name is too long");
21062           return -99;
21063         }
21064     }
21065
21066   u32 name_len = vec_len (pcap_file);
21067   /* Construct the API message */
21068   M (PG_CAPTURE, mp);
21069   mp->context = 0;
21070   mp->interface_id = ntohl (if_id);
21071   mp->is_enabled = enable;
21072   mp->count = ntohl (count);
21073   mp->pcap_name_length = ntohl (name_len);
21074   if (pcap_file_set != 0)
21075     {
21076       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21077     }
21078   vec_free (pcap_file);
21079
21080   S (mp);
21081   W (ret);
21082   return ret;
21083 }
21084
21085 int
21086 api_pg_enable_disable (vat_main_t * vam)
21087 {
21088   unformat_input_t *input = vam->input;
21089   vl_api_pg_enable_disable_t *mp;
21090
21091   u8 enable = 1;
21092   u8 stream_name_set = 0;
21093   u8 *stream_name = 0;
21094   int ret;
21095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21096     {
21097       if (unformat (input, "stream %s", &stream_name))
21098         stream_name_set = 1;
21099       else if (unformat (input, "disable"))
21100         enable = 0;
21101       else
21102         break;
21103     }
21104
21105   if (stream_name_set > 0)
21106     {
21107       if (vec_len (stream_name) > 255)
21108         {
21109           errmsg ("stream name too long");
21110           return -99;
21111         }
21112     }
21113
21114   u32 name_len = vec_len (stream_name);
21115   /* Construct the API message */
21116   M (PG_ENABLE_DISABLE, mp);
21117   mp->context = 0;
21118   mp->is_enabled = enable;
21119   if (stream_name_set != 0)
21120     {
21121       mp->stream_name_length = ntohl (name_len);
21122       clib_memcpy (mp->stream_name, stream_name, name_len);
21123     }
21124   vec_free (stream_name);
21125
21126   S (mp);
21127   W (ret);
21128   return ret;
21129 }
21130
21131 int
21132 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21133 {
21134   unformat_input_t *input = vam->input;
21135   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21136
21137   u16 *low_ports = 0;
21138   u16 *high_ports = 0;
21139   u16 this_low;
21140   u16 this_hi;
21141   ip4_address_t ip4_addr;
21142   ip6_address_t ip6_addr;
21143   u32 length;
21144   u32 tmp, tmp2;
21145   u8 prefix_set = 0;
21146   u32 vrf_id = ~0;
21147   u8 is_add = 1;
21148   u8 is_ipv6 = 0;
21149   int ret;
21150
21151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21152     {
21153       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21154         {
21155           prefix_set = 1;
21156         }
21157       else
21158         if (unformat
21159             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21160         {
21161           prefix_set = 1;
21162           is_ipv6 = 1;
21163         }
21164       else if (unformat (input, "vrf %d", &vrf_id))
21165         ;
21166       else if (unformat (input, "del"))
21167         is_add = 0;
21168       else if (unformat (input, "port %d", &tmp))
21169         {
21170           if (tmp == 0 || tmp > 65535)
21171             {
21172               errmsg ("port %d out of range", tmp);
21173               return -99;
21174             }
21175           this_low = tmp;
21176           this_hi = this_low + 1;
21177           vec_add1 (low_ports, this_low);
21178           vec_add1 (high_ports, this_hi);
21179         }
21180       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21181         {
21182           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21183             {
21184               errmsg ("incorrect range parameters");
21185               return -99;
21186             }
21187           this_low = tmp;
21188           /* Note: in debug CLI +1 is added to high before
21189              passing to real fn that does "the work"
21190              (ip_source_and_port_range_check_add_del).
21191              This fn is a wrapper around the binary API fn a
21192              control plane will call, which expects this increment
21193              to have occurred. Hence letting the binary API control
21194              plane fn do the increment for consistency between VAT
21195              and other control planes.
21196            */
21197           this_hi = tmp2;
21198           vec_add1 (low_ports, this_low);
21199           vec_add1 (high_ports, this_hi);
21200         }
21201       else
21202         break;
21203     }
21204
21205   if (prefix_set == 0)
21206     {
21207       errmsg ("<address>/<mask> not specified");
21208       return -99;
21209     }
21210
21211   if (vrf_id == ~0)
21212     {
21213       errmsg ("VRF ID required, not specified");
21214       return -99;
21215     }
21216
21217   if (vrf_id == 0)
21218     {
21219       errmsg
21220         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21221       return -99;
21222     }
21223
21224   if (vec_len (low_ports) == 0)
21225     {
21226       errmsg ("At least one port or port range required");
21227       return -99;
21228     }
21229
21230   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21231
21232   mp->is_add = is_add;
21233
21234   if (is_ipv6)
21235     {
21236       mp->is_ipv6 = 1;
21237       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21238     }
21239   else
21240     {
21241       mp->is_ipv6 = 0;
21242       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21243     }
21244
21245   mp->mask_length = length;
21246   mp->number_of_ranges = vec_len (low_ports);
21247
21248   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21249   vec_free (low_ports);
21250
21251   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21252   vec_free (high_ports);
21253
21254   mp->vrf_id = ntohl (vrf_id);
21255
21256   S (mp);
21257   W (ret);
21258   return ret;
21259 }
21260
21261 int
21262 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21263 {
21264   unformat_input_t *input = vam->input;
21265   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21266   u32 sw_if_index = ~0;
21267   int vrf_set = 0;
21268   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21269   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21270   u8 is_add = 1;
21271   int ret;
21272
21273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21274     {
21275       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21276         ;
21277       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21278         ;
21279       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21280         vrf_set = 1;
21281       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21282         vrf_set = 1;
21283       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21284         vrf_set = 1;
21285       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21286         vrf_set = 1;
21287       else if (unformat (input, "del"))
21288         is_add = 0;
21289       else
21290         break;
21291     }
21292
21293   if (sw_if_index == ~0)
21294     {
21295       errmsg ("Interface required but not specified");
21296       return -99;
21297     }
21298
21299   if (vrf_set == 0)
21300     {
21301       errmsg ("VRF ID required but not specified");
21302       return -99;
21303     }
21304
21305   if (tcp_out_vrf_id == 0
21306       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21307     {
21308       errmsg
21309         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21310       return -99;
21311     }
21312
21313   /* Construct the API message */
21314   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21315
21316   mp->sw_if_index = ntohl (sw_if_index);
21317   mp->is_add = is_add;
21318   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21319   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21320   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21321   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21322
21323   /* send it... */
21324   S (mp);
21325
21326   /* Wait for a reply... */
21327   W (ret);
21328   return ret;
21329 }
21330
21331 static int
21332 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21333 {
21334   unformat_input_t *i = vam->input;
21335   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21336   u32 local_sa_id = 0;
21337   u32 remote_sa_id = 0;
21338   ip4_address_t src_address;
21339   ip4_address_t dst_address;
21340   u8 is_add = 1;
21341   int ret;
21342
21343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21344     {
21345       if (unformat (i, "local_sa %d", &local_sa_id))
21346         ;
21347       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21348         ;
21349       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21350         ;
21351       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21352         ;
21353       else if (unformat (i, "del"))
21354         is_add = 0;
21355       else
21356         {
21357           clib_warning ("parse error '%U'", format_unformat_error, i);
21358           return -99;
21359         }
21360     }
21361
21362   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21363
21364   mp->local_sa_id = ntohl (local_sa_id);
21365   mp->remote_sa_id = ntohl (remote_sa_id);
21366   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21367   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21368   mp->is_add = is_add;
21369
21370   S (mp);
21371   W (ret);
21372   return ret;
21373 }
21374
21375 static int
21376 api_punt (vat_main_t * vam)
21377 {
21378   unformat_input_t *i = vam->input;
21379   vl_api_punt_t *mp;
21380   u32 ipv = ~0;
21381   u32 protocol = ~0;
21382   u32 port = ~0;
21383   int is_add = 1;
21384   int ret;
21385
21386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21387     {
21388       if (unformat (i, "ip %d", &ipv))
21389         ;
21390       else if (unformat (i, "protocol %d", &protocol))
21391         ;
21392       else if (unformat (i, "port %d", &port))
21393         ;
21394       else if (unformat (i, "del"))
21395         is_add = 0;
21396       else
21397         {
21398           clib_warning ("parse error '%U'", format_unformat_error, i);
21399           return -99;
21400         }
21401     }
21402
21403   M (PUNT, mp);
21404
21405   mp->is_add = (u8) is_add;
21406   mp->ipv = (u8) ipv;
21407   mp->l4_protocol = (u8) protocol;
21408   mp->l4_port = htons ((u16) port);
21409
21410   S (mp);
21411   W (ret);
21412   return ret;
21413 }
21414
21415 static void vl_api_ipsec_gre_tunnel_details_t_handler
21416   (vl_api_ipsec_gre_tunnel_details_t * mp)
21417 {
21418   vat_main_t *vam = &vat_main;
21419
21420   print (vam->ofp, "%11d%15U%15U%14d%14d",
21421          ntohl (mp->sw_if_index),
21422          format_ip4_address, &mp->src_address,
21423          format_ip4_address, &mp->dst_address,
21424          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21425 }
21426
21427 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21428   (vl_api_ipsec_gre_tunnel_details_t * mp)
21429 {
21430   vat_main_t *vam = &vat_main;
21431   vat_json_node_t *node = NULL;
21432   struct in_addr ip4;
21433
21434   if (VAT_JSON_ARRAY != vam->json_tree.type)
21435     {
21436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21437       vat_json_init_array (&vam->json_tree);
21438     }
21439   node = vat_json_array_add (&vam->json_tree);
21440
21441   vat_json_init_object (node);
21442   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21443   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21444   vat_json_object_add_ip4 (node, "src_address", ip4);
21445   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21446   vat_json_object_add_ip4 (node, "dst_address", ip4);
21447   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21448   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21449 }
21450
21451 static int
21452 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21453 {
21454   unformat_input_t *i = vam->input;
21455   vl_api_ipsec_gre_tunnel_dump_t *mp;
21456   vl_api_control_ping_t *mp_ping;
21457   u32 sw_if_index;
21458   u8 sw_if_index_set = 0;
21459   int ret;
21460
21461   /* Parse args required to build the message */
21462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21463     {
21464       if (unformat (i, "sw_if_index %d", &sw_if_index))
21465         sw_if_index_set = 1;
21466       else
21467         break;
21468     }
21469
21470   if (sw_if_index_set == 0)
21471     {
21472       sw_if_index = ~0;
21473     }
21474
21475   if (!vam->json_output)
21476     {
21477       print (vam->ofp, "%11s%15s%15s%14s%14s",
21478              "sw_if_index", "src_address", "dst_address",
21479              "local_sa_id", "remote_sa_id");
21480     }
21481
21482   /* Get list of gre-tunnel interfaces */
21483   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21484
21485   mp->sw_if_index = htonl (sw_if_index);
21486
21487   S (mp);
21488
21489   /* Use a control ping for synchronization */
21490   MPING (CONTROL_PING, mp_ping);
21491   S (mp_ping);
21492
21493   W (ret);
21494   return ret;
21495 }
21496
21497 static int
21498 api_delete_subif (vat_main_t * vam)
21499 {
21500   unformat_input_t *i = vam->input;
21501   vl_api_delete_subif_t *mp;
21502   u32 sw_if_index = ~0;
21503   int ret;
21504
21505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21506     {
21507       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21508         ;
21509       if (unformat (i, "sw_if_index %d", &sw_if_index))
21510         ;
21511       else
21512         break;
21513     }
21514
21515   if (sw_if_index == ~0)
21516     {
21517       errmsg ("missing sw_if_index");
21518       return -99;
21519     }
21520
21521   /* Construct the API message */
21522   M (DELETE_SUBIF, mp);
21523   mp->sw_if_index = ntohl (sw_if_index);
21524
21525   S (mp);
21526   W (ret);
21527   return ret;
21528 }
21529
21530 #define foreach_pbb_vtr_op      \
21531 _("disable",  L2_VTR_DISABLED)  \
21532 _("pop",  L2_VTR_POP_2)         \
21533 _("push",  L2_VTR_PUSH_2)
21534
21535 static int
21536 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21537 {
21538   unformat_input_t *i = vam->input;
21539   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21540   u32 sw_if_index = ~0, vtr_op = ~0;
21541   u16 outer_tag = ~0;
21542   u8 dmac[6], smac[6];
21543   u8 dmac_set = 0, smac_set = 0;
21544   u16 vlanid = 0;
21545   u32 sid = ~0;
21546   u32 tmp;
21547   int ret;
21548
21549   /* Shut up coverity */
21550   memset (dmac, 0, sizeof (dmac));
21551   memset (smac, 0, sizeof (smac));
21552
21553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21554     {
21555       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21556         ;
21557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21558         ;
21559       else if (unformat (i, "vtr_op %d", &vtr_op))
21560         ;
21561 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21562       foreach_pbb_vtr_op
21563 #undef _
21564         else if (unformat (i, "translate_pbb_stag"))
21565         {
21566           if (unformat (i, "%d", &tmp))
21567             {
21568               vtr_op = L2_VTR_TRANSLATE_2_1;
21569               outer_tag = tmp;
21570             }
21571           else
21572             {
21573               errmsg
21574                 ("translate_pbb_stag operation requires outer tag definition");
21575               return -99;
21576             }
21577         }
21578       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21579         dmac_set++;
21580       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21581         smac_set++;
21582       else if (unformat (i, "sid %d", &sid))
21583         ;
21584       else if (unformat (i, "vlanid %d", &tmp))
21585         vlanid = tmp;
21586       else
21587         {
21588           clib_warning ("parse error '%U'", format_unformat_error, i);
21589           return -99;
21590         }
21591     }
21592
21593   if ((sw_if_index == ~0) || (vtr_op == ~0))
21594     {
21595       errmsg ("missing sw_if_index or vtr operation");
21596       return -99;
21597     }
21598   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21599       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21600     {
21601       errmsg
21602         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21603       return -99;
21604     }
21605
21606   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21607   mp->sw_if_index = ntohl (sw_if_index);
21608   mp->vtr_op = ntohl (vtr_op);
21609   mp->outer_tag = ntohs (outer_tag);
21610   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21611   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21612   mp->b_vlanid = ntohs (vlanid);
21613   mp->i_sid = ntohl (sid);
21614
21615   S (mp);
21616   W (ret);
21617   return ret;
21618 }
21619
21620 static int
21621 api_flow_classify_set_interface (vat_main_t * vam)
21622 {
21623   unformat_input_t *i = vam->input;
21624   vl_api_flow_classify_set_interface_t *mp;
21625   u32 sw_if_index;
21626   int sw_if_index_set;
21627   u32 ip4_table_index = ~0;
21628   u32 ip6_table_index = ~0;
21629   u8 is_add = 1;
21630   int ret;
21631
21632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21633     {
21634       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21635         sw_if_index_set = 1;
21636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21637         sw_if_index_set = 1;
21638       else if (unformat (i, "del"))
21639         is_add = 0;
21640       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21641         ;
21642       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21643         ;
21644       else
21645         {
21646           clib_warning ("parse error '%U'", format_unformat_error, i);
21647           return -99;
21648         }
21649     }
21650
21651   if (sw_if_index_set == 0)
21652     {
21653       errmsg ("missing interface name or sw_if_index");
21654       return -99;
21655     }
21656
21657   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21658
21659   mp->sw_if_index = ntohl (sw_if_index);
21660   mp->ip4_table_index = ntohl (ip4_table_index);
21661   mp->ip6_table_index = ntohl (ip6_table_index);
21662   mp->is_add = is_add;
21663
21664   S (mp);
21665   W (ret);
21666   return ret;
21667 }
21668
21669 static int
21670 api_flow_classify_dump (vat_main_t * vam)
21671 {
21672   unformat_input_t *i = vam->input;
21673   vl_api_flow_classify_dump_t *mp;
21674   vl_api_control_ping_t *mp_ping;
21675   u8 type = FLOW_CLASSIFY_N_TABLES;
21676   int ret;
21677
21678   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21679     ;
21680   else
21681     {
21682       errmsg ("classify table type must be specified");
21683       return -99;
21684     }
21685
21686   if (!vam->json_output)
21687     {
21688       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21689     }
21690
21691   M (FLOW_CLASSIFY_DUMP, mp);
21692   mp->type = type;
21693   /* send it... */
21694   S (mp);
21695
21696   /* Use a control ping for synchronization */
21697   MPING (CONTROL_PING, mp_ping);
21698   S (mp_ping);
21699
21700   /* Wait for a reply... */
21701   W (ret);
21702   return ret;
21703 }
21704
21705 static int
21706 api_feature_enable_disable (vat_main_t * vam)
21707 {
21708   unformat_input_t *i = vam->input;
21709   vl_api_feature_enable_disable_t *mp;
21710   u8 *arc_name = 0;
21711   u8 *feature_name = 0;
21712   u32 sw_if_index = ~0;
21713   u8 enable = 1;
21714   int ret;
21715
21716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21717     {
21718       if (unformat (i, "arc_name %s", &arc_name))
21719         ;
21720       else if (unformat (i, "feature_name %s", &feature_name))
21721         ;
21722       else
21723         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21724         ;
21725       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21726         ;
21727       else if (unformat (i, "disable"))
21728         enable = 0;
21729       else
21730         break;
21731     }
21732
21733   if (arc_name == 0)
21734     {
21735       errmsg ("missing arc name");
21736       return -99;
21737     }
21738   if (vec_len (arc_name) > 63)
21739     {
21740       errmsg ("arc name too long");
21741     }
21742
21743   if (feature_name == 0)
21744     {
21745       errmsg ("missing feature name");
21746       return -99;
21747     }
21748   if (vec_len (feature_name) > 63)
21749     {
21750       errmsg ("feature name too long");
21751     }
21752
21753   if (sw_if_index == ~0)
21754     {
21755       errmsg ("missing interface name or sw_if_index");
21756       return -99;
21757     }
21758
21759   /* Construct the API message */
21760   M (FEATURE_ENABLE_DISABLE, mp);
21761   mp->sw_if_index = ntohl (sw_if_index);
21762   mp->enable = enable;
21763   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21764   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21765   vec_free (arc_name);
21766   vec_free (feature_name);
21767
21768   S (mp);
21769   W (ret);
21770   return ret;
21771 }
21772
21773 static int
21774 api_sw_interface_tag_add_del (vat_main_t * vam)
21775 {
21776   unformat_input_t *i = vam->input;
21777   vl_api_sw_interface_tag_add_del_t *mp;
21778   u32 sw_if_index = ~0;
21779   u8 *tag = 0;
21780   u8 enable = 1;
21781   int ret;
21782
21783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21784     {
21785       if (unformat (i, "tag %s", &tag))
21786         ;
21787       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21788         ;
21789       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21790         ;
21791       else if (unformat (i, "del"))
21792         enable = 0;
21793       else
21794         break;
21795     }
21796
21797   if (sw_if_index == ~0)
21798     {
21799       errmsg ("missing interface name or sw_if_index");
21800       return -99;
21801     }
21802
21803   if (enable && (tag == 0))
21804     {
21805       errmsg ("no tag specified");
21806       return -99;
21807     }
21808
21809   /* Construct the API message */
21810   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21811   mp->sw_if_index = ntohl (sw_if_index);
21812   mp->is_add = enable;
21813   if (enable)
21814     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21815   vec_free (tag);
21816
21817   S (mp);
21818   W (ret);
21819   return ret;
21820 }
21821
21822 static void vl_api_l2_xconnect_details_t_handler
21823   (vl_api_l2_xconnect_details_t * mp)
21824 {
21825   vat_main_t *vam = &vat_main;
21826
21827   print (vam->ofp, "%15d%15d",
21828          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21829 }
21830
21831 static void vl_api_l2_xconnect_details_t_handler_json
21832   (vl_api_l2_xconnect_details_t * mp)
21833 {
21834   vat_main_t *vam = &vat_main;
21835   vat_json_node_t *node = NULL;
21836
21837   if (VAT_JSON_ARRAY != vam->json_tree.type)
21838     {
21839       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21840       vat_json_init_array (&vam->json_tree);
21841     }
21842   node = vat_json_array_add (&vam->json_tree);
21843
21844   vat_json_init_object (node);
21845   vat_json_object_add_uint (node, "rx_sw_if_index",
21846                             ntohl (mp->rx_sw_if_index));
21847   vat_json_object_add_uint (node, "tx_sw_if_index",
21848                             ntohl (mp->tx_sw_if_index));
21849 }
21850
21851 static int
21852 api_l2_xconnect_dump (vat_main_t * vam)
21853 {
21854   vl_api_l2_xconnect_dump_t *mp;
21855   vl_api_control_ping_t *mp_ping;
21856   int ret;
21857
21858   if (!vam->json_output)
21859     {
21860       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21861     }
21862
21863   M (L2_XCONNECT_DUMP, mp);
21864
21865   S (mp);
21866
21867   /* Use a control ping for synchronization */
21868   MPING (CONTROL_PING, mp_ping);
21869   S (mp_ping);
21870
21871   W (ret);
21872   return ret;
21873 }
21874
21875 static int
21876 api_hw_interface_set_mtu (vat_main_t * vam)
21877 {
21878   unformat_input_t *i = vam->input;
21879   vl_api_hw_interface_set_mtu_t *mp;
21880   u32 sw_if_index = ~0;
21881   u32 mtu = 0;
21882   int ret;
21883
21884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21885     {
21886       if (unformat (i, "mtu %d", &mtu))
21887         ;
21888       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21889         ;
21890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21891         ;
21892       else
21893         break;
21894     }
21895
21896   if (sw_if_index == ~0)
21897     {
21898       errmsg ("missing interface name or sw_if_index");
21899       return -99;
21900     }
21901
21902   if (mtu == 0)
21903     {
21904       errmsg ("no mtu specified");
21905       return -99;
21906     }
21907
21908   /* Construct the API message */
21909   M (HW_INTERFACE_SET_MTU, mp);
21910   mp->sw_if_index = ntohl (sw_if_index);
21911   mp->mtu = ntohs ((u16) mtu);
21912
21913   S (mp);
21914   W (ret);
21915   return ret;
21916 }
21917
21918 static int
21919 api_p2p_ethernet_add (vat_main_t * vam)
21920 {
21921   unformat_input_t *i = vam->input;
21922   vl_api_p2p_ethernet_add_t *mp;
21923   u32 parent_if_index = ~0;
21924   u32 sub_id = ~0;
21925   u8 remote_mac[6];
21926   u8 mac_set = 0;
21927   int ret;
21928
21929   memset (remote_mac, 0, sizeof (remote_mac));
21930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21931     {
21932       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21933         ;
21934       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21935         ;
21936       else
21937         if (unformat
21938             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21939         mac_set++;
21940       else if (unformat (i, "sub_id %d", &sub_id))
21941         ;
21942       else
21943         {
21944           clib_warning ("parse error '%U'", format_unformat_error, i);
21945           return -99;
21946         }
21947     }
21948
21949   if (parent_if_index == ~0)
21950     {
21951       errmsg ("missing interface name or sw_if_index");
21952       return -99;
21953     }
21954   if (mac_set == 0)
21955     {
21956       errmsg ("missing remote mac address");
21957       return -99;
21958     }
21959   if (sub_id == ~0)
21960     {
21961       errmsg ("missing sub-interface id");
21962       return -99;
21963     }
21964
21965   M (P2P_ETHERNET_ADD, mp);
21966   mp->parent_if_index = ntohl (parent_if_index);
21967   mp->subif_id = ntohl (sub_id);
21968   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21969
21970   S (mp);
21971   W (ret);
21972   return ret;
21973 }
21974
21975 static int
21976 api_p2p_ethernet_del (vat_main_t * vam)
21977 {
21978   unformat_input_t *i = vam->input;
21979   vl_api_p2p_ethernet_del_t *mp;
21980   u32 parent_if_index = ~0;
21981   u8 remote_mac[6];
21982   u8 mac_set = 0;
21983   int ret;
21984
21985   memset (remote_mac, 0, sizeof (remote_mac));
21986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21987     {
21988       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21989         ;
21990       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21991         ;
21992       else
21993         if (unformat
21994             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21995         mac_set++;
21996       else
21997         {
21998           clib_warning ("parse error '%U'", format_unformat_error, i);
21999           return -99;
22000         }
22001     }
22002
22003   if (parent_if_index == ~0)
22004     {
22005       errmsg ("missing interface name or sw_if_index");
22006       return -99;
22007     }
22008   if (mac_set == 0)
22009     {
22010       errmsg ("missing remote mac address");
22011       return -99;
22012     }
22013
22014   M (P2P_ETHERNET_DEL, mp);
22015   mp->parent_if_index = ntohl (parent_if_index);
22016   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22017
22018   S (mp);
22019   W (ret);
22020   return ret;
22021 }
22022
22023 static int
22024 api_lldp_config (vat_main_t * vam)
22025 {
22026   unformat_input_t *i = vam->input;
22027   vl_api_lldp_config_t *mp;
22028   int tx_hold = 0;
22029   int tx_interval = 0;
22030   u8 *sys_name = NULL;
22031   int ret;
22032
22033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22034     {
22035       if (unformat (i, "system-name %s", &sys_name))
22036         ;
22037       else if (unformat (i, "tx-hold %d", &tx_hold))
22038         ;
22039       else if (unformat (i, "tx-interval %d", &tx_interval))
22040         ;
22041       else
22042         {
22043           clib_warning ("parse error '%U'", format_unformat_error, i);
22044           return -99;
22045         }
22046     }
22047
22048   vec_add1 (sys_name, 0);
22049
22050   M (LLDP_CONFIG, mp);
22051   mp->tx_hold = htonl (tx_hold);
22052   mp->tx_interval = htonl (tx_interval);
22053   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22054   vec_free (sys_name);
22055
22056   S (mp);
22057   W (ret);
22058   return ret;
22059 }
22060
22061 static int
22062 api_sw_interface_set_lldp (vat_main_t * vam)
22063 {
22064   unformat_input_t *i = vam->input;
22065   vl_api_sw_interface_set_lldp_t *mp;
22066   u32 sw_if_index = ~0;
22067   u32 enable = 1;
22068   u8 *port_desc = NULL, *mgmt_oid = NULL;
22069   ip4_address_t ip4_addr;
22070   ip6_address_t ip6_addr;
22071   int ret;
22072
22073   memset (&ip4_addr, 0, sizeof (ip4_addr));
22074   memset (&ip6_addr, 0, sizeof (ip6_addr));
22075
22076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22077     {
22078       if (unformat (i, "disable"))
22079         enable = 0;
22080       else
22081         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22082         ;
22083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22084         ;
22085       else if (unformat (i, "port-desc %s", &port_desc))
22086         ;
22087       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22088         ;
22089       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22090         ;
22091       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22092         ;
22093       else
22094         break;
22095     }
22096
22097   if (sw_if_index == ~0)
22098     {
22099       errmsg ("missing interface name or sw_if_index");
22100       return -99;
22101     }
22102
22103   /* Construct the API message */
22104   vec_add1 (port_desc, 0);
22105   vec_add1 (mgmt_oid, 0);
22106   M (SW_INTERFACE_SET_LLDP, mp);
22107   mp->sw_if_index = ntohl (sw_if_index);
22108   mp->enable = enable;
22109   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22110   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22111   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22112   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22113   vec_free (port_desc);
22114   vec_free (mgmt_oid);
22115
22116   S (mp);
22117   W (ret);
22118   return ret;
22119 }
22120
22121 static int
22122 api_tcp_configure_src_addresses (vat_main_t * vam)
22123 {
22124   vl_api_tcp_configure_src_addresses_t *mp;
22125   unformat_input_t *i = vam->input;
22126   ip4_address_t v4first, v4last;
22127   ip6_address_t v6first, v6last;
22128   u8 range_set = 0;
22129   u32 vrf_id = 0;
22130   int ret;
22131
22132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22133     {
22134       if (unformat (i, "%U - %U",
22135                     unformat_ip4_address, &v4first,
22136                     unformat_ip4_address, &v4last))
22137         {
22138           if (range_set)
22139             {
22140               errmsg ("one range per message (range already set)");
22141               return -99;
22142             }
22143           range_set = 1;
22144         }
22145       else if (unformat (i, "%U - %U",
22146                          unformat_ip6_address, &v6first,
22147                          unformat_ip6_address, &v6last))
22148         {
22149           if (range_set)
22150             {
22151               errmsg ("one range per message (range already set)");
22152               return -99;
22153             }
22154           range_set = 2;
22155         }
22156       else if (unformat (i, "vrf %d", &vrf_id))
22157         ;
22158       else
22159         break;
22160     }
22161
22162   if (range_set == 0)
22163     {
22164       errmsg ("address range not set");
22165       return -99;
22166     }
22167
22168   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22169   mp->vrf_id = ntohl (vrf_id);
22170   /* ipv6? */
22171   if (range_set == 2)
22172     {
22173       mp->is_ipv6 = 1;
22174       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22175       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22176     }
22177   else
22178     {
22179       mp->is_ipv6 = 0;
22180       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22181       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22182     }
22183   S (mp);
22184   W (ret);
22185   return ret;
22186 }
22187
22188 static void vl_api_app_namespace_add_del_reply_t_handler
22189   (vl_api_app_namespace_add_del_reply_t * mp)
22190 {
22191   vat_main_t *vam = &vat_main;
22192   i32 retval = ntohl (mp->retval);
22193   if (vam->async_mode)
22194     {
22195       vam->async_errors += (retval < 0);
22196     }
22197   else
22198     {
22199       vam->retval = retval;
22200       if (retval == 0)
22201         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22202       vam->result_ready = 1;
22203     }
22204 }
22205
22206 static void vl_api_app_namespace_add_del_reply_t_handler_json
22207   (vl_api_app_namespace_add_del_reply_t * mp)
22208 {
22209   vat_main_t *vam = &vat_main;
22210   vat_json_node_t node;
22211
22212   vat_json_init_object (&node);
22213   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22214   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22215
22216   vat_json_print (vam->ofp, &node);
22217   vat_json_free (&node);
22218
22219   vam->retval = ntohl (mp->retval);
22220   vam->result_ready = 1;
22221 }
22222
22223 static int
22224 api_app_namespace_add_del (vat_main_t * vam)
22225 {
22226   vl_api_app_namespace_add_del_t *mp;
22227   unformat_input_t *i = vam->input;
22228   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22229   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22230   u64 secret;
22231   int ret;
22232
22233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22234     {
22235       if (unformat (i, "id %_%v%_", &ns_id))
22236         ;
22237       else if (unformat (i, "secret %lu", &secret))
22238         secret_set = 1;
22239       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22240         sw_if_index_set = 1;
22241       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22242         ;
22243       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22244         ;
22245       else
22246         break;
22247     }
22248   if (!ns_id || !secret_set || !sw_if_index_set)
22249     {
22250       errmsg ("namespace id, secret and sw_if_index must be set");
22251       return -99;
22252     }
22253   if (vec_len (ns_id) > 64)
22254     {
22255       errmsg ("namespace id too long");
22256       return -99;
22257     }
22258   M (APP_NAMESPACE_ADD_DEL, mp);
22259
22260   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22261   mp->namespace_id_len = vec_len (ns_id);
22262   mp->secret = clib_host_to_net_u64 (secret);
22263   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22264   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22265   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22266   vec_free (ns_id);
22267   S (mp);
22268   W (ret);
22269   return ret;
22270 }
22271
22272 static int
22273 api_sock_init_shm (vat_main_t * vam)
22274 {
22275 #if VPP_API_TEST_BUILTIN == 0
22276   unformat_input_t *i = vam->input;
22277   vl_api_shm_elem_config_t *config = 0;
22278   u64 size = 64 << 20;
22279   int rv;
22280
22281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22282     {
22283       if (unformat (i, "size %U", unformat_memory_size, &size))
22284         ;
22285       else
22286         break;
22287     }
22288
22289   /*
22290    * Canned custom ring allocator config.
22291    * Should probably parse all of this
22292    */
22293   vec_validate (config, 6);
22294   config[0].type = VL_API_VLIB_RING;
22295   config[0].size = 256;
22296   config[0].count = 32;
22297
22298   config[1].type = VL_API_VLIB_RING;
22299   config[1].size = 1024;
22300   config[1].count = 16;
22301
22302   config[2].type = VL_API_VLIB_RING;
22303   config[2].size = 4096;
22304   config[2].count = 2;
22305
22306   config[3].type = VL_API_CLIENT_RING;
22307   config[3].size = 256;
22308   config[3].count = 32;
22309
22310   config[4].type = VL_API_CLIENT_RING;
22311   config[4].size = 1024;
22312   config[4].count = 16;
22313
22314   config[5].type = VL_API_CLIENT_RING;
22315   config[5].size = 4096;
22316   config[5].count = 2;
22317
22318   config[6].type = VL_API_QUEUE;
22319   config[6].count = 128;
22320   config[6].size = sizeof (uword);
22321
22322   rv = vl_socket_client_init_shm (config);
22323   if (!rv)
22324     vam->client_index_invalid = 1;
22325   return rv;
22326 #else
22327   return -99;
22328 #endif
22329 }
22330
22331 static int
22332 api_dns_enable_disable (vat_main_t * vam)
22333 {
22334   unformat_input_t *line_input = vam->input;
22335   vl_api_dns_enable_disable_t *mp;
22336   u8 enable_disable = 1;
22337   int ret;
22338
22339   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22340     {
22341       if (unformat (line_input, "disable"))
22342         enable_disable = 0;
22343       if (unformat (line_input, "enable"))
22344         enable_disable = 1;
22345       else
22346         break;
22347     }
22348
22349   /* Construct the API message */
22350   M (DNS_ENABLE_DISABLE, mp);
22351   mp->enable = enable_disable;
22352
22353   /* send it... */
22354   S (mp);
22355   /* Wait for the reply */
22356   W (ret);
22357   return ret;
22358 }
22359
22360 static int
22361 api_dns_resolve_name (vat_main_t * vam)
22362 {
22363   unformat_input_t *line_input = vam->input;
22364   vl_api_dns_resolve_name_t *mp;
22365   u8 *name = 0;
22366   int ret;
22367
22368   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22369     {
22370       if (unformat (line_input, "%s", &name))
22371         ;
22372       else
22373         break;
22374     }
22375
22376   if (vec_len (name) > 127)
22377     {
22378       errmsg ("name too long");
22379       return -99;
22380     }
22381
22382   /* Construct the API message */
22383   M (DNS_RESOLVE_NAME, mp);
22384   memcpy (mp->name, name, vec_len (name));
22385   vec_free (name);
22386
22387   /* send it... */
22388   S (mp);
22389   /* Wait for the reply */
22390   W (ret);
22391   return ret;
22392 }
22393
22394 static int
22395 api_dns_resolve_ip (vat_main_t * vam)
22396 {
22397   unformat_input_t *line_input = vam->input;
22398   vl_api_dns_resolve_ip_t *mp;
22399   int is_ip6 = -1;
22400   ip4_address_t addr4;
22401   ip6_address_t addr6;
22402   int ret;
22403
22404   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22405     {
22406       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22407         is_ip6 = 1;
22408       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22409         is_ip6 = 0;
22410       else
22411         break;
22412     }
22413
22414   if (is_ip6 == -1)
22415     {
22416       errmsg ("missing address");
22417       return -99;
22418     }
22419
22420   /* Construct the API message */
22421   M (DNS_RESOLVE_IP, mp);
22422   mp->is_ip6 = is_ip6;
22423   if (is_ip6)
22424     memcpy (mp->address, &addr6, sizeof (addr6));
22425   else
22426     memcpy (mp->address, &addr4, sizeof (addr4));
22427
22428   /* send it... */
22429   S (mp);
22430   /* Wait for the reply */
22431   W (ret);
22432   return ret;
22433 }
22434
22435 static int
22436 api_dns_name_server_add_del (vat_main_t * vam)
22437 {
22438   unformat_input_t *i = vam->input;
22439   vl_api_dns_name_server_add_del_t *mp;
22440   u8 is_add = 1;
22441   ip6_address_t ip6_server;
22442   ip4_address_t ip4_server;
22443   int ip6_set = 0;
22444   int ip4_set = 0;
22445   int ret = 0;
22446
22447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22448     {
22449       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22450         ip6_set = 1;
22451       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22452         ip4_set = 1;
22453       else if (unformat (i, "del"))
22454         is_add = 0;
22455       else
22456         {
22457           clib_warning ("parse error '%U'", format_unformat_error, i);
22458           return -99;
22459         }
22460     }
22461
22462   if (ip4_set && ip6_set)
22463     {
22464       errmsg ("Only one server address allowed per message");
22465       return -99;
22466     }
22467   if ((ip4_set + ip6_set) == 0)
22468     {
22469       errmsg ("Server address required");
22470       return -99;
22471     }
22472
22473   /* Construct the API message */
22474   M (DNS_NAME_SERVER_ADD_DEL, mp);
22475
22476   if (ip6_set)
22477     {
22478       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22479       mp->is_ip6 = 1;
22480     }
22481   else
22482     {
22483       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22484       mp->is_ip6 = 0;
22485     }
22486
22487   mp->is_add = is_add;
22488
22489   /* send it... */
22490   S (mp);
22491
22492   /* Wait for a reply, return good/bad news  */
22493   W (ret);
22494   return ret;
22495 }
22496
22497 static void
22498 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22499 {
22500   vat_main_t *vam = &vat_main;
22501
22502   if (mp->is_ip4)
22503     {
22504       print (vam->ofp,
22505              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22506              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22507              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22508              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22509              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22510              clib_net_to_host_u32 (mp->action_index), mp->tag);
22511     }
22512   else
22513     {
22514       print (vam->ofp,
22515              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22516              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22517              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22518              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22519              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22520              clib_net_to_host_u32 (mp->action_index), mp->tag);
22521     }
22522 }
22523
22524 static void
22525 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22526                                              mp)
22527 {
22528   vat_main_t *vam = &vat_main;
22529   vat_json_node_t *node = NULL;
22530   struct in6_addr ip6;
22531   struct in_addr ip4;
22532
22533   if (VAT_JSON_ARRAY != vam->json_tree.type)
22534     {
22535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22536       vat_json_init_array (&vam->json_tree);
22537     }
22538   node = vat_json_array_add (&vam->json_tree);
22539   vat_json_init_object (node);
22540
22541   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22542   vat_json_object_add_uint (node, "appns_index",
22543                             clib_net_to_host_u32 (mp->appns_index));
22544   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22545   vat_json_object_add_uint (node, "scope", mp->scope);
22546   vat_json_object_add_uint (node, "action_index",
22547                             clib_net_to_host_u32 (mp->action_index));
22548   vat_json_object_add_uint (node, "lcl_port",
22549                             clib_net_to_host_u16 (mp->lcl_port));
22550   vat_json_object_add_uint (node, "rmt_port",
22551                             clib_net_to_host_u16 (mp->rmt_port));
22552   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22553   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22554   vat_json_object_add_string_copy (node, "tag", mp->tag);
22555   if (mp->is_ip4)
22556     {
22557       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22558       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22559       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22560       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22561     }
22562   else
22563     {
22564       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22565       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22566       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22567       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22568     }
22569 }
22570
22571 static int
22572 api_session_rule_add_del (vat_main_t * vam)
22573 {
22574   vl_api_session_rule_add_del_t *mp;
22575   unformat_input_t *i = vam->input;
22576   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22577   u32 appns_index = 0, scope = 0;
22578   ip4_address_t lcl_ip4, rmt_ip4;
22579   ip6_address_t lcl_ip6, rmt_ip6;
22580   u8 is_ip4 = 1, conn_set = 0;
22581   u8 is_add = 1, *tag = 0;
22582   int ret;
22583
22584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22585     {
22586       if (unformat (i, "del"))
22587         is_add = 0;
22588       else if (unformat (i, "add"))
22589         ;
22590       else if (unformat (i, "proto tcp"))
22591         proto = 0;
22592       else if (unformat (i, "proto udp"))
22593         proto = 1;
22594       else if (unformat (i, "appns %d", &appns_index))
22595         ;
22596       else if (unformat (i, "scope %d", &scope))
22597         ;
22598       else if (unformat (i, "tag %_%v%_", &tag))
22599         ;
22600       else
22601         if (unformat
22602             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22603              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22604              &rmt_port))
22605         {
22606           is_ip4 = 1;
22607           conn_set = 1;
22608         }
22609       else
22610         if (unformat
22611             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22612              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22613              &rmt_port))
22614         {
22615           is_ip4 = 0;
22616           conn_set = 1;
22617         }
22618       else if (unformat (i, "action %d", &action))
22619         ;
22620       else
22621         break;
22622     }
22623   if (proto == ~0 || !conn_set || action == ~0)
22624     {
22625       errmsg ("transport proto, connection and action must be set");
22626       return -99;
22627     }
22628
22629   if (scope > 3)
22630     {
22631       errmsg ("scope should be 0-3");
22632       return -99;
22633     }
22634
22635   M (SESSION_RULE_ADD_DEL, mp);
22636
22637   mp->is_ip4 = is_ip4;
22638   mp->transport_proto = proto;
22639   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22640   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22641   mp->lcl_plen = lcl_plen;
22642   mp->rmt_plen = rmt_plen;
22643   mp->action_index = clib_host_to_net_u32 (action);
22644   mp->appns_index = clib_host_to_net_u32 (appns_index);
22645   mp->scope = scope;
22646   mp->is_add = is_add;
22647   if (is_ip4)
22648     {
22649       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22650       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22651     }
22652   else
22653     {
22654       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22655       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22656     }
22657   if (tag)
22658     {
22659       clib_memcpy (mp->tag, tag, vec_len (tag));
22660       vec_free (tag);
22661     }
22662
22663   S (mp);
22664   W (ret);
22665   return ret;
22666 }
22667
22668 static int
22669 api_session_rules_dump (vat_main_t * vam)
22670 {
22671   vl_api_session_rules_dump_t *mp;
22672   vl_api_control_ping_t *mp_ping;
22673   int ret;
22674
22675   if (!vam->json_output)
22676     {
22677       print (vam->ofp, "%=20s", "Session Rules");
22678     }
22679
22680   M (SESSION_RULES_DUMP, mp);
22681   /* send it... */
22682   S (mp);
22683
22684   /* Use a control ping for synchronization */
22685   MPING (CONTROL_PING, mp_ping);
22686   S (mp_ping);
22687
22688   /* Wait for a reply... */
22689   W (ret);
22690   return ret;
22691 }
22692
22693 static int
22694 api_ip_container_proxy_add_del (vat_main_t * vam)
22695 {
22696   vl_api_ip_container_proxy_add_del_t *mp;
22697   unformat_input_t *i = vam->input;
22698   u32 plen = ~0, sw_if_index = ~0;
22699   ip4_address_t ip4;
22700   ip6_address_t ip6;
22701   u8 is_ip4 = 1;
22702   u8 is_add = 1;
22703   int ret;
22704
22705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22706     {
22707       if (unformat (i, "del"))
22708         is_add = 0;
22709       else if (unformat (i, "add"))
22710         ;
22711       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22712         {
22713           is_ip4 = 1;
22714           plen = 32;
22715         }
22716       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22717         {
22718           is_ip4 = 0;
22719           plen = 128;
22720         }
22721       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22722         ;
22723       else
22724         break;
22725     }
22726   if (sw_if_index == ~0 || plen == ~0)
22727     {
22728       errmsg ("address and sw_if_index must be set");
22729       return -99;
22730     }
22731
22732   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22733
22734   mp->is_ip4 = is_ip4;
22735   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22736   mp->plen = plen;
22737   mp->is_add = is_add;
22738   if (is_ip4)
22739     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22740   else
22741     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22742
22743   S (mp);
22744   W (ret);
22745   return ret;
22746 }
22747
22748 static int
22749 api_qos_record_enable_disable (vat_main_t * vam)
22750 {
22751   unformat_input_t *i = vam->input;
22752   vl_api_qos_record_enable_disable_t *mp;
22753   u32 sw_if_index, qs = 0xff;
22754   u8 sw_if_index_set = 0;
22755   u8 enable = 1;
22756   int ret;
22757
22758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22759     {
22760       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22761         sw_if_index_set = 1;
22762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22763         sw_if_index_set = 1;
22764       else if (unformat (i, "%U", unformat_qos_source, &qs))
22765         ;
22766       else if (unformat (i, "disable"))
22767         enable = 0;
22768       else
22769         {
22770           clib_warning ("parse error '%U'", format_unformat_error, i);
22771           return -99;
22772         }
22773     }
22774
22775   if (sw_if_index_set == 0)
22776     {
22777       errmsg ("missing interface name or sw_if_index");
22778       return -99;
22779     }
22780   if (qs == 0xff)
22781     {
22782       errmsg ("input location must be specified");
22783       return -99;
22784     }
22785
22786   M (QOS_RECORD_ENABLE_DISABLE, mp);
22787
22788   mp->sw_if_index = ntohl (sw_if_index);
22789   mp->input_source = qs;
22790   mp->enable = enable;
22791
22792   S (mp);
22793   W (ret);
22794   return ret;
22795 }
22796
22797
22798 static int
22799 q_or_quit (vat_main_t * vam)
22800 {
22801 #if VPP_API_TEST_BUILTIN == 0
22802   longjmp (vam->jump_buf, 1);
22803 #endif
22804   return 0;                     /* not so much */
22805 }
22806
22807 static int
22808 q (vat_main_t * vam)
22809 {
22810   return q_or_quit (vam);
22811 }
22812
22813 static int
22814 quit (vat_main_t * vam)
22815 {
22816   return q_or_quit (vam);
22817 }
22818
22819 static int
22820 comment (vat_main_t * vam)
22821 {
22822   return 0;
22823 }
22824
22825 static int
22826 statseg (vat_main_t * vam)
22827 {
22828   ssvm_private_t *ssvmp = &vam->stat_segment;
22829   ssvm_shared_header_t *shared_header = ssvmp->sh;
22830   vlib_counter_t **counters;
22831   u64 thread0_index1_packets;
22832   u64 thread0_index1_bytes;
22833   f64 vector_rate, input_rate;
22834   uword *p;
22835
22836   uword *counter_vector_by_name;
22837   if (vam->stat_segment_lockp == 0)
22838     {
22839       errmsg ("Stat segment not mapped...");
22840       return -99;
22841     }
22842
22843   /* look up "/if/rx for sw_if_index 1 as a test */
22844
22845   clib_spinlock_lock (vam->stat_segment_lockp);
22846
22847   counter_vector_by_name = (uword *) shared_header->opaque[1];
22848
22849   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22850   if (p == 0)
22851     {
22852       clib_spinlock_unlock (vam->stat_segment_lockp);
22853       errmsg ("/if/tx not found?");
22854       return -99;
22855     }
22856
22857   /* Fish per-thread vector of combined counters from shared memory */
22858   counters = (vlib_counter_t **) p[0];
22859
22860   if (vec_len (counters[0]) < 2)
22861     {
22862       clib_spinlock_unlock (vam->stat_segment_lockp);
22863       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22864       return -99;
22865     }
22866
22867   /* Read thread 0 sw_if_index 1 counter */
22868   thread0_index1_packets = counters[0][1].packets;
22869   thread0_index1_bytes = counters[0][1].bytes;
22870
22871   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22872   if (p == 0)
22873     {
22874       clib_spinlock_unlock (vam->stat_segment_lockp);
22875       errmsg ("vector_rate not found?");
22876       return -99;
22877     }
22878
22879   vector_rate = *(f64 *) (p[0]);
22880   p = hash_get_mem (counter_vector_by_name, "input_rate");
22881   if (p == 0)
22882     {
22883       clib_spinlock_unlock (vam->stat_segment_lockp);
22884       errmsg ("input_rate not found?");
22885       return -99;
22886     }
22887   input_rate = *(f64 *) (p[0]);
22888
22889   clib_spinlock_unlock (vam->stat_segment_lockp);
22890
22891   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22892          vector_rate, input_rate);
22893   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22894          thread0_index1_packets, thread0_index1_bytes);
22895
22896   return 0;
22897 }
22898
22899 static int
22900 cmd_cmp (void *a1, void *a2)
22901 {
22902   u8 **c1 = a1;
22903   u8 **c2 = a2;
22904
22905   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22906 }
22907
22908 static int
22909 help (vat_main_t * vam)
22910 {
22911   u8 **cmds = 0;
22912   u8 *name = 0;
22913   hash_pair_t *p;
22914   unformat_input_t *i = vam->input;
22915   int j;
22916
22917   if (unformat (i, "%s", &name))
22918     {
22919       uword *hs;
22920
22921       vec_add1 (name, 0);
22922
22923       hs = hash_get_mem (vam->help_by_name, name);
22924       if (hs)
22925         print (vam->ofp, "usage: %s %s", name, hs[0]);
22926       else
22927         print (vam->ofp, "No such msg / command '%s'", name);
22928       vec_free (name);
22929       return 0;
22930     }
22931
22932   print (vam->ofp, "Help is available for the following:");
22933
22934     /* *INDENT-OFF* */
22935     hash_foreach_pair (p, vam->function_by_name,
22936     ({
22937       vec_add1 (cmds, (u8 *)(p->key));
22938     }));
22939     /* *INDENT-ON* */
22940
22941   vec_sort_with_function (cmds, cmd_cmp);
22942
22943   for (j = 0; j < vec_len (cmds); j++)
22944     print (vam->ofp, "%s", cmds[j]);
22945
22946   vec_free (cmds);
22947   return 0;
22948 }
22949
22950 static int
22951 set (vat_main_t * vam)
22952 {
22953   u8 *name = 0, *value = 0;
22954   unformat_input_t *i = vam->input;
22955
22956   if (unformat (i, "%s", &name))
22957     {
22958       /* The input buffer is a vector, not a string. */
22959       value = vec_dup (i->buffer);
22960       vec_delete (value, i->index, 0);
22961       /* Almost certainly has a trailing newline */
22962       if (value[vec_len (value) - 1] == '\n')
22963         value[vec_len (value) - 1] = 0;
22964       /* Make sure it's a proper string, one way or the other */
22965       vec_add1 (value, 0);
22966       (void) clib_macro_set_value (&vam->macro_main,
22967                                    (char *) name, (char *) value);
22968     }
22969   else
22970     errmsg ("usage: set <name> <value>");
22971
22972   vec_free (name);
22973   vec_free (value);
22974   return 0;
22975 }
22976
22977 static int
22978 unset (vat_main_t * vam)
22979 {
22980   u8 *name = 0;
22981
22982   if (unformat (vam->input, "%s", &name))
22983     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22984       errmsg ("unset: %s wasn't set", name);
22985   vec_free (name);
22986   return 0;
22987 }
22988
22989 typedef struct
22990 {
22991   u8 *name;
22992   u8 *value;
22993 } macro_sort_t;
22994
22995
22996 static int
22997 macro_sort_cmp (void *a1, void *a2)
22998 {
22999   macro_sort_t *s1 = a1;
23000   macro_sort_t *s2 = a2;
23001
23002   return strcmp ((char *) (s1->name), (char *) (s2->name));
23003 }
23004
23005 static int
23006 dump_macro_table (vat_main_t * vam)
23007 {
23008   macro_sort_t *sort_me = 0, *sm;
23009   int i;
23010   hash_pair_t *p;
23011
23012     /* *INDENT-OFF* */
23013     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23014     ({
23015       vec_add2 (sort_me, sm, 1);
23016       sm->name = (u8 *)(p->key);
23017       sm->value = (u8 *) (p->value[0]);
23018     }));
23019     /* *INDENT-ON* */
23020
23021   vec_sort_with_function (sort_me, macro_sort_cmp);
23022
23023   if (vec_len (sort_me))
23024     print (vam->ofp, "%-15s%s", "Name", "Value");
23025   else
23026     print (vam->ofp, "The macro table is empty...");
23027
23028   for (i = 0; i < vec_len (sort_me); i++)
23029     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23030   return 0;
23031 }
23032
23033 static int
23034 dump_node_table (vat_main_t * vam)
23035 {
23036   int i, j;
23037   vlib_node_t *node, *next_node;
23038
23039   if (vec_len (vam->graph_nodes) == 0)
23040     {
23041       print (vam->ofp, "Node table empty, issue get_node_graph...");
23042       return 0;
23043     }
23044
23045   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23046     {
23047       node = vam->graph_nodes[0][i];
23048       print (vam->ofp, "[%d] %s", i, node->name);
23049       for (j = 0; j < vec_len (node->next_nodes); j++)
23050         {
23051           if (node->next_nodes[j] != ~0)
23052             {
23053               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23054               print (vam->ofp, "  [%d] %s", j, next_node->name);
23055             }
23056         }
23057     }
23058   return 0;
23059 }
23060
23061 static int
23062 value_sort_cmp (void *a1, void *a2)
23063 {
23064   name_sort_t *n1 = a1;
23065   name_sort_t *n2 = a2;
23066
23067   if (n1->value < n2->value)
23068     return -1;
23069   if (n1->value > n2->value)
23070     return 1;
23071   return 0;
23072 }
23073
23074
23075 static int
23076 dump_msg_api_table (vat_main_t * vam)
23077 {
23078   api_main_t *am = &api_main;
23079   name_sort_t *nses = 0, *ns;
23080   hash_pair_t *hp;
23081   int i;
23082
23083   /* *INDENT-OFF* */
23084   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23085   ({
23086     vec_add2 (nses, ns, 1);
23087     ns->name = (u8 *)(hp->key);
23088     ns->value = (u32) hp->value[0];
23089   }));
23090   /* *INDENT-ON* */
23091
23092   vec_sort_with_function (nses, value_sort_cmp);
23093
23094   for (i = 0; i < vec_len (nses); i++)
23095     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23096   vec_free (nses);
23097   return 0;
23098 }
23099
23100 static int
23101 get_msg_id (vat_main_t * vam)
23102 {
23103   u8 *name_and_crc;
23104   u32 message_index;
23105
23106   if (unformat (vam->input, "%s", &name_and_crc))
23107     {
23108       message_index = vl_msg_api_get_msg_index (name_and_crc);
23109       if (message_index == ~0)
23110         {
23111           print (vam->ofp, " '%s' not found", name_and_crc);
23112           return 0;
23113         }
23114       print (vam->ofp, " '%s' has message index %d",
23115              name_and_crc, message_index);
23116       return 0;
23117     }
23118   errmsg ("name_and_crc required...");
23119   return 0;
23120 }
23121
23122 static int
23123 search_node_table (vat_main_t * vam)
23124 {
23125   unformat_input_t *line_input = vam->input;
23126   u8 *node_to_find;
23127   int j;
23128   vlib_node_t *node, *next_node;
23129   uword *p;
23130
23131   if (vam->graph_node_index_by_name == 0)
23132     {
23133       print (vam->ofp, "Node table empty, issue get_node_graph...");
23134       return 0;
23135     }
23136
23137   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23138     {
23139       if (unformat (line_input, "%s", &node_to_find))
23140         {
23141           vec_add1 (node_to_find, 0);
23142           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23143           if (p == 0)
23144             {
23145               print (vam->ofp, "%s not found...", node_to_find);
23146               goto out;
23147             }
23148           node = vam->graph_nodes[0][p[0]];
23149           print (vam->ofp, "[%d] %s", p[0], node->name);
23150           for (j = 0; j < vec_len (node->next_nodes); j++)
23151             {
23152               if (node->next_nodes[j] != ~0)
23153                 {
23154                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23155                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23156                 }
23157             }
23158         }
23159
23160       else
23161         {
23162           clib_warning ("parse error '%U'", format_unformat_error,
23163                         line_input);
23164           return -99;
23165         }
23166
23167     out:
23168       vec_free (node_to_find);
23169
23170     }
23171
23172   return 0;
23173 }
23174
23175
23176 static int
23177 script (vat_main_t * vam)
23178 {
23179 #if (VPP_API_TEST_BUILTIN==0)
23180   u8 *s = 0;
23181   char *save_current_file;
23182   unformat_input_t save_input;
23183   jmp_buf save_jump_buf;
23184   u32 save_line_number;
23185
23186   FILE *new_fp, *save_ifp;
23187
23188   if (unformat (vam->input, "%s", &s))
23189     {
23190       new_fp = fopen ((char *) s, "r");
23191       if (new_fp == 0)
23192         {
23193           errmsg ("Couldn't open script file %s", s);
23194           vec_free (s);
23195           return -99;
23196         }
23197     }
23198   else
23199     {
23200       errmsg ("Missing script name");
23201       return -99;
23202     }
23203
23204   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23205   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23206   save_ifp = vam->ifp;
23207   save_line_number = vam->input_line_number;
23208   save_current_file = (char *) vam->current_file;
23209
23210   vam->input_line_number = 0;
23211   vam->ifp = new_fp;
23212   vam->current_file = s;
23213   do_one_file (vam);
23214
23215   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23216   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23217   vam->ifp = save_ifp;
23218   vam->input_line_number = save_line_number;
23219   vam->current_file = (u8 *) save_current_file;
23220   vec_free (s);
23221
23222   return 0;
23223 #else
23224   clib_warning ("use the exec command...");
23225   return -99;
23226 #endif
23227 }
23228
23229 static int
23230 echo (vat_main_t * vam)
23231 {
23232   print (vam->ofp, "%v", vam->input->buffer);
23233   return 0;
23234 }
23235
23236 /* List of API message constructors, CLI names map to api_xxx */
23237 #define foreach_vpe_api_msg                                             \
23238 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23239 _(sw_interface_dump,"")                                                 \
23240 _(sw_interface_set_flags,                                               \
23241   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23242 _(sw_interface_add_del_address,                                         \
23243   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23244 _(sw_interface_set_rx_mode,                                             \
23245   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23246 _(sw_interface_set_table,                                               \
23247   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23248 _(sw_interface_set_mpls_enable,                                         \
23249   "<intfc> | sw_if_index [disable | dis]")                              \
23250 _(sw_interface_set_vpath,                                               \
23251   "<intfc> | sw_if_index <id> enable | disable")                        \
23252 _(sw_interface_set_vxlan_bypass,                                        \
23253   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23254 _(sw_interface_set_geneve_bypass,                                       \
23255   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23256 _(sw_interface_set_l2_xconnect,                                         \
23257   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23258   "enable | disable")                                                   \
23259 _(sw_interface_set_l2_bridge,                                           \
23260   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23261   "[shg <split-horizon-group>] [bvi]\n"                                 \
23262   "enable | disable")                                                   \
23263 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23264 _(bridge_domain_add_del,                                                \
23265   "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") \
23266 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23267 _(l2fib_add_del,                                                        \
23268   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23269 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23270 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23271 _(l2_flags,                                                             \
23272   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23273 _(bridge_flags,                                                         \
23274   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23275 _(tap_connect,                                                          \
23276   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23277 _(tap_modify,                                                           \
23278   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23279 _(tap_delete,                                                           \
23280   "<vpp-if-name> | sw_if_index <id>")                                   \
23281 _(sw_interface_tap_dump, "")                                            \
23282 _(tap_create_v2,                                                        \
23283   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23284 _(tap_delete_v2,                                                        \
23285   "<vpp-if-name> | sw_if_index <id>")                                   \
23286 _(sw_interface_tap_v2_dump, "")                                         \
23287 _(bond_create,                                                          \
23288   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23289   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23290 _(bond_delete,                                                          \
23291   "<vpp-if-name> | sw_if_index <id>")                                   \
23292 _(bond_enslave,                                                         \
23293   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23294 _(bond_detach_slave,                                                    \
23295   "sw_if_index <n>")                                                    \
23296 _(sw_interface_bond_dump, "")                                           \
23297 _(sw_interface_slave_dump,                                              \
23298   "<vpp-if-name> | sw_if_index <id>")                                   \
23299 _(ip_table_add_del,                                                     \
23300   "table-id <n> [ipv6]\n")                                              \
23301 _(ip_add_del_route,                                                     \
23302   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23303   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23304   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23305   "[multipath] [count <n>]")                                            \
23306 _(ip_mroute_add_del,                                                    \
23307   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23308   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23309 _(mpls_table_add_del,                                                   \
23310   "table-id <n>\n")                                                     \
23311 _(mpls_route_add_del,                                                   \
23312   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23313   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23314   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23315   "[multipath] [count <n>]")                                            \
23316 _(mpls_ip_bind_unbind,                                                  \
23317   "<label> <addr/len>")                                                 \
23318 _(mpls_tunnel_add_del,                                                  \
23319   " via <addr> [table-id <n>]\n"                                        \
23320   "sw_if_index <id>] [l2]  [del]")                                      \
23321 _(bier_table_add_del,                                                   \
23322   "<label> <sub-domain> <set> <bsl> [del]")                             \
23323 _(bier_route_add_del,                                                   \
23324   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23325   "[<intfc> | sw_if_index <id>]"                                        \
23326   "[weight <n>] [del] [multipath]")                                     \
23327 _(proxy_arp_add_del,                                                    \
23328   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23329 _(proxy_arp_intfc_enable_disable,                                       \
23330   "<intfc> | sw_if_index <id> enable | disable")                        \
23331 _(sw_interface_set_unnumbered,                                          \
23332   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23333 _(ip_neighbor_add_del,                                                  \
23334   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23335   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23336 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23337 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23338   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23339   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23340   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23341 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23342 _(reset_fib, "vrf <n> [ipv6]")                                          \
23343 _(dhcp_proxy_config,                                                    \
23344   "svr <v46-address> src <v46-address>\n"                               \
23345    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23346 _(dhcp_proxy_set_vss,                                                   \
23347   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23348 _(dhcp_proxy_dump, "ip6")                                               \
23349 _(dhcp_client_config,                                                   \
23350   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23351 _(set_ip_flow_hash,                                                     \
23352   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23353 _(sw_interface_ip6_enable_disable,                                      \
23354   "<intfc> | sw_if_index <id> enable | disable")                        \
23355 _(sw_interface_ip6_set_link_local_address,                              \
23356   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23357 _(ip6nd_proxy_add_del,                                                  \
23358   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23359 _(ip6nd_proxy_dump, "")                                                 \
23360 _(sw_interface_ip6nd_ra_prefix,                                         \
23361   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23362   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23363   "[nolink] [isno]")                                                    \
23364 _(sw_interface_ip6nd_ra_config,                                         \
23365   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23366   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23367   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23368 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23369 _(l2_patch_add_del,                                                     \
23370   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23371   "enable | disable")                                                   \
23372 _(sr_localsid_add_del,                                                  \
23373   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23374   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23375 _(classify_add_del_table,                                               \
23376   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23377   " [del] [del-chain] mask <mask-value>\n"                              \
23378   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23379   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23380 _(classify_add_del_session,                                             \
23381   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23382   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23383   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23384   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23385 _(classify_set_interface_ip_table,                                      \
23386   "<intfc> | sw_if_index <nn> table <nn>")                              \
23387 _(classify_set_interface_l2_tables,                                     \
23388   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23389   "  [other-table <nn>]")                                               \
23390 _(get_node_index, "node <node-name")                                    \
23391 _(add_node_next, "node <node-name> next <next-node-name>")              \
23392 _(l2tpv3_create_tunnel,                                                 \
23393   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23394   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23395   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23396 _(l2tpv3_set_tunnel_cookies,                                            \
23397   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23398   "[new_remote_cookie <nn>]\n")                                         \
23399 _(l2tpv3_interface_enable_disable,                                      \
23400   "<intfc> | sw_if_index <nn> enable | disable")                        \
23401 _(l2tpv3_set_lookup_key,                                                \
23402   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23403 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23404 _(vxlan_offload_rx,                                                     \
23405   "hw { <interface name> | hw_if_index <nn>} "                          \
23406   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23407 _(vxlan_add_del_tunnel,                                                 \
23408   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23409   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23410   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23411 _(geneve_add_del_tunnel,                                                \
23412   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23413   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23414   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23415 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23416 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23417 _(gre_add_del_tunnel,                                                   \
23418   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23419   "[teb | erspan <session-id>] [del]")                                  \
23420 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23421 _(l2_fib_clear_table, "")                                               \
23422 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23423 _(l2_interface_vlan_tag_rewrite,                                        \
23424   "<intfc> | sw_if_index <nn> \n"                                       \
23425   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23426   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23427 _(create_vhost_user_if,                                                 \
23428         "socket <filename> [server] [renumber <dev_instance>] "         \
23429         "[mac <mac_address>]")                                          \
23430 _(modify_vhost_user_if,                                                 \
23431         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23432         "[server] [renumber <dev_instance>]")                           \
23433 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23434 _(sw_interface_vhost_user_dump, "")                                     \
23435 _(show_version, "")                                                     \
23436 _(vxlan_gpe_add_del_tunnel,                                             \
23437   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23438   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23439   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23440   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23441 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23442 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23443 _(interface_name_renumber,                                              \
23444   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23445 _(input_acl_set_interface,                                              \
23446   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23447   "  [l2-table <nn>] [del]")                                            \
23448 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23449 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23450   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23451 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23452 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23453 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23454 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23455 _(ip_dump, "ipv4 | ipv6")                                               \
23456 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23457 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23458   "  spid_id <n> ")                                                     \
23459 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23460   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23461   "  integ_alg <alg> integ_key <hex>")                                  \
23462 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23463   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23464   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23465   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23466 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23467 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23468   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23469   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23470   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23471   "  [instance <n>]")     \
23472 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23473 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23474   "  <alg> <hex>\n")                                                    \
23475 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23476 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23477 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23478   "(auth_data 0x<data> | auth_data <data>)")                            \
23479 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23480   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23481 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23482   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23483   "(local|remote)")                                                     \
23484 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23485 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23486 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23487 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23488 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23489 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23490 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23491 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23492 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23493 _(delete_loopback,"sw_if_index <nn>")                                   \
23494 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23495 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23496 _(want_interface_events,  "enable|disable")                             \
23497 _(want_stats,"enable|disable")                                          \
23498 _(get_first_msg_id, "client <name>")                                    \
23499 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23500 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23501   "fib-id <nn> [ip4][ip6][default]")                                    \
23502 _(get_node_graph, " ")                                                  \
23503 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23504 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23505 _(ioam_disable, "")                                                     \
23506 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23507                             " sw_if_index <sw_if_index> p <priority> "  \
23508                             "w <weight>] [del]")                        \
23509 _(one_add_del_locator, "locator-set <locator_name> "                    \
23510                         "iface <intf> | sw_if_index <sw_if_index> "     \
23511                         "p <priority> w <weight> [del]")                \
23512 _(one_add_del_local_eid,"vni <vni> eid "                                \
23513                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23514                          "locator-set <locator_name> [del]"             \
23515                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23516 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23517 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23518 _(one_enable_disable, "enable|disable")                                 \
23519 _(one_map_register_enable_disable, "enable|disable")                    \
23520 _(one_map_register_fallback_threshold, "<value>")                       \
23521 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23522 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23523                                "[seid <seid>] "                         \
23524                                "rloc <locator> p <prio> "               \
23525                                "w <weight> [rloc <loc> ... ] "          \
23526                                "action <action> [del-all]")             \
23527 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23528                           "<local-eid>")                                \
23529 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23530 _(one_use_petr, "ip-address> | disable")                                \
23531 _(one_map_request_mode, "src-dst|dst-only")                             \
23532 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23533 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23534 _(one_locator_set_dump, "[local | remote]")                             \
23535 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23536 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23537                        "[local] | [remote]")                            \
23538 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23539 _(one_ndp_bd_get, "")                                                   \
23540 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23541 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23542 _(one_l2_arp_bd_get, "")                                                \
23543 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23544 _(one_stats_enable_disable, "enable|disalbe")                           \
23545 _(show_one_stats_enable_disable, "")                                    \
23546 _(one_eid_table_vni_dump, "")                                           \
23547 _(one_eid_table_map_dump, "l2|l3")                                      \
23548 _(one_map_resolver_dump, "")                                            \
23549 _(one_map_server_dump, "")                                              \
23550 _(one_adjacencies_get, "vni <vni>")                                     \
23551 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23552 _(show_one_rloc_probe_state, "")                                        \
23553 _(show_one_map_register_state, "")                                      \
23554 _(show_one_status, "")                                                  \
23555 _(one_stats_dump, "")                                                   \
23556 _(one_stats_flush, "")                                                  \
23557 _(one_get_map_request_itr_rlocs, "")                                    \
23558 _(one_map_register_set_ttl, "<ttl>")                                    \
23559 _(one_set_transport_protocol, "udp|api")                                \
23560 _(one_get_transport_protocol, "")                                       \
23561 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23562 _(one_show_xtr_mode, "")                                                \
23563 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23564 _(one_show_pitr_mode, "")                                               \
23565 _(one_enable_disable_petr_mode, "enable|disable")                       \
23566 _(one_show_petr_mode, "")                                               \
23567 _(show_one_nsh_mapping, "")                                             \
23568 _(show_one_pitr, "")                                                    \
23569 _(show_one_use_petr, "")                                                \
23570 _(show_one_map_request_mode, "")                                        \
23571 _(show_one_map_register_ttl, "")                                        \
23572 _(show_one_map_register_fallback_threshold, "")                         \
23573 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23574                             " sw_if_index <sw_if_index> p <priority> "  \
23575                             "w <weight>] [del]")                        \
23576 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23577                         "iface <intf> | sw_if_index <sw_if_index> "     \
23578                         "p <priority> w <weight> [del]")                \
23579 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23580                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23581                          "locator-set <locator_name> [del]"             \
23582                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23583 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23584 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23585 _(lisp_enable_disable, "enable|disable")                                \
23586 _(lisp_map_register_enable_disable, "enable|disable")                   \
23587 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23588 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23589                                "[seid <seid>] "                         \
23590                                "rloc <locator> p <prio> "               \
23591                                "w <weight> [rloc <loc> ... ] "          \
23592                                "action <action> [del-all]")             \
23593 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23594                           "<local-eid>")                                \
23595 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23596 _(lisp_use_petr, "<ip-address> | disable")                              \
23597 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23598 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23599 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23600 _(lisp_locator_set_dump, "[local | remote]")                            \
23601 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23602 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23603                        "[local] | [remote]")                            \
23604 _(lisp_eid_table_vni_dump, "")                                          \
23605 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23606 _(lisp_map_resolver_dump, "")                                           \
23607 _(lisp_map_server_dump, "")                                             \
23608 _(lisp_adjacencies_get, "vni <vni>")                                    \
23609 _(gpe_fwd_entry_vnis_get, "")                                           \
23610 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23611 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23612                                 "[table <table-id>]")                   \
23613 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23614 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23615 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23616 _(gpe_get_encap_mode, "")                                               \
23617 _(lisp_gpe_add_del_iface, "up|down")                                    \
23618 _(lisp_gpe_enable_disable, "enable|disable")                            \
23619 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23620   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23621 _(show_lisp_rloc_probe_state, "")                                       \
23622 _(show_lisp_map_register_state, "")                                     \
23623 _(show_lisp_status, "")                                                 \
23624 _(lisp_get_map_request_itr_rlocs, "")                                   \
23625 _(show_lisp_pitr, "")                                                   \
23626 _(show_lisp_use_petr, "")                                               \
23627 _(show_lisp_map_request_mode, "")                                       \
23628 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23629 _(af_packet_delete, "name <host interface name>")                       \
23630 _(af_packet_dump, "")                                                   \
23631 _(policer_add_del, "name <policer name> <params> [del]")                \
23632 _(policer_dump, "[name <policer name>]")                                \
23633 _(policer_classify_set_interface,                                       \
23634   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23635   "  [l2-table <nn>] [del]")                                            \
23636 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23637 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23638     "[master|slave]")                                                   \
23639 _(netmap_delete, "name <interface name>")                               \
23640 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23641 _(mpls_fib_dump, "")                                                    \
23642 _(classify_table_ids, "")                                               \
23643 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23644 _(classify_table_info, "table_id <nn>")                                 \
23645 _(classify_session_dump, "table_id <nn>")                               \
23646 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23647     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23648     "[template_interval <nn>] [udp_checksum]")                          \
23649 _(ipfix_exporter_dump, "")                                              \
23650 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23651 _(ipfix_classify_stream_dump, "")                                       \
23652 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23653 _(ipfix_classify_table_dump, "")                                        \
23654 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23655 _(sw_interface_span_dump, "[l2]")                                           \
23656 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23657 _(pg_create_interface, "if_id <nn>")                                    \
23658 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23659 _(pg_enable_disable, "[stream <id>] disable")                           \
23660 _(ip_source_and_port_range_check_add_del,                               \
23661   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23662 _(ip_source_and_port_range_check_interface_add_del,                     \
23663   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23664   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23665 _(ipsec_gre_add_del_tunnel,                                             \
23666   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23667 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23668 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23669 _(l2_interface_pbb_tag_rewrite,                                         \
23670   "<intfc> | sw_if_index <nn> \n"                                       \
23671   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23672   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23673 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23674 _(flow_classify_set_interface,                                          \
23675   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23676 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23677 _(ip_fib_dump, "")                                                      \
23678 _(ip_mfib_dump, "")                                                     \
23679 _(ip6_fib_dump, "")                                                     \
23680 _(ip6_mfib_dump, "")                                                    \
23681 _(feature_enable_disable, "arc_name <arc_name> "                        \
23682   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23683 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23684 "[disable]")                                                            \
23685 _(l2_xconnect_dump, "")                                                 \
23686 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23687 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23688 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23689 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23690 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23691 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23692 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23693   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23694 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23695 _(sock_init_shm, "size <nnn>")                                          \
23696 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23697 _(dns_enable_disable, "[enable][disable]")                              \
23698 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23699 _(dns_resolve_name, "<hostname>")                                       \
23700 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23701 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23702 _(dns_resolve_name, "<hostname>")                                       \
23703 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23704   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23705 _(session_rules_dump, "")                                               \
23706 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23707 _(output_acl_set_interface,                                             \
23708   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23709   "  [l2-table <nn>] [del]")                                            \
23710 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23711
23712 /* List of command functions, CLI names map directly to functions */
23713 #define foreach_cli_function                                    \
23714 _(comment, "usage: comment <ignore-rest-of-line>")              \
23715 _(dump_interface_table, "usage: dump_interface_table")          \
23716 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23717 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23718 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23719 _(dump_stats_table, "usage: dump_stats_table")                  \
23720 _(dump_macro_table, "usage: dump_macro_table ")                 \
23721 _(dump_node_table, "usage: dump_node_table")                    \
23722 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23723 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23724 _(echo, "usage: echo <message>")                                \
23725 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23726 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23727 _(help, "usage: help")                                          \
23728 _(q, "usage: quit")                                             \
23729 _(quit, "usage: quit")                                          \
23730 _(search_node_table, "usage: search_node_table <name>...")      \
23731 _(set, "usage: set <variable-name> <value>")                    \
23732 _(script, "usage: script <file-name>")                          \
23733 _(statseg, "usage: statseg");                                   \
23734 _(unset, "usage: unset <variable-name>")
23735
23736 #define _(N,n)                                  \
23737     static void vl_api_##n##_t_handler_uni      \
23738     (vl_api_##n##_t * mp)                       \
23739     {                                           \
23740         vat_main_t * vam = &vat_main;           \
23741         if (vam->json_output) {                 \
23742             vl_api_##n##_t_handler_json(mp);    \
23743         } else {                                \
23744             vl_api_##n##_t_handler(mp);         \
23745         }                                       \
23746     }
23747 foreach_vpe_api_reply_msg;
23748 #if VPP_API_TEST_BUILTIN == 0
23749 foreach_standalone_reply_msg;
23750 #endif
23751 #undef _
23752
23753 void
23754 vat_api_hookup (vat_main_t * vam)
23755 {
23756 #define _(N,n)                                                  \
23757     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23758                            vl_api_##n##_t_handler_uni,          \
23759                            vl_noop_handler,                     \
23760                            vl_api_##n##_t_endian,               \
23761                            vl_api_##n##_t_print,                \
23762                            sizeof(vl_api_##n##_t), 1);
23763   foreach_vpe_api_reply_msg;
23764 #if VPP_API_TEST_BUILTIN == 0
23765   foreach_standalone_reply_msg;
23766 #endif
23767 #undef _
23768
23769 #if (VPP_API_TEST_BUILTIN==0)
23770   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23771
23772   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23773
23774   vam->function_by_name = hash_create_string (0, sizeof (uword));
23775
23776   vam->help_by_name = hash_create_string (0, sizeof (uword));
23777 #endif
23778
23779   /* API messages we can send */
23780 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23781   foreach_vpe_api_msg;
23782 #undef _
23783
23784   /* Help strings */
23785 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23786   foreach_vpe_api_msg;
23787 #undef _
23788
23789   /* CLI functions */
23790 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23791   foreach_cli_function;
23792 #undef _
23793
23794   /* Help strings */
23795 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23796   foreach_cli_function;
23797 #undef _
23798 }
23799
23800 #if VPP_API_TEST_BUILTIN
23801 static clib_error_t *
23802 vat_api_hookup_shim (vlib_main_t * vm)
23803 {
23804   vat_api_hookup (&vat_main);
23805   return 0;
23806 }
23807
23808 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23809 #endif
23810
23811 /*
23812  * fd.io coding-style-patch-verification: ON
23813  *
23814  * Local Variables:
23815  * eval: (c-set-style "gnu")
23816  * End:
23817  */