Stat segment / client: show run" works now
[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/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57
58 #include <inttypes.h>
59 #include <sys/stat.h>
60
61 #define vl_typedefs             /* define message structures */
62 #include <vpp/api/vpe_all_api_h.h>
63 #undef vl_typedefs
64
65 /* declare message handlers for each api */
66
67 #define vl_endianfun            /* define message structures */
68 #include <vpp/api/vpe_all_api_h.h>
69 #undef vl_endianfun
70
71 /* instantiate all the print functions we know about */
72 #define vl_print(handle, ...)
73 #define vl_printfun
74 #include <vpp/api/vpe_all_api_h.h>
75 #undef vl_printfun
76
77 #define __plugin_msg_base 0
78 #include <vlibapi/vat_helper_macros.h>
79
80 #if VPP_API_TEST_BUILTIN == 0
81 #include <netdb.h>
82
83 u32
84 vl (void *p)
85 {
86   return vec_len (p);
87 }
88
89 int
90 vat_socket_connect (vat_main_t * vam)
91 {
92   vam->socket_client_main = &socket_client_main;
93   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
94                                    0 /* default socket rx, tx buffer */ );
95 }
96 #else /* vpp built-in case, we don't do sockets... */
97 int
98 vat_socket_connect (vat_main_t * vam)
99 {
100   return 0;
101 }
102
103 int
104 vl_socket_client_read (int wait)
105 {
106   return -1;
107 };
108
109 int
110 vl_socket_client_write ()
111 {
112   return -1;
113 };
114
115 void *
116 vl_socket_client_msg_alloc (int nbytes)
117 {
118   return 0;
119 }
120 #endif
121
122
123 f64
124 vat_time_now (vat_main_t * vam)
125 {
126 #if VPP_API_TEST_BUILTIN
127   return vlib_time_now (vam->vlib_main);
128 #else
129   return clib_time_now (&vam->clib_time);
130 #endif
131 }
132
133 void
134 errmsg (char *fmt, ...)
135 {
136   vat_main_t *vam = &vat_main;
137   va_list va;
138   u8 *s;
139
140   va_start (va, fmt);
141   s = va_format (0, fmt, &va);
142   va_end (va);
143
144   vec_add1 (s, 0);
145
146 #if VPP_API_TEST_BUILTIN
147   vlib_cli_output (vam->vlib_main, (char *) s);
148 #else
149   {
150     if (vam->ifp != stdin)
151       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
152                vam->input_line_number);
153     fformat (vam->ofp, (char *) s);
154     fflush (vam->ofp);
155   }
156 #endif
157
158   vec_free (s);
159 }
160
161 #if VPP_API_TEST_BUILTIN == 0
162 static uword
163 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
164 {
165   vat_main_t *vam = va_arg (*args, vat_main_t *);
166   u32 *result = va_arg (*args, u32 *);
167   u8 *if_name;
168   uword *p;
169
170   if (!unformat (input, "%s", &if_name))
171     return 0;
172
173   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
174   if (p == 0)
175     return 0;
176   *result = p[0];
177   return 1;
178 }
179
180 static uword
181 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
182 {
183   return 0;
184 }
185
186 /* Parse an IP4 address %d.%d.%d.%d. */
187 uword
188 unformat_ip4_address (unformat_input_t * input, va_list * args)
189 {
190   u8 *result = va_arg (*args, u8 *);
191   unsigned a[4];
192
193   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
194     return 0;
195
196   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
197     return 0;
198
199   result[0] = a[0];
200   result[1] = a[1];
201   result[2] = a[2];
202   result[3] = a[3];
203
204   return 1;
205 }
206
207 uword
208 unformat_ethernet_address (unformat_input_t * input, va_list * args)
209 {
210   u8 *result = va_arg (*args, u8 *);
211   u32 i, a[6];
212
213   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
214                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
215     return 0;
216
217   /* Check range. */
218   for (i = 0; i < 6; i++)
219     if (a[i] >= (1 << 8))
220       return 0;
221
222   for (i = 0; i < 6; i++)
223     result[i] = a[i];
224
225   return 1;
226 }
227
228 /* Returns ethernet type as an int in host byte order. */
229 uword
230 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
231                                         va_list * args)
232 {
233   u16 *result = va_arg (*args, u16 *);
234   int type;
235
236   /* Numeric type. */
237   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
238     {
239       if (type >= (1 << 16))
240         return 0;
241       *result = type;
242       return 1;
243     }
244   return 0;
245 }
246
247 /* Parse an IP6 address. */
248 uword
249 unformat_ip6_address (unformat_input_t * input, va_list * args)
250 {
251   ip6_address_t *result = va_arg (*args, ip6_address_t *);
252   u16 hex_quads[8];
253   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
254   uword c, n_colon, double_colon_index;
255
256   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
257   double_colon_index = ARRAY_LEN (hex_quads);
258   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
259     {
260       hex_digit = 16;
261       if (c >= '0' && c <= '9')
262         hex_digit = c - '0';
263       else if (c >= 'a' && c <= 'f')
264         hex_digit = c + 10 - 'a';
265       else if (c >= 'A' && c <= 'F')
266         hex_digit = c + 10 - 'A';
267       else if (c == ':' && n_colon < 2)
268         n_colon++;
269       else
270         {
271           unformat_put_input (input);
272           break;
273         }
274
275       /* Too many hex quads. */
276       if (n_hex_quads >= ARRAY_LEN (hex_quads))
277         return 0;
278
279       if (hex_digit < 16)
280         {
281           hex_quad = (hex_quad << 4) | hex_digit;
282
283           /* Hex quad must fit in 16 bits. */
284           if (n_hex_digits >= 4)
285             return 0;
286
287           n_colon = 0;
288           n_hex_digits++;
289         }
290
291       /* Save position of :: */
292       if (n_colon == 2)
293         {
294           /* More than one :: ? */
295           if (double_colon_index < ARRAY_LEN (hex_quads))
296             return 0;
297           double_colon_index = n_hex_quads;
298         }
299
300       if (n_colon > 0 && n_hex_digits > 0)
301         {
302           hex_quads[n_hex_quads++] = hex_quad;
303           hex_quad = 0;
304           n_hex_digits = 0;
305         }
306     }
307
308   if (n_hex_digits > 0)
309     hex_quads[n_hex_quads++] = hex_quad;
310
311   {
312     word i;
313
314     /* Expand :: to appropriate number of zero hex quads. */
315     if (double_colon_index < ARRAY_LEN (hex_quads))
316       {
317         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
318
319         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
320           hex_quads[n_zero + i] = hex_quads[i];
321
322         for (i = 0; i < n_zero; i++)
323           hex_quads[double_colon_index + i] = 0;
324
325         n_hex_quads = ARRAY_LEN (hex_quads);
326       }
327
328     /* Too few hex quads given. */
329     if (n_hex_quads < ARRAY_LEN (hex_quads))
330       return 0;
331
332     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
333       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
334
335     return 1;
336   }
337 }
338
339 uword
340 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
341 {
342   u32 *r = va_arg (*args, u32 *);
343
344   if (0);
345 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
346   foreach_ipsec_policy_action
347 #undef _
348     else
349     return 0;
350   return 1;
351 }
352
353 uword
354 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
355 {
356   u32 *r = va_arg (*args, u32 *);
357
358   if (0);
359 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
360   foreach_ipsec_crypto_alg
361 #undef _
362     else
363     return 0;
364   return 1;
365 }
366
367 u8 *
368 format_ipsec_crypto_alg (u8 * s, va_list * args)
369 {
370   u32 i = va_arg (*args, u32);
371   u8 *t = 0;
372
373   switch (i)
374     {
375 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
376       foreach_ipsec_crypto_alg
377 #undef _
378     default:
379       return format (s, "unknown");
380     }
381   return format (s, "%s", t);
382 }
383
384 uword
385 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
386 {
387   u32 *r = va_arg (*args, u32 *);
388
389   if (0);
390 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
391   foreach_ipsec_integ_alg
392 #undef _
393     else
394     return 0;
395   return 1;
396 }
397
398 u8 *
399 format_ipsec_integ_alg (u8 * s, va_list * args)
400 {
401   u32 i = va_arg (*args, u32);
402   u8 *t = 0;
403
404   switch (i)
405     {
406 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
407       foreach_ipsec_integ_alg
408 #undef _
409     default:
410       return format (s, "unknown");
411     }
412   return format (s, "%s", t);
413 }
414
415 uword
416 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
417 {
418   u32 *r = va_arg (*args, u32 *);
419
420   if (0);
421 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
422   foreach_ikev2_auth_method
423 #undef _
424     else
425     return 0;
426   return 1;
427 }
428
429 uword
430 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
431 {
432   u32 *r = va_arg (*args, u32 *);
433
434   if (0);
435 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
436   foreach_ikev2_id_type
437 #undef _
438     else
439     return 0;
440   return 1;
441 }
442 #else /* VPP_API_TEST_BUILTIN == 1 */
443 static uword
444 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
445 {
446   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
447   vnet_main_t *vnm = vnet_get_main ();
448   u32 *result = va_arg (*args, u32 *);
449
450   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
451 }
452
453 static uword
454 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
455 {
456   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
457   vnet_main_t *vnm = vnet_get_main ();
458   u32 *result = va_arg (*args, u32 *);
459
460   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
461 }
462
463 #endif /* VPP_API_TEST_BUILTIN */
464
465 static uword
466 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
467 {
468   u8 *r = va_arg (*args, u8 *);
469
470   if (unformat (input, "kbps"))
471     *r = SSE2_QOS_RATE_KBPS;
472   else if (unformat (input, "pps"))
473     *r = SSE2_QOS_RATE_PPS;
474   else
475     return 0;
476   return 1;
477 }
478
479 static uword
480 unformat_policer_round_type (unformat_input_t * input, va_list * args)
481 {
482   u8 *r = va_arg (*args, u8 *);
483
484   if (unformat (input, "closest"))
485     *r = SSE2_QOS_ROUND_TO_CLOSEST;
486   else if (unformat (input, "up"))
487     *r = SSE2_QOS_ROUND_TO_UP;
488   else if (unformat (input, "down"))
489     *r = SSE2_QOS_ROUND_TO_DOWN;
490   else
491     return 0;
492   return 1;
493 }
494
495 static uword
496 unformat_policer_type (unformat_input_t * input, va_list * args)
497 {
498   u8 *r = va_arg (*args, u8 *);
499
500   if (unformat (input, "1r2c"))
501     *r = SSE2_QOS_POLICER_TYPE_1R2C;
502   else if (unformat (input, "1r3c"))
503     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
504   else if (unformat (input, "2r3c-2698"))
505     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
506   else if (unformat (input, "2r3c-4115"))
507     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
508   else if (unformat (input, "2r3c-mef5cf1"))
509     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
510   else
511     return 0;
512   return 1;
513 }
514
515 static uword
516 unformat_dscp (unformat_input_t * input, va_list * va)
517 {
518   u8 *r = va_arg (*va, u8 *);
519
520   if (0);
521 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
522   foreach_vnet_dscp
523 #undef _
524     else
525     return 0;
526   return 1;
527 }
528
529 static uword
530 unformat_policer_action_type (unformat_input_t * input, va_list * va)
531 {
532   sse2_qos_pol_action_params_st *a
533     = va_arg (*va, sse2_qos_pol_action_params_st *);
534
535   if (unformat (input, "drop"))
536     a->action_type = SSE2_QOS_ACTION_DROP;
537   else if (unformat (input, "transmit"))
538     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
539   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
540     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
541   else
542     return 0;
543   return 1;
544 }
545
546 static uword
547 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
548 {
549   u32 *r = va_arg (*va, u32 *);
550   u32 tid;
551
552   if (unformat (input, "ip4"))
553     tid = POLICER_CLASSIFY_TABLE_IP4;
554   else if (unformat (input, "ip6"))
555     tid = POLICER_CLASSIFY_TABLE_IP6;
556   else if (unformat (input, "l2"))
557     tid = POLICER_CLASSIFY_TABLE_L2;
558   else
559     return 0;
560
561   *r = tid;
562   return 1;
563 }
564
565 static uword
566 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
567 {
568   u32 *r = va_arg (*va, u32 *);
569   u32 tid;
570
571   if (unformat (input, "ip4"))
572     tid = FLOW_CLASSIFY_TABLE_IP4;
573   else if (unformat (input, "ip6"))
574     tid = FLOW_CLASSIFY_TABLE_IP6;
575   else
576     return 0;
577
578   *r = tid;
579   return 1;
580 }
581
582 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
583 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
584 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
585 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
586
587 #if (VPP_API_TEST_BUILTIN==0)
588 uword
589 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
590 {
591   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
592   mfib_itf_attribute_t attr;
593
594   old = *iflags;
595   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
596   {
597     if (unformat (input, mfib_itf_flag_long_names[attr]))
598       *iflags |= (1 << attr);
599   }
600   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
601   {
602     if (unformat (input, mfib_itf_flag_names[attr]))
603       *iflags |= (1 << attr);
604   }
605
606   return (old == *iflags ? 0 : 1);
607 }
608
609 uword
610 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
611 {
612   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
613   mfib_entry_attribute_t attr;
614
615   old = *eflags;
616   FOR_EACH_MFIB_ATTRIBUTE (attr)
617   {
618     if (unformat (input, mfib_flag_long_names[attr]))
619       *eflags |= (1 << attr);
620   }
621   FOR_EACH_MFIB_ATTRIBUTE (attr)
622   {
623     if (unformat (input, mfib_flag_names[attr]))
624       *eflags |= (1 << attr);
625   }
626
627   return (old == *eflags ? 0 : 1);
628 }
629
630 u8 *
631 format_ip4_address (u8 * s, va_list * args)
632 {
633   u8 *a = va_arg (*args, u8 *);
634   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
635 }
636
637 u8 *
638 format_ip6_address (u8 * s, va_list * args)
639 {
640   ip6_address_t *a = va_arg (*args, ip6_address_t *);
641   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
642
643   i_max_n_zero = ARRAY_LEN (a->as_u16);
644   max_n_zeros = 0;
645   i_first_zero = i_max_n_zero;
646   n_zeros = 0;
647   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
648     {
649       u32 is_zero = a->as_u16[i] == 0;
650       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
651         {
652           i_first_zero = i;
653           n_zeros = 0;
654         }
655       n_zeros += is_zero;
656       if ((!is_zero && n_zeros > max_n_zeros)
657           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
658         {
659           i_max_n_zero = i_first_zero;
660           max_n_zeros = n_zeros;
661           i_first_zero = ARRAY_LEN (a->as_u16);
662           n_zeros = 0;
663         }
664     }
665
666   last_double_colon = 0;
667   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
668     {
669       if (i == i_max_n_zero && max_n_zeros > 1)
670         {
671           s = format (s, "::");
672           i += max_n_zeros - 1;
673           last_double_colon = 1;
674         }
675       else
676         {
677           s = format (s, "%s%x",
678                       (last_double_colon || i == 0) ? "" : ":",
679                       clib_net_to_host_u16 (a->as_u16[i]));
680           last_double_colon = 0;
681         }
682     }
683
684   return s;
685 }
686
687 /* Format an IP46 address. */
688 u8 *
689 format_ip46_address (u8 * s, va_list * args)
690 {
691   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
692   ip46_type_t type = va_arg (*args, ip46_type_t);
693   int is_ip4 = 1;
694
695   switch (type)
696     {
697     case IP46_TYPE_ANY:
698       is_ip4 = ip46_address_is_ip4 (ip46);
699       break;
700     case IP46_TYPE_IP4:
701       is_ip4 = 1;
702       break;
703     case IP46_TYPE_IP6:
704       is_ip4 = 0;
705       break;
706     }
707
708   return is_ip4 ?
709     format (s, "%U", format_ip4_address, &ip46->ip4) :
710     format (s, "%U", format_ip6_address, &ip46->ip6);
711 }
712
713 u8 *
714 format_ethernet_address (u8 * s, va_list * args)
715 {
716   u8 *a = va_arg (*args, u8 *);
717
718   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
719                  a[0], a[1], a[2], a[3], a[4], a[5]);
720 }
721 #endif
722
723 static void
724 increment_v4_address (ip4_address_t * a)
725 {
726   u32 v;
727
728   v = ntohl (a->as_u32) + 1;
729   a->as_u32 = ntohl (v);
730 }
731
732 static void
733 increment_v6_address (ip6_address_t * a)
734 {
735   u64 v0, v1;
736
737   v0 = clib_net_to_host_u64 (a->as_u64[0]);
738   v1 = clib_net_to_host_u64 (a->as_u64[1]);
739
740   v1 += 1;
741   if (v1 == 0)
742     v0 += 1;
743   a->as_u64[0] = clib_net_to_host_u64 (v0);
744   a->as_u64[1] = clib_net_to_host_u64 (v1);
745 }
746
747 static void
748 increment_mac_address (u8 * mac)
749 {
750   u64 tmp = *((u64 *) mac);
751   tmp = clib_net_to_host_u64 (tmp);
752   tmp += 1 << 16;               /* skip unused (least significant) octets */
753   tmp = clib_host_to_net_u64 (tmp);
754
755   clib_memcpy (mac, &tmp, 6);
756 }
757
758 static void vl_api_create_loopback_reply_t_handler
759   (vl_api_create_loopback_reply_t * mp)
760 {
761   vat_main_t *vam = &vat_main;
762   i32 retval = ntohl (mp->retval);
763
764   vam->retval = retval;
765   vam->regenerate_interface_table = 1;
766   vam->sw_if_index = ntohl (mp->sw_if_index);
767   vam->result_ready = 1;
768 }
769
770 static void vl_api_create_loopback_reply_t_handler_json
771   (vl_api_create_loopback_reply_t * mp)
772 {
773   vat_main_t *vam = &vat_main;
774   vat_json_node_t node;
775
776   vat_json_init_object (&node);
777   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
778   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
779
780   vat_json_print (vam->ofp, &node);
781   vat_json_free (&node);
782   vam->retval = ntohl (mp->retval);
783   vam->result_ready = 1;
784 }
785
786 static void vl_api_create_loopback_instance_reply_t_handler
787   (vl_api_create_loopback_instance_reply_t * mp)
788 {
789   vat_main_t *vam = &vat_main;
790   i32 retval = ntohl (mp->retval);
791
792   vam->retval = retval;
793   vam->regenerate_interface_table = 1;
794   vam->sw_if_index = ntohl (mp->sw_if_index);
795   vam->result_ready = 1;
796 }
797
798 static void vl_api_create_loopback_instance_reply_t_handler_json
799   (vl_api_create_loopback_instance_reply_t * mp)
800 {
801   vat_main_t *vam = &vat_main;
802   vat_json_node_t node;
803
804   vat_json_init_object (&node);
805   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
806   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
807
808   vat_json_print (vam->ofp, &node);
809   vat_json_free (&node);
810   vam->retval = ntohl (mp->retval);
811   vam->result_ready = 1;
812 }
813
814 static void vl_api_af_packet_create_reply_t_handler
815   (vl_api_af_packet_create_reply_t * mp)
816 {
817   vat_main_t *vam = &vat_main;
818   i32 retval = ntohl (mp->retval);
819
820   vam->retval = retval;
821   vam->regenerate_interface_table = 1;
822   vam->sw_if_index = ntohl (mp->sw_if_index);
823   vam->result_ready = 1;
824 }
825
826 static void vl_api_af_packet_create_reply_t_handler_json
827   (vl_api_af_packet_create_reply_t * mp)
828 {
829   vat_main_t *vam = &vat_main;
830   vat_json_node_t node;
831
832   vat_json_init_object (&node);
833   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
834   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
835
836   vat_json_print (vam->ofp, &node);
837   vat_json_free (&node);
838
839   vam->retval = ntohl (mp->retval);
840   vam->result_ready = 1;
841 }
842
843 static void vl_api_create_vlan_subif_reply_t_handler
844   (vl_api_create_vlan_subif_reply_t * mp)
845 {
846   vat_main_t *vam = &vat_main;
847   i32 retval = ntohl (mp->retval);
848
849   vam->retval = retval;
850   vam->regenerate_interface_table = 1;
851   vam->sw_if_index = ntohl (mp->sw_if_index);
852   vam->result_ready = 1;
853 }
854
855 static void vl_api_create_vlan_subif_reply_t_handler_json
856   (vl_api_create_vlan_subif_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860
861   vat_json_init_object (&node);
862   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
863   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
864
865   vat_json_print (vam->ofp, &node);
866   vat_json_free (&node);
867
868   vam->retval = ntohl (mp->retval);
869   vam->result_ready = 1;
870 }
871
872 static void vl_api_create_subif_reply_t_handler
873   (vl_api_create_subif_reply_t * mp)
874 {
875   vat_main_t *vam = &vat_main;
876   i32 retval = ntohl (mp->retval);
877
878   vam->retval = retval;
879   vam->regenerate_interface_table = 1;
880   vam->sw_if_index = ntohl (mp->sw_if_index);
881   vam->result_ready = 1;
882 }
883
884 static void vl_api_create_subif_reply_t_handler_json
885   (vl_api_create_subif_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   vat_json_node_t node;
889
890   vat_json_init_object (&node);
891   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
892   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
893
894   vat_json_print (vam->ofp, &node);
895   vat_json_free (&node);
896
897   vam->retval = ntohl (mp->retval);
898   vam->result_ready = 1;
899 }
900
901 static void vl_api_interface_name_renumber_reply_t_handler
902   (vl_api_interface_name_renumber_reply_t * mp)
903 {
904   vat_main_t *vam = &vat_main;
905   i32 retval = ntohl (mp->retval);
906
907   vam->retval = retval;
908   vam->regenerate_interface_table = 1;
909   vam->result_ready = 1;
910 }
911
912 static void vl_api_interface_name_renumber_reply_t_handler_json
913   (vl_api_interface_name_renumber_reply_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t node;
917
918   vat_json_init_object (&node);
919   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
920
921   vat_json_print (vam->ofp, &node);
922   vat_json_free (&node);
923
924   vam->retval = ntohl (mp->retval);
925   vam->result_ready = 1;
926 }
927
928 /*
929  * Special-case: build the interface table, maintain
930  * the next loopback sw_if_index vbl.
931  */
932 static void vl_api_sw_interface_details_t_handler
933   (vl_api_sw_interface_details_t * mp)
934 {
935   vat_main_t *vam = &vat_main;
936   u8 *s = format (0, "%s%c", mp->interface_name, 0);
937
938   hash_set_mem (vam->sw_if_index_by_interface_name, s,
939                 ntohl (mp->sw_if_index));
940
941   /* In sub interface case, fill the sub interface table entry */
942   if (mp->sw_if_index != mp->sup_sw_if_index)
943     {
944       sw_interface_subif_t *sub = NULL;
945
946       vec_add2 (vam->sw_if_subif_table, sub, 1);
947
948       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
949       strncpy ((char *) sub->interface_name, (char *) s,
950                vec_len (sub->interface_name));
951       sub->sw_if_index = ntohl (mp->sw_if_index);
952       sub->sub_id = ntohl (mp->sub_id);
953
954       sub->sub_dot1ad = mp->sub_dot1ad;
955       sub->sub_number_of_tags = mp->sub_number_of_tags;
956       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
957       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
958       sub->sub_exact_match = mp->sub_exact_match;
959       sub->sub_default = mp->sub_default;
960       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
961       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
962
963       /* vlan tag rewrite */
964       sub->vtr_op = ntohl (mp->vtr_op);
965       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
966       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
967       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
968     }
969 }
970
971 static void vl_api_sw_interface_details_t_handler_json
972   (vl_api_sw_interface_details_t * mp)
973 {
974   vat_main_t *vam = &vat_main;
975   vat_json_node_t *node = NULL;
976
977   if (VAT_JSON_ARRAY != vam->json_tree.type)
978     {
979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
980       vat_json_init_array (&vam->json_tree);
981     }
982   node = vat_json_array_add (&vam->json_tree);
983
984   vat_json_init_object (node);
985   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
986   vat_json_object_add_uint (node, "sup_sw_if_index",
987                             ntohl (mp->sup_sw_if_index));
988   vat_json_object_add_uint (node, "l2_address_length",
989                             ntohl (mp->l2_address_length));
990   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
991                              sizeof (mp->l2_address));
992   vat_json_object_add_string_copy (node, "interface_name",
993                                    mp->interface_name);
994   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
995   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
996   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
997   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
998   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
999   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1000   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1001   vat_json_object_add_uint (node, "sub_number_of_tags",
1002                             mp->sub_number_of_tags);
1003   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1004                             ntohs (mp->sub_outer_vlan_id));
1005   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1006                             ntohs (mp->sub_inner_vlan_id));
1007   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1008   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1009   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1010                             mp->sub_outer_vlan_id_any);
1011   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1012                             mp->sub_inner_vlan_id_any);
1013   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1014   vat_json_object_add_uint (node, "vtr_push_dot1q",
1015                             ntohl (mp->vtr_push_dot1q));
1016   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1017   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1018   if (mp->sub_dot1ah)
1019     {
1020       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1021                                        format (0, "%U",
1022                                                format_ethernet_address,
1023                                                &mp->b_dmac));
1024       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1025                                        format (0, "%U",
1026                                                format_ethernet_address,
1027                                                &mp->b_smac));
1028       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1029       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1030     }
1031 }
1032
1033 #if VPP_API_TEST_BUILTIN == 0
1034 static void vl_api_sw_interface_event_t_handler
1035   (vl_api_sw_interface_event_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   if (vam->interface_event_display)
1039     errmsg ("interface flags: sw_if_index %d %s %s",
1040             ntohl (mp->sw_if_index),
1041             mp->admin_up_down ? "admin-up" : "admin-down",
1042             mp->link_up_down ? "link-up" : "link-down");
1043 }
1044 #endif
1045
1046 static void vl_api_sw_interface_event_t_handler_json
1047   (vl_api_sw_interface_event_t * mp)
1048 {
1049   /* JSON output not supported */
1050 }
1051
1052 static void
1053 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1054 {
1055   vat_main_t *vam = &vat_main;
1056   i32 retval = ntohl (mp->retval);
1057
1058   vam->retval = retval;
1059   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1060   vam->result_ready = 1;
1061 }
1062
1063 static void
1064 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1065 {
1066   vat_main_t *vam = &vat_main;
1067   vat_json_node_t node;
1068   api_main_t *am = &api_main;
1069   void *oldheap;
1070   u8 *reply;
1071
1072   vat_json_init_object (&node);
1073   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1074   vat_json_object_add_uint (&node, "reply_in_shmem",
1075                             ntohl (mp->reply_in_shmem));
1076   /* Toss the shared-memory original... */
1077   pthread_mutex_lock (&am->vlib_rp->mutex);
1078   oldheap = svm_push_data_heap (am->vlib_rp);
1079
1080   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1081   vec_free (reply);
1082
1083   svm_pop_heap (oldheap);
1084   pthread_mutex_unlock (&am->vlib_rp->mutex);
1085
1086   vat_json_print (vam->ofp, &node);
1087   vat_json_free (&node);
1088
1089   vam->retval = ntohl (mp->retval);
1090   vam->result_ready = 1;
1091 }
1092
1093 static void
1094 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   i32 retval = ntohl (mp->retval);
1098   u32 length = ntohl (mp->length);
1099
1100   vec_reset_length (vam->cmd_reply);
1101
1102   vam->retval = retval;
1103   if (retval == 0)
1104     {
1105       vec_validate (vam->cmd_reply, length);
1106       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1107       vam->cmd_reply[length] = 0;
1108     }
1109   vam->result_ready = 1;
1110 }
1111
1112 static void
1113 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   vat_json_node_t node;
1117
1118   vec_reset_length (vam->cmd_reply);
1119
1120   vat_json_init_object (&node);
1121   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1122   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1123
1124   vat_json_print (vam->ofp, &node);
1125   vat_json_free (&node);
1126
1127   vam->retval = ntohl (mp->retval);
1128   vam->result_ready = 1;
1129 }
1130
1131 static void vl_api_classify_add_del_table_reply_t_handler
1132   (vl_api_classify_add_del_table_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   i32 retval = ntohl (mp->retval);
1136   if (vam->async_mode)
1137     {
1138       vam->async_errors += (retval < 0);
1139     }
1140   else
1141     {
1142       vam->retval = retval;
1143       if (retval == 0 &&
1144           ((mp->new_table_index != 0xFFFFFFFF) ||
1145            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1146            (mp->match_n_vectors != 0xFFFFFFFF)))
1147         /*
1148          * Note: this is just barely thread-safe, depends on
1149          * the main thread spinning waiting for an answer...
1150          */
1151         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1152                 ntohl (mp->new_table_index),
1153                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1154       vam->result_ready = 1;
1155     }
1156 }
1157
1158 static void vl_api_classify_add_del_table_reply_t_handler_json
1159   (vl_api_classify_add_del_table_reply_t * mp)
1160 {
1161   vat_main_t *vam = &vat_main;
1162   vat_json_node_t node;
1163
1164   vat_json_init_object (&node);
1165   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1166   vat_json_object_add_uint (&node, "new_table_index",
1167                             ntohl (mp->new_table_index));
1168   vat_json_object_add_uint (&node, "skip_n_vectors",
1169                             ntohl (mp->skip_n_vectors));
1170   vat_json_object_add_uint (&node, "match_n_vectors",
1171                             ntohl (mp->match_n_vectors));
1172
1173   vat_json_print (vam->ofp, &node);
1174   vat_json_free (&node);
1175
1176   vam->retval = ntohl (mp->retval);
1177   vam->result_ready = 1;
1178 }
1179
1180 static void vl_api_get_node_index_reply_t_handler
1181   (vl_api_get_node_index_reply_t * mp)
1182 {
1183   vat_main_t *vam = &vat_main;
1184   i32 retval = ntohl (mp->retval);
1185   if (vam->async_mode)
1186     {
1187       vam->async_errors += (retval < 0);
1188     }
1189   else
1190     {
1191       vam->retval = retval;
1192       if (retval == 0)
1193         errmsg ("node index %d", ntohl (mp->node_index));
1194       vam->result_ready = 1;
1195     }
1196 }
1197
1198 static void vl_api_get_node_index_reply_t_handler_json
1199   (vl_api_get_node_index_reply_t * mp)
1200 {
1201   vat_main_t *vam = &vat_main;
1202   vat_json_node_t node;
1203
1204   vat_json_init_object (&node);
1205   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1206   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1207
1208   vat_json_print (vam->ofp, &node);
1209   vat_json_free (&node);
1210
1211   vam->retval = ntohl (mp->retval);
1212   vam->result_ready = 1;
1213 }
1214
1215 static void vl_api_get_next_index_reply_t_handler
1216   (vl_api_get_next_index_reply_t * mp)
1217 {
1218   vat_main_t *vam = &vat_main;
1219   i32 retval = ntohl (mp->retval);
1220   if (vam->async_mode)
1221     {
1222       vam->async_errors += (retval < 0);
1223     }
1224   else
1225     {
1226       vam->retval = retval;
1227       if (retval == 0)
1228         errmsg ("next node index %d", ntohl (mp->next_index));
1229       vam->result_ready = 1;
1230     }
1231 }
1232
1233 static void vl_api_get_next_index_reply_t_handler_json
1234   (vl_api_get_next_index_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1242
1243   vat_json_print (vam->ofp, &node);
1244   vat_json_free (&node);
1245
1246   vam->retval = ntohl (mp->retval);
1247   vam->result_ready = 1;
1248 }
1249
1250 static void vl_api_add_node_next_reply_t_handler
1251   (vl_api_add_node_next_reply_t * mp)
1252 {
1253   vat_main_t *vam = &vat_main;
1254   i32 retval = ntohl (mp->retval);
1255   if (vam->async_mode)
1256     {
1257       vam->async_errors += (retval < 0);
1258     }
1259   else
1260     {
1261       vam->retval = retval;
1262       if (retval == 0)
1263         errmsg ("next index %d", ntohl (mp->next_index));
1264       vam->result_ready = 1;
1265     }
1266 }
1267
1268 static void vl_api_add_node_next_reply_t_handler_json
1269   (vl_api_add_node_next_reply_t * mp)
1270 {
1271   vat_main_t *vam = &vat_main;
1272   vat_json_node_t node;
1273
1274   vat_json_init_object (&node);
1275   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1276   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1277
1278   vat_json_print (vam->ofp, &node);
1279   vat_json_free (&node);
1280
1281   vam->retval = ntohl (mp->retval);
1282   vam->result_ready = 1;
1283 }
1284
1285 static void vl_api_show_version_reply_t_handler
1286   (vl_api_show_version_reply_t * mp)
1287 {
1288   vat_main_t *vam = &vat_main;
1289   i32 retval = ntohl (mp->retval);
1290
1291   if (retval >= 0)
1292     {
1293       errmsg ("        program: %s", mp->program);
1294       errmsg ("        version: %s", mp->version);
1295       errmsg ("     build date: %s", mp->build_date);
1296       errmsg ("build directory: %s", mp->build_directory);
1297     }
1298   vam->retval = retval;
1299   vam->result_ready = 1;
1300 }
1301
1302 static void vl_api_show_version_reply_t_handler_json
1303   (vl_api_show_version_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   vat_json_node_t node;
1307
1308   vat_json_init_object (&node);
1309   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1310   vat_json_object_add_string_copy (&node, "program", mp->program);
1311   vat_json_object_add_string_copy (&node, "version", mp->version);
1312   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1313   vat_json_object_add_string_copy (&node, "build_directory",
1314                                    mp->build_directory);
1315
1316   vat_json_print (vam->ofp, &node);
1317   vat_json_free (&node);
1318
1319   vam->retval = ntohl (mp->retval);
1320   vam->result_ready = 1;
1321 }
1322
1323 static void
1324 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1325 {
1326   u32 sw_if_index = ntohl (mp->sw_if_index);
1327   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1328           mp->mac_ip ? "mac/ip binding" : "address resolution",
1329           ntohl (mp->pid), format_ip4_address, &mp->address,
1330           format_ethernet_address, mp->new_mac, sw_if_index);
1331 }
1332
1333 static void
1334 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1335 {
1336   /* JSON output not supported */
1337 }
1338
1339 static void
1340 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1341 {
1342   u32 sw_if_index = ntohl (mp->sw_if_index);
1343   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1344           mp->mac_ip ? "mac/ip binding" : "address resolution",
1345           ntohl (mp->pid), format_ip6_address, mp->address,
1346           format_ethernet_address, mp->new_mac, sw_if_index);
1347 }
1348
1349 static void
1350 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1351 {
1352   /* JSON output not supported */
1353 }
1354
1355 static void
1356 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1357 {
1358   u32 n_macs = ntohl (mp->n_macs);
1359   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1360           ntohl (mp->pid), mp->client_index, n_macs);
1361   int i;
1362   for (i = 0; i < n_macs; i++)
1363     {
1364       vl_api_mac_entry_t *mac = &mp->mac[i];
1365       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1366               i + 1, ntohl (mac->sw_if_index),
1367               format_ethernet_address, mac->mac_addr, mac->action);
1368       if (i == 1000)
1369         break;
1370     }
1371 }
1372
1373 static void
1374 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1375 {
1376   /* JSON output not supported */
1377 }
1378
1379 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1380 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1381
1382 /*
1383  * Special-case: build the bridge domain table, maintain
1384  * the next bd id vbl.
1385  */
1386 static void vl_api_bridge_domain_details_t_handler
1387   (vl_api_bridge_domain_details_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1391   int i;
1392
1393   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1394          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1395
1396   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1397          ntohl (mp->bd_id), mp->learn, mp->forward,
1398          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1399
1400   if (n_sw_ifs)
1401     {
1402       vl_api_bridge_domain_sw_if_t *sw_ifs;
1403       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1404              "Interface Name");
1405
1406       sw_ifs = mp->sw_if_details;
1407       for (i = 0; i < n_sw_ifs; i++)
1408         {
1409           u8 *sw_if_name = 0;
1410           u32 sw_if_index;
1411           hash_pair_t *p;
1412
1413           sw_if_index = ntohl (sw_ifs->sw_if_index);
1414
1415           /* *INDENT-OFF* */
1416           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1417                              ({
1418                                if ((u32) p->value[0] == sw_if_index)
1419                                  {
1420                                    sw_if_name = (u8 *)(p->key);
1421                                    break;
1422                                  }
1423                              }));
1424           /* *INDENT-ON* */
1425           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1426                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1427                  "sw_if_index not found!");
1428
1429           sw_ifs++;
1430         }
1431     }
1432 }
1433
1434 static void vl_api_bridge_domain_details_t_handler_json
1435   (vl_api_bridge_domain_details_t * mp)
1436 {
1437   vat_main_t *vam = &vat_main;
1438   vat_json_node_t *node, *array = NULL;
1439   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1440
1441   if (VAT_JSON_ARRAY != vam->json_tree.type)
1442     {
1443       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1444       vat_json_init_array (&vam->json_tree);
1445     }
1446   node = vat_json_array_add (&vam->json_tree);
1447
1448   vat_json_init_object (node);
1449   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1450   vat_json_object_add_uint (node, "flood", mp->flood);
1451   vat_json_object_add_uint (node, "forward", mp->forward);
1452   vat_json_object_add_uint (node, "learn", mp->learn);
1453   vat_json_object_add_uint (node, "bvi_sw_if_index",
1454                             ntohl (mp->bvi_sw_if_index));
1455   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1456   array = vat_json_object_add (node, "sw_if");
1457   vat_json_init_array (array);
1458
1459
1460
1461   if (n_sw_ifs)
1462     {
1463       vl_api_bridge_domain_sw_if_t *sw_ifs;
1464       int i;
1465
1466       sw_ifs = mp->sw_if_details;
1467       for (i = 0; i < n_sw_ifs; i++)
1468         {
1469           node = vat_json_array_add (array);
1470           vat_json_init_object (node);
1471           vat_json_object_add_uint (node, "sw_if_index",
1472                                     ntohl (sw_ifs->sw_if_index));
1473           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1474           sw_ifs++;
1475         }
1476     }
1477 }
1478
1479 static void vl_api_control_ping_reply_t_handler
1480   (vl_api_control_ping_reply_t * mp)
1481 {
1482   vat_main_t *vam = &vat_main;
1483   i32 retval = ntohl (mp->retval);
1484   if (vam->async_mode)
1485     {
1486       vam->async_errors += (retval < 0);
1487     }
1488   else
1489     {
1490       vam->retval = retval;
1491       vam->result_ready = 1;
1492     }
1493   if (vam->socket_client_main)
1494     vam->socket_client_main->control_pings_outstanding--;
1495 }
1496
1497 static void vl_api_control_ping_reply_t_handler_json
1498   (vl_api_control_ping_reply_t * mp)
1499 {
1500   vat_main_t *vam = &vat_main;
1501   i32 retval = ntohl (mp->retval);
1502
1503   if (VAT_JSON_NONE != vam->json_tree.type)
1504     {
1505       vat_json_print (vam->ofp, &vam->json_tree);
1506       vat_json_free (&vam->json_tree);
1507       vam->json_tree.type = VAT_JSON_NONE;
1508     }
1509   else
1510     {
1511       /* just print [] */
1512       vat_json_init_array (&vam->json_tree);
1513       vat_json_print (vam->ofp, &vam->json_tree);
1514       vam->json_tree.type = VAT_JSON_NONE;
1515     }
1516
1517   vam->retval = retval;
1518   vam->result_ready = 1;
1519 }
1520
1521 static void
1522   vl_api_bridge_domain_set_mac_age_reply_t_handler
1523   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   i32 retval = ntohl (mp->retval);
1527   if (vam->async_mode)
1528     {
1529       vam->async_errors += (retval < 0);
1530     }
1531   else
1532     {
1533       vam->retval = retval;
1534       vam->result_ready = 1;
1535     }
1536 }
1537
1538 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1539   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1540 {
1541   vat_main_t *vam = &vat_main;
1542   vat_json_node_t node;
1543
1544   vat_json_init_object (&node);
1545   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1546
1547   vat_json_print (vam->ofp, &node);
1548   vat_json_free (&node);
1549
1550   vam->retval = ntohl (mp->retval);
1551   vam->result_ready = 1;
1552 }
1553
1554 static void
1555 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1556 {
1557   vat_main_t *vam = &vat_main;
1558   i32 retval = ntohl (mp->retval);
1559   if (vam->async_mode)
1560     {
1561       vam->async_errors += (retval < 0);
1562     }
1563   else
1564     {
1565       vam->retval = retval;
1566       vam->result_ready = 1;
1567     }
1568 }
1569
1570 static void vl_api_l2_flags_reply_t_handler_json
1571   (vl_api_l2_flags_reply_t * mp)
1572 {
1573   vat_main_t *vam = &vat_main;
1574   vat_json_node_t node;
1575
1576   vat_json_init_object (&node);
1577   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1578   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1579                             ntohl (mp->resulting_feature_bitmap));
1580
1581   vat_json_print (vam->ofp, &node);
1582   vat_json_free (&node);
1583
1584   vam->retval = ntohl (mp->retval);
1585   vam->result_ready = 1;
1586 }
1587
1588 static void vl_api_bridge_flags_reply_t_handler
1589   (vl_api_bridge_flags_reply_t * mp)
1590 {
1591   vat_main_t *vam = &vat_main;
1592   i32 retval = ntohl (mp->retval);
1593   if (vam->async_mode)
1594     {
1595       vam->async_errors += (retval < 0);
1596     }
1597   else
1598     {
1599       vam->retval = retval;
1600       vam->result_ready = 1;
1601     }
1602 }
1603
1604 static void vl_api_bridge_flags_reply_t_handler_json
1605   (vl_api_bridge_flags_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   vat_json_node_t node;
1609
1610   vat_json_init_object (&node);
1611   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1612   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1613                             ntohl (mp->resulting_feature_bitmap));
1614
1615   vat_json_print (vam->ofp, &node);
1616   vat_json_free (&node);
1617
1618   vam->retval = ntohl (mp->retval);
1619   vam->result_ready = 1;
1620 }
1621
1622 static void vl_api_tap_connect_reply_t_handler
1623   (vl_api_tap_connect_reply_t * mp)
1624 {
1625   vat_main_t *vam = &vat_main;
1626   i32 retval = ntohl (mp->retval);
1627   if (vam->async_mode)
1628     {
1629       vam->async_errors += (retval < 0);
1630     }
1631   else
1632     {
1633       vam->retval = retval;
1634       vam->sw_if_index = ntohl (mp->sw_if_index);
1635       vam->result_ready = 1;
1636     }
1637
1638 }
1639
1640 static void vl_api_tap_connect_reply_t_handler_json
1641   (vl_api_tap_connect_reply_t * mp)
1642 {
1643   vat_main_t *vam = &vat_main;
1644   vat_json_node_t node;
1645
1646   vat_json_init_object (&node);
1647   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1648   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1649
1650   vat_json_print (vam->ofp, &node);
1651   vat_json_free (&node);
1652
1653   vam->retval = ntohl (mp->retval);
1654   vam->result_ready = 1;
1655
1656 }
1657
1658 static void
1659 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->sw_if_index = ntohl (mp->sw_if_index);
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_tap_modify_reply_t_handler_json
1676   (vl_api_tap_modify_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void
1693 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   i32 retval = ntohl (mp->retval);
1697   if (vam->async_mode)
1698     {
1699       vam->async_errors += (retval < 0);
1700     }
1701   else
1702     {
1703       vam->retval = retval;
1704       vam->result_ready = 1;
1705     }
1706 }
1707
1708 static void vl_api_tap_delete_reply_t_handler_json
1709   (vl_api_tap_delete_reply_t * mp)
1710 {
1711   vat_main_t *vam = &vat_main;
1712   vat_json_node_t node;
1713
1714   vat_json_init_object (&node);
1715   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1716
1717   vat_json_print (vam->ofp, &node);
1718   vat_json_free (&node);
1719
1720   vam->retval = ntohl (mp->retval);
1721   vam->result_ready = 1;
1722 }
1723
1724 static void
1725 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1726 {
1727   vat_main_t *vam = &vat_main;
1728   i32 retval = ntohl (mp->retval);
1729   if (vam->async_mode)
1730     {
1731       vam->async_errors += (retval < 0);
1732     }
1733   else
1734     {
1735       vam->retval = retval;
1736       vam->sw_if_index = ntohl (mp->sw_if_index);
1737       vam->result_ready = 1;
1738     }
1739
1740 }
1741
1742 static void vl_api_tap_create_v2_reply_t_handler_json
1743   (vl_api_tap_create_v2_reply_t * mp)
1744 {
1745   vat_main_t *vam = &vat_main;
1746   vat_json_node_t node;
1747
1748   vat_json_init_object (&node);
1749   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1750   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1751
1752   vat_json_print (vam->ofp, &node);
1753   vat_json_free (&node);
1754
1755   vam->retval = ntohl (mp->retval);
1756   vam->result_ready = 1;
1757
1758 }
1759
1760 static void
1761 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1762 {
1763   vat_main_t *vam = &vat_main;
1764   i32 retval = ntohl (mp->retval);
1765   if (vam->async_mode)
1766     {
1767       vam->async_errors += (retval < 0);
1768     }
1769   else
1770     {
1771       vam->retval = retval;
1772       vam->result_ready = 1;
1773     }
1774 }
1775
1776 static void vl_api_tap_delete_v2_reply_t_handler_json
1777   (vl_api_tap_delete_v2_reply_t * mp)
1778 {
1779   vat_main_t *vam = &vat_main;
1780   vat_json_node_t node;
1781
1782   vat_json_init_object (&node);
1783   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1784
1785   vat_json_print (vam->ofp, &node);
1786   vat_json_free (&node);
1787
1788   vam->retval = ntohl (mp->retval);
1789   vam->result_ready = 1;
1790 }
1791
1792 static void
1793 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1794 {
1795   vat_main_t *vam = &vat_main;
1796   i32 retval = ntohl (mp->retval);
1797
1798   if (vam->async_mode)
1799     {
1800       vam->async_errors += (retval < 0);
1801     }
1802   else
1803     {
1804       vam->retval = retval;
1805       vam->sw_if_index = ntohl (mp->sw_if_index);
1806       vam->result_ready = 1;
1807     }
1808 }
1809
1810 static void vl_api_bond_create_reply_t_handler_json
1811   (vl_api_bond_create_reply_t * mp)
1812 {
1813   vat_main_t *vam = &vat_main;
1814   vat_json_node_t node;
1815
1816   vat_json_init_object (&node);
1817   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1818   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1819
1820   vat_json_print (vam->ofp, &node);
1821   vat_json_free (&node);
1822
1823   vam->retval = ntohl (mp->retval);
1824   vam->result_ready = 1;
1825 }
1826
1827 static void
1828 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   i32 retval = ntohl (mp->retval);
1832
1833   if (vam->async_mode)
1834     {
1835       vam->async_errors += (retval < 0);
1836     }
1837   else
1838     {
1839       vam->retval = retval;
1840       vam->result_ready = 1;
1841     }
1842 }
1843
1844 static void vl_api_bond_delete_reply_t_handler_json
1845   (vl_api_bond_delete_reply_t * mp)
1846 {
1847   vat_main_t *vam = &vat_main;
1848   vat_json_node_t node;
1849
1850   vat_json_init_object (&node);
1851   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1852
1853   vat_json_print (vam->ofp, &node);
1854   vat_json_free (&node);
1855
1856   vam->retval = ntohl (mp->retval);
1857   vam->result_ready = 1;
1858 }
1859
1860 static void
1861 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1862 {
1863   vat_main_t *vam = &vat_main;
1864   i32 retval = ntohl (mp->retval);
1865
1866   if (vam->async_mode)
1867     {
1868       vam->async_errors += (retval < 0);
1869     }
1870   else
1871     {
1872       vam->retval = retval;
1873       vam->result_ready = 1;
1874     }
1875 }
1876
1877 static void vl_api_bond_enslave_reply_t_handler_json
1878   (vl_api_bond_enslave_reply_t * mp)
1879 {
1880   vat_main_t *vam = &vat_main;
1881   vat_json_node_t node;
1882
1883   vat_json_init_object (&node);
1884   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1885
1886   vat_json_print (vam->ofp, &node);
1887   vat_json_free (&node);
1888
1889   vam->retval = ntohl (mp->retval);
1890   vam->result_ready = 1;
1891 }
1892
1893 static void
1894 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1895                                           mp)
1896 {
1897   vat_main_t *vam = &vat_main;
1898   i32 retval = ntohl (mp->retval);
1899
1900   if (vam->async_mode)
1901     {
1902       vam->async_errors += (retval < 0);
1903     }
1904   else
1905     {
1906       vam->retval = retval;
1907       vam->result_ready = 1;
1908     }
1909 }
1910
1911 static void vl_api_bond_detach_slave_reply_t_handler_json
1912   (vl_api_bond_detach_slave_reply_t * mp)
1913 {
1914   vat_main_t *vam = &vat_main;
1915   vat_json_node_t node;
1916
1917   vat_json_init_object (&node);
1918   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1919
1920   vat_json_print (vam->ofp, &node);
1921   vat_json_free (&node);
1922
1923   vam->retval = ntohl (mp->retval);
1924   vam->result_ready = 1;
1925 }
1926
1927 static void vl_api_sw_interface_bond_details_t_handler
1928   (vl_api_sw_interface_bond_details_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931
1932   print (vam->ofp,
1933          "%-16s %-12d %-12U %-13U %-14u %-14u",
1934          mp->interface_name, ntohl (mp->sw_if_index),
1935          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1936          ntohl (mp->active_slaves), ntohl (mp->slaves));
1937 }
1938
1939 static void vl_api_sw_interface_bond_details_t_handler_json
1940   (vl_api_sw_interface_bond_details_t * mp)
1941 {
1942   vat_main_t *vam = &vat_main;
1943   vat_json_node_t *node = NULL;
1944
1945   if (VAT_JSON_ARRAY != vam->json_tree.type)
1946     {
1947       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1948       vat_json_init_array (&vam->json_tree);
1949     }
1950   node = vat_json_array_add (&vam->json_tree);
1951
1952   vat_json_init_object (node);
1953   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1954   vat_json_object_add_string_copy (node, "interface_name",
1955                                    mp->interface_name);
1956   vat_json_object_add_uint (node, "mode", mp->mode);
1957   vat_json_object_add_uint (node, "load_balance", mp->lb);
1958   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1959   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1960 }
1961
1962 static int
1963 api_sw_interface_bond_dump (vat_main_t * vam)
1964 {
1965   vl_api_sw_interface_bond_dump_t *mp;
1966   vl_api_control_ping_t *mp_ping;
1967   int ret;
1968
1969   print (vam->ofp,
1970          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1971          "interface name", "sw_if_index", "mode", "load balance",
1972          "active slaves", "slaves");
1973
1974   /* Get list of bond interfaces */
1975   M (SW_INTERFACE_BOND_DUMP, mp);
1976   S (mp);
1977
1978   /* Use a control ping for synchronization */
1979   MPING (CONTROL_PING, mp_ping);
1980   S (mp_ping);
1981
1982   W (ret);
1983   return ret;
1984 }
1985
1986 static void vl_api_sw_interface_slave_details_t_handler
1987   (vl_api_sw_interface_slave_details_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990
1991   print (vam->ofp,
1992          "%-25s %-12d %-12d %d", mp->interface_name,
1993          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1994 }
1995
1996 static void vl_api_sw_interface_slave_details_t_handler_json
1997   (vl_api_sw_interface_slave_details_t * mp)
1998 {
1999   vat_main_t *vam = &vat_main;
2000   vat_json_node_t *node = NULL;
2001
2002   if (VAT_JSON_ARRAY != vam->json_tree.type)
2003     {
2004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2005       vat_json_init_array (&vam->json_tree);
2006     }
2007   node = vat_json_array_add (&vam->json_tree);
2008
2009   vat_json_init_object (node);
2010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2011   vat_json_object_add_string_copy (node, "interface_name",
2012                                    mp->interface_name);
2013   vat_json_object_add_uint (node, "passive", mp->is_passive);
2014   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2015 }
2016
2017 static int
2018 api_sw_interface_slave_dump (vat_main_t * vam)
2019 {
2020   unformat_input_t *i = vam->input;
2021   vl_api_sw_interface_slave_dump_t *mp;
2022   vl_api_control_ping_t *mp_ping;
2023   u32 sw_if_index = ~0;
2024   u8 sw_if_index_set = 0;
2025   int ret;
2026
2027   /* Parse args required to build the message */
2028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2029     {
2030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2031         sw_if_index_set = 1;
2032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2033         sw_if_index_set = 1;
2034       else
2035         break;
2036     }
2037
2038   if (sw_if_index_set == 0)
2039     {
2040       errmsg ("missing vpp interface name. ");
2041       return -99;
2042     }
2043
2044   print (vam->ofp,
2045          "\n%-25s %-12s %-12s %s",
2046          "slave interface name", "sw_if_index", "passive", "long_timeout");
2047
2048   /* Get list of bond interfaces */
2049   M (SW_INTERFACE_SLAVE_DUMP, mp);
2050   mp->sw_if_index = ntohl (sw_if_index);
2051   S (mp);
2052
2053   /* Use a control ping for synchronization */
2054   MPING (CONTROL_PING, mp_ping);
2055   S (mp_ping);
2056
2057   W (ret);
2058   return ret;
2059 }
2060
2061 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2062   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2063 {
2064   vat_main_t *vam = &vat_main;
2065   i32 retval = ntohl (mp->retval);
2066   if (vam->async_mode)
2067     {
2068       vam->async_errors += (retval < 0);
2069     }
2070   else
2071     {
2072       vam->retval = retval;
2073       vam->result_ready = 1;
2074     }
2075 }
2076
2077 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2078   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2079 {
2080   vat_main_t *vam = &vat_main;
2081   vat_json_node_t node;
2082
2083   vat_json_init_object (&node);
2084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2085   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2086                             ntohl (mp->sw_if_index));
2087
2088   vat_json_print (vam->ofp, &node);
2089   vat_json_free (&node);
2090
2091   vam->retval = ntohl (mp->retval);
2092   vam->result_ready = 1;
2093 }
2094
2095 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2096   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2097 {
2098   vat_main_t *vam = &vat_main;
2099   i32 retval = ntohl (mp->retval);
2100   if (vam->async_mode)
2101     {
2102       vam->async_errors += (retval < 0);
2103     }
2104   else
2105     {
2106       vam->retval = retval;
2107       vam->sw_if_index = ntohl (mp->sw_if_index);
2108       vam->result_ready = 1;
2109     }
2110 }
2111
2112 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2113   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116   vat_json_node_t node;
2117
2118   vat_json_init_object (&node);
2119   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2120   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2121
2122   vat_json_print (vam->ofp, &node);
2123   vat_json_free (&node);
2124
2125   vam->retval = ntohl (mp->retval);
2126   vam->result_ready = 1;
2127 }
2128
2129 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2130   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2131 {
2132   vat_main_t *vam = &vat_main;
2133   i32 retval = ntohl (mp->retval);
2134   if (vam->async_mode)
2135     {
2136       vam->async_errors += (retval < 0);
2137     }
2138   else
2139     {
2140       vam->retval = retval;
2141       vam->result_ready = 1;
2142     }
2143 }
2144
2145 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2146   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2147 {
2148   vat_main_t *vam = &vat_main;
2149   vat_json_node_t node;
2150
2151   vat_json_init_object (&node);
2152   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2153   vat_json_object_add_uint (&node, "fwd_entry_index",
2154                             clib_net_to_host_u32 (mp->fwd_entry_index));
2155
2156   vat_json_print (vam->ofp, &node);
2157   vat_json_free (&node);
2158
2159   vam->retval = ntohl (mp->retval);
2160   vam->result_ready = 1;
2161 }
2162
2163 u8 *
2164 format_lisp_transport_protocol (u8 * s, va_list * args)
2165 {
2166   u32 proto = va_arg (*args, u32);
2167
2168   switch (proto)
2169     {
2170     case 1:
2171       return format (s, "udp");
2172     case 2:
2173       return format (s, "api");
2174     default:
2175       return 0;
2176     }
2177   return 0;
2178 }
2179
2180 static void vl_api_one_get_transport_protocol_reply_t_handler
2181   (vl_api_one_get_transport_protocol_reply_t * mp)
2182 {
2183   vat_main_t *vam = &vat_main;
2184   i32 retval = ntohl (mp->retval);
2185   if (vam->async_mode)
2186     {
2187       vam->async_errors += (retval < 0);
2188     }
2189   else
2190     {
2191       u32 proto = mp->protocol;
2192       print (vam->ofp, "Transport protocol: %U",
2193              format_lisp_transport_protocol, proto);
2194       vam->retval = retval;
2195       vam->result_ready = 1;
2196     }
2197 }
2198
2199 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2200   (vl_api_one_get_transport_protocol_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   vat_json_node_t node;
2204   u8 *s;
2205
2206   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2207   vec_add1 (s, 0);
2208
2209   vat_json_init_object (&node);
2210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2211   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2212
2213   vec_free (s);
2214   vat_json_print (vam->ofp, &node);
2215   vat_json_free (&node);
2216
2217   vam->retval = ntohl (mp->retval);
2218   vam->result_ready = 1;
2219 }
2220
2221 static void vl_api_one_add_del_locator_set_reply_t_handler
2222   (vl_api_one_add_del_locator_set_reply_t * mp)
2223 {
2224   vat_main_t *vam = &vat_main;
2225   i32 retval = ntohl (mp->retval);
2226   if (vam->async_mode)
2227     {
2228       vam->async_errors += (retval < 0);
2229     }
2230   else
2231     {
2232       vam->retval = retval;
2233       vam->result_ready = 1;
2234     }
2235 }
2236
2237 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2238   (vl_api_one_add_del_locator_set_reply_t * mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   vat_json_node_t node;
2242
2243   vat_json_init_object (&node);
2244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2245   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2246
2247   vat_json_print (vam->ofp, &node);
2248   vat_json_free (&node);
2249
2250   vam->retval = ntohl (mp->retval);
2251   vam->result_ready = 1;
2252 }
2253
2254 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2255   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   i32 retval = ntohl (mp->retval);
2259   if (vam->async_mode)
2260     {
2261       vam->async_errors += (retval < 0);
2262     }
2263   else
2264     {
2265       vam->retval = retval;
2266       vam->sw_if_index = ntohl (mp->sw_if_index);
2267       vam->result_ready = 1;
2268     }
2269   vam->regenerate_interface_table = 1;
2270 }
2271
2272 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2273   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2274 {
2275   vat_main_t *vam = &vat_main;
2276   vat_json_node_t node;
2277
2278   vat_json_init_object (&node);
2279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2280   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2281
2282   vat_json_print (vam->ofp, &node);
2283   vat_json_free (&node);
2284
2285   vam->retval = ntohl (mp->retval);
2286   vam->result_ready = 1;
2287 }
2288
2289 static void vl_api_vxlan_offload_rx_reply_t_handler
2290   (vl_api_vxlan_offload_rx_reply_t * mp)
2291 {
2292   vat_main_t *vam = &vat_main;
2293   i32 retval = ntohl (mp->retval);
2294   if (vam->async_mode)
2295     {
2296       vam->async_errors += (retval < 0);
2297     }
2298   else
2299     {
2300       vam->retval = retval;
2301       vam->result_ready = 1;
2302     }
2303 }
2304
2305 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2306   (vl_api_vxlan_offload_rx_reply_t * mp)
2307 {
2308   vat_main_t *vam = &vat_main;
2309   vat_json_node_t node;
2310
2311   vat_json_init_object (&node);
2312   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2313
2314   vat_json_print (vam->ofp, &node);
2315   vat_json_free (&node);
2316
2317   vam->retval = ntohl (mp->retval);
2318   vam->result_ready = 1;
2319 }
2320
2321 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2322   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2323 {
2324   vat_main_t *vam = &vat_main;
2325   i32 retval = ntohl (mp->retval);
2326   if (vam->async_mode)
2327     {
2328       vam->async_errors += (retval < 0);
2329     }
2330   else
2331     {
2332       vam->retval = retval;
2333       vam->sw_if_index = ntohl (mp->sw_if_index);
2334       vam->result_ready = 1;
2335     }
2336 }
2337
2338 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2339   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2340 {
2341   vat_main_t *vam = &vat_main;
2342   vat_json_node_t node;
2343
2344   vat_json_init_object (&node);
2345   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2346   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2347
2348   vat_json_print (vam->ofp, &node);
2349   vat_json_free (&node);
2350
2351   vam->retval = ntohl (mp->retval);
2352   vam->result_ready = 1;
2353 }
2354
2355 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2356   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   i32 retval = ntohl (mp->retval);
2360   if (vam->async_mode)
2361     {
2362       vam->async_errors += (retval < 0);
2363     }
2364   else
2365     {
2366       vam->retval = retval;
2367       vam->sw_if_index = ntohl (mp->sw_if_index);
2368       vam->result_ready = 1;
2369     }
2370   vam->regenerate_interface_table = 1;
2371 }
2372
2373 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2374   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2375 {
2376   vat_main_t *vam = &vat_main;
2377   vat_json_node_t node;
2378
2379   vat_json_init_object (&node);
2380   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2381   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2382
2383   vat_json_print (vam->ofp, &node);
2384   vat_json_free (&node);
2385
2386   vam->retval = ntohl (mp->retval);
2387   vam->result_ready = 1;
2388 }
2389
2390 static void vl_api_gre_add_del_tunnel_reply_t_handler
2391   (vl_api_gre_add_del_tunnel_reply_t * mp)
2392 {
2393   vat_main_t *vam = &vat_main;
2394   i32 retval = ntohl (mp->retval);
2395   if (vam->async_mode)
2396     {
2397       vam->async_errors += (retval < 0);
2398     }
2399   else
2400     {
2401       vam->retval = retval;
2402       vam->sw_if_index = ntohl (mp->sw_if_index);
2403       vam->result_ready = 1;
2404     }
2405 }
2406
2407 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2408   (vl_api_gre_add_del_tunnel_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   vat_json_node_t node;
2412
2413   vat_json_init_object (&node);
2414   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2415   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2416
2417   vat_json_print (vam->ofp, &node);
2418   vat_json_free (&node);
2419
2420   vam->retval = ntohl (mp->retval);
2421   vam->result_ready = 1;
2422 }
2423
2424 static void vl_api_create_vhost_user_if_reply_t_handler
2425   (vl_api_create_vhost_user_if_reply_t * mp)
2426 {
2427   vat_main_t *vam = &vat_main;
2428   i32 retval = ntohl (mp->retval);
2429   if (vam->async_mode)
2430     {
2431       vam->async_errors += (retval < 0);
2432     }
2433   else
2434     {
2435       vam->retval = retval;
2436       vam->sw_if_index = ntohl (mp->sw_if_index);
2437       vam->result_ready = 1;
2438     }
2439   vam->regenerate_interface_table = 1;
2440 }
2441
2442 static void vl_api_create_vhost_user_if_reply_t_handler_json
2443   (vl_api_create_vhost_user_if_reply_t * mp)
2444 {
2445   vat_main_t *vam = &vat_main;
2446   vat_json_node_t node;
2447
2448   vat_json_init_object (&node);
2449   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2450   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2451
2452   vat_json_print (vam->ofp, &node);
2453   vat_json_free (&node);
2454
2455   vam->retval = ntohl (mp->retval);
2456   vam->result_ready = 1;
2457 }
2458
2459 static void vl_api_dns_resolve_name_reply_t_handler
2460   (vl_api_dns_resolve_name_reply_t * mp)
2461 {
2462   vat_main_t *vam = &vat_main;
2463   i32 retval = ntohl (mp->retval);
2464   if (vam->async_mode)
2465     {
2466       vam->async_errors += (retval < 0);
2467     }
2468   else
2469     {
2470       vam->retval = retval;
2471       vam->result_ready = 1;
2472
2473       if (retval == 0)
2474         {
2475           if (mp->ip4_set)
2476             clib_warning ("ip4 address %U", format_ip4_address,
2477                           (ip4_address_t *) mp->ip4_address);
2478           if (mp->ip6_set)
2479             clib_warning ("ip6 address %U", format_ip6_address,
2480                           (ip6_address_t *) mp->ip6_address);
2481         }
2482       else
2483         clib_warning ("retval %d", retval);
2484     }
2485 }
2486
2487 static void vl_api_dns_resolve_name_reply_t_handler_json
2488   (vl_api_dns_resolve_name_reply_t * mp)
2489 {
2490   clib_warning ("not implemented");
2491 }
2492
2493 static void vl_api_dns_resolve_ip_reply_t_handler
2494   (vl_api_dns_resolve_ip_reply_t * mp)
2495 {
2496   vat_main_t *vam = &vat_main;
2497   i32 retval = ntohl (mp->retval);
2498   if (vam->async_mode)
2499     {
2500       vam->async_errors += (retval < 0);
2501     }
2502   else
2503     {
2504       vam->retval = retval;
2505       vam->result_ready = 1;
2506
2507       if (retval == 0)
2508         {
2509           clib_warning ("canonical name %s", mp->name);
2510         }
2511       else
2512         clib_warning ("retval %d", retval);
2513     }
2514 }
2515
2516 static void vl_api_dns_resolve_ip_reply_t_handler_json
2517   (vl_api_dns_resolve_ip_reply_t * mp)
2518 {
2519   clib_warning ("not implemented");
2520 }
2521
2522
2523 static void vl_api_ip_address_details_t_handler
2524   (vl_api_ip_address_details_t * mp)
2525 {
2526   vat_main_t *vam = &vat_main;
2527   static ip_address_details_t empty_ip_address_details = { {0} };
2528   ip_address_details_t *address = NULL;
2529   ip_details_t *current_ip_details = NULL;
2530   ip_details_t *details = NULL;
2531
2532   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2533
2534   if (!details || vam->current_sw_if_index >= vec_len (details)
2535       || !details[vam->current_sw_if_index].present)
2536     {
2537       errmsg ("ip address details arrived but not stored");
2538       errmsg ("ip_dump should be called first");
2539       return;
2540     }
2541
2542   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2543
2544 #define addresses (current_ip_details->addr)
2545
2546   vec_validate_init_empty (addresses, vec_len (addresses),
2547                            empty_ip_address_details);
2548
2549   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2550
2551   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2552   address->prefix_length = mp->prefix_length;
2553 #undef addresses
2554 }
2555
2556 static void vl_api_ip_address_details_t_handler_json
2557   (vl_api_ip_address_details_t * mp)
2558 {
2559   vat_main_t *vam = &vat_main;
2560   vat_json_node_t *node = NULL;
2561   struct in6_addr ip6;
2562   struct in_addr ip4;
2563
2564   if (VAT_JSON_ARRAY != vam->json_tree.type)
2565     {
2566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2567       vat_json_init_array (&vam->json_tree);
2568     }
2569   node = vat_json_array_add (&vam->json_tree);
2570
2571   vat_json_init_object (node);
2572   if (vam->is_ipv6)
2573     {
2574       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2575       vat_json_object_add_ip6 (node, "ip", ip6);
2576     }
2577   else
2578     {
2579       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2580       vat_json_object_add_ip4 (node, "ip", ip4);
2581     }
2582   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2583 }
2584
2585 static void
2586 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2587 {
2588   vat_main_t *vam = &vat_main;
2589   static ip_details_t empty_ip_details = { 0 };
2590   ip_details_t *ip = NULL;
2591   u32 sw_if_index = ~0;
2592
2593   sw_if_index = ntohl (mp->sw_if_index);
2594
2595   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2596                            sw_if_index, empty_ip_details);
2597
2598   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2599                          sw_if_index);
2600
2601   ip->present = 1;
2602 }
2603
2604 static void
2605 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2606 {
2607   vat_main_t *vam = &vat_main;
2608
2609   if (VAT_JSON_ARRAY != vam->json_tree.type)
2610     {
2611       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2612       vat_json_init_array (&vam->json_tree);
2613     }
2614   vat_json_array_add_uint (&vam->json_tree,
2615                            clib_net_to_host_u32 (mp->sw_if_index));
2616 }
2617
2618 static void vl_api_map_domain_details_t_handler_json
2619   (vl_api_map_domain_details_t * mp)
2620 {
2621   vat_json_node_t *node = NULL;
2622   vat_main_t *vam = &vat_main;
2623   struct in6_addr ip6;
2624   struct in_addr ip4;
2625
2626   if (VAT_JSON_ARRAY != vam->json_tree.type)
2627     {
2628       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2629       vat_json_init_array (&vam->json_tree);
2630     }
2631
2632   node = vat_json_array_add (&vam->json_tree);
2633   vat_json_init_object (node);
2634
2635   vat_json_object_add_uint (node, "domain_index",
2636                             clib_net_to_host_u32 (mp->domain_index));
2637   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2638   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2639   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2640   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2641   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2642   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2643   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2644   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2645   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2646   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2647   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2648   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2649   vat_json_object_add_uint (node, "flags", mp->flags);
2650   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2651   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2652 }
2653
2654 static void vl_api_map_domain_details_t_handler
2655   (vl_api_map_domain_details_t * mp)
2656 {
2657   vat_main_t *vam = &vat_main;
2658
2659   if (mp->is_translation)
2660     {
2661       print (vam->ofp,
2662              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2663              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2664              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2665              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2666              clib_net_to_host_u32 (mp->domain_index));
2667     }
2668   else
2669     {
2670       print (vam->ofp,
2671              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2672              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2673              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2674              format_ip6_address, mp->ip6_src,
2675              clib_net_to_host_u32 (mp->domain_index));
2676     }
2677   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2678          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2679          mp->is_translation ? "map-t" : "");
2680 }
2681
2682 static void vl_api_map_rule_details_t_handler_json
2683   (vl_api_map_rule_details_t * mp)
2684 {
2685   struct in6_addr ip6;
2686   vat_json_node_t *node = NULL;
2687   vat_main_t *vam = &vat_main;
2688
2689   if (VAT_JSON_ARRAY != vam->json_tree.type)
2690     {
2691       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2692       vat_json_init_array (&vam->json_tree);
2693     }
2694
2695   node = vat_json_array_add (&vam->json_tree);
2696   vat_json_init_object (node);
2697
2698   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2699   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2700   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2701 }
2702
2703 static void
2704 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2708          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2709 }
2710
2711 static void
2712 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2713 {
2714   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2715           "router_addr %U host_mac %U",
2716           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2717           mp->lease.hostname,
2718           format_ip4_address, &mp->lease.host_address,
2719           format_ip4_address, &mp->lease.router_address,
2720           format_ethernet_address, mp->lease.host_mac);
2721 }
2722
2723 static void vl_api_dhcp_compl_event_t_handler_json
2724   (vl_api_dhcp_compl_event_t * mp)
2725 {
2726   /* JSON output not supported */
2727 }
2728
2729 static void
2730 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2731                               u32 counter)
2732 {
2733   vat_main_t *vam = &vat_main;
2734   static u64 default_counter = 0;
2735
2736   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2737                            NULL);
2738   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2739                            sw_if_index, default_counter);
2740   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2741 }
2742
2743 static void
2744 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2745                                 interface_counter_t counter)
2746 {
2747   vat_main_t *vam = &vat_main;
2748   static interface_counter_t default_counter = { 0, };
2749
2750   vec_validate_init_empty (vam->combined_interface_counters,
2751                            vnet_counter_type, NULL);
2752   vec_validate_init_empty (vam->combined_interface_counters
2753                            [vnet_counter_type], sw_if_index, default_counter);
2754   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2755 }
2756
2757 static void vl_api_vnet_interface_simple_counters_t_handler
2758   (vl_api_vnet_interface_simple_counters_t * mp)
2759 {
2760   /* not supported */
2761 }
2762
2763 static void vl_api_vnet_interface_combined_counters_t_handler
2764   (vl_api_vnet_interface_combined_counters_t * mp)
2765 {
2766   /* not supported */
2767 }
2768
2769 static void vl_api_vnet_interface_simple_counters_t_handler_json
2770   (vl_api_vnet_interface_simple_counters_t * mp)
2771 {
2772   u64 *v_packets;
2773   u64 packets;
2774   u32 count;
2775   u32 first_sw_if_index;
2776   int i;
2777
2778   count = ntohl (mp->count);
2779   first_sw_if_index = ntohl (mp->first_sw_if_index);
2780
2781   v_packets = (u64 *) & mp->data;
2782   for (i = 0; i < count; i++)
2783     {
2784       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2785       set_simple_interface_counter (mp->vnet_counter_type,
2786                                     first_sw_if_index + i, packets);
2787       v_packets++;
2788     }
2789 }
2790
2791 static void vl_api_vnet_interface_combined_counters_t_handler_json
2792   (vl_api_vnet_interface_combined_counters_t * mp)
2793 {
2794   interface_counter_t counter;
2795   vlib_counter_t *v;
2796   u32 first_sw_if_index;
2797   int i;
2798   u32 count;
2799
2800   count = ntohl (mp->count);
2801   first_sw_if_index = ntohl (mp->first_sw_if_index);
2802
2803   v = (vlib_counter_t *) & mp->data;
2804   for (i = 0; i < count; i++)
2805     {
2806       counter.packets =
2807         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2808       counter.bytes =
2809         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2810       set_combined_interface_counter (mp->vnet_counter_type,
2811                                       first_sw_if_index + i, counter);
2812       v++;
2813     }
2814 }
2815
2816 static u32
2817 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   u32 i;
2821
2822   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2823     {
2824       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2825         {
2826           return i;
2827         }
2828     }
2829   return ~0;
2830 }
2831
2832 static u32
2833 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2834 {
2835   vat_main_t *vam = &vat_main;
2836   u32 i;
2837
2838   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2839     {
2840       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2841         {
2842           return i;
2843         }
2844     }
2845   return ~0;
2846 }
2847
2848 static void vl_api_vnet_ip4_fib_counters_t_handler
2849   (vl_api_vnet_ip4_fib_counters_t * mp)
2850 {
2851   /* not supported */
2852 }
2853
2854 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2855   (vl_api_vnet_ip4_fib_counters_t * mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   vl_api_ip4_fib_counter_t *v;
2859   ip4_fib_counter_t *counter;
2860   struct in_addr ip4;
2861   u32 vrf_id;
2862   u32 vrf_index;
2863   u32 count;
2864   int i;
2865
2866   vrf_id = ntohl (mp->vrf_id);
2867   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2868   if (~0 == vrf_index)
2869     {
2870       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2871       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2872       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2873       vec_validate (vam->ip4_fib_counters, vrf_index);
2874       vam->ip4_fib_counters[vrf_index] = NULL;
2875     }
2876
2877   vec_free (vam->ip4_fib_counters[vrf_index]);
2878   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2879   count = ntohl (mp->count);
2880   for (i = 0; i < count; i++)
2881     {
2882       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2883       counter = &vam->ip4_fib_counters[vrf_index][i];
2884       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2885       counter->address = ip4;
2886       counter->address_length = v->address_length;
2887       counter->packets = clib_net_to_host_u64 (v->packets);
2888       counter->bytes = clib_net_to_host_u64 (v->bytes);
2889       v++;
2890     }
2891 }
2892
2893 static void vl_api_vnet_ip4_nbr_counters_t_handler
2894   (vl_api_vnet_ip4_nbr_counters_t * mp)
2895 {
2896   /* not supported */
2897 }
2898
2899 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2900   (vl_api_vnet_ip4_nbr_counters_t * mp)
2901 {
2902   vat_main_t *vam = &vat_main;
2903   vl_api_ip4_nbr_counter_t *v;
2904   ip4_nbr_counter_t *counter;
2905   u32 sw_if_index;
2906   u32 count;
2907   int i;
2908
2909   sw_if_index = ntohl (mp->sw_if_index);
2910   count = ntohl (mp->count);
2911   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2912
2913   if (mp->begin)
2914     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2915
2916   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2917   for (i = 0; i < count; i++)
2918     {
2919       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2920       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2921       counter->address.s_addr = v->address;
2922       counter->packets = clib_net_to_host_u64 (v->packets);
2923       counter->bytes = clib_net_to_host_u64 (v->bytes);
2924       counter->linkt = v->link_type;
2925       v++;
2926     }
2927 }
2928
2929 static void vl_api_vnet_ip6_fib_counters_t_handler
2930   (vl_api_vnet_ip6_fib_counters_t * mp)
2931 {
2932   /* not supported */
2933 }
2934
2935 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2936   (vl_api_vnet_ip6_fib_counters_t * mp)
2937 {
2938   vat_main_t *vam = &vat_main;
2939   vl_api_ip6_fib_counter_t *v;
2940   ip6_fib_counter_t *counter;
2941   struct in6_addr ip6;
2942   u32 vrf_id;
2943   u32 vrf_index;
2944   u32 count;
2945   int i;
2946
2947   vrf_id = ntohl (mp->vrf_id);
2948   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2949   if (~0 == vrf_index)
2950     {
2951       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2952       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2953       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2954       vec_validate (vam->ip6_fib_counters, vrf_index);
2955       vam->ip6_fib_counters[vrf_index] = NULL;
2956     }
2957
2958   vec_free (vam->ip6_fib_counters[vrf_index]);
2959   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2960   count = ntohl (mp->count);
2961   for (i = 0; i < count; i++)
2962     {
2963       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2964       counter = &vam->ip6_fib_counters[vrf_index][i];
2965       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2966       counter->address = ip6;
2967       counter->address_length = v->address_length;
2968       counter->packets = clib_net_to_host_u64 (v->packets);
2969       counter->bytes = clib_net_to_host_u64 (v->bytes);
2970       v++;
2971     }
2972 }
2973
2974 static void vl_api_vnet_ip6_nbr_counters_t_handler
2975   (vl_api_vnet_ip6_nbr_counters_t * mp)
2976 {
2977   /* not supported */
2978 }
2979
2980 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2981   (vl_api_vnet_ip6_nbr_counters_t * mp)
2982 {
2983   vat_main_t *vam = &vat_main;
2984   vl_api_ip6_nbr_counter_t *v;
2985   ip6_nbr_counter_t *counter;
2986   struct in6_addr ip6;
2987   u32 sw_if_index;
2988   u32 count;
2989   int i;
2990
2991   sw_if_index = ntohl (mp->sw_if_index);
2992   count = ntohl (mp->count);
2993   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2994
2995   if (mp->begin)
2996     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2997
2998   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2999   for (i = 0; i < count; i++)
3000     {
3001       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
3002       counter = &vam->ip6_nbr_counters[sw_if_index][i];
3003       clib_memcpy (&ip6, &v->address, sizeof (ip6));
3004       counter->address = ip6;
3005       counter->packets = clib_net_to_host_u64 (v->packets);
3006       counter->bytes = clib_net_to_host_u64 (v->bytes);
3007       v++;
3008     }
3009 }
3010
3011 static void vl_api_get_first_msg_id_reply_t_handler
3012   (vl_api_get_first_msg_id_reply_t * mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   i32 retval = ntohl (mp->retval);
3016
3017   if (vam->async_mode)
3018     {
3019       vam->async_errors += (retval < 0);
3020     }
3021   else
3022     {
3023       vam->retval = retval;
3024       vam->result_ready = 1;
3025     }
3026   if (retval >= 0)
3027     {
3028       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3029     }
3030 }
3031
3032 static void vl_api_get_first_msg_id_reply_t_handler_json
3033   (vl_api_get_first_msg_id_reply_t * mp)
3034 {
3035   vat_main_t *vam = &vat_main;
3036   vat_json_node_t node;
3037
3038   vat_json_init_object (&node);
3039   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3040   vat_json_object_add_uint (&node, "first_msg_id",
3041                             (uint) ntohs (mp->first_msg_id));
3042
3043   vat_json_print (vam->ofp, &node);
3044   vat_json_free (&node);
3045
3046   vam->retval = ntohl (mp->retval);
3047   vam->result_ready = 1;
3048 }
3049
3050 static void vl_api_get_node_graph_reply_t_handler
3051   (vl_api_get_node_graph_reply_t * mp)
3052 {
3053   vat_main_t *vam = &vat_main;
3054   api_main_t *am = &api_main;
3055   i32 retval = ntohl (mp->retval);
3056   u8 *pvt_copy, *reply;
3057   void *oldheap;
3058   vlib_node_t *node;
3059   int i;
3060
3061   if (vam->async_mode)
3062     {
3063       vam->async_errors += (retval < 0);
3064     }
3065   else
3066     {
3067       vam->retval = retval;
3068       vam->result_ready = 1;
3069     }
3070
3071   /* "Should never happen..." */
3072   if (retval != 0)
3073     return;
3074
3075   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3076   pvt_copy = vec_dup (reply);
3077
3078   /* Toss the shared-memory original... */
3079   pthread_mutex_lock (&am->vlib_rp->mutex);
3080   oldheap = svm_push_data_heap (am->vlib_rp);
3081
3082   vec_free (reply);
3083
3084   svm_pop_heap (oldheap);
3085   pthread_mutex_unlock (&am->vlib_rp->mutex);
3086
3087   if (vam->graph_nodes)
3088     {
3089       hash_free (vam->graph_node_index_by_name);
3090
3091       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3092         {
3093           node = vam->graph_nodes[0][i];
3094           vec_free (node->name);
3095           vec_free (node->next_nodes);
3096           vec_free (node);
3097         }
3098       vec_free (vam->graph_nodes[0]);
3099       vec_free (vam->graph_nodes);
3100     }
3101
3102   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3103   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3104   vec_free (pvt_copy);
3105
3106   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3107     {
3108       node = vam->graph_nodes[0][i];
3109       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3110     }
3111 }
3112
3113 static void vl_api_get_node_graph_reply_t_handler_json
3114   (vl_api_get_node_graph_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   api_main_t *am = &api_main;
3118   void *oldheap;
3119   vat_json_node_t node;
3120   u8 *reply;
3121
3122   /* $$$$ make this real? */
3123   vat_json_init_object (&node);
3124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3125   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3126
3127   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3128
3129   /* Toss the shared-memory original... */
3130   pthread_mutex_lock (&am->vlib_rp->mutex);
3131   oldheap = svm_push_data_heap (am->vlib_rp);
3132
3133   vec_free (reply);
3134
3135   svm_pop_heap (oldheap);
3136   pthread_mutex_unlock (&am->vlib_rp->mutex);
3137
3138   vat_json_print (vam->ofp, &node);
3139   vat_json_free (&node);
3140
3141   vam->retval = ntohl (mp->retval);
3142   vam->result_ready = 1;
3143 }
3144
3145 static void
3146 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3147 {
3148   vat_main_t *vam = &vat_main;
3149   u8 *s = 0;
3150
3151   if (mp->local)
3152     {
3153       s = format (s, "%=16d%=16d%=16d",
3154                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3155     }
3156   else
3157     {
3158       s = format (s, "%=16U%=16d%=16d",
3159                   mp->is_ipv6 ? format_ip6_address :
3160                   format_ip4_address,
3161                   mp->ip_address, mp->priority, mp->weight);
3162     }
3163
3164   print (vam->ofp, "%v", s);
3165   vec_free (s);
3166 }
3167
3168 static void
3169 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3170 {
3171   vat_main_t *vam = &vat_main;
3172   vat_json_node_t *node = NULL;
3173   struct in6_addr ip6;
3174   struct in_addr ip4;
3175
3176   if (VAT_JSON_ARRAY != vam->json_tree.type)
3177     {
3178       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3179       vat_json_init_array (&vam->json_tree);
3180     }
3181   node = vat_json_array_add (&vam->json_tree);
3182   vat_json_init_object (node);
3183
3184   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3185   vat_json_object_add_uint (node, "priority", mp->priority);
3186   vat_json_object_add_uint (node, "weight", mp->weight);
3187
3188   if (mp->local)
3189     vat_json_object_add_uint (node, "sw_if_index",
3190                               clib_net_to_host_u32 (mp->sw_if_index));
3191   else
3192     {
3193       if (mp->is_ipv6)
3194         {
3195           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3196           vat_json_object_add_ip6 (node, "address", ip6);
3197         }
3198       else
3199         {
3200           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3201           vat_json_object_add_ip4 (node, "address", ip4);
3202         }
3203     }
3204 }
3205
3206 static void
3207 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3208                                           mp)
3209 {
3210   vat_main_t *vam = &vat_main;
3211   u8 *ls_name = 0;
3212
3213   ls_name = format (0, "%s", mp->ls_name);
3214
3215   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3216          ls_name);
3217   vec_free (ls_name);
3218 }
3219
3220 static void
3221   vl_api_one_locator_set_details_t_handler_json
3222   (vl_api_one_locator_set_details_t * mp)
3223 {
3224   vat_main_t *vam = &vat_main;
3225   vat_json_node_t *node = 0;
3226   u8 *ls_name = 0;
3227
3228   ls_name = format (0, "%s", mp->ls_name);
3229   vec_add1 (ls_name, 0);
3230
3231   if (VAT_JSON_ARRAY != vam->json_tree.type)
3232     {
3233       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3234       vat_json_init_array (&vam->json_tree);
3235     }
3236   node = vat_json_array_add (&vam->json_tree);
3237
3238   vat_json_init_object (node);
3239   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3240   vat_json_object_add_uint (node, "ls_index",
3241                             clib_net_to_host_u32 (mp->ls_index));
3242   vec_free (ls_name);
3243 }
3244
3245 typedef struct
3246 {
3247   u32 spi;
3248   u8 si;
3249 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3250
3251 uword
3252 unformat_nsh_address (unformat_input_t * input, va_list * args)
3253 {
3254   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3255   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3256 }
3257
3258 u8 *
3259 format_nsh_address_vat (u8 * s, va_list * args)
3260 {
3261   nsh_t *a = va_arg (*args, nsh_t *);
3262   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3263 }
3264
3265 static u8 *
3266 format_lisp_flat_eid (u8 * s, va_list * args)
3267 {
3268   u32 type = va_arg (*args, u32);
3269   u8 *eid = va_arg (*args, u8 *);
3270   u32 eid_len = va_arg (*args, u32);
3271
3272   switch (type)
3273     {
3274     case 0:
3275       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3276     case 1:
3277       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3278     case 2:
3279       return format (s, "%U", format_ethernet_address, eid);
3280     case 3:
3281       return format (s, "%U", format_nsh_address_vat, eid);
3282     }
3283   return 0;
3284 }
3285
3286 static u8 *
3287 format_lisp_eid_vat (u8 * s, va_list * args)
3288 {
3289   u32 type = va_arg (*args, u32);
3290   u8 *eid = va_arg (*args, u8 *);
3291   u32 eid_len = va_arg (*args, u32);
3292   u8 *seid = va_arg (*args, u8 *);
3293   u32 seid_len = va_arg (*args, u32);
3294   u32 is_src_dst = va_arg (*args, u32);
3295
3296   if (is_src_dst)
3297     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3298
3299   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3300
3301   return s;
3302 }
3303
3304 static void
3305 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3306 {
3307   vat_main_t *vam = &vat_main;
3308   u8 *s = 0, *eid = 0;
3309
3310   if (~0 == mp->locator_set_index)
3311     s = format (0, "action: %d", mp->action);
3312   else
3313     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3314
3315   eid = format (0, "%U", format_lisp_eid_vat,
3316                 mp->eid_type,
3317                 mp->eid,
3318                 mp->eid_prefix_len,
3319                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3320   vec_add1 (eid, 0);
3321
3322   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3323          clib_net_to_host_u32 (mp->vni),
3324          eid,
3325          mp->is_local ? "local" : "remote",
3326          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3327          clib_net_to_host_u16 (mp->key_id), mp->key);
3328
3329   vec_free (s);
3330   vec_free (eid);
3331 }
3332
3333 static void
3334 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3335                                              * mp)
3336 {
3337   vat_main_t *vam = &vat_main;
3338   vat_json_node_t *node = 0;
3339   u8 *eid = 0;
3340
3341   if (VAT_JSON_ARRAY != vam->json_tree.type)
3342     {
3343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3344       vat_json_init_array (&vam->json_tree);
3345     }
3346   node = vat_json_array_add (&vam->json_tree);
3347
3348   vat_json_init_object (node);
3349   if (~0 == mp->locator_set_index)
3350     vat_json_object_add_uint (node, "action", mp->action);
3351   else
3352     vat_json_object_add_uint (node, "locator_set_index",
3353                               clib_net_to_host_u32 (mp->locator_set_index));
3354
3355   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3356   if (mp->eid_type == 3)
3357     {
3358       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3359       vat_json_init_object (nsh_json);
3360       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3361       vat_json_object_add_uint (nsh_json, "spi",
3362                                 clib_net_to_host_u32 (nsh->spi));
3363       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3364     }
3365   else
3366     {
3367       eid = format (0, "%U", format_lisp_eid_vat,
3368                     mp->eid_type,
3369                     mp->eid,
3370                     mp->eid_prefix_len,
3371                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3372       vec_add1 (eid, 0);
3373       vat_json_object_add_string_copy (node, "eid", eid);
3374       vec_free (eid);
3375     }
3376   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3377   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3378   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3379
3380   if (mp->key_id)
3381     {
3382       vat_json_object_add_uint (node, "key_id",
3383                                 clib_net_to_host_u16 (mp->key_id));
3384       vat_json_object_add_string_copy (node, "key", mp->key);
3385     }
3386 }
3387
3388 static void
3389 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3390 {
3391   vat_main_t *vam = &vat_main;
3392   u8 *seid = 0, *deid = 0;
3393   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3394
3395   deid = format (0, "%U", format_lisp_eid_vat,
3396                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3397
3398   seid = format (0, "%U", format_lisp_eid_vat,
3399                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3400
3401   vec_add1 (deid, 0);
3402   vec_add1 (seid, 0);
3403
3404   if (mp->is_ip4)
3405     format_ip_address_fcn = format_ip4_address;
3406   else
3407     format_ip_address_fcn = format_ip6_address;
3408
3409
3410   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3411          clib_net_to_host_u32 (mp->vni),
3412          seid, deid,
3413          format_ip_address_fcn, mp->lloc,
3414          format_ip_address_fcn, mp->rloc,
3415          clib_net_to_host_u32 (mp->pkt_count),
3416          clib_net_to_host_u32 (mp->bytes));
3417
3418   vec_free (deid);
3419   vec_free (seid);
3420 }
3421
3422 static void
3423 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3424 {
3425   struct in6_addr ip6;
3426   struct in_addr ip4;
3427   vat_main_t *vam = &vat_main;
3428   vat_json_node_t *node = 0;
3429   u8 *deid = 0, *seid = 0;
3430
3431   if (VAT_JSON_ARRAY != vam->json_tree.type)
3432     {
3433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3434       vat_json_init_array (&vam->json_tree);
3435     }
3436   node = vat_json_array_add (&vam->json_tree);
3437
3438   vat_json_init_object (node);
3439   deid = format (0, "%U", format_lisp_eid_vat,
3440                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3441
3442   seid = format (0, "%U", format_lisp_eid_vat,
3443                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3444
3445   vec_add1 (deid, 0);
3446   vec_add1 (seid, 0);
3447
3448   vat_json_object_add_string_copy (node, "seid", seid);
3449   vat_json_object_add_string_copy (node, "deid", deid);
3450   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3451
3452   if (mp->is_ip4)
3453     {
3454       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3455       vat_json_object_add_ip4 (node, "lloc", ip4);
3456       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3457       vat_json_object_add_ip4 (node, "rloc", ip4);
3458     }
3459   else
3460     {
3461       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3462       vat_json_object_add_ip6 (node, "lloc", ip6);
3463       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3464       vat_json_object_add_ip6 (node, "rloc", ip6);
3465     }
3466   vat_json_object_add_uint (node, "pkt_count",
3467                             clib_net_to_host_u32 (mp->pkt_count));
3468   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3469
3470   vec_free (deid);
3471   vec_free (seid);
3472 }
3473
3474 static void
3475   vl_api_one_eid_table_map_details_t_handler
3476   (vl_api_one_eid_table_map_details_t * mp)
3477 {
3478   vat_main_t *vam = &vat_main;
3479
3480   u8 *line = format (0, "%=10d%=10d",
3481                      clib_net_to_host_u32 (mp->vni),
3482                      clib_net_to_host_u32 (mp->dp_table));
3483   print (vam->ofp, "%v", line);
3484   vec_free (line);
3485 }
3486
3487 static void
3488   vl_api_one_eid_table_map_details_t_handler_json
3489   (vl_api_one_eid_table_map_details_t * mp)
3490 {
3491   vat_main_t *vam = &vat_main;
3492   vat_json_node_t *node = NULL;
3493
3494   if (VAT_JSON_ARRAY != vam->json_tree.type)
3495     {
3496       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3497       vat_json_init_array (&vam->json_tree);
3498     }
3499   node = vat_json_array_add (&vam->json_tree);
3500   vat_json_init_object (node);
3501   vat_json_object_add_uint (node, "dp_table",
3502                             clib_net_to_host_u32 (mp->dp_table));
3503   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3504 }
3505
3506 static void
3507   vl_api_one_eid_table_vni_details_t_handler
3508   (vl_api_one_eid_table_vni_details_t * mp)
3509 {
3510   vat_main_t *vam = &vat_main;
3511
3512   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3513   print (vam->ofp, "%v", line);
3514   vec_free (line);
3515 }
3516
3517 static void
3518   vl_api_one_eid_table_vni_details_t_handler_json
3519   (vl_api_one_eid_table_vni_details_t * mp)
3520 {
3521   vat_main_t *vam = &vat_main;
3522   vat_json_node_t *node = NULL;
3523
3524   if (VAT_JSON_ARRAY != vam->json_tree.type)
3525     {
3526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3527       vat_json_init_array (&vam->json_tree);
3528     }
3529   node = vat_json_array_add (&vam->json_tree);
3530   vat_json_init_object (node);
3531   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3532 }
3533
3534 static void
3535   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3536   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3537 {
3538   vat_main_t *vam = &vat_main;
3539   int retval = clib_net_to_host_u32 (mp->retval);
3540
3541   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3542   print (vam->ofp, "fallback threshold value: %d", mp->value);
3543
3544   vam->retval = retval;
3545   vam->result_ready = 1;
3546 }
3547
3548 static void
3549   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3550   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3551 {
3552   vat_main_t *vam = &vat_main;
3553   vat_json_node_t _node, *node = &_node;
3554   int retval = clib_net_to_host_u32 (mp->retval);
3555
3556   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3557   vat_json_init_object (node);
3558   vat_json_object_add_uint (node, "value", mp->value);
3559
3560   vat_json_print (vam->ofp, node);
3561   vat_json_free (node);
3562
3563   vam->retval = retval;
3564   vam->result_ready = 1;
3565 }
3566
3567 static void
3568   vl_api_show_one_map_register_state_reply_t_handler
3569   (vl_api_show_one_map_register_state_reply_t * mp)
3570 {
3571   vat_main_t *vam = &vat_main;
3572   int retval = clib_net_to_host_u32 (mp->retval);
3573
3574   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3575
3576   vam->retval = retval;
3577   vam->result_ready = 1;
3578 }
3579
3580 static void
3581   vl_api_show_one_map_register_state_reply_t_handler_json
3582   (vl_api_show_one_map_register_state_reply_t * mp)
3583 {
3584   vat_main_t *vam = &vat_main;
3585   vat_json_node_t _node, *node = &_node;
3586   int retval = clib_net_to_host_u32 (mp->retval);
3587
3588   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3589
3590   vat_json_init_object (node);
3591   vat_json_object_add_string_copy (node, "state", s);
3592
3593   vat_json_print (vam->ofp, node);
3594   vat_json_free (node);
3595
3596   vam->retval = retval;
3597   vam->result_ready = 1;
3598   vec_free (s);
3599 }
3600
3601 static void
3602   vl_api_show_one_rloc_probe_state_reply_t_handler
3603   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3604 {
3605   vat_main_t *vam = &vat_main;
3606   int retval = clib_net_to_host_u32 (mp->retval);
3607
3608   if (retval)
3609     goto end;
3610
3611   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3612 end:
3613   vam->retval = retval;
3614   vam->result_ready = 1;
3615 }
3616
3617 static void
3618   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3619   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3620 {
3621   vat_main_t *vam = &vat_main;
3622   vat_json_node_t _node, *node = &_node;
3623   int retval = clib_net_to_host_u32 (mp->retval);
3624
3625   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3626   vat_json_init_object (node);
3627   vat_json_object_add_string_copy (node, "state", s);
3628
3629   vat_json_print (vam->ofp, node);
3630   vat_json_free (node);
3631
3632   vam->retval = retval;
3633   vam->result_ready = 1;
3634   vec_free (s);
3635 }
3636
3637 static void
3638   vl_api_show_one_stats_enable_disable_reply_t_handler
3639   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3640 {
3641   vat_main_t *vam = &vat_main;
3642   int retval = clib_net_to_host_u32 (mp->retval);
3643
3644   if (retval)
3645     goto end;
3646
3647   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3648 end:
3649   vam->retval = retval;
3650   vam->result_ready = 1;
3651 }
3652
3653 static void
3654   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3655   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3656 {
3657   vat_main_t *vam = &vat_main;
3658   vat_json_node_t _node, *node = &_node;
3659   int retval = clib_net_to_host_u32 (mp->retval);
3660
3661   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3662   vat_json_init_object (node);
3663   vat_json_object_add_string_copy (node, "state", s);
3664
3665   vat_json_print (vam->ofp, node);
3666   vat_json_free (node);
3667
3668   vam->retval = retval;
3669   vam->result_ready = 1;
3670   vec_free (s);
3671 }
3672
3673 static void
3674 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3675 {
3676   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3677   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3678   e->vni = clib_net_to_host_u32 (e->vni);
3679 }
3680
3681 static void
3682   gpe_fwd_entries_get_reply_t_net_to_host
3683   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3684 {
3685   u32 i;
3686
3687   mp->count = clib_net_to_host_u32 (mp->count);
3688   for (i = 0; i < mp->count; i++)
3689     {
3690       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3691     }
3692 }
3693
3694 static u8 *
3695 format_gpe_encap_mode (u8 * s, va_list * args)
3696 {
3697   u32 mode = va_arg (*args, u32);
3698
3699   switch (mode)
3700     {
3701     case 0:
3702       return format (s, "lisp");
3703     case 1:
3704       return format (s, "vxlan");
3705     }
3706   return 0;
3707 }
3708
3709 static void
3710   vl_api_gpe_get_encap_mode_reply_t_handler
3711   (vl_api_gpe_get_encap_mode_reply_t * mp)
3712 {
3713   vat_main_t *vam = &vat_main;
3714
3715   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3716   vam->retval = ntohl (mp->retval);
3717   vam->result_ready = 1;
3718 }
3719
3720 static void
3721   vl_api_gpe_get_encap_mode_reply_t_handler_json
3722   (vl_api_gpe_get_encap_mode_reply_t * mp)
3723 {
3724   vat_main_t *vam = &vat_main;
3725   vat_json_node_t node;
3726
3727   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3728   vec_add1 (encap_mode, 0);
3729
3730   vat_json_init_object (&node);
3731   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3732
3733   vec_free (encap_mode);
3734   vat_json_print (vam->ofp, &node);
3735   vat_json_free (&node);
3736
3737   vam->retval = ntohl (mp->retval);
3738   vam->result_ready = 1;
3739 }
3740
3741 static void
3742   vl_api_gpe_fwd_entry_path_details_t_handler
3743   (vl_api_gpe_fwd_entry_path_details_t * mp)
3744 {
3745   vat_main_t *vam = &vat_main;
3746   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3747
3748   if (mp->lcl_loc.is_ip4)
3749     format_ip_address_fcn = format_ip4_address;
3750   else
3751     format_ip_address_fcn = format_ip6_address;
3752
3753   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3754          format_ip_address_fcn, &mp->lcl_loc,
3755          format_ip_address_fcn, &mp->rmt_loc);
3756 }
3757
3758 static void
3759 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3760 {
3761   struct in6_addr ip6;
3762   struct in_addr ip4;
3763
3764   if (loc->is_ip4)
3765     {
3766       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3767       vat_json_object_add_ip4 (n, "address", ip4);
3768     }
3769   else
3770     {
3771       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3772       vat_json_object_add_ip6 (n, "address", ip6);
3773     }
3774   vat_json_object_add_uint (n, "weight", loc->weight);
3775 }
3776
3777 static void
3778   vl_api_gpe_fwd_entry_path_details_t_handler_json
3779   (vl_api_gpe_fwd_entry_path_details_t * mp)
3780 {
3781   vat_main_t *vam = &vat_main;
3782   vat_json_node_t *node = NULL;
3783   vat_json_node_t *loc_node;
3784
3785   if (VAT_JSON_ARRAY != vam->json_tree.type)
3786     {
3787       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3788       vat_json_init_array (&vam->json_tree);
3789     }
3790   node = vat_json_array_add (&vam->json_tree);
3791   vat_json_init_object (node);
3792
3793   loc_node = vat_json_object_add (node, "local_locator");
3794   vat_json_init_object (loc_node);
3795   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3796
3797   loc_node = vat_json_object_add (node, "remote_locator");
3798   vat_json_init_object (loc_node);
3799   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3800 }
3801
3802 static void
3803   vl_api_gpe_fwd_entries_get_reply_t_handler
3804   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3805 {
3806   vat_main_t *vam = &vat_main;
3807   u32 i;
3808   int retval = clib_net_to_host_u32 (mp->retval);
3809   vl_api_gpe_fwd_entry_t *e;
3810
3811   if (retval)
3812     goto end;
3813
3814   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3815
3816   for (i = 0; i < mp->count; i++)
3817     {
3818       e = &mp->entries[i];
3819       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3820              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3821              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3822     }
3823
3824 end:
3825   vam->retval = retval;
3826   vam->result_ready = 1;
3827 }
3828
3829 static void
3830   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3831   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3832 {
3833   u8 *s = 0;
3834   vat_main_t *vam = &vat_main;
3835   vat_json_node_t *e = 0, root;
3836   u32 i;
3837   int retval = clib_net_to_host_u32 (mp->retval);
3838   vl_api_gpe_fwd_entry_t *fwd;
3839
3840   if (retval)
3841     goto end;
3842
3843   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3844   vat_json_init_array (&root);
3845
3846   for (i = 0; i < mp->count; i++)
3847     {
3848       e = vat_json_array_add (&root);
3849       fwd = &mp->entries[i];
3850
3851       vat_json_init_object (e);
3852       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3853       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3854       vat_json_object_add_int (e, "vni", fwd->vni);
3855       vat_json_object_add_int (e, "action", fwd->action);
3856
3857       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3858                   fwd->leid_prefix_len);
3859       vec_add1 (s, 0);
3860       vat_json_object_add_string_copy (e, "leid", s);
3861       vec_free (s);
3862
3863       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3864                   fwd->reid_prefix_len);
3865       vec_add1 (s, 0);
3866       vat_json_object_add_string_copy (e, "reid", s);
3867       vec_free (s);
3868     }
3869
3870   vat_json_print (vam->ofp, &root);
3871   vat_json_free (&root);
3872
3873 end:
3874   vam->retval = retval;
3875   vam->result_ready = 1;
3876 }
3877
3878 static void
3879   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3880   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3881 {
3882   vat_main_t *vam = &vat_main;
3883   u32 i, n;
3884   int retval = clib_net_to_host_u32 (mp->retval);
3885   vl_api_gpe_native_fwd_rpath_t *r;
3886
3887   if (retval)
3888     goto end;
3889
3890   n = clib_net_to_host_u32 (mp->count);
3891
3892   for (i = 0; i < n; i++)
3893     {
3894       r = &mp->entries[i];
3895       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3896              clib_net_to_host_u32 (r->fib_index),
3897              clib_net_to_host_u32 (r->nh_sw_if_index),
3898              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3899     }
3900
3901 end:
3902   vam->retval = retval;
3903   vam->result_ready = 1;
3904 }
3905
3906 static void
3907   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3908   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3909 {
3910   vat_main_t *vam = &vat_main;
3911   vat_json_node_t root, *e;
3912   u32 i, n;
3913   int retval = clib_net_to_host_u32 (mp->retval);
3914   vl_api_gpe_native_fwd_rpath_t *r;
3915   u8 *s;
3916
3917   if (retval)
3918     goto end;
3919
3920   n = clib_net_to_host_u32 (mp->count);
3921   vat_json_init_array (&root);
3922
3923   for (i = 0; i < n; i++)
3924     {
3925       e = vat_json_array_add (&root);
3926       vat_json_init_object (e);
3927       r = &mp->entries[i];
3928       s =
3929         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3930                 r->nh_addr);
3931       vec_add1 (s, 0);
3932       vat_json_object_add_string_copy (e, "ip4", s);
3933       vec_free (s);
3934
3935       vat_json_object_add_uint (e, "fib_index",
3936                                 clib_net_to_host_u32 (r->fib_index));
3937       vat_json_object_add_uint (e, "nh_sw_if_index",
3938                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3939     }
3940
3941   vat_json_print (vam->ofp, &root);
3942   vat_json_free (&root);
3943
3944 end:
3945   vam->retval = retval;
3946   vam->result_ready = 1;
3947 }
3948
3949 static void
3950   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3951   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3952 {
3953   vat_main_t *vam = &vat_main;
3954   u32 i, n;
3955   int retval = clib_net_to_host_u32 (mp->retval);
3956
3957   if (retval)
3958     goto end;
3959
3960   n = clib_net_to_host_u32 (mp->count);
3961
3962   for (i = 0; i < n; i++)
3963     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3964
3965 end:
3966   vam->retval = retval;
3967   vam->result_ready = 1;
3968 }
3969
3970 static void
3971   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3972   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3973 {
3974   vat_main_t *vam = &vat_main;
3975   vat_json_node_t root;
3976   u32 i, n;
3977   int retval = clib_net_to_host_u32 (mp->retval);
3978
3979   if (retval)
3980     goto end;
3981
3982   n = clib_net_to_host_u32 (mp->count);
3983   vat_json_init_array (&root);
3984
3985   for (i = 0; i < n; i++)
3986     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3987
3988   vat_json_print (vam->ofp, &root);
3989   vat_json_free (&root);
3990
3991 end:
3992   vam->retval = retval;
3993   vam->result_ready = 1;
3994 }
3995
3996 static void
3997   vl_api_one_ndp_entries_get_reply_t_handler
3998   (vl_api_one_ndp_entries_get_reply_t * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001   u32 i, n;
4002   int retval = clib_net_to_host_u32 (mp->retval);
4003
4004   if (retval)
4005     goto end;
4006
4007   n = clib_net_to_host_u32 (mp->count);
4008
4009   for (i = 0; i < n; i++)
4010     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
4011            format_ethernet_address, mp->entries[i].mac);
4012
4013 end:
4014   vam->retval = retval;
4015   vam->result_ready = 1;
4016 }
4017
4018 static void
4019   vl_api_one_ndp_entries_get_reply_t_handler_json
4020   (vl_api_one_ndp_entries_get_reply_t * mp)
4021 {
4022   u8 *s = 0;
4023   vat_main_t *vam = &vat_main;
4024   vat_json_node_t *e = 0, root;
4025   u32 i, n;
4026   int retval = clib_net_to_host_u32 (mp->retval);
4027   vl_api_one_ndp_entry_t *arp_entry;
4028
4029   if (retval)
4030     goto end;
4031
4032   n = clib_net_to_host_u32 (mp->count);
4033   vat_json_init_array (&root);
4034
4035   for (i = 0; i < n; i++)
4036     {
4037       e = vat_json_array_add (&root);
4038       arp_entry = &mp->entries[i];
4039
4040       vat_json_init_object (e);
4041       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4042       vec_add1 (s, 0);
4043
4044       vat_json_object_add_string_copy (e, "mac", s);
4045       vec_free (s);
4046
4047       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4048       vec_add1 (s, 0);
4049       vat_json_object_add_string_copy (e, "ip6", s);
4050       vec_free (s);
4051     }
4052
4053   vat_json_print (vam->ofp, &root);
4054   vat_json_free (&root);
4055
4056 end:
4057   vam->retval = retval;
4058   vam->result_ready = 1;
4059 }
4060
4061 static void
4062   vl_api_one_l2_arp_entries_get_reply_t_handler
4063   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4064 {
4065   vat_main_t *vam = &vat_main;
4066   u32 i, n;
4067   int retval = clib_net_to_host_u32 (mp->retval);
4068
4069   if (retval)
4070     goto end;
4071
4072   n = clib_net_to_host_u32 (mp->count);
4073
4074   for (i = 0; i < n; i++)
4075     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4076            format_ethernet_address, mp->entries[i].mac);
4077
4078 end:
4079   vam->retval = retval;
4080   vam->result_ready = 1;
4081 }
4082
4083 static void
4084   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4085   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4086 {
4087   u8 *s = 0;
4088   vat_main_t *vam = &vat_main;
4089   vat_json_node_t *e = 0, root;
4090   u32 i, n;
4091   int retval = clib_net_to_host_u32 (mp->retval);
4092   vl_api_one_l2_arp_entry_t *arp_entry;
4093
4094   if (retval)
4095     goto end;
4096
4097   n = clib_net_to_host_u32 (mp->count);
4098   vat_json_init_array (&root);
4099
4100   for (i = 0; i < n; i++)
4101     {
4102       e = vat_json_array_add (&root);
4103       arp_entry = &mp->entries[i];
4104
4105       vat_json_init_object (e);
4106       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4107       vec_add1 (s, 0);
4108
4109       vat_json_object_add_string_copy (e, "mac", s);
4110       vec_free (s);
4111
4112       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4113       vec_add1 (s, 0);
4114       vat_json_object_add_string_copy (e, "ip4", s);
4115       vec_free (s);
4116     }
4117
4118   vat_json_print (vam->ofp, &root);
4119   vat_json_free (&root);
4120
4121 end:
4122   vam->retval = retval;
4123   vam->result_ready = 1;
4124 }
4125
4126 static void
4127 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4128 {
4129   vat_main_t *vam = &vat_main;
4130   u32 i, n;
4131   int retval = clib_net_to_host_u32 (mp->retval);
4132
4133   if (retval)
4134     goto end;
4135
4136   n = clib_net_to_host_u32 (mp->count);
4137
4138   for (i = 0; i < n; i++)
4139     {
4140       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4141     }
4142
4143 end:
4144   vam->retval = retval;
4145   vam->result_ready = 1;
4146 }
4147
4148 static void
4149   vl_api_one_ndp_bd_get_reply_t_handler_json
4150   (vl_api_one_ndp_bd_get_reply_t * mp)
4151 {
4152   vat_main_t *vam = &vat_main;
4153   vat_json_node_t root;
4154   u32 i, n;
4155   int retval = clib_net_to_host_u32 (mp->retval);
4156
4157   if (retval)
4158     goto end;
4159
4160   n = clib_net_to_host_u32 (mp->count);
4161   vat_json_init_array (&root);
4162
4163   for (i = 0; i < n; i++)
4164     {
4165       vat_json_array_add_uint (&root,
4166                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4167     }
4168
4169   vat_json_print (vam->ofp, &root);
4170   vat_json_free (&root);
4171
4172 end:
4173   vam->retval = retval;
4174   vam->result_ready = 1;
4175 }
4176
4177 static void
4178   vl_api_one_l2_arp_bd_get_reply_t_handler
4179   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4180 {
4181   vat_main_t *vam = &vat_main;
4182   u32 i, n;
4183   int retval = clib_net_to_host_u32 (mp->retval);
4184
4185   if (retval)
4186     goto end;
4187
4188   n = clib_net_to_host_u32 (mp->count);
4189
4190   for (i = 0; i < n; i++)
4191     {
4192       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4193     }
4194
4195 end:
4196   vam->retval = retval;
4197   vam->result_ready = 1;
4198 }
4199
4200 static void
4201   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4202   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4203 {
4204   vat_main_t *vam = &vat_main;
4205   vat_json_node_t root;
4206   u32 i, n;
4207   int retval = clib_net_to_host_u32 (mp->retval);
4208
4209   if (retval)
4210     goto end;
4211
4212   n = clib_net_to_host_u32 (mp->count);
4213   vat_json_init_array (&root);
4214
4215   for (i = 0; i < n; i++)
4216     {
4217       vat_json_array_add_uint (&root,
4218                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4219     }
4220
4221   vat_json_print (vam->ofp, &root);
4222   vat_json_free (&root);
4223
4224 end:
4225   vam->retval = retval;
4226   vam->result_ready = 1;
4227 }
4228
4229 static void
4230   vl_api_one_adjacencies_get_reply_t_handler
4231   (vl_api_one_adjacencies_get_reply_t * mp)
4232 {
4233   vat_main_t *vam = &vat_main;
4234   u32 i, n;
4235   int retval = clib_net_to_host_u32 (mp->retval);
4236   vl_api_one_adjacency_t *a;
4237
4238   if (retval)
4239     goto end;
4240
4241   n = clib_net_to_host_u32 (mp->count);
4242
4243   for (i = 0; i < n; i++)
4244     {
4245       a = &mp->adjacencies[i];
4246       print (vam->ofp, "%U %40U",
4247              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4248              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4249     }
4250
4251 end:
4252   vam->retval = retval;
4253   vam->result_ready = 1;
4254 }
4255
4256 static void
4257   vl_api_one_adjacencies_get_reply_t_handler_json
4258   (vl_api_one_adjacencies_get_reply_t * mp)
4259 {
4260   u8 *s = 0;
4261   vat_main_t *vam = &vat_main;
4262   vat_json_node_t *e = 0, root;
4263   u32 i, n;
4264   int retval = clib_net_to_host_u32 (mp->retval);
4265   vl_api_one_adjacency_t *a;
4266
4267   if (retval)
4268     goto end;
4269
4270   n = clib_net_to_host_u32 (mp->count);
4271   vat_json_init_array (&root);
4272
4273   for (i = 0; i < n; i++)
4274     {
4275       e = vat_json_array_add (&root);
4276       a = &mp->adjacencies[i];
4277
4278       vat_json_init_object (e);
4279       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4280                   a->leid_prefix_len);
4281       vec_add1 (s, 0);
4282       vat_json_object_add_string_copy (e, "leid", s);
4283       vec_free (s);
4284
4285       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4286                   a->reid_prefix_len);
4287       vec_add1 (s, 0);
4288       vat_json_object_add_string_copy (e, "reid", s);
4289       vec_free (s);
4290     }
4291
4292   vat_json_print (vam->ofp, &root);
4293   vat_json_free (&root);
4294
4295 end:
4296   vam->retval = retval;
4297   vam->result_ready = 1;
4298 }
4299
4300 static void
4301 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4302 {
4303   vat_main_t *vam = &vat_main;
4304
4305   print (vam->ofp, "%=20U",
4306          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4307          mp->ip_address);
4308 }
4309
4310 static void
4311   vl_api_one_map_server_details_t_handler_json
4312   (vl_api_one_map_server_details_t * mp)
4313 {
4314   vat_main_t *vam = &vat_main;
4315   vat_json_node_t *node = NULL;
4316   struct in6_addr ip6;
4317   struct in_addr ip4;
4318
4319   if (VAT_JSON_ARRAY != vam->json_tree.type)
4320     {
4321       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4322       vat_json_init_array (&vam->json_tree);
4323     }
4324   node = vat_json_array_add (&vam->json_tree);
4325
4326   vat_json_init_object (node);
4327   if (mp->is_ipv6)
4328     {
4329       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4330       vat_json_object_add_ip6 (node, "map-server", ip6);
4331     }
4332   else
4333     {
4334       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4335       vat_json_object_add_ip4 (node, "map-server", ip4);
4336     }
4337 }
4338
4339 static void
4340 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4341                                            * mp)
4342 {
4343   vat_main_t *vam = &vat_main;
4344
4345   print (vam->ofp, "%=20U",
4346          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4347          mp->ip_address);
4348 }
4349
4350 static void
4351   vl_api_one_map_resolver_details_t_handler_json
4352   (vl_api_one_map_resolver_details_t * mp)
4353 {
4354   vat_main_t *vam = &vat_main;
4355   vat_json_node_t *node = NULL;
4356   struct in6_addr ip6;
4357   struct in_addr ip4;
4358
4359   if (VAT_JSON_ARRAY != vam->json_tree.type)
4360     {
4361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4362       vat_json_init_array (&vam->json_tree);
4363     }
4364   node = vat_json_array_add (&vam->json_tree);
4365
4366   vat_json_init_object (node);
4367   if (mp->is_ipv6)
4368     {
4369       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4370       vat_json_object_add_ip6 (node, "map resolver", ip6);
4371     }
4372   else
4373     {
4374       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4375       vat_json_object_add_ip4 (node, "map resolver", ip4);
4376     }
4377 }
4378
4379 static void
4380 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4381 {
4382   vat_main_t *vam = &vat_main;
4383   i32 retval = ntohl (mp->retval);
4384
4385   if (0 <= retval)
4386     {
4387       print (vam->ofp, "feature: %s\ngpe: %s",
4388              mp->feature_status ? "enabled" : "disabled",
4389              mp->gpe_status ? "enabled" : "disabled");
4390     }
4391
4392   vam->retval = retval;
4393   vam->result_ready = 1;
4394 }
4395
4396 static void
4397   vl_api_show_one_status_reply_t_handler_json
4398   (vl_api_show_one_status_reply_t * mp)
4399 {
4400   vat_main_t *vam = &vat_main;
4401   vat_json_node_t node;
4402   u8 *gpe_status = NULL;
4403   u8 *feature_status = NULL;
4404
4405   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4406   feature_status = format (0, "%s",
4407                            mp->feature_status ? "enabled" : "disabled");
4408   vec_add1 (gpe_status, 0);
4409   vec_add1 (feature_status, 0);
4410
4411   vat_json_init_object (&node);
4412   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4413   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4414
4415   vec_free (gpe_status);
4416   vec_free (feature_status);
4417
4418   vat_json_print (vam->ofp, &node);
4419   vat_json_free (&node);
4420
4421   vam->retval = ntohl (mp->retval);
4422   vam->result_ready = 1;
4423 }
4424
4425 static void
4426   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4427   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4428 {
4429   vat_main_t *vam = &vat_main;
4430   i32 retval = ntohl (mp->retval);
4431
4432   if (retval >= 0)
4433     {
4434       print (vam->ofp, "%=20s", mp->locator_set_name);
4435     }
4436
4437   vam->retval = retval;
4438   vam->result_ready = 1;
4439 }
4440
4441 static void
4442   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4443   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4444 {
4445   vat_main_t *vam = &vat_main;
4446   vat_json_node_t *node = NULL;
4447
4448   if (VAT_JSON_ARRAY != vam->json_tree.type)
4449     {
4450       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4451       vat_json_init_array (&vam->json_tree);
4452     }
4453   node = vat_json_array_add (&vam->json_tree);
4454
4455   vat_json_init_object (node);
4456   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4457
4458   vat_json_print (vam->ofp, node);
4459   vat_json_free (node);
4460
4461   vam->retval = ntohl (mp->retval);
4462   vam->result_ready = 1;
4463 }
4464
4465 static u8 *
4466 format_lisp_map_request_mode (u8 * s, va_list * args)
4467 {
4468   u32 mode = va_arg (*args, u32);
4469
4470   switch (mode)
4471     {
4472     case 0:
4473       return format (0, "dst-only");
4474     case 1:
4475       return format (0, "src-dst");
4476     }
4477   return 0;
4478 }
4479
4480 static void
4481   vl_api_show_one_map_request_mode_reply_t_handler
4482   (vl_api_show_one_map_request_mode_reply_t * mp)
4483 {
4484   vat_main_t *vam = &vat_main;
4485   i32 retval = ntohl (mp->retval);
4486
4487   if (0 <= retval)
4488     {
4489       u32 mode = mp->mode;
4490       print (vam->ofp, "map_request_mode: %U",
4491              format_lisp_map_request_mode, mode);
4492     }
4493
4494   vam->retval = retval;
4495   vam->result_ready = 1;
4496 }
4497
4498 static void
4499   vl_api_show_one_map_request_mode_reply_t_handler_json
4500   (vl_api_show_one_map_request_mode_reply_t * mp)
4501 {
4502   vat_main_t *vam = &vat_main;
4503   vat_json_node_t node;
4504   u8 *s = 0;
4505   u32 mode;
4506
4507   mode = mp->mode;
4508   s = format (0, "%U", format_lisp_map_request_mode, mode);
4509   vec_add1 (s, 0);
4510
4511   vat_json_init_object (&node);
4512   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4513   vat_json_print (vam->ofp, &node);
4514   vat_json_free (&node);
4515
4516   vec_free (s);
4517   vam->retval = ntohl (mp->retval);
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522   vl_api_one_show_xtr_mode_reply_t_handler
4523   (vl_api_one_show_xtr_mode_reply_t * mp)
4524 {
4525   vat_main_t *vam = &vat_main;
4526   i32 retval = ntohl (mp->retval);
4527
4528   if (0 <= retval)
4529     {
4530       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4531     }
4532
4533   vam->retval = retval;
4534   vam->result_ready = 1;
4535 }
4536
4537 static void
4538   vl_api_one_show_xtr_mode_reply_t_handler_json
4539   (vl_api_one_show_xtr_mode_reply_t * mp)
4540 {
4541   vat_main_t *vam = &vat_main;
4542   vat_json_node_t node;
4543   u8 *status = 0;
4544
4545   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4546   vec_add1 (status, 0);
4547
4548   vat_json_init_object (&node);
4549   vat_json_object_add_string_copy (&node, "status", status);
4550
4551   vec_free (status);
4552
4553   vat_json_print (vam->ofp, &node);
4554   vat_json_free (&node);
4555
4556   vam->retval = ntohl (mp->retval);
4557   vam->result_ready = 1;
4558 }
4559
4560 static void
4561   vl_api_one_show_pitr_mode_reply_t_handler
4562   (vl_api_one_show_pitr_mode_reply_t * mp)
4563 {
4564   vat_main_t *vam = &vat_main;
4565   i32 retval = ntohl (mp->retval);
4566
4567   if (0 <= retval)
4568     {
4569       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4570     }
4571
4572   vam->retval = retval;
4573   vam->result_ready = 1;
4574 }
4575
4576 static void
4577   vl_api_one_show_pitr_mode_reply_t_handler_json
4578   (vl_api_one_show_pitr_mode_reply_t * mp)
4579 {
4580   vat_main_t *vam = &vat_main;
4581   vat_json_node_t node;
4582   u8 *status = 0;
4583
4584   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4585   vec_add1 (status, 0);
4586
4587   vat_json_init_object (&node);
4588   vat_json_object_add_string_copy (&node, "status", status);
4589
4590   vec_free (status);
4591
4592   vat_json_print (vam->ofp, &node);
4593   vat_json_free (&node);
4594
4595   vam->retval = ntohl (mp->retval);
4596   vam->result_ready = 1;
4597 }
4598
4599 static void
4600   vl_api_one_show_petr_mode_reply_t_handler
4601   (vl_api_one_show_petr_mode_reply_t * mp)
4602 {
4603   vat_main_t *vam = &vat_main;
4604   i32 retval = ntohl (mp->retval);
4605
4606   if (0 <= retval)
4607     {
4608       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4609     }
4610
4611   vam->retval = retval;
4612   vam->result_ready = 1;
4613 }
4614
4615 static void
4616   vl_api_one_show_petr_mode_reply_t_handler_json
4617   (vl_api_one_show_petr_mode_reply_t * mp)
4618 {
4619   vat_main_t *vam = &vat_main;
4620   vat_json_node_t node;
4621   u8 *status = 0;
4622
4623   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4624   vec_add1 (status, 0);
4625
4626   vat_json_init_object (&node);
4627   vat_json_object_add_string_copy (&node, "status", status);
4628
4629   vec_free (status);
4630
4631   vat_json_print (vam->ofp, &node);
4632   vat_json_free (&node);
4633
4634   vam->retval = ntohl (mp->retval);
4635   vam->result_ready = 1;
4636 }
4637
4638 static void
4639   vl_api_show_one_use_petr_reply_t_handler
4640   (vl_api_show_one_use_petr_reply_t * mp)
4641 {
4642   vat_main_t *vam = &vat_main;
4643   i32 retval = ntohl (mp->retval);
4644
4645   if (0 <= retval)
4646     {
4647       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4648       if (mp->status)
4649         {
4650           print (vam->ofp, "Proxy-ETR address; %U",
4651                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4652                  mp->address);
4653         }
4654     }
4655
4656   vam->retval = retval;
4657   vam->result_ready = 1;
4658 }
4659
4660 static void
4661   vl_api_show_one_use_petr_reply_t_handler_json
4662   (vl_api_show_one_use_petr_reply_t * mp)
4663 {
4664   vat_main_t *vam = &vat_main;
4665   vat_json_node_t node;
4666   u8 *status = 0;
4667   struct in_addr ip4;
4668   struct in6_addr ip6;
4669
4670   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4671   vec_add1 (status, 0);
4672
4673   vat_json_init_object (&node);
4674   vat_json_object_add_string_copy (&node, "status", status);
4675   if (mp->status)
4676     {
4677       if (mp->is_ip4)
4678         {
4679           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4680           vat_json_object_add_ip6 (&node, "address", ip6);
4681         }
4682       else
4683         {
4684           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4685           vat_json_object_add_ip4 (&node, "address", ip4);
4686         }
4687     }
4688
4689   vec_free (status);
4690
4691   vat_json_print (vam->ofp, &node);
4692   vat_json_free (&node);
4693
4694   vam->retval = ntohl (mp->retval);
4695   vam->result_ready = 1;
4696 }
4697
4698 static void
4699   vl_api_show_one_nsh_mapping_reply_t_handler
4700   (vl_api_show_one_nsh_mapping_reply_t * mp)
4701 {
4702   vat_main_t *vam = &vat_main;
4703   i32 retval = ntohl (mp->retval);
4704
4705   if (0 <= retval)
4706     {
4707       print (vam->ofp, "%-20s%-16s",
4708              mp->is_set ? "set" : "not-set",
4709              mp->is_set ? (char *) mp->locator_set_name : "");
4710     }
4711
4712   vam->retval = retval;
4713   vam->result_ready = 1;
4714 }
4715
4716 static void
4717   vl_api_show_one_nsh_mapping_reply_t_handler_json
4718   (vl_api_show_one_nsh_mapping_reply_t * mp)
4719 {
4720   vat_main_t *vam = &vat_main;
4721   vat_json_node_t node;
4722   u8 *status = 0;
4723
4724   status = format (0, "%s", mp->is_set ? "yes" : "no");
4725   vec_add1 (status, 0);
4726
4727   vat_json_init_object (&node);
4728   vat_json_object_add_string_copy (&node, "is_set", status);
4729   if (mp->is_set)
4730     {
4731       vat_json_object_add_string_copy (&node, "locator_set",
4732                                        mp->locator_set_name);
4733     }
4734
4735   vec_free (status);
4736
4737   vat_json_print (vam->ofp, &node);
4738   vat_json_free (&node);
4739
4740   vam->retval = ntohl (mp->retval);
4741   vam->result_ready = 1;
4742 }
4743
4744 static void
4745   vl_api_show_one_map_register_ttl_reply_t_handler
4746   (vl_api_show_one_map_register_ttl_reply_t * mp)
4747 {
4748   vat_main_t *vam = &vat_main;
4749   i32 retval = ntohl (mp->retval);
4750
4751   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4752
4753   if (0 <= retval)
4754     {
4755       print (vam->ofp, "ttl: %u", mp->ttl);
4756     }
4757
4758   vam->retval = retval;
4759   vam->result_ready = 1;
4760 }
4761
4762 static void
4763   vl_api_show_one_map_register_ttl_reply_t_handler_json
4764   (vl_api_show_one_map_register_ttl_reply_t * mp)
4765 {
4766   vat_main_t *vam = &vat_main;
4767   vat_json_node_t node;
4768
4769   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4770   vat_json_init_object (&node);
4771   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4772
4773   vat_json_print (vam->ofp, &node);
4774   vat_json_free (&node);
4775
4776   vam->retval = ntohl (mp->retval);
4777   vam->result_ready = 1;
4778 }
4779
4780 static void
4781 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4782 {
4783   vat_main_t *vam = &vat_main;
4784   i32 retval = ntohl (mp->retval);
4785
4786   if (0 <= retval)
4787     {
4788       print (vam->ofp, "%-20s%-16s",
4789              mp->status ? "enabled" : "disabled",
4790              mp->status ? (char *) mp->locator_set_name : "");
4791     }
4792
4793   vam->retval = retval;
4794   vam->result_ready = 1;
4795 }
4796
4797 static void
4798 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4799 {
4800   vat_main_t *vam = &vat_main;
4801   vat_json_node_t node;
4802   u8 *status = 0;
4803
4804   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4805   vec_add1 (status, 0);
4806
4807   vat_json_init_object (&node);
4808   vat_json_object_add_string_copy (&node, "status", status);
4809   if (mp->status)
4810     {
4811       vat_json_object_add_string_copy (&node, "locator_set",
4812                                        mp->locator_set_name);
4813     }
4814
4815   vec_free (status);
4816
4817   vat_json_print (vam->ofp, &node);
4818   vat_json_free (&node);
4819
4820   vam->retval = ntohl (mp->retval);
4821   vam->result_ready = 1;
4822 }
4823
4824 static u8 *
4825 format_policer_type (u8 * s, va_list * va)
4826 {
4827   u32 i = va_arg (*va, u32);
4828
4829   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4830     s = format (s, "1r2c");
4831   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4832     s = format (s, "1r3c");
4833   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4834     s = format (s, "2r3c-2698");
4835   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4836     s = format (s, "2r3c-4115");
4837   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4838     s = format (s, "2r3c-mef5cf1");
4839   else
4840     s = format (s, "ILLEGAL");
4841   return s;
4842 }
4843
4844 static u8 *
4845 format_policer_rate_type (u8 * s, va_list * va)
4846 {
4847   u32 i = va_arg (*va, u32);
4848
4849   if (i == SSE2_QOS_RATE_KBPS)
4850     s = format (s, "kbps");
4851   else if (i == SSE2_QOS_RATE_PPS)
4852     s = format (s, "pps");
4853   else
4854     s = format (s, "ILLEGAL");
4855   return s;
4856 }
4857
4858 static u8 *
4859 format_policer_round_type (u8 * s, va_list * va)
4860 {
4861   u32 i = va_arg (*va, u32);
4862
4863   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4864     s = format (s, "closest");
4865   else if (i == SSE2_QOS_ROUND_TO_UP)
4866     s = format (s, "up");
4867   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4868     s = format (s, "down");
4869   else
4870     s = format (s, "ILLEGAL");
4871   return s;
4872 }
4873
4874 static u8 *
4875 format_policer_action_type (u8 * s, va_list * va)
4876 {
4877   u32 i = va_arg (*va, u32);
4878
4879   if (i == SSE2_QOS_ACTION_DROP)
4880     s = format (s, "drop");
4881   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4882     s = format (s, "transmit");
4883   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4884     s = format (s, "mark-and-transmit");
4885   else
4886     s = format (s, "ILLEGAL");
4887   return s;
4888 }
4889
4890 static u8 *
4891 format_dscp (u8 * s, va_list * va)
4892 {
4893   u32 i = va_arg (*va, u32);
4894   char *t = 0;
4895
4896   switch (i)
4897     {
4898 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4899       foreach_vnet_dscp
4900 #undef _
4901     default:
4902       return format (s, "ILLEGAL");
4903     }
4904   s = format (s, "%s", t);
4905   return s;
4906 }
4907
4908 static void
4909 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4910 {
4911   vat_main_t *vam = &vat_main;
4912   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4913
4914   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4915     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4916   else
4917     conform_dscp_str = format (0, "");
4918
4919   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4920     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4921   else
4922     exceed_dscp_str = format (0, "");
4923
4924   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4925     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4926   else
4927     violate_dscp_str = format (0, "");
4928
4929   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4930          "rate type %U, round type %U, %s rate, %s color-aware, "
4931          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4932          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4933          "conform action %U%s, exceed action %U%s, violate action %U%s",
4934          mp->name,
4935          format_policer_type, mp->type,
4936          ntohl (mp->cir),
4937          ntohl (mp->eir),
4938          clib_net_to_host_u64 (mp->cb),
4939          clib_net_to_host_u64 (mp->eb),
4940          format_policer_rate_type, mp->rate_type,
4941          format_policer_round_type, mp->round_type,
4942          mp->single_rate ? "single" : "dual",
4943          mp->color_aware ? "is" : "not",
4944          ntohl (mp->cir_tokens_per_period),
4945          ntohl (mp->pir_tokens_per_period),
4946          ntohl (mp->scale),
4947          ntohl (mp->current_limit),
4948          ntohl (mp->current_bucket),
4949          ntohl (mp->extended_limit),
4950          ntohl (mp->extended_bucket),
4951          clib_net_to_host_u64 (mp->last_update_time),
4952          format_policer_action_type, mp->conform_action_type,
4953          conform_dscp_str,
4954          format_policer_action_type, mp->exceed_action_type,
4955          exceed_dscp_str,
4956          format_policer_action_type, mp->violate_action_type,
4957          violate_dscp_str);
4958
4959   vec_free (conform_dscp_str);
4960   vec_free (exceed_dscp_str);
4961   vec_free (violate_dscp_str);
4962 }
4963
4964 static void vl_api_policer_details_t_handler_json
4965   (vl_api_policer_details_t * mp)
4966 {
4967   vat_main_t *vam = &vat_main;
4968   vat_json_node_t *node;
4969   u8 *rate_type_str, *round_type_str, *type_str;
4970   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4971
4972   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4973   round_type_str =
4974     format (0, "%U", format_policer_round_type, mp->round_type);
4975   type_str = format (0, "%U", format_policer_type, mp->type);
4976   conform_action_str = format (0, "%U", format_policer_action_type,
4977                                mp->conform_action_type);
4978   exceed_action_str = format (0, "%U", format_policer_action_type,
4979                               mp->exceed_action_type);
4980   violate_action_str = format (0, "%U", format_policer_action_type,
4981                                mp->violate_action_type);
4982
4983   if (VAT_JSON_ARRAY != vam->json_tree.type)
4984     {
4985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4986       vat_json_init_array (&vam->json_tree);
4987     }
4988   node = vat_json_array_add (&vam->json_tree);
4989
4990   vat_json_init_object (node);
4991   vat_json_object_add_string_copy (node, "name", mp->name);
4992   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4993   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4994   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4995   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4996   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4997   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4998   vat_json_object_add_string_copy (node, "type", type_str);
4999   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
5000   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
5001   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
5002   vat_json_object_add_uint (node, "cir_tokens_per_period",
5003                             ntohl (mp->cir_tokens_per_period));
5004   vat_json_object_add_uint (node, "eir_tokens_per_period",
5005                             ntohl (mp->pir_tokens_per_period));
5006   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
5007   vat_json_object_add_uint (node, "current_bucket",
5008                             ntohl (mp->current_bucket));
5009   vat_json_object_add_uint (node, "extended_limit",
5010                             ntohl (mp->extended_limit));
5011   vat_json_object_add_uint (node, "extended_bucket",
5012                             ntohl (mp->extended_bucket));
5013   vat_json_object_add_uint (node, "last_update_time",
5014                             ntohl (mp->last_update_time));
5015   vat_json_object_add_string_copy (node, "conform_action",
5016                                    conform_action_str);
5017   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5018     {
5019       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5020       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5021       vec_free (dscp_str);
5022     }
5023   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5024   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5025     {
5026       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5027       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5028       vec_free (dscp_str);
5029     }
5030   vat_json_object_add_string_copy (node, "violate_action",
5031                                    violate_action_str);
5032   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5033     {
5034       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5035       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5036       vec_free (dscp_str);
5037     }
5038
5039   vec_free (rate_type_str);
5040   vec_free (round_type_str);
5041   vec_free (type_str);
5042   vec_free (conform_action_str);
5043   vec_free (exceed_action_str);
5044   vec_free (violate_action_str);
5045 }
5046
5047 static void
5048 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5049                                            mp)
5050 {
5051   vat_main_t *vam = &vat_main;
5052   int i, count = ntohl (mp->count);
5053
5054   if (count > 0)
5055     print (vam->ofp, "classify table ids (%d) : ", count);
5056   for (i = 0; i < count; i++)
5057     {
5058       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5059       print (vam->ofp, (i < count - 1) ? "," : "");
5060     }
5061   vam->retval = ntohl (mp->retval);
5062   vam->result_ready = 1;
5063 }
5064
5065 static void
5066   vl_api_classify_table_ids_reply_t_handler_json
5067   (vl_api_classify_table_ids_reply_t * mp)
5068 {
5069   vat_main_t *vam = &vat_main;
5070   int i, count = ntohl (mp->count);
5071
5072   if (count > 0)
5073     {
5074       vat_json_node_t node;
5075
5076       vat_json_init_object (&node);
5077       for (i = 0; i < count; i++)
5078         {
5079           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5080         }
5081       vat_json_print (vam->ofp, &node);
5082       vat_json_free (&node);
5083     }
5084   vam->retval = ntohl (mp->retval);
5085   vam->result_ready = 1;
5086 }
5087
5088 static void
5089   vl_api_classify_table_by_interface_reply_t_handler
5090   (vl_api_classify_table_by_interface_reply_t * mp)
5091 {
5092   vat_main_t *vam = &vat_main;
5093   u32 table_id;
5094
5095   table_id = ntohl (mp->l2_table_id);
5096   if (table_id != ~0)
5097     print (vam->ofp, "l2 table id : %d", table_id);
5098   else
5099     print (vam->ofp, "l2 table id : No input ACL tables configured");
5100   table_id = ntohl (mp->ip4_table_id);
5101   if (table_id != ~0)
5102     print (vam->ofp, "ip4 table id : %d", table_id);
5103   else
5104     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5105   table_id = ntohl (mp->ip6_table_id);
5106   if (table_id != ~0)
5107     print (vam->ofp, "ip6 table id : %d", table_id);
5108   else
5109     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5110   vam->retval = ntohl (mp->retval);
5111   vam->result_ready = 1;
5112 }
5113
5114 static void
5115   vl_api_classify_table_by_interface_reply_t_handler_json
5116   (vl_api_classify_table_by_interface_reply_t * mp)
5117 {
5118   vat_main_t *vam = &vat_main;
5119   vat_json_node_t node;
5120
5121   vat_json_init_object (&node);
5122
5123   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5124   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5125   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5126
5127   vat_json_print (vam->ofp, &node);
5128   vat_json_free (&node);
5129
5130   vam->retval = ntohl (mp->retval);
5131   vam->result_ready = 1;
5132 }
5133
5134 static void vl_api_policer_add_del_reply_t_handler
5135   (vl_api_policer_add_del_reply_t * mp)
5136 {
5137   vat_main_t *vam = &vat_main;
5138   i32 retval = ntohl (mp->retval);
5139   if (vam->async_mode)
5140     {
5141       vam->async_errors += (retval < 0);
5142     }
5143   else
5144     {
5145       vam->retval = retval;
5146       vam->result_ready = 1;
5147       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5148         /*
5149          * Note: this is just barely thread-safe, depends on
5150          * the main thread spinning waiting for an answer...
5151          */
5152         errmsg ("policer index %d", ntohl (mp->policer_index));
5153     }
5154 }
5155
5156 static void vl_api_policer_add_del_reply_t_handler_json
5157   (vl_api_policer_add_del_reply_t * mp)
5158 {
5159   vat_main_t *vam = &vat_main;
5160   vat_json_node_t node;
5161
5162   vat_json_init_object (&node);
5163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5164   vat_json_object_add_uint (&node, "policer_index",
5165                             ntohl (mp->policer_index));
5166
5167   vat_json_print (vam->ofp, &node);
5168   vat_json_free (&node);
5169
5170   vam->retval = ntohl (mp->retval);
5171   vam->result_ready = 1;
5172 }
5173
5174 /* Format hex dump. */
5175 u8 *
5176 format_hex_bytes (u8 * s, va_list * va)
5177 {
5178   u8 *bytes = va_arg (*va, u8 *);
5179   int n_bytes = va_arg (*va, int);
5180   uword i;
5181
5182   /* Print short or long form depending on byte count. */
5183   uword short_form = n_bytes <= 32;
5184   u32 indent = format_get_indent (s);
5185
5186   if (n_bytes == 0)
5187     return s;
5188
5189   for (i = 0; i < n_bytes; i++)
5190     {
5191       if (!short_form && (i % 32) == 0)
5192         s = format (s, "%08x: ", i);
5193       s = format (s, "%02x", bytes[i]);
5194       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5195         s = format (s, "\n%U", format_white_space, indent);
5196     }
5197
5198   return s;
5199 }
5200
5201 static void
5202 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5203                                             * mp)
5204 {
5205   vat_main_t *vam = &vat_main;
5206   i32 retval = ntohl (mp->retval);
5207   if (retval == 0)
5208     {
5209       print (vam->ofp, "classify table info :");
5210       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5211              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5212              ntohl (mp->miss_next_index));
5213       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5214              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5215              ntohl (mp->match_n_vectors));
5216       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5217              ntohl (mp->mask_length));
5218     }
5219   vam->retval = retval;
5220   vam->result_ready = 1;
5221 }
5222
5223 static void
5224   vl_api_classify_table_info_reply_t_handler_json
5225   (vl_api_classify_table_info_reply_t * mp)
5226 {
5227   vat_main_t *vam = &vat_main;
5228   vat_json_node_t node;
5229
5230   i32 retval = ntohl (mp->retval);
5231   if (retval == 0)
5232     {
5233       vat_json_init_object (&node);
5234
5235       vat_json_object_add_int (&node, "sessions",
5236                                ntohl (mp->active_sessions));
5237       vat_json_object_add_int (&node, "nexttbl",
5238                                ntohl (mp->next_table_index));
5239       vat_json_object_add_int (&node, "nextnode",
5240                                ntohl (mp->miss_next_index));
5241       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5242       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5243       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5244       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5245                       ntohl (mp->mask_length), 0);
5246       vat_json_object_add_string_copy (&node, "mask", s);
5247
5248       vat_json_print (vam->ofp, &node);
5249       vat_json_free (&node);
5250     }
5251   vam->retval = ntohl (mp->retval);
5252   vam->result_ready = 1;
5253 }
5254
5255 static void
5256 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5257                                            mp)
5258 {
5259   vat_main_t *vam = &vat_main;
5260
5261   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5262          ntohl (mp->hit_next_index), ntohl (mp->advance),
5263          ntohl (mp->opaque_index));
5264   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5265          ntohl (mp->match_length));
5266 }
5267
5268 static void
5269   vl_api_classify_session_details_t_handler_json
5270   (vl_api_classify_session_details_t * mp)
5271 {
5272   vat_main_t *vam = &vat_main;
5273   vat_json_node_t *node = NULL;
5274
5275   if (VAT_JSON_ARRAY != vam->json_tree.type)
5276     {
5277       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5278       vat_json_init_array (&vam->json_tree);
5279     }
5280   node = vat_json_array_add (&vam->json_tree);
5281
5282   vat_json_init_object (node);
5283   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5284   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5285   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5286   u8 *s =
5287     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5288             0);
5289   vat_json_object_add_string_copy (node, "match", s);
5290 }
5291
5292 static void vl_api_pg_create_interface_reply_t_handler
5293   (vl_api_pg_create_interface_reply_t * mp)
5294 {
5295   vat_main_t *vam = &vat_main;
5296
5297   vam->retval = ntohl (mp->retval);
5298   vam->result_ready = 1;
5299 }
5300
5301 static void vl_api_pg_create_interface_reply_t_handler_json
5302   (vl_api_pg_create_interface_reply_t * mp)
5303 {
5304   vat_main_t *vam = &vat_main;
5305   vat_json_node_t node;
5306
5307   i32 retval = ntohl (mp->retval);
5308   if (retval == 0)
5309     {
5310       vat_json_init_object (&node);
5311
5312       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5313
5314       vat_json_print (vam->ofp, &node);
5315       vat_json_free (&node);
5316     }
5317   vam->retval = ntohl (mp->retval);
5318   vam->result_ready = 1;
5319 }
5320
5321 static void vl_api_policer_classify_details_t_handler
5322   (vl_api_policer_classify_details_t * mp)
5323 {
5324   vat_main_t *vam = &vat_main;
5325
5326   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5327          ntohl (mp->table_index));
5328 }
5329
5330 static void vl_api_policer_classify_details_t_handler_json
5331   (vl_api_policer_classify_details_t * mp)
5332 {
5333   vat_main_t *vam = &vat_main;
5334   vat_json_node_t *node;
5335
5336   if (VAT_JSON_ARRAY != vam->json_tree.type)
5337     {
5338       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5339       vat_json_init_array (&vam->json_tree);
5340     }
5341   node = vat_json_array_add (&vam->json_tree);
5342
5343   vat_json_init_object (node);
5344   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5345   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5346 }
5347
5348 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5349   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5350 {
5351   vat_main_t *vam = &vat_main;
5352   i32 retval = ntohl (mp->retval);
5353   if (vam->async_mode)
5354     {
5355       vam->async_errors += (retval < 0);
5356     }
5357   else
5358     {
5359       vam->retval = retval;
5360       vam->sw_if_index = ntohl (mp->sw_if_index);
5361       vam->result_ready = 1;
5362     }
5363   vam->regenerate_interface_table = 1;
5364 }
5365
5366 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5367   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5368 {
5369   vat_main_t *vam = &vat_main;
5370   vat_json_node_t node;
5371
5372   vat_json_init_object (&node);
5373   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5374   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5375
5376   vat_json_print (vam->ofp, &node);
5377   vat_json_free (&node);
5378
5379   vam->retval = ntohl (mp->retval);
5380   vam->result_ready = 1;
5381 }
5382
5383 static void vl_api_flow_classify_details_t_handler
5384   (vl_api_flow_classify_details_t * mp)
5385 {
5386   vat_main_t *vam = &vat_main;
5387
5388   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5389          ntohl (mp->table_index));
5390 }
5391
5392 static void vl_api_flow_classify_details_t_handler_json
5393   (vl_api_flow_classify_details_t * mp)
5394 {
5395   vat_main_t *vam = &vat_main;
5396   vat_json_node_t *node;
5397
5398   if (VAT_JSON_ARRAY != vam->json_tree.type)
5399     {
5400       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5401       vat_json_init_array (&vam->json_tree);
5402     }
5403   node = vat_json_array_add (&vam->json_tree);
5404
5405   vat_json_init_object (node);
5406   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5407   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5408 }
5409
5410 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5411 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5412 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5413 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5414 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5415 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5416 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5417 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5418 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5419 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5420 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5421 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5422 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5423 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5424 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5425 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5426 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5427 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5428 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5429 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5430 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5431 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5432
5433 /*
5434  * Generate boilerplate reply handlers, which
5435  * dig the return value out of the xxx_reply_t API message,
5436  * stick it into vam->retval, and set vam->result_ready
5437  *
5438  * Could also do this by pointing N message decode slots at
5439  * a single function, but that could break in subtle ways.
5440  */
5441
5442 #define foreach_standard_reply_retval_handler           \
5443 _(sw_interface_set_flags_reply)                         \
5444 _(sw_interface_add_del_address_reply)                   \
5445 _(sw_interface_set_rx_mode_reply)                       \
5446 _(sw_interface_set_table_reply)                         \
5447 _(sw_interface_set_mpls_enable_reply)                   \
5448 _(sw_interface_set_vpath_reply)                         \
5449 _(sw_interface_set_vxlan_bypass_reply)                  \
5450 _(sw_interface_set_geneve_bypass_reply)                 \
5451 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5452 _(sw_interface_set_l2_bridge_reply)                     \
5453 _(bridge_domain_add_del_reply)                          \
5454 _(sw_interface_set_l2_xconnect_reply)                   \
5455 _(l2fib_add_del_reply)                                  \
5456 _(l2fib_flush_int_reply)                                \
5457 _(l2fib_flush_bd_reply)                                 \
5458 _(ip_add_del_route_reply)                               \
5459 _(ip_table_add_del_reply)                               \
5460 _(ip_mroute_add_del_reply)                              \
5461 _(mpls_route_add_del_reply)                             \
5462 _(mpls_table_add_del_reply)                             \
5463 _(mpls_ip_bind_unbind_reply)                            \
5464 _(bier_route_add_del_reply)                             \
5465 _(bier_table_add_del_reply)                             \
5466 _(proxy_arp_add_del_reply)                              \
5467 _(proxy_arp_intfc_enable_disable_reply)                 \
5468 _(sw_interface_set_unnumbered_reply)                    \
5469 _(ip_neighbor_add_del_reply)                            \
5470 _(oam_add_del_reply)                                    \
5471 _(reset_fib_reply)                                      \
5472 _(dhcp_proxy_config_reply)                              \
5473 _(dhcp_proxy_set_vss_reply)                             \
5474 _(dhcp_client_config_reply)                             \
5475 _(set_ip_flow_hash_reply)                               \
5476 _(sw_interface_ip6_enable_disable_reply)                \
5477 _(sw_interface_ip6_set_link_local_address_reply)        \
5478 _(ip6nd_proxy_add_del_reply)                            \
5479 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5480 _(sw_interface_ip6nd_ra_config_reply)                   \
5481 _(set_arp_neighbor_limit_reply)                         \
5482 _(l2_patch_add_del_reply)                               \
5483 _(sr_policy_add_reply)                                  \
5484 _(sr_policy_mod_reply)                                  \
5485 _(sr_policy_del_reply)                                  \
5486 _(sr_localsid_add_del_reply)                            \
5487 _(sr_steering_add_del_reply)                            \
5488 _(classify_add_del_session_reply)                       \
5489 _(classify_set_interface_ip_table_reply)                \
5490 _(classify_set_interface_l2_tables_reply)               \
5491 _(l2tpv3_set_tunnel_cookies_reply)                      \
5492 _(l2tpv3_interface_enable_disable_reply)                \
5493 _(l2tpv3_set_lookup_key_reply)                          \
5494 _(l2_fib_clear_table_reply)                             \
5495 _(l2_interface_efp_filter_reply)                        \
5496 _(l2_interface_vlan_tag_rewrite_reply)                  \
5497 _(modify_vhost_user_if_reply)                           \
5498 _(delete_vhost_user_if_reply)                           \
5499 _(ip_probe_neighbor_reply)                              \
5500 _(ip_scan_neighbor_enable_disable_reply)                \
5501 _(want_ip4_arp_events_reply)                            \
5502 _(want_ip6_nd_events_reply)                             \
5503 _(want_l2_macs_events_reply)                            \
5504 _(input_acl_set_interface_reply)                        \
5505 _(ipsec_spd_add_del_reply)                              \
5506 _(ipsec_interface_add_del_spd_reply)                    \
5507 _(ipsec_spd_add_del_entry_reply)                        \
5508 _(ipsec_sad_add_del_entry_reply)                        \
5509 _(ipsec_sa_set_key_reply)                               \
5510 _(ipsec_tunnel_if_add_del_reply)                        \
5511 _(ipsec_tunnel_if_set_key_reply)                        \
5512 _(ipsec_tunnel_if_set_sa_reply)                         \
5513 _(ikev2_profile_add_del_reply)                          \
5514 _(ikev2_profile_set_auth_reply)                         \
5515 _(ikev2_profile_set_id_reply)                           \
5516 _(ikev2_profile_set_ts_reply)                           \
5517 _(ikev2_set_local_key_reply)                            \
5518 _(ikev2_set_responder_reply)                            \
5519 _(ikev2_set_ike_transforms_reply)                       \
5520 _(ikev2_set_esp_transforms_reply)                       \
5521 _(ikev2_set_sa_lifetime_reply)                          \
5522 _(ikev2_initiate_sa_init_reply)                         \
5523 _(ikev2_initiate_del_ike_sa_reply)                      \
5524 _(ikev2_initiate_del_child_sa_reply)                    \
5525 _(ikev2_initiate_rekey_child_sa_reply)                  \
5526 _(delete_loopback_reply)                                \
5527 _(bd_ip_mac_add_del_reply)                              \
5528 _(map_del_domain_reply)                                 \
5529 _(map_add_del_rule_reply)                               \
5530 _(want_interface_events_reply)                          \
5531 _(want_stats_reply)                                     \
5532 _(cop_interface_enable_disable_reply)                   \
5533 _(cop_whitelist_enable_disable_reply)                   \
5534 _(sw_interface_clear_stats_reply)                       \
5535 _(ioam_enable_reply)                                    \
5536 _(ioam_disable_reply)                                   \
5537 _(one_add_del_locator_reply)                            \
5538 _(one_add_del_local_eid_reply)                          \
5539 _(one_add_del_remote_mapping_reply)                     \
5540 _(one_add_del_adjacency_reply)                          \
5541 _(one_add_del_map_resolver_reply)                       \
5542 _(one_add_del_map_server_reply)                         \
5543 _(one_enable_disable_reply)                             \
5544 _(one_rloc_probe_enable_disable_reply)                  \
5545 _(one_map_register_enable_disable_reply)                \
5546 _(one_map_register_set_ttl_reply)                       \
5547 _(one_set_transport_protocol_reply)                     \
5548 _(one_map_register_fallback_threshold_reply)            \
5549 _(one_pitr_set_locator_set_reply)                       \
5550 _(one_map_request_mode_reply)                           \
5551 _(one_add_del_map_request_itr_rlocs_reply)              \
5552 _(one_eid_table_add_del_map_reply)                      \
5553 _(one_use_petr_reply)                                   \
5554 _(one_stats_enable_disable_reply)                       \
5555 _(one_add_del_l2_arp_entry_reply)                       \
5556 _(one_add_del_ndp_entry_reply)                          \
5557 _(one_stats_flush_reply)                                \
5558 _(one_enable_disable_xtr_mode_reply)                    \
5559 _(one_enable_disable_pitr_mode_reply)                   \
5560 _(one_enable_disable_petr_mode_reply)                   \
5561 _(gpe_enable_disable_reply)                             \
5562 _(gpe_set_encap_mode_reply)                             \
5563 _(gpe_add_del_iface_reply)                              \
5564 _(gpe_add_del_native_fwd_rpath_reply)                   \
5565 _(af_packet_delete_reply)                               \
5566 _(policer_classify_set_interface_reply)                 \
5567 _(netmap_create_reply)                                  \
5568 _(netmap_delete_reply)                                  \
5569 _(set_ipfix_exporter_reply)                             \
5570 _(set_ipfix_classify_stream_reply)                      \
5571 _(ipfix_classify_table_add_del_reply)                   \
5572 _(flow_classify_set_interface_reply)                    \
5573 _(sw_interface_span_enable_disable_reply)               \
5574 _(pg_capture_reply)                                     \
5575 _(pg_enable_disable_reply)                              \
5576 _(ip_source_and_port_range_check_add_del_reply)         \
5577 _(ip_source_and_port_range_check_interface_add_del_reply)\
5578 _(delete_subif_reply)                                   \
5579 _(l2_interface_pbb_tag_rewrite_reply)                   \
5580 _(punt_reply)                                           \
5581 _(feature_enable_disable_reply)                         \
5582 _(sw_interface_tag_add_del_reply)                       \
5583 _(hw_interface_set_mtu_reply)                           \
5584 _(p2p_ethernet_add_reply)                               \
5585 _(p2p_ethernet_del_reply)                               \
5586 _(lldp_config_reply)                                    \
5587 _(sw_interface_set_lldp_reply)                          \
5588 _(tcp_configure_src_addresses_reply)                    \
5589 _(dns_enable_disable_reply)                             \
5590 _(dns_name_server_add_del_reply)                        \
5591 _(session_rule_add_del_reply)                           \
5592 _(ip_container_proxy_add_del_reply)                     \
5593 _(output_acl_set_interface_reply)                       \
5594 _(qos_record_enable_disable_reply)
5595
5596 #define _(n)                                    \
5597     static void vl_api_##n##_t_handler          \
5598     (vl_api_##n##_t * mp)                       \
5599     {                                           \
5600         vat_main_t * vam = &vat_main;           \
5601         i32 retval = ntohl(mp->retval);         \
5602         if (vam->async_mode) {                  \
5603             vam->async_errors += (retval < 0);  \
5604         } else {                                \
5605             vam->retval = retval;               \
5606             vam->result_ready = 1;              \
5607         }                                       \
5608     }
5609 foreach_standard_reply_retval_handler;
5610 #undef _
5611
5612 #define _(n)                                    \
5613     static void vl_api_##n##_t_handler_json     \
5614     (vl_api_##n##_t * mp)                       \
5615     {                                           \
5616         vat_main_t * vam = &vat_main;           \
5617         vat_json_node_t node;                   \
5618         vat_json_init_object(&node);            \
5619         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5620         vat_json_print(vam->ofp, &node);        \
5621         vam->retval = ntohl(mp->retval);        \
5622         vam->result_ready = 1;                  \
5623     }
5624 foreach_standard_reply_retval_handler;
5625 #undef _
5626
5627 /*
5628  * Table of message reply handlers, must include boilerplate handlers
5629  * we just generated
5630  */
5631
5632 #define foreach_vpe_api_reply_msg                                       \
5633 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5634 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5635 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5636 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5637 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5638 _(CLI_REPLY, cli_reply)                                                 \
5639 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5640 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5641   sw_interface_add_del_address_reply)                                   \
5642 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5643 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5644 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5645 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5646 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5647 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5648 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5649 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5650   sw_interface_set_l2_xconnect_reply)                                   \
5651 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5652   sw_interface_set_l2_bridge_reply)                                     \
5653 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5654 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5655 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5656 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5657 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5658 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5659 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5660 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5661 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5662 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5663 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5664 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5665 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5666 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5667 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5668 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5669 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5670 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5671 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5672 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5673 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5674 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5675 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5676 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5677 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5678 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5679 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5680 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5681 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5682 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5683 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5684   proxy_arp_intfc_enable_disable_reply)                                 \
5685 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5686 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5687   sw_interface_set_unnumbered_reply)                                    \
5688 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5689 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5690 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5691 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5692 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5693 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5694 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5695 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5696 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5697 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5698 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5699   sw_interface_ip6_enable_disable_reply)                                \
5700 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5701   sw_interface_ip6_set_link_local_address_reply)                        \
5702 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5703 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5704 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5705   sw_interface_ip6nd_ra_prefix_reply)                                   \
5706 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5707   sw_interface_ip6nd_ra_config_reply)                                   \
5708 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5709 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5710 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5711 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5712 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5713 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5714 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5715 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5716 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5717 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5718 classify_set_interface_ip_table_reply)                                  \
5719 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5720   classify_set_interface_l2_tables_reply)                               \
5721 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5722 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5723 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5724 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5725 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5726   l2tpv3_interface_enable_disable_reply)                                \
5727 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5728 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5729 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5730 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5731 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5732 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5733 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5734 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5735 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5736 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5737 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5738 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5739 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5740 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5741 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5742 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5743 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5744 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5745 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5746 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5747 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5748 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5749 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5750 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5751 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5752 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5753 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5754 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5755 _(L2_MACS_EVENT, l2_macs_event)                                         \
5756 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5757 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5758 _(IP_DETAILS, ip_details)                                               \
5759 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5760 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5761 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5762 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5763 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5764 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5765 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5766 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5767 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5768 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5769 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5770 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5771 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5772 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5773 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5774 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5775 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5776 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5777 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5778 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5779 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5780 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5781 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5782 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5783 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5784 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5785 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5786 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5787 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5788 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5789 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5790 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5791 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5792 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5793 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5794 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5795 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5796 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5797 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5798 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5799 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5800 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5801 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5802 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5803 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5804 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5805 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5806 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5807   one_map_register_enable_disable_reply)                                \
5808 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5809 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5810 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5811 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5812   one_map_register_fallback_threshold_reply)                            \
5813 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5814   one_rloc_probe_enable_disable_reply)                                  \
5815 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5816 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5817 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5818 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5819 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5820 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5821 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5822 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5823 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5824 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5825 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5826 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5827 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5828 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5829 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5830 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5831   show_one_stats_enable_disable_reply)                                  \
5832 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5833 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5834 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5835 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5836 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5837 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5838 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5839 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5840   one_enable_disable_pitr_mode_reply)                                   \
5841 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5842   one_enable_disable_petr_mode_reply)                                   \
5843 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5844 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5845 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5846 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5847 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5848 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5849 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5850 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5851 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5852 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5853 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5854 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5855   gpe_add_del_native_fwd_rpath_reply)                                   \
5856 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5857   gpe_fwd_entry_path_details)                                           \
5858 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5859 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5860   one_add_del_map_request_itr_rlocs_reply)                              \
5861 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5862   one_get_map_request_itr_rlocs_reply)                                  \
5863 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5864 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5865 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5866 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5867 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5868 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5869   show_one_map_register_state_reply)                                    \
5870 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5871 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5872   show_one_map_register_fallback_threshold_reply)                       \
5873 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5874 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5875 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5876 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5877 _(POLICER_DETAILS, policer_details)                                     \
5878 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5879 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5880 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5881 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5882 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5883 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5884 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5885 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5886 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5887 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5888 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5889 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5890 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5891 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5892 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5893 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5894 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5895 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5896 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5897 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5898 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5899 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5900 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5901 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5902 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5903  ip_source_and_port_range_check_add_del_reply)                          \
5904 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5905  ip_source_and_port_range_check_interface_add_del_reply)                \
5906 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5907 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5908 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5909 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5910 _(PUNT_REPLY, punt_reply)                                               \
5911 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5912 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5913 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5914 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5915 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5916 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5917 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5918 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5919 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5920 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5921 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5922 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5923 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5924 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5925 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5926 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5927 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5928 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5929 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5930 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5931 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5932 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5933 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)     \
5934 _(MAP_STATS_SEGMENT_REPLY, map_stats_segment_reply)
5935
5936 #define foreach_standalone_reply_msg                                    \
5937 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5938 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5939 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5940 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5941 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5942 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5943 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5944
5945 typedef struct
5946 {
5947   u8 *name;
5948   u32 value;
5949 } name_sort_t;
5950
5951 #define STR_VTR_OP_CASE(op)     \
5952     case L2_VTR_ ## op:         \
5953         return "" # op;
5954
5955 static const char *
5956 str_vtr_op (u32 vtr_op)
5957 {
5958   switch (vtr_op)
5959     {
5960       STR_VTR_OP_CASE (DISABLED);
5961       STR_VTR_OP_CASE (PUSH_1);
5962       STR_VTR_OP_CASE (PUSH_2);
5963       STR_VTR_OP_CASE (POP_1);
5964       STR_VTR_OP_CASE (POP_2);
5965       STR_VTR_OP_CASE (TRANSLATE_1_1);
5966       STR_VTR_OP_CASE (TRANSLATE_1_2);
5967       STR_VTR_OP_CASE (TRANSLATE_2_1);
5968       STR_VTR_OP_CASE (TRANSLATE_2_2);
5969     }
5970
5971   return "UNKNOWN";
5972 }
5973
5974 static int
5975 dump_sub_interface_table (vat_main_t * vam)
5976 {
5977   const sw_interface_subif_t *sub = NULL;
5978
5979   if (vam->json_output)
5980     {
5981       clib_warning
5982         ("JSON output supported only for VPE API calls and dump_stats_table");
5983       return -99;
5984     }
5985
5986   print (vam->ofp,
5987          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5988          "Interface", "sw_if_index",
5989          "sub id", "dot1ad", "tags", "outer id",
5990          "inner id", "exact", "default", "outer any", "inner any");
5991
5992   vec_foreach (sub, vam->sw_if_subif_table)
5993   {
5994     print (vam->ofp,
5995            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5996            sub->interface_name,
5997            sub->sw_if_index,
5998            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5999            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
6000            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
6001            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
6002     if (sub->vtr_op != L2_VTR_DISABLED)
6003       {
6004         print (vam->ofp,
6005                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
6006                "tag1: %d tag2: %d ]",
6007                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
6008                sub->vtr_tag1, sub->vtr_tag2);
6009       }
6010   }
6011
6012   return 0;
6013 }
6014
6015 static int
6016 name_sort_cmp (void *a1, void *a2)
6017 {
6018   name_sort_t *n1 = a1;
6019   name_sort_t *n2 = a2;
6020
6021   return strcmp ((char *) n1->name, (char *) n2->name);
6022 }
6023
6024 static int
6025 dump_interface_table (vat_main_t * vam)
6026 {
6027   hash_pair_t *p;
6028   name_sort_t *nses = 0, *ns;
6029
6030   if (vam->json_output)
6031     {
6032       clib_warning
6033         ("JSON output supported only for VPE API calls and dump_stats_table");
6034       return -99;
6035     }
6036
6037   /* *INDENT-OFF* */
6038   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6039   ({
6040     vec_add2 (nses, ns, 1);
6041     ns->name = (u8 *)(p->key);
6042     ns->value = (u32) p->value[0];
6043   }));
6044   /* *INDENT-ON* */
6045
6046   vec_sort_with_function (nses, name_sort_cmp);
6047
6048   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6049   vec_foreach (ns, nses)
6050   {
6051     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6052   }
6053   vec_free (nses);
6054   return 0;
6055 }
6056
6057 static int
6058 dump_ip_table (vat_main_t * vam, int is_ipv6)
6059 {
6060   const ip_details_t *det = NULL;
6061   const ip_address_details_t *address = NULL;
6062   u32 i = ~0;
6063
6064   print (vam->ofp, "%-12s", "sw_if_index");
6065
6066   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6067   {
6068     i++;
6069     if (!det->present)
6070       {
6071         continue;
6072       }
6073     print (vam->ofp, "%-12d", i);
6074     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6075     if (!det->addr)
6076       {
6077         continue;
6078       }
6079     vec_foreach (address, det->addr)
6080     {
6081       print (vam->ofp,
6082              "            %-30U%-13d",
6083              is_ipv6 ? format_ip6_address : format_ip4_address,
6084              address->ip, address->prefix_length);
6085     }
6086   }
6087
6088   return 0;
6089 }
6090
6091 static int
6092 dump_ipv4_table (vat_main_t * vam)
6093 {
6094   if (vam->json_output)
6095     {
6096       clib_warning
6097         ("JSON output supported only for VPE API calls and dump_stats_table");
6098       return -99;
6099     }
6100
6101   return dump_ip_table (vam, 0);
6102 }
6103
6104 static int
6105 dump_ipv6_table (vat_main_t * vam)
6106 {
6107   if (vam->json_output)
6108     {
6109       clib_warning
6110         ("JSON output supported only for VPE API calls and dump_stats_table");
6111       return -99;
6112     }
6113
6114   return dump_ip_table (vam, 1);
6115 }
6116
6117 static char *
6118 counter_type_to_str (u8 counter_type, u8 is_combined)
6119 {
6120   if (!is_combined)
6121     {
6122       switch (counter_type)
6123         {
6124         case VNET_INTERFACE_COUNTER_DROP:
6125           return "drop";
6126         case VNET_INTERFACE_COUNTER_PUNT:
6127           return "punt";
6128         case VNET_INTERFACE_COUNTER_IP4:
6129           return "ip4";
6130         case VNET_INTERFACE_COUNTER_IP6:
6131           return "ip6";
6132         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6133           return "rx-no-buf";
6134         case VNET_INTERFACE_COUNTER_RX_MISS:
6135           return "rx-miss";
6136         case VNET_INTERFACE_COUNTER_RX_ERROR:
6137           return "rx-error";
6138         case VNET_INTERFACE_COUNTER_TX_ERROR:
6139           return "tx-error";
6140         default:
6141           return "INVALID-COUNTER-TYPE";
6142         }
6143     }
6144   else
6145     {
6146       switch (counter_type)
6147         {
6148         case VNET_INTERFACE_COUNTER_RX:
6149           return "rx";
6150         case VNET_INTERFACE_COUNTER_TX:
6151           return "tx";
6152         default:
6153           return "INVALID-COUNTER-TYPE";
6154         }
6155     }
6156 }
6157
6158 static int
6159 dump_stats_table (vat_main_t * vam)
6160 {
6161   vat_json_node_t node;
6162   vat_json_node_t *msg_array;
6163   vat_json_node_t *msg;
6164   vat_json_node_t *counter_array;
6165   vat_json_node_t *counter;
6166   interface_counter_t c;
6167   u64 packets;
6168   ip4_fib_counter_t *c4;
6169   ip6_fib_counter_t *c6;
6170   ip4_nbr_counter_t *n4;
6171   ip6_nbr_counter_t *n6;
6172   int i, j;
6173
6174   if (!vam->json_output)
6175     {
6176       clib_warning ("dump_stats_table supported only in JSON format");
6177       return -99;
6178     }
6179
6180   vat_json_init_object (&node);
6181
6182   /* interface counters */
6183   msg_array = vat_json_object_add (&node, "interface_counters");
6184   vat_json_init_array (msg_array);
6185   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6186     {
6187       msg = vat_json_array_add (msg_array);
6188       vat_json_init_object (msg);
6189       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6190                                        (u8 *) counter_type_to_str (i, 0));
6191       vat_json_object_add_int (msg, "is_combined", 0);
6192       counter_array = vat_json_object_add (msg, "data");
6193       vat_json_init_array (counter_array);
6194       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6195         {
6196           packets = vam->simple_interface_counters[i][j];
6197           vat_json_array_add_uint (counter_array, packets);
6198         }
6199     }
6200   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6201     {
6202       msg = vat_json_array_add (msg_array);
6203       vat_json_init_object (msg);
6204       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6205                                        (u8 *) counter_type_to_str (i, 1));
6206       vat_json_object_add_int (msg, "is_combined", 1);
6207       counter_array = vat_json_object_add (msg, "data");
6208       vat_json_init_array (counter_array);
6209       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6210         {
6211           c = vam->combined_interface_counters[i][j];
6212           counter = vat_json_array_add (counter_array);
6213           vat_json_init_object (counter);
6214           vat_json_object_add_uint (counter, "packets", c.packets);
6215           vat_json_object_add_uint (counter, "bytes", c.bytes);
6216         }
6217     }
6218
6219   /* ip4 fib counters */
6220   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6221   vat_json_init_array (msg_array);
6222   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6223     {
6224       msg = vat_json_array_add (msg_array);
6225       vat_json_init_object (msg);
6226       vat_json_object_add_uint (msg, "vrf_id",
6227                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6228       counter_array = vat_json_object_add (msg, "c");
6229       vat_json_init_array (counter_array);
6230       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6231         {
6232           counter = vat_json_array_add (counter_array);
6233           vat_json_init_object (counter);
6234           c4 = &vam->ip4_fib_counters[i][j];
6235           vat_json_object_add_ip4 (counter, "address", c4->address);
6236           vat_json_object_add_uint (counter, "address_length",
6237                                     c4->address_length);
6238           vat_json_object_add_uint (counter, "packets", c4->packets);
6239           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6240         }
6241     }
6242
6243   /* ip6 fib counters */
6244   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6245   vat_json_init_array (msg_array);
6246   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6247     {
6248       msg = vat_json_array_add (msg_array);
6249       vat_json_init_object (msg);
6250       vat_json_object_add_uint (msg, "vrf_id",
6251                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6252       counter_array = vat_json_object_add (msg, "c");
6253       vat_json_init_array (counter_array);
6254       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6255         {
6256           counter = vat_json_array_add (counter_array);
6257           vat_json_init_object (counter);
6258           c6 = &vam->ip6_fib_counters[i][j];
6259           vat_json_object_add_ip6 (counter, "address", c6->address);
6260           vat_json_object_add_uint (counter, "address_length",
6261                                     c6->address_length);
6262           vat_json_object_add_uint (counter, "packets", c6->packets);
6263           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6264         }
6265     }
6266
6267   /* ip4 nbr counters */
6268   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6269   vat_json_init_array (msg_array);
6270   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6271     {
6272       msg = vat_json_array_add (msg_array);
6273       vat_json_init_object (msg);
6274       vat_json_object_add_uint (msg, "sw_if_index", i);
6275       counter_array = vat_json_object_add (msg, "c");
6276       vat_json_init_array (counter_array);
6277       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6278         {
6279           counter = vat_json_array_add (counter_array);
6280           vat_json_init_object (counter);
6281           n4 = &vam->ip4_nbr_counters[i][j];
6282           vat_json_object_add_ip4 (counter, "address", n4->address);
6283           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6284           vat_json_object_add_uint (counter, "packets", n4->packets);
6285           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6286         }
6287     }
6288
6289   /* ip6 nbr counters */
6290   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6291   vat_json_init_array (msg_array);
6292   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6293     {
6294       msg = vat_json_array_add (msg_array);
6295       vat_json_init_object (msg);
6296       vat_json_object_add_uint (msg, "sw_if_index", i);
6297       counter_array = vat_json_object_add (msg, "c");
6298       vat_json_init_array (counter_array);
6299       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6300         {
6301           counter = vat_json_array_add (counter_array);
6302           vat_json_init_object (counter);
6303           n6 = &vam->ip6_nbr_counters[i][j];
6304           vat_json_object_add_ip6 (counter, "address", n6->address);
6305           vat_json_object_add_uint (counter, "packets", n6->packets);
6306           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6307         }
6308     }
6309
6310   vat_json_print (vam->ofp, &node);
6311   vat_json_free (&node);
6312
6313   return 0;
6314 }
6315
6316 /*
6317  * Pass CLI buffers directly in the CLI_INBAND API message,
6318  * instead of an additional shared memory area.
6319  */
6320 static int
6321 exec_inband (vat_main_t * vam)
6322 {
6323   vl_api_cli_inband_t *mp;
6324   unformat_input_t *i = vam->input;
6325   int ret;
6326
6327   if (vec_len (i->buffer) == 0)
6328     return -1;
6329
6330   if (vam->exec_mode == 0 && unformat (i, "mode"))
6331     {
6332       vam->exec_mode = 1;
6333       return 0;
6334     }
6335   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6336     {
6337       vam->exec_mode = 0;
6338       return 0;
6339     }
6340
6341   /*
6342    * In order for the CLI command to work, it
6343    * must be a vector ending in \n, not a C-string ending
6344    * in \n\0.
6345    */
6346   u32 len = vec_len (vam->input->buffer);
6347   M2 (CLI_INBAND, mp, len);
6348   clib_memcpy (mp->cmd, vam->input->buffer, len);
6349   mp->length = htonl (len);
6350
6351   S (mp);
6352   W (ret);
6353   /* json responses may or may not include a useful reply... */
6354   if (vec_len (vam->cmd_reply))
6355     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6356   return ret;
6357 }
6358
6359 int
6360 exec (vat_main_t * vam)
6361 {
6362   return exec_inband (vam);
6363 }
6364
6365 static int
6366 api_create_loopback (vat_main_t * vam)
6367 {
6368   unformat_input_t *i = vam->input;
6369   vl_api_create_loopback_t *mp;
6370   vl_api_create_loopback_instance_t *mp_lbi;
6371   u8 mac_address[6];
6372   u8 mac_set = 0;
6373   u8 is_specified = 0;
6374   u32 user_instance = 0;
6375   int ret;
6376
6377   memset (mac_address, 0, sizeof (mac_address));
6378
6379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6380     {
6381       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6382         mac_set = 1;
6383       if (unformat (i, "instance %d", &user_instance))
6384         is_specified = 1;
6385       else
6386         break;
6387     }
6388
6389   if (is_specified)
6390     {
6391       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6392       mp_lbi->is_specified = is_specified;
6393       if (is_specified)
6394         mp_lbi->user_instance = htonl (user_instance);
6395       if (mac_set)
6396         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6397       S (mp_lbi);
6398     }
6399   else
6400     {
6401       /* Construct the API message */
6402       M (CREATE_LOOPBACK, mp);
6403       if (mac_set)
6404         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6405       S (mp);
6406     }
6407
6408   W (ret);
6409   return ret;
6410 }
6411
6412 static int
6413 api_delete_loopback (vat_main_t * vam)
6414 {
6415   unformat_input_t *i = vam->input;
6416   vl_api_delete_loopback_t *mp;
6417   u32 sw_if_index = ~0;
6418   int ret;
6419
6420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6421     {
6422       if (unformat (i, "sw_if_index %d", &sw_if_index))
6423         ;
6424       else
6425         break;
6426     }
6427
6428   if (sw_if_index == ~0)
6429     {
6430       errmsg ("missing sw_if_index");
6431       return -99;
6432     }
6433
6434   /* Construct the API message */
6435   M (DELETE_LOOPBACK, mp);
6436   mp->sw_if_index = ntohl (sw_if_index);
6437
6438   S (mp);
6439   W (ret);
6440   return ret;
6441 }
6442
6443 static int
6444 api_want_stats (vat_main_t * vam)
6445 {
6446   unformat_input_t *i = vam->input;
6447   vl_api_want_stats_t *mp;
6448   int enable = -1;
6449   int ret;
6450
6451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6452     {
6453       if (unformat (i, "enable"))
6454         enable = 1;
6455       else if (unformat (i, "disable"))
6456         enable = 0;
6457       else
6458         break;
6459     }
6460
6461   if (enable == -1)
6462     {
6463       errmsg ("missing enable|disable");
6464       return -99;
6465     }
6466
6467   M (WANT_STATS, mp);
6468   mp->enable_disable = enable;
6469
6470   S (mp);
6471   W (ret);
6472   return ret;
6473 }
6474
6475 static int
6476 api_want_interface_events (vat_main_t * vam)
6477 {
6478   unformat_input_t *i = vam->input;
6479   vl_api_want_interface_events_t *mp;
6480   int enable = -1;
6481   int ret;
6482
6483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6484     {
6485       if (unformat (i, "enable"))
6486         enable = 1;
6487       else if (unformat (i, "disable"))
6488         enable = 0;
6489       else
6490         break;
6491     }
6492
6493   if (enable == -1)
6494     {
6495       errmsg ("missing enable|disable");
6496       return -99;
6497     }
6498
6499   M (WANT_INTERFACE_EVENTS, mp);
6500   mp->enable_disable = enable;
6501
6502   vam->interface_event_display = enable;
6503
6504   S (mp);
6505   W (ret);
6506   return ret;
6507 }
6508
6509
6510 /* Note: non-static, called once to set up the initial intfc table */
6511 int
6512 api_sw_interface_dump (vat_main_t * vam)
6513 {
6514   vl_api_sw_interface_dump_t *mp;
6515   vl_api_control_ping_t *mp_ping;
6516   hash_pair_t *p;
6517   name_sort_t *nses = 0, *ns;
6518   sw_interface_subif_t *sub = NULL;
6519   int ret;
6520
6521   /* Toss the old name table */
6522   /* *INDENT-OFF* */
6523   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6524   ({
6525     vec_add2 (nses, ns, 1);
6526     ns->name = (u8 *)(p->key);
6527     ns->value = (u32) p->value[0];
6528   }));
6529   /* *INDENT-ON* */
6530
6531   hash_free (vam->sw_if_index_by_interface_name);
6532
6533   vec_foreach (ns, nses) vec_free (ns->name);
6534
6535   vec_free (nses);
6536
6537   vec_foreach (sub, vam->sw_if_subif_table)
6538   {
6539     vec_free (sub->interface_name);
6540   }
6541   vec_free (vam->sw_if_subif_table);
6542
6543   /* recreate the interface name hash table */
6544   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6545
6546   /*
6547    * Ask for all interface names. Otherwise, the epic catalog of
6548    * name filters becomes ridiculously long, and vat ends up needing
6549    * to be taught about new interface types.
6550    */
6551   M (SW_INTERFACE_DUMP, mp);
6552   S (mp);
6553
6554   /* Use a control ping for synchronization */
6555   MPING (CONTROL_PING, mp_ping);
6556   S (mp_ping);
6557
6558   W (ret);
6559   return ret;
6560 }
6561
6562 static int
6563 api_sw_interface_set_flags (vat_main_t * vam)
6564 {
6565   unformat_input_t *i = vam->input;
6566   vl_api_sw_interface_set_flags_t *mp;
6567   u32 sw_if_index;
6568   u8 sw_if_index_set = 0;
6569   u8 admin_up = 0;
6570   int ret;
6571
6572   /* Parse args required to build the message */
6573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6574     {
6575       if (unformat (i, "admin-up"))
6576         admin_up = 1;
6577       else if (unformat (i, "admin-down"))
6578         admin_up = 0;
6579       else
6580         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6581         sw_if_index_set = 1;
6582       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6583         sw_if_index_set = 1;
6584       else
6585         break;
6586     }
6587
6588   if (sw_if_index_set == 0)
6589     {
6590       errmsg ("missing interface name or sw_if_index");
6591       return -99;
6592     }
6593
6594   /* Construct the API message */
6595   M (SW_INTERFACE_SET_FLAGS, mp);
6596   mp->sw_if_index = ntohl (sw_if_index);
6597   mp->admin_up_down = admin_up;
6598
6599   /* send it... */
6600   S (mp);
6601
6602   /* Wait for a reply, return the good/bad news... */
6603   W (ret);
6604   return ret;
6605 }
6606
6607 static int
6608 api_sw_interface_set_rx_mode (vat_main_t * vam)
6609 {
6610   unformat_input_t *i = vam->input;
6611   vl_api_sw_interface_set_rx_mode_t *mp;
6612   u32 sw_if_index;
6613   u8 sw_if_index_set = 0;
6614   int ret;
6615   u8 queue_id_valid = 0;
6616   u32 queue_id;
6617   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6618
6619   /* Parse args required to build the message */
6620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6621     {
6622       if (unformat (i, "queue %d", &queue_id))
6623         queue_id_valid = 1;
6624       else if (unformat (i, "polling"))
6625         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6626       else if (unformat (i, "interrupt"))
6627         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6628       else if (unformat (i, "adaptive"))
6629         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6630       else
6631         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6632         sw_if_index_set = 1;
6633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6634         sw_if_index_set = 1;
6635       else
6636         break;
6637     }
6638
6639   if (sw_if_index_set == 0)
6640     {
6641       errmsg ("missing interface name or sw_if_index");
6642       return -99;
6643     }
6644   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6645     {
6646       errmsg ("missing rx-mode");
6647       return -99;
6648     }
6649
6650   /* Construct the API message */
6651   M (SW_INTERFACE_SET_RX_MODE, mp);
6652   mp->sw_if_index = ntohl (sw_if_index);
6653   mp->mode = mode;
6654   mp->queue_id_valid = queue_id_valid;
6655   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6656
6657   /* send it... */
6658   S (mp);
6659
6660   /* Wait for a reply, return the good/bad news... */
6661   W (ret);
6662   return ret;
6663 }
6664
6665 static int
6666 api_sw_interface_clear_stats (vat_main_t * vam)
6667 {
6668   unformat_input_t *i = vam->input;
6669   vl_api_sw_interface_clear_stats_t *mp;
6670   u32 sw_if_index;
6671   u8 sw_if_index_set = 0;
6672   int ret;
6673
6674   /* Parse args required to build the message */
6675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6676     {
6677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6678         sw_if_index_set = 1;
6679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6680         sw_if_index_set = 1;
6681       else
6682         break;
6683     }
6684
6685   /* Construct the API message */
6686   M (SW_INTERFACE_CLEAR_STATS, mp);
6687
6688   if (sw_if_index_set == 1)
6689     mp->sw_if_index = ntohl (sw_if_index);
6690   else
6691     mp->sw_if_index = ~0;
6692
6693   /* send it... */
6694   S (mp);
6695
6696   /* Wait for a reply, return the good/bad news... */
6697   W (ret);
6698   return ret;
6699 }
6700
6701 static int
6702 api_sw_interface_add_del_address (vat_main_t * vam)
6703 {
6704   unformat_input_t *i = vam->input;
6705   vl_api_sw_interface_add_del_address_t *mp;
6706   u32 sw_if_index;
6707   u8 sw_if_index_set = 0;
6708   u8 is_add = 1, del_all = 0;
6709   u32 address_length = 0;
6710   u8 v4_address_set = 0;
6711   u8 v6_address_set = 0;
6712   ip4_address_t v4address;
6713   ip6_address_t v6address;
6714   int ret;
6715
6716   /* Parse args required to build the message */
6717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6718     {
6719       if (unformat (i, "del-all"))
6720         del_all = 1;
6721       else if (unformat (i, "del"))
6722         is_add = 0;
6723       else
6724         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6725         sw_if_index_set = 1;
6726       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6727         sw_if_index_set = 1;
6728       else if (unformat (i, "%U/%d",
6729                          unformat_ip4_address, &v4address, &address_length))
6730         v4_address_set = 1;
6731       else if (unformat (i, "%U/%d",
6732                          unformat_ip6_address, &v6address, &address_length))
6733         v6_address_set = 1;
6734       else
6735         break;
6736     }
6737
6738   if (sw_if_index_set == 0)
6739     {
6740       errmsg ("missing interface name or sw_if_index");
6741       return -99;
6742     }
6743   if (v4_address_set && v6_address_set)
6744     {
6745       errmsg ("both v4 and v6 addresses set");
6746       return -99;
6747     }
6748   if (!v4_address_set && !v6_address_set && !del_all)
6749     {
6750       errmsg ("no addresses set");
6751       return -99;
6752     }
6753
6754   /* Construct the API message */
6755   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6756
6757   mp->sw_if_index = ntohl (sw_if_index);
6758   mp->is_add = is_add;
6759   mp->del_all = del_all;
6760   if (v6_address_set)
6761     {
6762       mp->is_ipv6 = 1;
6763       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6764     }
6765   else
6766     {
6767       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6768     }
6769   mp->address_length = address_length;
6770
6771   /* send it... */
6772   S (mp);
6773
6774   /* Wait for a reply, return good/bad news  */
6775   W (ret);
6776   return ret;
6777 }
6778
6779 static int
6780 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6781 {
6782   unformat_input_t *i = vam->input;
6783   vl_api_sw_interface_set_mpls_enable_t *mp;
6784   u32 sw_if_index;
6785   u8 sw_if_index_set = 0;
6786   u8 enable = 1;
6787   int ret;
6788
6789   /* Parse args required to build the message */
6790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6791     {
6792       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6793         sw_if_index_set = 1;
6794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6795         sw_if_index_set = 1;
6796       else if (unformat (i, "disable"))
6797         enable = 0;
6798       else if (unformat (i, "dis"))
6799         enable = 0;
6800       else
6801         break;
6802     }
6803
6804   if (sw_if_index_set == 0)
6805     {
6806       errmsg ("missing interface name or sw_if_index");
6807       return -99;
6808     }
6809
6810   /* Construct the API message */
6811   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6812
6813   mp->sw_if_index = ntohl (sw_if_index);
6814   mp->enable = enable;
6815
6816   /* send it... */
6817   S (mp);
6818
6819   /* Wait for a reply... */
6820   W (ret);
6821   return ret;
6822 }
6823
6824 static int
6825 api_sw_interface_set_table (vat_main_t * vam)
6826 {
6827   unformat_input_t *i = vam->input;
6828   vl_api_sw_interface_set_table_t *mp;
6829   u32 sw_if_index, vrf_id = 0;
6830   u8 sw_if_index_set = 0;
6831   u8 is_ipv6 = 0;
6832   int ret;
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6838         sw_if_index_set = 1;
6839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6840         sw_if_index_set = 1;
6841       else if (unformat (i, "vrf %d", &vrf_id))
6842         ;
6843       else if (unformat (i, "ipv6"))
6844         is_ipv6 = 1;
6845       else
6846         break;
6847     }
6848
6849   if (sw_if_index_set == 0)
6850     {
6851       errmsg ("missing interface name or sw_if_index");
6852       return -99;
6853     }
6854
6855   /* Construct the API message */
6856   M (SW_INTERFACE_SET_TABLE, mp);
6857
6858   mp->sw_if_index = ntohl (sw_if_index);
6859   mp->is_ipv6 = is_ipv6;
6860   mp->vrf_id = ntohl (vrf_id);
6861
6862   /* send it... */
6863   S (mp);
6864
6865   /* Wait for a reply... */
6866   W (ret);
6867   return ret;
6868 }
6869
6870 static void vl_api_sw_interface_get_table_reply_t_handler
6871   (vl_api_sw_interface_get_table_reply_t * mp)
6872 {
6873   vat_main_t *vam = &vat_main;
6874
6875   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6876
6877   vam->retval = ntohl (mp->retval);
6878   vam->result_ready = 1;
6879
6880 }
6881
6882 static void vl_api_sw_interface_get_table_reply_t_handler_json
6883   (vl_api_sw_interface_get_table_reply_t * mp)
6884 {
6885   vat_main_t *vam = &vat_main;
6886   vat_json_node_t node;
6887
6888   vat_json_init_object (&node);
6889   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6890   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6891
6892   vat_json_print (vam->ofp, &node);
6893   vat_json_free (&node);
6894
6895   vam->retval = ntohl (mp->retval);
6896   vam->result_ready = 1;
6897 }
6898
6899 static int
6900 api_sw_interface_get_table (vat_main_t * vam)
6901 {
6902   unformat_input_t *i = vam->input;
6903   vl_api_sw_interface_get_table_t *mp;
6904   u32 sw_if_index;
6905   u8 sw_if_index_set = 0;
6906   u8 is_ipv6 = 0;
6907   int ret;
6908
6909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6910     {
6911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6912         sw_if_index_set = 1;
6913       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6914         sw_if_index_set = 1;
6915       else if (unformat (i, "ipv6"))
6916         is_ipv6 = 1;
6917       else
6918         break;
6919     }
6920
6921   if (sw_if_index_set == 0)
6922     {
6923       errmsg ("missing interface name or sw_if_index");
6924       return -99;
6925     }
6926
6927   M (SW_INTERFACE_GET_TABLE, mp);
6928   mp->sw_if_index = htonl (sw_if_index);
6929   mp->is_ipv6 = is_ipv6;
6930
6931   S (mp);
6932   W (ret);
6933   return ret;
6934 }
6935
6936 static int
6937 api_sw_interface_set_vpath (vat_main_t * vam)
6938 {
6939   unformat_input_t *i = vam->input;
6940   vl_api_sw_interface_set_vpath_t *mp;
6941   u32 sw_if_index = 0;
6942   u8 sw_if_index_set = 0;
6943   u8 is_enable = 0;
6944   int ret;
6945
6946   /* Parse args required to build the message */
6947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6948     {
6949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6950         sw_if_index_set = 1;
6951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6952         sw_if_index_set = 1;
6953       else if (unformat (i, "enable"))
6954         is_enable = 1;
6955       else if (unformat (i, "disable"))
6956         is_enable = 0;
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_VPATH, mp);
6969
6970   mp->sw_if_index = ntohl (sw_if_index);
6971   mp->enable = is_enable;
6972
6973   /* send it... */
6974   S (mp);
6975
6976   /* Wait for a reply... */
6977   W (ret);
6978   return ret;
6979 }
6980
6981 static int
6982 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6983 {
6984   unformat_input_t *i = vam->input;
6985   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6986   u32 sw_if_index = 0;
6987   u8 sw_if_index_set = 0;
6988   u8 is_enable = 1;
6989   u8 is_ipv6 = 0;
6990   int ret;
6991
6992   /* Parse args required to build the message */
6993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6994     {
6995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6996         sw_if_index_set = 1;
6997       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6998         sw_if_index_set = 1;
6999       else if (unformat (i, "enable"))
7000         is_enable = 1;
7001       else if (unformat (i, "disable"))
7002         is_enable = 0;
7003       else if (unformat (i, "ip4"))
7004         is_ipv6 = 0;
7005       else if (unformat (i, "ip6"))
7006         is_ipv6 = 1;
7007       else
7008         break;
7009     }
7010
7011   if (sw_if_index_set == 0)
7012     {
7013       errmsg ("missing interface name or sw_if_index");
7014       return -99;
7015     }
7016
7017   /* Construct the API message */
7018   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7019
7020   mp->sw_if_index = ntohl (sw_if_index);
7021   mp->enable = is_enable;
7022   mp->is_ipv6 = is_ipv6;
7023
7024   /* send it... */
7025   S (mp);
7026
7027   /* Wait for a reply... */
7028   W (ret);
7029   return ret;
7030 }
7031
7032 static int
7033 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7034 {
7035   unformat_input_t *i = vam->input;
7036   vl_api_sw_interface_set_geneve_bypass_t *mp;
7037   u32 sw_if_index = 0;
7038   u8 sw_if_index_set = 0;
7039   u8 is_enable = 1;
7040   u8 is_ipv6 = 0;
7041   int ret;
7042
7043   /* Parse args required to build the message */
7044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7045     {
7046       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7047         sw_if_index_set = 1;
7048       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7049         sw_if_index_set = 1;
7050       else if (unformat (i, "enable"))
7051         is_enable = 1;
7052       else if (unformat (i, "disable"))
7053         is_enable = 0;
7054       else if (unformat (i, "ip4"))
7055         is_ipv6 = 0;
7056       else if (unformat (i, "ip6"))
7057         is_ipv6 = 1;
7058       else
7059         break;
7060     }
7061
7062   if (sw_if_index_set == 0)
7063     {
7064       errmsg ("missing interface name or sw_if_index");
7065       return -99;
7066     }
7067
7068   /* Construct the API message */
7069   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7070
7071   mp->sw_if_index = ntohl (sw_if_index);
7072   mp->enable = is_enable;
7073   mp->is_ipv6 = is_ipv6;
7074
7075   /* send it... */
7076   S (mp);
7077
7078   /* Wait for a reply... */
7079   W (ret);
7080   return ret;
7081 }
7082
7083 static int
7084 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7085 {
7086   unformat_input_t *i = vam->input;
7087   vl_api_sw_interface_set_l2_xconnect_t *mp;
7088   u32 rx_sw_if_index;
7089   u8 rx_sw_if_index_set = 0;
7090   u32 tx_sw_if_index;
7091   u8 tx_sw_if_index_set = 0;
7092   u8 enable = 1;
7093   int ret;
7094
7095   /* Parse args required to build the message */
7096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7097     {
7098       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7099         rx_sw_if_index_set = 1;
7100       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7101         tx_sw_if_index_set = 1;
7102       else if (unformat (i, "rx"))
7103         {
7104           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7105             {
7106               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7107                             &rx_sw_if_index))
7108                 rx_sw_if_index_set = 1;
7109             }
7110           else
7111             break;
7112         }
7113       else if (unformat (i, "tx"))
7114         {
7115           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7116             {
7117               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7118                             &tx_sw_if_index))
7119                 tx_sw_if_index_set = 1;
7120             }
7121           else
7122             break;
7123         }
7124       else if (unformat (i, "enable"))
7125         enable = 1;
7126       else if (unformat (i, "disable"))
7127         enable = 0;
7128       else
7129         break;
7130     }
7131
7132   if (rx_sw_if_index_set == 0)
7133     {
7134       errmsg ("missing rx interface name or rx_sw_if_index");
7135       return -99;
7136     }
7137
7138   if (enable && (tx_sw_if_index_set == 0))
7139     {
7140       errmsg ("missing tx interface name or tx_sw_if_index");
7141       return -99;
7142     }
7143
7144   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7145
7146   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7147   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7148   mp->enable = enable;
7149
7150   S (mp);
7151   W (ret);
7152   return ret;
7153 }
7154
7155 static int
7156 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7157 {
7158   unformat_input_t *i = vam->input;
7159   vl_api_sw_interface_set_l2_bridge_t *mp;
7160   u32 rx_sw_if_index;
7161   u8 rx_sw_if_index_set = 0;
7162   u32 bd_id;
7163   u8 bd_id_set = 0;
7164   u8 bvi = 0;
7165   u32 shg = 0;
7166   u8 enable = 1;
7167   int ret;
7168
7169   /* Parse args required to build the message */
7170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171     {
7172       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7173         rx_sw_if_index_set = 1;
7174       else if (unformat (i, "bd_id %d", &bd_id))
7175         bd_id_set = 1;
7176       else
7177         if (unformat
7178             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7179         rx_sw_if_index_set = 1;
7180       else if (unformat (i, "shg %d", &shg))
7181         ;
7182       else if (unformat (i, "bvi"))
7183         bvi = 1;
7184       else if (unformat (i, "enable"))
7185         enable = 1;
7186       else if (unformat (i, "disable"))
7187         enable = 0;
7188       else
7189         break;
7190     }
7191
7192   if (rx_sw_if_index_set == 0)
7193     {
7194       errmsg ("missing rx interface name or sw_if_index");
7195       return -99;
7196     }
7197
7198   if (enable && (bd_id_set == 0))
7199     {
7200       errmsg ("missing bridge domain");
7201       return -99;
7202     }
7203
7204   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7205
7206   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7207   mp->bd_id = ntohl (bd_id);
7208   mp->shg = (u8) shg;
7209   mp->bvi = bvi;
7210   mp->enable = enable;
7211
7212   S (mp);
7213   W (ret);
7214   return ret;
7215 }
7216
7217 static int
7218 api_bridge_domain_dump (vat_main_t * vam)
7219 {
7220   unformat_input_t *i = vam->input;
7221   vl_api_bridge_domain_dump_t *mp;
7222   vl_api_control_ping_t *mp_ping;
7223   u32 bd_id = ~0;
7224   int ret;
7225
7226   /* Parse args required to build the message */
7227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228     {
7229       if (unformat (i, "bd_id %d", &bd_id))
7230         ;
7231       else
7232         break;
7233     }
7234
7235   M (BRIDGE_DOMAIN_DUMP, mp);
7236   mp->bd_id = ntohl (bd_id);
7237   S (mp);
7238
7239   /* Use a control ping for synchronization */
7240   MPING (CONTROL_PING, mp_ping);
7241   S (mp_ping);
7242
7243   W (ret);
7244   return ret;
7245 }
7246
7247 static int
7248 api_bridge_domain_add_del (vat_main_t * vam)
7249 {
7250   unformat_input_t *i = vam->input;
7251   vl_api_bridge_domain_add_del_t *mp;
7252   u32 bd_id = ~0;
7253   u8 is_add = 1;
7254   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7255   u8 *bd_tag = NULL;
7256   u32 mac_age = 0;
7257   int ret;
7258
7259   /* Parse args required to build the message */
7260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261     {
7262       if (unformat (i, "bd_id %d", &bd_id))
7263         ;
7264       else if (unformat (i, "flood %d", &flood))
7265         ;
7266       else if (unformat (i, "uu-flood %d", &uu_flood))
7267         ;
7268       else if (unformat (i, "forward %d", &forward))
7269         ;
7270       else if (unformat (i, "learn %d", &learn))
7271         ;
7272       else if (unformat (i, "arp-term %d", &arp_term))
7273         ;
7274       else if (unformat (i, "mac-age %d", &mac_age))
7275         ;
7276       else if (unformat (i, "bd-tag %s", &bd_tag))
7277         ;
7278       else if (unformat (i, "del"))
7279         {
7280           is_add = 0;
7281           flood = uu_flood = forward = learn = 0;
7282         }
7283       else
7284         break;
7285     }
7286
7287   if (bd_id == ~0)
7288     {
7289       errmsg ("missing bridge domain");
7290       ret = -99;
7291       goto done;
7292     }
7293
7294   if (mac_age > 255)
7295     {
7296       errmsg ("mac age must be less than 256 ");
7297       ret = -99;
7298       goto done;
7299     }
7300
7301   if ((bd_tag) && (vec_len (bd_tag) > 63))
7302     {
7303       errmsg ("bd-tag cannot be longer than 63");
7304       ret = -99;
7305       goto done;
7306     }
7307
7308   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7309
7310   mp->bd_id = ntohl (bd_id);
7311   mp->flood = flood;
7312   mp->uu_flood = uu_flood;
7313   mp->forward = forward;
7314   mp->learn = learn;
7315   mp->arp_term = arp_term;
7316   mp->is_add = is_add;
7317   mp->mac_age = (u8) mac_age;
7318   if (bd_tag)
7319     {
7320       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7321       mp->bd_tag[vec_len (bd_tag)] = 0;
7322     }
7323   S (mp);
7324   W (ret);
7325
7326 done:
7327   vec_free (bd_tag);
7328   return ret;
7329 }
7330
7331 static int
7332 api_l2fib_flush_bd (vat_main_t * vam)
7333 {
7334   unformat_input_t *i = vam->input;
7335   vl_api_l2fib_flush_bd_t *mp;
7336   u32 bd_id = ~0;
7337   int ret;
7338
7339   /* Parse args required to build the message */
7340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7341     {
7342       if (unformat (i, "bd_id %d", &bd_id));
7343       else
7344         break;
7345     }
7346
7347   if (bd_id == ~0)
7348     {
7349       errmsg ("missing bridge domain");
7350       return -99;
7351     }
7352
7353   M (L2FIB_FLUSH_BD, mp);
7354
7355   mp->bd_id = htonl (bd_id);
7356
7357   S (mp);
7358   W (ret);
7359   return ret;
7360 }
7361
7362 static int
7363 api_l2fib_flush_int (vat_main_t * vam)
7364 {
7365   unformat_input_t *i = vam->input;
7366   vl_api_l2fib_flush_int_t *mp;
7367   u32 sw_if_index = ~0;
7368   int ret;
7369
7370   /* Parse args required to build the message */
7371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7372     {
7373       if (unformat (i, "sw_if_index %d", &sw_if_index));
7374       else
7375         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7376       else
7377         break;
7378     }
7379
7380   if (sw_if_index == ~0)
7381     {
7382       errmsg ("missing interface name or sw_if_index");
7383       return -99;
7384     }
7385
7386   M (L2FIB_FLUSH_INT, mp);
7387
7388   mp->sw_if_index = ntohl (sw_if_index);
7389
7390   S (mp);
7391   W (ret);
7392   return ret;
7393 }
7394
7395 static int
7396 api_l2fib_add_del (vat_main_t * vam)
7397 {
7398   unformat_input_t *i = vam->input;
7399   vl_api_l2fib_add_del_t *mp;
7400   f64 timeout;
7401   u8 mac[6] = { 0 };
7402   u8 mac_set = 0;
7403   u32 bd_id;
7404   u8 bd_id_set = 0;
7405   u32 sw_if_index = 0;
7406   u8 sw_if_index_set = 0;
7407   u8 is_add = 1;
7408   u8 static_mac = 0;
7409   u8 filter_mac = 0;
7410   u8 bvi_mac = 0;
7411   int count = 1;
7412   f64 before = 0;
7413   int j;
7414
7415   /* Parse args required to build the message */
7416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7417     {
7418       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7419         mac_set = 1;
7420       else if (unformat (i, "bd_id %d", &bd_id))
7421         bd_id_set = 1;
7422       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7423         sw_if_index_set = 1;
7424       else if (unformat (i, "sw_if"))
7425         {
7426           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7427             {
7428               if (unformat
7429                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7430                 sw_if_index_set = 1;
7431             }
7432           else
7433             break;
7434         }
7435       else if (unformat (i, "static"))
7436         static_mac = 1;
7437       else if (unformat (i, "filter"))
7438         {
7439           filter_mac = 1;
7440           static_mac = 1;
7441         }
7442       else if (unformat (i, "bvi"))
7443         {
7444           bvi_mac = 1;
7445           static_mac = 1;
7446         }
7447       else if (unformat (i, "del"))
7448         is_add = 0;
7449       else if (unformat (i, "count %d", &count))
7450         ;
7451       else
7452         break;
7453     }
7454
7455   if (mac_set == 0)
7456     {
7457       errmsg ("missing mac address");
7458       return -99;
7459     }
7460
7461   if (bd_id_set == 0)
7462     {
7463       errmsg ("missing bridge domain");
7464       return -99;
7465     }
7466
7467   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7468     {
7469       errmsg ("missing interface name or sw_if_index");
7470       return -99;
7471     }
7472
7473   if (count > 1)
7474     {
7475       /* Turn on async mode */
7476       vam->async_mode = 1;
7477       vam->async_errors = 0;
7478       before = vat_time_now (vam);
7479     }
7480
7481   for (j = 0; j < count; j++)
7482     {
7483       M (L2FIB_ADD_DEL, mp);
7484
7485       clib_memcpy (mp->mac, mac, 6);
7486       mp->bd_id = ntohl (bd_id);
7487       mp->is_add = is_add;
7488       mp->sw_if_index = ntohl (sw_if_index);
7489
7490       if (is_add)
7491         {
7492           mp->static_mac = static_mac;
7493           mp->filter_mac = filter_mac;
7494           mp->bvi_mac = bvi_mac;
7495         }
7496       increment_mac_address (mac);
7497       /* send it... */
7498       S (mp);
7499     }
7500
7501   if (count > 1)
7502     {
7503       vl_api_control_ping_t *mp_ping;
7504       f64 after;
7505
7506       /* Shut off async mode */
7507       vam->async_mode = 0;
7508
7509       MPING (CONTROL_PING, mp_ping);
7510       S (mp_ping);
7511
7512       timeout = vat_time_now (vam) + 1.0;
7513       while (vat_time_now (vam) < timeout)
7514         if (vam->result_ready == 1)
7515           goto out;
7516       vam->retval = -99;
7517
7518     out:
7519       if (vam->retval == -99)
7520         errmsg ("timeout");
7521
7522       if (vam->async_errors > 0)
7523         {
7524           errmsg ("%d asynchronous errors", vam->async_errors);
7525           vam->retval = -98;
7526         }
7527       vam->async_errors = 0;
7528       after = vat_time_now (vam);
7529
7530       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7531              count, after - before, count / (after - before));
7532     }
7533   else
7534     {
7535       int ret;
7536
7537       /* Wait for a reply... */
7538       W (ret);
7539       return ret;
7540     }
7541   /* Return the good/bad news */
7542   return (vam->retval);
7543 }
7544
7545 static int
7546 api_bridge_domain_set_mac_age (vat_main_t * vam)
7547 {
7548   unformat_input_t *i = vam->input;
7549   vl_api_bridge_domain_set_mac_age_t *mp;
7550   u32 bd_id = ~0;
7551   u32 mac_age = 0;
7552   int ret;
7553
7554   /* Parse args required to build the message */
7555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7556     {
7557       if (unformat (i, "bd_id %d", &bd_id));
7558       else if (unformat (i, "mac-age %d", &mac_age));
7559       else
7560         break;
7561     }
7562
7563   if (bd_id == ~0)
7564     {
7565       errmsg ("missing bridge domain");
7566       return -99;
7567     }
7568
7569   if (mac_age > 255)
7570     {
7571       errmsg ("mac age must be less than 256 ");
7572       return -99;
7573     }
7574
7575   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7576
7577   mp->bd_id = htonl (bd_id);
7578   mp->mac_age = (u8) mac_age;
7579
7580   S (mp);
7581   W (ret);
7582   return ret;
7583 }
7584
7585 static int
7586 api_l2_flags (vat_main_t * vam)
7587 {
7588   unformat_input_t *i = vam->input;
7589   vl_api_l2_flags_t *mp;
7590   u32 sw_if_index;
7591   u32 flags = 0;
7592   u8 sw_if_index_set = 0;
7593   u8 is_set = 0;
7594   int ret;
7595
7596   /* Parse args required to build the message */
7597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7598     {
7599       if (unformat (i, "sw_if_index %d", &sw_if_index))
7600         sw_if_index_set = 1;
7601       else if (unformat (i, "sw_if"))
7602         {
7603           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7604             {
7605               if (unformat
7606                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7607                 sw_if_index_set = 1;
7608             }
7609           else
7610             break;
7611         }
7612       else if (unformat (i, "learn"))
7613         flags |= L2_LEARN;
7614       else if (unformat (i, "forward"))
7615         flags |= L2_FWD;
7616       else if (unformat (i, "flood"))
7617         flags |= L2_FLOOD;
7618       else if (unformat (i, "uu-flood"))
7619         flags |= L2_UU_FLOOD;
7620       else if (unformat (i, "arp-term"))
7621         flags |= L2_ARP_TERM;
7622       else if (unformat (i, "off"))
7623         is_set = 0;
7624       else if (unformat (i, "disable"))
7625         is_set = 0;
7626       else
7627         break;
7628     }
7629
7630   if (sw_if_index_set == 0)
7631     {
7632       errmsg ("missing interface name or sw_if_index");
7633       return -99;
7634     }
7635
7636   M (L2_FLAGS, mp);
7637
7638   mp->sw_if_index = ntohl (sw_if_index);
7639   mp->feature_bitmap = ntohl (flags);
7640   mp->is_set = is_set;
7641
7642   S (mp);
7643   W (ret);
7644   return ret;
7645 }
7646
7647 static int
7648 api_bridge_flags (vat_main_t * vam)
7649 {
7650   unformat_input_t *i = vam->input;
7651   vl_api_bridge_flags_t *mp;
7652   u32 bd_id;
7653   u8 bd_id_set = 0;
7654   u8 is_set = 1;
7655   u32 flags = 0;
7656   int ret;
7657
7658   /* Parse args required to build the message */
7659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7660     {
7661       if (unformat (i, "bd_id %d", &bd_id))
7662         bd_id_set = 1;
7663       else if (unformat (i, "learn"))
7664         flags |= L2_LEARN;
7665       else if (unformat (i, "forward"))
7666         flags |= L2_FWD;
7667       else if (unformat (i, "flood"))
7668         flags |= L2_FLOOD;
7669       else if (unformat (i, "uu-flood"))
7670         flags |= L2_UU_FLOOD;
7671       else if (unformat (i, "arp-term"))
7672         flags |= L2_ARP_TERM;
7673       else if (unformat (i, "off"))
7674         is_set = 0;
7675       else if (unformat (i, "disable"))
7676         is_set = 0;
7677       else
7678         break;
7679     }
7680
7681   if (bd_id_set == 0)
7682     {
7683       errmsg ("missing bridge domain");
7684       return -99;
7685     }
7686
7687   M (BRIDGE_FLAGS, mp);
7688
7689   mp->bd_id = ntohl (bd_id);
7690   mp->feature_bitmap = ntohl (flags);
7691   mp->is_set = is_set;
7692
7693   S (mp);
7694   W (ret);
7695   return ret;
7696 }
7697
7698 static int
7699 api_bd_ip_mac_add_del (vat_main_t * vam)
7700 {
7701   unformat_input_t *i = vam->input;
7702   vl_api_bd_ip_mac_add_del_t *mp;
7703   u32 bd_id;
7704   u8 is_ipv6 = 0;
7705   u8 is_add = 1;
7706   u8 bd_id_set = 0;
7707   u8 ip_set = 0;
7708   u8 mac_set = 0;
7709   ip4_address_t v4addr;
7710   ip6_address_t v6addr;
7711   u8 macaddr[6];
7712   int ret;
7713
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "bd_id %d", &bd_id))
7719         {
7720           bd_id_set++;
7721         }
7722       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7723         {
7724           ip_set++;
7725         }
7726       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7727         {
7728           ip_set++;
7729           is_ipv6++;
7730         }
7731       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7732         {
7733           mac_set++;
7734         }
7735       else if (unformat (i, "del"))
7736         is_add = 0;
7737       else
7738         break;
7739     }
7740
7741   if (bd_id_set == 0)
7742     {
7743       errmsg ("missing bridge domain");
7744       return -99;
7745     }
7746   else if (ip_set == 0)
7747     {
7748       errmsg ("missing IP address");
7749       return -99;
7750     }
7751   else if (mac_set == 0)
7752     {
7753       errmsg ("missing MAC address");
7754       return -99;
7755     }
7756
7757   M (BD_IP_MAC_ADD_DEL, mp);
7758
7759   mp->bd_id = ntohl (bd_id);
7760   mp->is_ipv6 = is_ipv6;
7761   mp->is_add = is_add;
7762   if (is_ipv6)
7763     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7764   else
7765     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7766   clib_memcpy (mp->mac_address, macaddr, 6);
7767   S (mp);
7768   W (ret);
7769   return ret;
7770 }
7771
7772 static int
7773 api_tap_connect (vat_main_t * vam)
7774 {
7775   unformat_input_t *i = vam->input;
7776   vl_api_tap_connect_t *mp;
7777   u8 mac_address[6];
7778   u8 random_mac = 1;
7779   u8 name_set = 0;
7780   u8 *tap_name;
7781   u8 *tag = 0;
7782   ip4_address_t ip4_address;
7783   u32 ip4_mask_width;
7784   int ip4_address_set = 0;
7785   ip6_address_t ip6_address;
7786   u32 ip6_mask_width;
7787   int ip6_address_set = 0;
7788   int ret;
7789
7790   memset (mac_address, 0, sizeof (mac_address));
7791
7792   /* Parse args required to build the message */
7793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7794     {
7795       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7796         {
7797           random_mac = 0;
7798         }
7799       else if (unformat (i, "random-mac"))
7800         random_mac = 1;
7801       else if (unformat (i, "tapname %s", &tap_name))
7802         name_set = 1;
7803       else if (unformat (i, "tag %s", &tag))
7804         ;
7805       else if (unformat (i, "address %U/%d",
7806                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7807         ip4_address_set = 1;
7808       else if (unformat (i, "address %U/%d",
7809                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7810         ip6_address_set = 1;
7811       else
7812         break;
7813     }
7814
7815   if (name_set == 0)
7816     {
7817       errmsg ("missing tap name");
7818       return -99;
7819     }
7820   if (vec_len (tap_name) > 63)
7821     {
7822       errmsg ("tap name too long");
7823       return -99;
7824     }
7825   vec_add1 (tap_name, 0);
7826
7827   if (vec_len (tag) > 63)
7828     {
7829       errmsg ("tag too long");
7830       return -99;
7831     }
7832
7833   /* Construct the API message */
7834   M (TAP_CONNECT, mp);
7835
7836   mp->use_random_mac = random_mac;
7837   clib_memcpy (mp->mac_address, mac_address, 6);
7838   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7839   if (tag)
7840     clib_memcpy (mp->tag, tag, vec_len (tag));
7841
7842   if (ip4_address_set)
7843     {
7844       mp->ip4_address_set = 1;
7845       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7846       mp->ip4_mask_width = ip4_mask_width;
7847     }
7848   if (ip6_address_set)
7849     {
7850       mp->ip6_address_set = 1;
7851       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7852       mp->ip6_mask_width = ip6_mask_width;
7853     }
7854
7855   vec_free (tap_name);
7856   vec_free (tag);
7857
7858   /* send it... */
7859   S (mp);
7860
7861   /* Wait for a reply... */
7862   W (ret);
7863   return ret;
7864 }
7865
7866 static int
7867 api_tap_modify (vat_main_t * vam)
7868 {
7869   unformat_input_t *i = vam->input;
7870   vl_api_tap_modify_t *mp;
7871   u8 mac_address[6];
7872   u8 random_mac = 1;
7873   u8 name_set = 0;
7874   u8 *tap_name;
7875   u32 sw_if_index = ~0;
7876   u8 sw_if_index_set = 0;
7877   int ret;
7878
7879   memset (mac_address, 0, sizeof (mac_address));
7880
7881   /* Parse args required to build the message */
7882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7883     {
7884       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7885         sw_if_index_set = 1;
7886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7887         sw_if_index_set = 1;
7888       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7889         {
7890           random_mac = 0;
7891         }
7892       else if (unformat (i, "random-mac"))
7893         random_mac = 1;
7894       else if (unformat (i, "tapname %s", &tap_name))
7895         name_set = 1;
7896       else
7897         break;
7898     }
7899
7900   if (sw_if_index_set == 0)
7901     {
7902       errmsg ("missing vpp interface name");
7903       return -99;
7904     }
7905   if (name_set == 0)
7906     {
7907       errmsg ("missing tap name");
7908       return -99;
7909     }
7910   if (vec_len (tap_name) > 63)
7911     {
7912       errmsg ("tap name too long");
7913     }
7914   vec_add1 (tap_name, 0);
7915
7916   /* Construct the API message */
7917   M (TAP_MODIFY, mp);
7918
7919   mp->use_random_mac = random_mac;
7920   mp->sw_if_index = ntohl (sw_if_index);
7921   clib_memcpy (mp->mac_address, mac_address, 6);
7922   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7923   vec_free (tap_name);
7924
7925   /* send it... */
7926   S (mp);
7927
7928   /* Wait for a reply... */
7929   W (ret);
7930   return ret;
7931 }
7932
7933 static int
7934 api_tap_delete (vat_main_t * vam)
7935 {
7936   unformat_input_t *i = vam->input;
7937   vl_api_tap_delete_t *mp;
7938   u32 sw_if_index = ~0;
7939   u8 sw_if_index_set = 0;
7940   int ret;
7941
7942   /* Parse args required to build the message */
7943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7944     {
7945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7946         sw_if_index_set = 1;
7947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7948         sw_if_index_set = 1;
7949       else
7950         break;
7951     }
7952
7953   if (sw_if_index_set == 0)
7954     {
7955       errmsg ("missing vpp interface name");
7956       return -99;
7957     }
7958
7959   /* Construct the API message */
7960   M (TAP_DELETE, mp);
7961
7962   mp->sw_if_index = ntohl (sw_if_index);
7963
7964   /* send it... */
7965   S (mp);
7966
7967   /* Wait for a reply... */
7968   W (ret);
7969   return ret;
7970 }
7971
7972 static int
7973 api_tap_create_v2 (vat_main_t * vam)
7974 {
7975   unformat_input_t *i = vam->input;
7976   vl_api_tap_create_v2_t *mp;
7977   u8 mac_address[6];
7978   u8 random_mac = 1;
7979   u32 id = ~0;
7980   u8 *host_if_name = 0;
7981   u8 *host_ns = 0;
7982   u8 host_mac_addr[6];
7983   u8 host_mac_addr_set = 0;
7984   u8 *host_bridge = 0;
7985   ip4_address_t host_ip4_addr;
7986   ip4_address_t host_ip4_gw;
7987   u8 host_ip4_gw_set = 0;
7988   u32 host_ip4_prefix_len = 0;
7989   ip6_address_t host_ip6_addr;
7990   ip6_address_t host_ip6_gw;
7991   u8 host_ip6_gw_set = 0;
7992   u32 host_ip6_prefix_len = 0;
7993   int ret;
7994   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7995
7996   memset (mac_address, 0, sizeof (mac_address));
7997
7998   /* Parse args required to build the message */
7999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8000     {
8001       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8002         {
8003           random_mac = 0;
8004         }
8005       else if (unformat (i, "id %u", &id))
8006         ;
8007       else if (unformat (i, "host-if-name %s", &host_if_name))
8008         ;
8009       else if (unformat (i, "host-ns %s", &host_ns))
8010         ;
8011       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8012                          host_mac_addr))
8013         host_mac_addr_set = 1;
8014       else if (unformat (i, "host-bridge %s", &host_bridge))
8015         ;
8016       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8017                          &host_ip4_addr, &host_ip4_prefix_len))
8018         ;
8019       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8020                          &host_ip6_addr, &host_ip6_prefix_len))
8021         ;
8022       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8023                          &host_ip4_gw))
8024         host_ip4_gw_set = 1;
8025       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8026                          &host_ip6_gw))
8027         host_ip6_gw_set = 1;
8028       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8029         ;
8030       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8031         ;
8032       else
8033         break;
8034     }
8035
8036   if (vec_len (host_if_name) > 63)
8037     {
8038       errmsg ("tap name too long. ");
8039       return -99;
8040     }
8041   if (vec_len (host_ns) > 63)
8042     {
8043       errmsg ("host name space too long. ");
8044       return -99;
8045     }
8046   if (vec_len (host_bridge) > 63)
8047     {
8048       errmsg ("host bridge name too long. ");
8049       return -99;
8050     }
8051   if (host_ip4_prefix_len > 32)
8052     {
8053       errmsg ("host ip4 prefix length not valid. ");
8054       return -99;
8055     }
8056   if (host_ip6_prefix_len > 128)
8057     {
8058       errmsg ("host ip6 prefix length not valid. ");
8059       return -99;
8060     }
8061   if (!is_pow2 (rx_ring_sz))
8062     {
8063       errmsg ("rx ring size must be power of 2. ");
8064       return -99;
8065     }
8066   if (rx_ring_sz > 32768)
8067     {
8068       errmsg ("rx ring size must be 32768 or lower. ");
8069       return -99;
8070     }
8071   if (!is_pow2 (tx_ring_sz))
8072     {
8073       errmsg ("tx ring size must be power of 2. ");
8074       return -99;
8075     }
8076   if (tx_ring_sz > 32768)
8077     {
8078       errmsg ("tx ring size must be 32768 or lower. ");
8079       return -99;
8080     }
8081
8082   /* Construct the API message */
8083   M (TAP_CREATE_V2, mp);
8084
8085   mp->use_random_mac = random_mac;
8086
8087   mp->id = ntohl (id);
8088   mp->host_namespace_set = host_ns != 0;
8089   mp->host_bridge_set = host_bridge != 0;
8090   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8091   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8092   mp->rx_ring_sz = ntohs (rx_ring_sz);
8093   mp->tx_ring_sz = ntohs (tx_ring_sz);
8094
8095   if (random_mac == 0)
8096     clib_memcpy (mp->mac_address, mac_address, 6);
8097   if (host_mac_addr_set)
8098     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8099   if (host_if_name)
8100     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8101   if (host_ns)
8102     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8103   if (host_bridge)
8104     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8105   if (host_ip4_prefix_len)
8106     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8107   if (host_ip4_prefix_len)
8108     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8109   if (host_ip4_gw_set)
8110     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8111   if (host_ip6_gw_set)
8112     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8113
8114   vec_free (host_ns);
8115   vec_free (host_if_name);
8116   vec_free (host_bridge);
8117
8118   /* send it... */
8119   S (mp);
8120
8121   /* Wait for a reply... */
8122   W (ret);
8123   return ret;
8124 }
8125
8126 static int
8127 api_tap_delete_v2 (vat_main_t * vam)
8128 {
8129   unformat_input_t *i = vam->input;
8130   vl_api_tap_delete_v2_t *mp;
8131   u32 sw_if_index = ~0;
8132   u8 sw_if_index_set = 0;
8133   int ret;
8134
8135   /* Parse args required to build the message */
8136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8137     {
8138       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8139         sw_if_index_set = 1;
8140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8141         sw_if_index_set = 1;
8142       else
8143         break;
8144     }
8145
8146   if (sw_if_index_set == 0)
8147     {
8148       errmsg ("missing vpp interface name. ");
8149       return -99;
8150     }
8151
8152   /* Construct the API message */
8153   M (TAP_DELETE_V2, mp);
8154
8155   mp->sw_if_index = ntohl (sw_if_index);
8156
8157   /* send it... */
8158   S (mp);
8159
8160   /* Wait for a reply... */
8161   W (ret);
8162   return ret;
8163 }
8164
8165 static int
8166 api_bond_create (vat_main_t * vam)
8167 {
8168   unformat_input_t *i = vam->input;
8169   vl_api_bond_create_t *mp;
8170   u8 mac_address[6];
8171   u8 custom_mac = 0;
8172   int ret;
8173   u8 mode;
8174   u8 lb;
8175   u8 mode_is_set = 0;
8176
8177   memset (mac_address, 0, sizeof (mac_address));
8178   lb = BOND_LB_L2;
8179
8180   /* Parse args required to build the message */
8181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8182     {
8183       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8184         mode_is_set = 1;
8185       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8186                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8187         ;
8188       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8189                          mac_address))
8190         custom_mac = 1;
8191       else
8192         break;
8193     }
8194
8195   if (mode_is_set == 0)
8196     {
8197       errmsg ("Missing bond mode. ");
8198       return -99;
8199     }
8200
8201   /* Construct the API message */
8202   M (BOND_CREATE, mp);
8203
8204   mp->use_custom_mac = custom_mac;
8205
8206   mp->mode = mode;
8207   mp->lb = lb;
8208
8209   if (custom_mac)
8210     clib_memcpy (mp->mac_address, mac_address, 6);
8211
8212   /* send it... */
8213   S (mp);
8214
8215   /* Wait for a reply... */
8216   W (ret);
8217   return ret;
8218 }
8219
8220 static int
8221 api_bond_delete (vat_main_t * vam)
8222 {
8223   unformat_input_t *i = vam->input;
8224   vl_api_bond_delete_t *mp;
8225   u32 sw_if_index = ~0;
8226   u8 sw_if_index_set = 0;
8227   int ret;
8228
8229   /* Parse args required to build the message */
8230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8231     {
8232       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8233         sw_if_index_set = 1;
8234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8235         sw_if_index_set = 1;
8236       else
8237         break;
8238     }
8239
8240   if (sw_if_index_set == 0)
8241     {
8242       errmsg ("missing vpp interface name. ");
8243       return -99;
8244     }
8245
8246   /* Construct the API message */
8247   M (BOND_DELETE, mp);
8248
8249   mp->sw_if_index = ntohl (sw_if_index);
8250
8251   /* send it... */
8252   S (mp);
8253
8254   /* Wait for a reply... */
8255   W (ret);
8256   return ret;
8257 }
8258
8259 static int
8260 api_bond_enslave (vat_main_t * vam)
8261 {
8262   unformat_input_t *i = vam->input;
8263   vl_api_bond_enslave_t *mp;
8264   u32 bond_sw_if_index;
8265   int ret;
8266   u8 is_passive;
8267   u8 is_long_timeout;
8268   u32 bond_sw_if_index_is_set = 0;
8269   u32 sw_if_index;
8270   u8 sw_if_index_is_set = 0;
8271
8272   /* Parse args required to build the message */
8273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8274     {
8275       if (unformat (i, "sw_if_index %d", &sw_if_index))
8276         sw_if_index_is_set = 1;
8277       else if (unformat (i, "bond %u", &bond_sw_if_index))
8278         bond_sw_if_index_is_set = 1;
8279       else if (unformat (i, "passive %d", &is_passive))
8280         ;
8281       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8282         ;
8283       else
8284         break;
8285     }
8286
8287   if (bond_sw_if_index_is_set == 0)
8288     {
8289       errmsg ("Missing bond sw_if_index. ");
8290       return -99;
8291     }
8292   if (sw_if_index_is_set == 0)
8293     {
8294       errmsg ("Missing slave sw_if_index. ");
8295       return -99;
8296     }
8297
8298   /* Construct the API message */
8299   M (BOND_ENSLAVE, mp);
8300
8301   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8302   mp->sw_if_index = ntohl (sw_if_index);
8303   mp->is_long_timeout = is_long_timeout;
8304   mp->is_passive = is_passive;
8305
8306   /* send it... */
8307   S (mp);
8308
8309   /* Wait for a reply... */
8310   W (ret);
8311   return ret;
8312 }
8313
8314 static int
8315 api_bond_detach_slave (vat_main_t * vam)
8316 {
8317   unformat_input_t *i = vam->input;
8318   vl_api_bond_detach_slave_t *mp;
8319   u32 sw_if_index = ~0;
8320   u8 sw_if_index_set = 0;
8321   int ret;
8322
8323   /* Parse args required to build the message */
8324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8325     {
8326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8327         sw_if_index_set = 1;
8328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8329         sw_if_index_set = 1;
8330       else
8331         break;
8332     }
8333
8334   if (sw_if_index_set == 0)
8335     {
8336       errmsg ("missing vpp interface name. ");
8337       return -99;
8338     }
8339
8340   /* Construct the API message */
8341   M (BOND_DETACH_SLAVE, mp);
8342
8343   mp->sw_if_index = ntohl (sw_if_index);
8344
8345   /* send it... */
8346   S (mp);
8347
8348   /* Wait for a reply... */
8349   W (ret);
8350   return ret;
8351 }
8352
8353 static int
8354 api_ip_table_add_del (vat_main_t * vam)
8355 {
8356   unformat_input_t *i = vam->input;
8357   vl_api_ip_table_add_del_t *mp;
8358   u32 table_id = ~0;
8359   u8 is_ipv6 = 0;
8360   u8 is_add = 1;
8361   int ret = 0;
8362
8363   /* Parse args required to build the message */
8364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8365     {
8366       if (unformat (i, "ipv6"))
8367         is_ipv6 = 1;
8368       else if (unformat (i, "del"))
8369         is_add = 0;
8370       else if (unformat (i, "add"))
8371         is_add = 1;
8372       else if (unformat (i, "table %d", &table_id))
8373         ;
8374       else
8375         {
8376           clib_warning ("parse error '%U'", format_unformat_error, i);
8377           return -99;
8378         }
8379     }
8380
8381   if (~0 == table_id)
8382     {
8383       errmsg ("missing table-ID");
8384       return -99;
8385     }
8386
8387   /* Construct the API message */
8388   M (IP_TABLE_ADD_DEL, mp);
8389
8390   mp->table_id = ntohl (table_id);
8391   mp->is_ipv6 = is_ipv6;
8392   mp->is_add = is_add;
8393
8394   /* send it... */
8395   S (mp);
8396
8397   /* Wait for a reply... */
8398   W (ret);
8399
8400   return ret;
8401 }
8402
8403 static int
8404 api_ip_add_del_route (vat_main_t * vam)
8405 {
8406   unformat_input_t *i = vam->input;
8407   vl_api_ip_add_del_route_t *mp;
8408   u32 sw_if_index = ~0, vrf_id = 0;
8409   u8 is_ipv6 = 0;
8410   u8 is_local = 0, is_drop = 0;
8411   u8 is_unreach = 0, is_prohibit = 0;
8412   u8 is_add = 1;
8413   u32 next_hop_weight = 1;
8414   u8 is_multipath = 0;
8415   u8 address_set = 0;
8416   u8 address_length_set = 0;
8417   u32 next_hop_table_id = 0;
8418   u32 resolve_attempts = 0;
8419   u32 dst_address_length = 0;
8420   u8 next_hop_set = 0;
8421   ip4_address_t v4_dst_address, v4_next_hop_address;
8422   ip6_address_t v6_dst_address, v6_next_hop_address;
8423   int count = 1;
8424   int j;
8425   f64 before = 0;
8426   u32 random_add_del = 0;
8427   u32 *random_vector = 0;
8428   uword *random_hash;
8429   u32 random_seed = 0xdeaddabe;
8430   u32 classify_table_index = ~0;
8431   u8 is_classify = 0;
8432   u8 resolve_host = 0, resolve_attached = 0;
8433   mpls_label_t *next_hop_out_label_stack = NULL;
8434   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8435   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8436
8437   /* Parse args required to build the message */
8438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8439     {
8440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8441         ;
8442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8443         ;
8444       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8445         {
8446           address_set = 1;
8447           is_ipv6 = 0;
8448         }
8449       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8450         {
8451           address_set = 1;
8452           is_ipv6 = 1;
8453         }
8454       else if (unformat (i, "/%d", &dst_address_length))
8455         {
8456           address_length_set = 1;
8457         }
8458
8459       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8460                                          &v4_next_hop_address))
8461         {
8462           next_hop_set = 1;
8463         }
8464       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8465                                          &v6_next_hop_address))
8466         {
8467           next_hop_set = 1;
8468         }
8469       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8470         ;
8471       else if (unformat (i, "weight %d", &next_hop_weight))
8472         ;
8473       else if (unformat (i, "drop"))
8474         {
8475           is_drop = 1;
8476         }
8477       else if (unformat (i, "null-send-unreach"))
8478         {
8479           is_unreach = 1;
8480         }
8481       else if (unformat (i, "null-send-prohibit"))
8482         {
8483           is_prohibit = 1;
8484         }
8485       else if (unformat (i, "local"))
8486         {
8487           is_local = 1;
8488         }
8489       else if (unformat (i, "classify %d", &classify_table_index))
8490         {
8491           is_classify = 1;
8492         }
8493       else if (unformat (i, "del"))
8494         is_add = 0;
8495       else if (unformat (i, "add"))
8496         is_add = 1;
8497       else if (unformat (i, "resolve-via-host"))
8498         resolve_host = 1;
8499       else if (unformat (i, "resolve-via-attached"))
8500         resolve_attached = 1;
8501       else if (unformat (i, "multipath"))
8502         is_multipath = 1;
8503       else if (unformat (i, "vrf %d", &vrf_id))
8504         ;
8505       else if (unformat (i, "count %d", &count))
8506         ;
8507       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8508         ;
8509       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8510         ;
8511       else if (unformat (i, "out-label %d", &next_hop_out_label))
8512         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8513       else if (unformat (i, "via-label %d", &next_hop_via_label))
8514         ;
8515       else if (unformat (i, "random"))
8516         random_add_del = 1;
8517       else if (unformat (i, "seed %d", &random_seed))
8518         ;
8519       else
8520         {
8521           clib_warning ("parse error '%U'", format_unformat_error, i);
8522           return -99;
8523         }
8524     }
8525
8526   if (!next_hop_set && !is_drop && !is_local &&
8527       !is_classify && !is_unreach && !is_prohibit &&
8528       MPLS_LABEL_INVALID == next_hop_via_label)
8529     {
8530       errmsg
8531         ("next hop / local / drop / unreach / prohibit / classify not set");
8532       return -99;
8533     }
8534
8535   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8536     {
8537       errmsg ("next hop and next-hop via label set");
8538       return -99;
8539     }
8540   if (address_set == 0)
8541     {
8542       errmsg ("missing addresses");
8543       return -99;
8544     }
8545
8546   if (address_length_set == 0)
8547     {
8548       errmsg ("missing address length");
8549       return -99;
8550     }
8551
8552   /* Generate a pile of unique, random routes */
8553   if (random_add_del)
8554     {
8555       u32 this_random_address;
8556       random_hash = hash_create (count, sizeof (uword));
8557
8558       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8559       for (j = 0; j <= count; j++)
8560         {
8561           do
8562             {
8563               this_random_address = random_u32 (&random_seed);
8564               this_random_address =
8565                 clib_host_to_net_u32 (this_random_address);
8566             }
8567           while (hash_get (random_hash, this_random_address));
8568           vec_add1 (random_vector, this_random_address);
8569           hash_set (random_hash, this_random_address, 1);
8570         }
8571       hash_free (random_hash);
8572       v4_dst_address.as_u32 = random_vector[0];
8573     }
8574
8575   if (count > 1)
8576     {
8577       /* Turn on async mode */
8578       vam->async_mode = 1;
8579       vam->async_errors = 0;
8580       before = vat_time_now (vam);
8581     }
8582
8583   for (j = 0; j < count; j++)
8584     {
8585       /* Construct the API message */
8586       M2 (IP_ADD_DEL_ROUTE, mp,
8587           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8588
8589       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8590       mp->table_id = ntohl (vrf_id);
8591
8592       mp->is_add = is_add;
8593       mp->is_drop = is_drop;
8594       mp->is_unreach = is_unreach;
8595       mp->is_prohibit = is_prohibit;
8596       mp->is_ipv6 = is_ipv6;
8597       mp->is_local = is_local;
8598       mp->is_classify = is_classify;
8599       mp->is_multipath = is_multipath;
8600       mp->is_resolve_host = resolve_host;
8601       mp->is_resolve_attached = resolve_attached;
8602       mp->next_hop_weight = next_hop_weight;
8603       mp->dst_address_length = dst_address_length;
8604       mp->next_hop_table_id = ntohl (next_hop_table_id);
8605       mp->classify_table_index = ntohl (classify_table_index);
8606       mp->next_hop_via_label = ntohl (next_hop_via_label);
8607       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8608       if (0 != mp->next_hop_n_out_labels)
8609         {
8610           memcpy (mp->next_hop_out_label_stack,
8611                   next_hop_out_label_stack,
8612                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8613           vec_free (next_hop_out_label_stack);
8614         }
8615
8616       if (is_ipv6)
8617         {
8618           clib_memcpy (mp->dst_address, &v6_dst_address,
8619                        sizeof (v6_dst_address));
8620           if (next_hop_set)
8621             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8622                          sizeof (v6_next_hop_address));
8623           increment_v6_address (&v6_dst_address);
8624         }
8625       else
8626         {
8627           clib_memcpy (mp->dst_address, &v4_dst_address,
8628                        sizeof (v4_dst_address));
8629           if (next_hop_set)
8630             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8631                          sizeof (v4_next_hop_address));
8632           if (random_add_del)
8633             v4_dst_address.as_u32 = random_vector[j + 1];
8634           else
8635             increment_v4_address (&v4_dst_address);
8636         }
8637       /* send it... */
8638       S (mp);
8639       /* If we receive SIGTERM, stop now... */
8640       if (vam->do_exit)
8641         break;
8642     }
8643
8644   /* When testing multiple add/del ops, use a control-ping to sync */
8645   if (count > 1)
8646     {
8647       vl_api_control_ping_t *mp_ping;
8648       f64 after;
8649       f64 timeout;
8650
8651       /* Shut off async mode */
8652       vam->async_mode = 0;
8653
8654       MPING (CONTROL_PING, mp_ping);
8655       S (mp_ping);
8656
8657       timeout = vat_time_now (vam) + 1.0;
8658       while (vat_time_now (vam) < timeout)
8659         if (vam->result_ready == 1)
8660           goto out;
8661       vam->retval = -99;
8662
8663     out:
8664       if (vam->retval == -99)
8665         errmsg ("timeout");
8666
8667       if (vam->async_errors > 0)
8668         {
8669           errmsg ("%d asynchronous errors", vam->async_errors);
8670           vam->retval = -98;
8671         }
8672       vam->async_errors = 0;
8673       after = vat_time_now (vam);
8674
8675       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8676       if (j > 0)
8677         count = j;
8678
8679       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8680              count, after - before, count / (after - before));
8681     }
8682   else
8683     {
8684       int ret;
8685
8686       /* Wait for a reply... */
8687       W (ret);
8688       return ret;
8689     }
8690
8691   /* Return the good/bad news */
8692   return (vam->retval);
8693 }
8694
8695 static int
8696 api_ip_mroute_add_del (vat_main_t * vam)
8697 {
8698   unformat_input_t *i = vam->input;
8699   vl_api_ip_mroute_add_del_t *mp;
8700   u32 sw_if_index = ~0, vrf_id = 0;
8701   u8 is_ipv6 = 0;
8702   u8 is_local = 0;
8703   u8 is_add = 1;
8704   u8 address_set = 0;
8705   u32 grp_address_length = 0;
8706   ip4_address_t v4_grp_address, v4_src_address;
8707   ip6_address_t v6_grp_address, v6_src_address;
8708   mfib_itf_flags_t iflags = 0;
8709   mfib_entry_flags_t eflags = 0;
8710   int ret;
8711
8712   /* Parse args required to build the message */
8713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8714     {
8715       if (unformat (i, "sw_if_index %d", &sw_if_index))
8716         ;
8717       else if (unformat (i, "%U %U",
8718                          unformat_ip4_address, &v4_src_address,
8719                          unformat_ip4_address, &v4_grp_address))
8720         {
8721           grp_address_length = 64;
8722           address_set = 1;
8723           is_ipv6 = 0;
8724         }
8725       else if (unformat (i, "%U %U",
8726                          unformat_ip6_address, &v6_src_address,
8727                          unformat_ip6_address, &v6_grp_address))
8728         {
8729           grp_address_length = 256;
8730           address_set = 1;
8731           is_ipv6 = 1;
8732         }
8733       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8734         {
8735           memset (&v4_src_address, 0, sizeof (v4_src_address));
8736           grp_address_length = 32;
8737           address_set = 1;
8738           is_ipv6 = 0;
8739         }
8740       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8741         {
8742           memset (&v6_src_address, 0, sizeof (v6_src_address));
8743           grp_address_length = 128;
8744           address_set = 1;
8745           is_ipv6 = 1;
8746         }
8747       else if (unformat (i, "/%d", &grp_address_length))
8748         ;
8749       else if (unformat (i, "local"))
8750         {
8751           is_local = 1;
8752         }
8753       else if (unformat (i, "del"))
8754         is_add = 0;
8755       else if (unformat (i, "add"))
8756         is_add = 1;
8757       else if (unformat (i, "vrf %d", &vrf_id))
8758         ;
8759       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8760         ;
8761       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8762         ;
8763       else
8764         {
8765           clib_warning ("parse error '%U'", format_unformat_error, i);
8766           return -99;
8767         }
8768     }
8769
8770   if (address_set == 0)
8771     {
8772       errmsg ("missing addresses\n");
8773       return -99;
8774     }
8775
8776   /* Construct the API message */
8777   M (IP_MROUTE_ADD_DEL, mp);
8778
8779   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8780   mp->table_id = ntohl (vrf_id);
8781
8782   mp->is_add = is_add;
8783   mp->is_ipv6 = is_ipv6;
8784   mp->is_local = is_local;
8785   mp->itf_flags = ntohl (iflags);
8786   mp->entry_flags = ntohl (eflags);
8787   mp->grp_address_length = grp_address_length;
8788   mp->grp_address_length = ntohs (mp->grp_address_length);
8789
8790   if (is_ipv6)
8791     {
8792       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8793       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8794     }
8795   else
8796     {
8797       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8798       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8799
8800     }
8801
8802   /* send it... */
8803   S (mp);
8804   /* Wait for a reply... */
8805   W (ret);
8806   return ret;
8807 }
8808
8809 static int
8810 api_mpls_table_add_del (vat_main_t * vam)
8811 {
8812   unformat_input_t *i = vam->input;
8813   vl_api_mpls_table_add_del_t *mp;
8814   u32 table_id = ~0;
8815   u8 is_add = 1;
8816   int ret = 0;
8817
8818   /* Parse args required to build the message */
8819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8820     {
8821       if (unformat (i, "table %d", &table_id))
8822         ;
8823       else if (unformat (i, "del"))
8824         is_add = 0;
8825       else if (unformat (i, "add"))
8826         is_add = 1;
8827       else
8828         {
8829           clib_warning ("parse error '%U'", format_unformat_error, i);
8830           return -99;
8831         }
8832     }
8833
8834   if (~0 == table_id)
8835     {
8836       errmsg ("missing table-ID");
8837       return -99;
8838     }
8839
8840   /* Construct the API message */
8841   M (MPLS_TABLE_ADD_DEL, mp);
8842
8843   mp->mt_table_id = ntohl (table_id);
8844   mp->mt_is_add = is_add;
8845
8846   /* send it... */
8847   S (mp);
8848
8849   /* Wait for a reply... */
8850   W (ret);
8851
8852   return ret;
8853 }
8854
8855 static int
8856 api_mpls_route_add_del (vat_main_t * vam)
8857 {
8858   unformat_input_t *i = vam->input;
8859   vl_api_mpls_route_add_del_t *mp;
8860   u32 sw_if_index = ~0, table_id = 0;
8861   u8 is_add = 1;
8862   u32 next_hop_weight = 1;
8863   u8 is_multipath = 0;
8864   u32 next_hop_table_id = 0;
8865   u8 next_hop_set = 0;
8866   ip4_address_t v4_next_hop_address = {
8867     .as_u32 = 0,
8868   };
8869   ip6_address_t v6_next_hop_address = { {0} };
8870   int count = 1;
8871   int j;
8872   f64 before = 0;
8873   u32 classify_table_index = ~0;
8874   u8 is_classify = 0;
8875   u8 resolve_host = 0, resolve_attached = 0;
8876   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8877   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8878   mpls_label_t *next_hop_out_label_stack = NULL;
8879   mpls_label_t local_label = MPLS_LABEL_INVALID;
8880   u8 is_eos = 0;
8881   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8882
8883   /* Parse args required to build the message */
8884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8885     {
8886       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8887         ;
8888       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8889         ;
8890       else if (unformat (i, "%d", &local_label))
8891         ;
8892       else if (unformat (i, "eos"))
8893         is_eos = 1;
8894       else if (unformat (i, "non-eos"))
8895         is_eos = 0;
8896       else if (unformat (i, "via %U", unformat_ip4_address,
8897                          &v4_next_hop_address))
8898         {
8899           next_hop_set = 1;
8900           next_hop_proto = DPO_PROTO_IP4;
8901         }
8902       else if (unformat (i, "via %U", unformat_ip6_address,
8903                          &v6_next_hop_address))
8904         {
8905           next_hop_set = 1;
8906           next_hop_proto = DPO_PROTO_IP6;
8907         }
8908       else if (unformat (i, "weight %d", &next_hop_weight))
8909         ;
8910       else if (unformat (i, "classify %d", &classify_table_index))
8911         {
8912           is_classify = 1;
8913         }
8914       else if (unformat (i, "del"))
8915         is_add = 0;
8916       else if (unformat (i, "add"))
8917         is_add = 1;
8918       else if (unformat (i, "resolve-via-host"))
8919         resolve_host = 1;
8920       else if (unformat (i, "resolve-via-attached"))
8921         resolve_attached = 1;
8922       else if (unformat (i, "multipath"))
8923         is_multipath = 1;
8924       else if (unformat (i, "count %d", &count))
8925         ;
8926       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8927         {
8928           next_hop_set = 1;
8929           next_hop_proto = DPO_PROTO_IP4;
8930         }
8931       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8932         {
8933           next_hop_set = 1;
8934           next_hop_proto = DPO_PROTO_IP6;
8935         }
8936       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8937         ;
8938       else if (unformat (i, "via-label %d", &next_hop_via_label))
8939         ;
8940       else if (unformat (i, "out-label %d", &next_hop_out_label))
8941         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8942       else
8943         {
8944           clib_warning ("parse error '%U'", format_unformat_error, i);
8945           return -99;
8946         }
8947     }
8948
8949   if (!next_hop_set && !is_classify)
8950     {
8951       errmsg ("next hop / classify not set");
8952       return -99;
8953     }
8954
8955   if (MPLS_LABEL_INVALID == local_label)
8956     {
8957       errmsg ("missing label");
8958       return -99;
8959     }
8960
8961   if (count > 1)
8962     {
8963       /* Turn on async mode */
8964       vam->async_mode = 1;
8965       vam->async_errors = 0;
8966       before = vat_time_now (vam);
8967     }
8968
8969   for (j = 0; j < count; j++)
8970     {
8971       /* Construct the API message */
8972       M2 (MPLS_ROUTE_ADD_DEL, mp,
8973           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8974
8975       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8976       mp->mr_table_id = ntohl (table_id);
8977
8978       mp->mr_is_add = is_add;
8979       mp->mr_next_hop_proto = next_hop_proto;
8980       mp->mr_is_classify = is_classify;
8981       mp->mr_is_multipath = is_multipath;
8982       mp->mr_is_resolve_host = resolve_host;
8983       mp->mr_is_resolve_attached = resolve_attached;
8984       mp->mr_next_hop_weight = next_hop_weight;
8985       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8986       mp->mr_classify_table_index = ntohl (classify_table_index);
8987       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8988       mp->mr_label = ntohl (local_label);
8989       mp->mr_eos = is_eos;
8990
8991       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8992       if (0 != mp->mr_next_hop_n_out_labels)
8993         {
8994           memcpy (mp->mr_next_hop_out_label_stack,
8995                   next_hop_out_label_stack,
8996                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8997           vec_free (next_hop_out_label_stack);
8998         }
8999
9000       if (next_hop_set)
9001         {
9002           if (DPO_PROTO_IP4 == next_hop_proto)
9003             {
9004               clib_memcpy (mp->mr_next_hop,
9005                            &v4_next_hop_address,
9006                            sizeof (v4_next_hop_address));
9007             }
9008           else if (DPO_PROTO_IP6 == next_hop_proto)
9009
9010             {
9011               clib_memcpy (mp->mr_next_hop,
9012                            &v6_next_hop_address,
9013                            sizeof (v6_next_hop_address));
9014             }
9015         }
9016       local_label++;
9017
9018       /* send it... */
9019       S (mp);
9020       /* If we receive SIGTERM, stop now... */
9021       if (vam->do_exit)
9022         break;
9023     }
9024
9025   /* When testing multiple add/del ops, use a control-ping to sync */
9026   if (count > 1)
9027     {
9028       vl_api_control_ping_t *mp_ping;
9029       f64 after;
9030       f64 timeout;
9031
9032       /* Shut off async mode */
9033       vam->async_mode = 0;
9034
9035       MPING (CONTROL_PING, mp_ping);
9036       S (mp_ping);
9037
9038       timeout = vat_time_now (vam) + 1.0;
9039       while (vat_time_now (vam) < timeout)
9040         if (vam->result_ready == 1)
9041           goto out;
9042       vam->retval = -99;
9043
9044     out:
9045       if (vam->retval == -99)
9046         errmsg ("timeout");
9047
9048       if (vam->async_errors > 0)
9049         {
9050           errmsg ("%d asynchronous errors", vam->async_errors);
9051           vam->retval = -98;
9052         }
9053       vam->async_errors = 0;
9054       after = vat_time_now (vam);
9055
9056       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9057       if (j > 0)
9058         count = j;
9059
9060       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9061              count, after - before, count / (after - before));
9062     }
9063   else
9064     {
9065       int ret;
9066
9067       /* Wait for a reply... */
9068       W (ret);
9069       return ret;
9070     }
9071
9072   /* Return the good/bad news */
9073   return (vam->retval);
9074 }
9075
9076 static int
9077 api_mpls_ip_bind_unbind (vat_main_t * vam)
9078 {
9079   unformat_input_t *i = vam->input;
9080   vl_api_mpls_ip_bind_unbind_t *mp;
9081   u32 ip_table_id = 0;
9082   u8 is_bind = 1;
9083   u8 is_ip4 = 1;
9084   ip4_address_t v4_address;
9085   ip6_address_t v6_address;
9086   u32 address_length;
9087   u8 address_set = 0;
9088   mpls_label_t local_label = MPLS_LABEL_INVALID;
9089   int ret;
9090
9091   /* Parse args required to build the message */
9092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9093     {
9094       if (unformat (i, "%U/%d", unformat_ip4_address,
9095                     &v4_address, &address_length))
9096         {
9097           is_ip4 = 1;
9098           address_set = 1;
9099         }
9100       else if (unformat (i, "%U/%d", unformat_ip6_address,
9101                          &v6_address, &address_length))
9102         {
9103           is_ip4 = 0;
9104           address_set = 1;
9105         }
9106       else if (unformat (i, "%d", &local_label))
9107         ;
9108       else if (unformat (i, "table-id %d", &ip_table_id))
9109         ;
9110       else if (unformat (i, "unbind"))
9111         is_bind = 0;
9112       else if (unformat (i, "bind"))
9113         is_bind = 1;
9114       else
9115         {
9116           clib_warning ("parse error '%U'", format_unformat_error, i);
9117           return -99;
9118         }
9119     }
9120
9121   if (!address_set)
9122     {
9123       errmsg ("IP addres not set");
9124       return -99;
9125     }
9126
9127   if (MPLS_LABEL_INVALID == local_label)
9128     {
9129       errmsg ("missing label");
9130       return -99;
9131     }
9132
9133   /* Construct the API message */
9134   M (MPLS_IP_BIND_UNBIND, mp);
9135
9136   mp->mb_is_bind = is_bind;
9137   mp->mb_is_ip4 = is_ip4;
9138   mp->mb_ip_table_id = ntohl (ip_table_id);
9139   mp->mb_mpls_table_id = 0;
9140   mp->mb_label = ntohl (local_label);
9141   mp->mb_address_length = address_length;
9142
9143   if (is_ip4)
9144     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9145   else
9146     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9147
9148   /* send it... */
9149   S (mp);
9150
9151   /* Wait for a reply... */
9152   W (ret);
9153   return ret;
9154 }
9155
9156 static int
9157 api_bier_table_add_del (vat_main_t * vam)
9158 {
9159   unformat_input_t *i = vam->input;
9160   vl_api_bier_table_add_del_t *mp;
9161   u8 is_add = 1;
9162   u32 set = 0, sub_domain = 0, hdr_len = 3;
9163   mpls_label_t local_label = MPLS_LABEL_INVALID;
9164   int ret;
9165
9166   /* Parse args required to build the message */
9167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9168     {
9169       if (unformat (i, "sub-domain %d", &sub_domain))
9170         ;
9171       else if (unformat (i, "set %d", &set))
9172         ;
9173       else if (unformat (i, "label %d", &local_label))
9174         ;
9175       else if (unformat (i, "hdr-len %d", &hdr_len))
9176         ;
9177       else if (unformat (i, "add"))
9178         is_add = 1;
9179       else if (unformat (i, "del"))
9180         is_add = 0;
9181       else
9182         {
9183           clib_warning ("parse error '%U'", format_unformat_error, i);
9184           return -99;
9185         }
9186     }
9187
9188   if (MPLS_LABEL_INVALID == local_label)
9189     {
9190       errmsg ("missing label\n");
9191       return -99;
9192     }
9193
9194   /* Construct the API message */
9195   M (BIER_TABLE_ADD_DEL, mp);
9196
9197   mp->bt_is_add = is_add;
9198   mp->bt_label = ntohl (local_label);
9199   mp->bt_tbl_id.bt_set = set;
9200   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9201   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9202
9203   /* send it... */
9204   S (mp);
9205
9206   /* Wait for a reply... */
9207   W (ret);
9208
9209   return (ret);
9210 }
9211
9212 static int
9213 api_bier_route_add_del (vat_main_t * vam)
9214 {
9215   unformat_input_t *i = vam->input;
9216   vl_api_bier_route_add_del_t *mp;
9217   u8 is_add = 1;
9218   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9219   ip4_address_t v4_next_hop_address;
9220   ip6_address_t v6_next_hop_address;
9221   u8 next_hop_set = 0;
9222   u8 next_hop_proto_is_ip4 = 1;
9223   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9224   int ret;
9225
9226   /* Parse args required to build the message */
9227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9228     {
9229       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9230         {
9231           next_hop_proto_is_ip4 = 1;
9232           next_hop_set = 1;
9233         }
9234       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9235         {
9236           next_hop_proto_is_ip4 = 0;
9237           next_hop_set = 1;
9238         }
9239       if (unformat (i, "sub-domain %d", &sub_domain))
9240         ;
9241       else if (unformat (i, "set %d", &set))
9242         ;
9243       else if (unformat (i, "hdr-len %d", &hdr_len))
9244         ;
9245       else if (unformat (i, "bp %d", &bp))
9246         ;
9247       else if (unformat (i, "add"))
9248         is_add = 1;
9249       else if (unformat (i, "del"))
9250         is_add = 0;
9251       else if (unformat (i, "out-label %d", &next_hop_out_label))
9252         ;
9253       else
9254         {
9255           clib_warning ("parse error '%U'", format_unformat_error, i);
9256           return -99;
9257         }
9258     }
9259
9260   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9261     {
9262       errmsg ("next hop / label set\n");
9263       return -99;
9264     }
9265   if (0 == bp)
9266     {
9267       errmsg ("bit=position not set\n");
9268       return -99;
9269     }
9270
9271   /* Construct the API message */
9272   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9273
9274   mp->br_is_add = is_add;
9275   mp->br_tbl_id.bt_set = set;
9276   mp->br_tbl_id.bt_sub_domain = sub_domain;
9277   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9278   mp->br_bp = ntohs (bp);
9279   mp->br_n_paths = 1;
9280   mp->br_paths[0].n_labels = 1;
9281   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9282   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9283
9284   if (next_hop_proto_is_ip4)
9285     {
9286       clib_memcpy (mp->br_paths[0].next_hop,
9287                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9288     }
9289   else
9290     {
9291       clib_memcpy (mp->br_paths[0].next_hop,
9292                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9293     }
9294
9295   /* send it... */
9296   S (mp);
9297
9298   /* Wait for a reply... */
9299   W (ret);
9300
9301   return (ret);
9302 }
9303
9304 static int
9305 api_proxy_arp_add_del (vat_main_t * vam)
9306 {
9307   unformat_input_t *i = vam->input;
9308   vl_api_proxy_arp_add_del_t *mp;
9309   u32 vrf_id = 0;
9310   u8 is_add = 1;
9311   ip4_address_t lo, hi;
9312   u8 range_set = 0;
9313   int ret;
9314
9315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9316     {
9317       if (unformat (i, "vrf %d", &vrf_id))
9318         ;
9319       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9320                          unformat_ip4_address, &hi))
9321         range_set = 1;
9322       else if (unformat (i, "del"))
9323         is_add = 0;
9324       else
9325         {
9326           clib_warning ("parse error '%U'", format_unformat_error, i);
9327           return -99;
9328         }
9329     }
9330
9331   if (range_set == 0)
9332     {
9333       errmsg ("address range not set");
9334       return -99;
9335     }
9336
9337   M (PROXY_ARP_ADD_DEL, mp);
9338
9339   mp->proxy.vrf_id = ntohl (vrf_id);
9340   mp->is_add = is_add;
9341   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9342   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9343
9344   S (mp);
9345   W (ret);
9346   return ret;
9347 }
9348
9349 static int
9350 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9351 {
9352   unformat_input_t *i = vam->input;
9353   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9354   u32 sw_if_index;
9355   u8 enable = 1;
9356   u8 sw_if_index_set = 0;
9357   int ret;
9358
9359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9360     {
9361       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9362         sw_if_index_set = 1;
9363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9364         sw_if_index_set = 1;
9365       else if (unformat (i, "enable"))
9366         enable = 1;
9367       else if (unformat (i, "disable"))
9368         enable = 0;
9369       else
9370         {
9371           clib_warning ("parse error '%U'", format_unformat_error, i);
9372           return -99;
9373         }
9374     }
9375
9376   if (sw_if_index_set == 0)
9377     {
9378       errmsg ("missing interface name or sw_if_index");
9379       return -99;
9380     }
9381
9382   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9383
9384   mp->sw_if_index = ntohl (sw_if_index);
9385   mp->enable_disable = enable;
9386
9387   S (mp);
9388   W (ret);
9389   return ret;
9390 }
9391
9392 static int
9393 api_mpls_tunnel_add_del (vat_main_t * vam)
9394 {
9395   unformat_input_t *i = vam->input;
9396   vl_api_mpls_tunnel_add_del_t *mp;
9397
9398   u8 is_add = 1;
9399   u8 l2_only = 0;
9400   u32 sw_if_index = ~0;
9401   u32 next_hop_sw_if_index = ~0;
9402   u32 next_hop_proto_is_ip4 = 1;
9403
9404   u32 next_hop_table_id = 0;
9405   ip4_address_t v4_next_hop_address = {
9406     .as_u32 = 0,
9407   };
9408   ip6_address_t v6_next_hop_address = { {0} };
9409   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9410   int ret;
9411
9412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9413     {
9414       if (unformat (i, "add"))
9415         is_add = 1;
9416       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9417         is_add = 0;
9418       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9419         ;
9420       else if (unformat (i, "via %U",
9421                          unformat_ip4_address, &v4_next_hop_address))
9422         {
9423           next_hop_proto_is_ip4 = 1;
9424         }
9425       else if (unformat (i, "via %U",
9426                          unformat_ip6_address, &v6_next_hop_address))
9427         {
9428           next_hop_proto_is_ip4 = 0;
9429         }
9430       else if (unformat (i, "l2-only"))
9431         l2_only = 1;
9432       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9433         ;
9434       else if (unformat (i, "out-label %d", &next_hop_out_label))
9435         vec_add1 (labels, ntohl (next_hop_out_label));
9436       else
9437         {
9438           clib_warning ("parse error '%U'", format_unformat_error, i);
9439           return -99;
9440         }
9441     }
9442
9443   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9444
9445   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9446   mp->mt_sw_if_index = ntohl (sw_if_index);
9447   mp->mt_is_add = is_add;
9448   mp->mt_l2_only = l2_only;
9449   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9450   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9451
9452   mp->mt_next_hop_n_out_labels = vec_len (labels);
9453
9454   if (0 != mp->mt_next_hop_n_out_labels)
9455     {
9456       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9457                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9458       vec_free (labels);
9459     }
9460
9461   if (next_hop_proto_is_ip4)
9462     {
9463       clib_memcpy (mp->mt_next_hop,
9464                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9465     }
9466   else
9467     {
9468       clib_memcpy (mp->mt_next_hop,
9469                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9470     }
9471
9472   S (mp);
9473   W (ret);
9474   return ret;
9475 }
9476
9477 static int
9478 api_sw_interface_set_unnumbered (vat_main_t * vam)
9479 {
9480   unformat_input_t *i = vam->input;
9481   vl_api_sw_interface_set_unnumbered_t *mp;
9482   u32 sw_if_index;
9483   u32 unnum_sw_index = ~0;
9484   u8 is_add = 1;
9485   u8 sw_if_index_set = 0;
9486   int ret;
9487
9488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9489     {
9490       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9491         sw_if_index_set = 1;
9492       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9493         sw_if_index_set = 1;
9494       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9495         ;
9496       else if (unformat (i, "del"))
9497         is_add = 0;
9498       else
9499         {
9500           clib_warning ("parse error '%U'", format_unformat_error, i);
9501           return -99;
9502         }
9503     }
9504
9505   if (sw_if_index_set == 0)
9506     {
9507       errmsg ("missing interface name or sw_if_index");
9508       return -99;
9509     }
9510
9511   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9512
9513   mp->sw_if_index = ntohl (sw_if_index);
9514   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9515   mp->is_add = is_add;
9516
9517   S (mp);
9518   W (ret);
9519   return ret;
9520 }
9521
9522 static int
9523 api_ip_neighbor_add_del (vat_main_t * vam)
9524 {
9525   unformat_input_t *i = vam->input;
9526   vl_api_ip_neighbor_add_del_t *mp;
9527   u32 sw_if_index;
9528   u8 sw_if_index_set = 0;
9529   u8 is_add = 1;
9530   u8 is_static = 0;
9531   u8 is_no_fib_entry = 0;
9532   u8 mac_address[6];
9533   u8 mac_set = 0;
9534   u8 v4_address_set = 0;
9535   u8 v6_address_set = 0;
9536   ip4_address_t v4address;
9537   ip6_address_t v6address;
9538   int ret;
9539
9540   memset (mac_address, 0, sizeof (mac_address));
9541
9542   /* Parse args required to build the message */
9543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9544     {
9545       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9546         {
9547           mac_set = 1;
9548         }
9549       else if (unformat (i, "del"))
9550         is_add = 0;
9551       else
9552         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9553         sw_if_index_set = 1;
9554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9555         sw_if_index_set = 1;
9556       else if (unformat (i, "is_static"))
9557         is_static = 1;
9558       else if (unformat (i, "no-fib-entry"))
9559         is_no_fib_entry = 1;
9560       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9561         v4_address_set = 1;
9562       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9563         v6_address_set = 1;
9564       else
9565         {
9566           clib_warning ("parse error '%U'", format_unformat_error, i);
9567           return -99;
9568         }
9569     }
9570
9571   if (sw_if_index_set == 0)
9572     {
9573       errmsg ("missing interface name or sw_if_index");
9574       return -99;
9575     }
9576   if (v4_address_set && v6_address_set)
9577     {
9578       errmsg ("both v4 and v6 addresses set");
9579       return -99;
9580     }
9581   if (!v4_address_set && !v6_address_set)
9582     {
9583       errmsg ("no address set");
9584       return -99;
9585     }
9586
9587   /* Construct the API message */
9588   M (IP_NEIGHBOR_ADD_DEL, mp);
9589
9590   mp->sw_if_index = ntohl (sw_if_index);
9591   mp->is_add = is_add;
9592   mp->is_static = is_static;
9593   mp->is_no_adj_fib = is_no_fib_entry;
9594   if (mac_set)
9595     clib_memcpy (mp->mac_address, mac_address, 6);
9596   if (v6_address_set)
9597     {
9598       mp->is_ipv6 = 1;
9599       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9600     }
9601   else
9602     {
9603       /* mp->is_ipv6 = 0; via memset in M macro above */
9604       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9605     }
9606
9607   /* send it... */
9608   S (mp);
9609
9610   /* Wait for a reply, return good/bad news  */
9611   W (ret);
9612   return ret;
9613 }
9614
9615 static int
9616 api_create_vlan_subif (vat_main_t * vam)
9617 {
9618   unformat_input_t *i = vam->input;
9619   vl_api_create_vlan_subif_t *mp;
9620   u32 sw_if_index;
9621   u8 sw_if_index_set = 0;
9622   u32 vlan_id;
9623   u8 vlan_id_set = 0;
9624   int ret;
9625
9626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9627     {
9628       if (unformat (i, "sw_if_index %d", &sw_if_index))
9629         sw_if_index_set = 1;
9630       else
9631         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9632         sw_if_index_set = 1;
9633       else if (unformat (i, "vlan %d", &vlan_id))
9634         vlan_id_set = 1;
9635       else
9636         {
9637           clib_warning ("parse error '%U'", format_unformat_error, i);
9638           return -99;
9639         }
9640     }
9641
9642   if (sw_if_index_set == 0)
9643     {
9644       errmsg ("missing interface name or sw_if_index");
9645       return -99;
9646     }
9647
9648   if (vlan_id_set == 0)
9649     {
9650       errmsg ("missing vlan_id");
9651       return -99;
9652     }
9653   M (CREATE_VLAN_SUBIF, mp);
9654
9655   mp->sw_if_index = ntohl (sw_if_index);
9656   mp->vlan_id = ntohl (vlan_id);
9657
9658   S (mp);
9659   W (ret);
9660   return ret;
9661 }
9662
9663 #define foreach_create_subif_bit                \
9664 _(no_tags)                                      \
9665 _(one_tag)                                      \
9666 _(two_tags)                                     \
9667 _(dot1ad)                                       \
9668 _(exact_match)                                  \
9669 _(default_sub)                                  \
9670 _(outer_vlan_id_any)                            \
9671 _(inner_vlan_id_any)
9672
9673 static int
9674 api_create_subif (vat_main_t * vam)
9675 {
9676   unformat_input_t *i = vam->input;
9677   vl_api_create_subif_t *mp;
9678   u32 sw_if_index;
9679   u8 sw_if_index_set = 0;
9680   u32 sub_id;
9681   u8 sub_id_set = 0;
9682   u32 no_tags = 0;
9683   u32 one_tag = 0;
9684   u32 two_tags = 0;
9685   u32 dot1ad = 0;
9686   u32 exact_match = 0;
9687   u32 default_sub = 0;
9688   u32 outer_vlan_id_any = 0;
9689   u32 inner_vlan_id_any = 0;
9690   u32 tmp;
9691   u16 outer_vlan_id = 0;
9692   u16 inner_vlan_id = 0;
9693   int ret;
9694
9695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9696     {
9697       if (unformat (i, "sw_if_index %d", &sw_if_index))
9698         sw_if_index_set = 1;
9699       else
9700         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9701         sw_if_index_set = 1;
9702       else if (unformat (i, "sub_id %d", &sub_id))
9703         sub_id_set = 1;
9704       else if (unformat (i, "outer_vlan_id %d", &tmp))
9705         outer_vlan_id = tmp;
9706       else if (unformat (i, "inner_vlan_id %d", &tmp))
9707         inner_vlan_id = tmp;
9708
9709 #define _(a) else if (unformat (i, #a)) a = 1 ;
9710       foreach_create_subif_bit
9711 #undef _
9712         else
9713         {
9714           clib_warning ("parse error '%U'", format_unformat_error, i);
9715           return -99;
9716         }
9717     }
9718
9719   if (sw_if_index_set == 0)
9720     {
9721       errmsg ("missing interface name or sw_if_index");
9722       return -99;
9723     }
9724
9725   if (sub_id_set == 0)
9726     {
9727       errmsg ("missing sub_id");
9728       return -99;
9729     }
9730   M (CREATE_SUBIF, mp);
9731
9732   mp->sw_if_index = ntohl (sw_if_index);
9733   mp->sub_id = ntohl (sub_id);
9734
9735 #define _(a) mp->a = a;
9736   foreach_create_subif_bit;
9737 #undef _
9738
9739   mp->outer_vlan_id = ntohs (outer_vlan_id);
9740   mp->inner_vlan_id = ntohs (inner_vlan_id);
9741
9742   S (mp);
9743   W (ret);
9744   return ret;
9745 }
9746
9747 static int
9748 api_oam_add_del (vat_main_t * vam)
9749 {
9750   unformat_input_t *i = vam->input;
9751   vl_api_oam_add_del_t *mp;
9752   u32 vrf_id = 0;
9753   u8 is_add = 1;
9754   ip4_address_t src, dst;
9755   u8 src_set = 0;
9756   u8 dst_set = 0;
9757   int ret;
9758
9759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9760     {
9761       if (unformat (i, "vrf %d", &vrf_id))
9762         ;
9763       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9764         src_set = 1;
9765       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9766         dst_set = 1;
9767       else if (unformat (i, "del"))
9768         is_add = 0;
9769       else
9770         {
9771           clib_warning ("parse error '%U'", format_unformat_error, i);
9772           return -99;
9773         }
9774     }
9775
9776   if (src_set == 0)
9777     {
9778       errmsg ("missing src addr");
9779       return -99;
9780     }
9781
9782   if (dst_set == 0)
9783     {
9784       errmsg ("missing dst addr");
9785       return -99;
9786     }
9787
9788   M (OAM_ADD_DEL, mp);
9789
9790   mp->vrf_id = ntohl (vrf_id);
9791   mp->is_add = is_add;
9792   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9793   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9794
9795   S (mp);
9796   W (ret);
9797   return ret;
9798 }
9799
9800 static int
9801 api_reset_fib (vat_main_t * vam)
9802 {
9803   unformat_input_t *i = vam->input;
9804   vl_api_reset_fib_t *mp;
9805   u32 vrf_id = 0;
9806   u8 is_ipv6 = 0;
9807   u8 vrf_id_set = 0;
9808
9809   int ret;
9810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (i, "vrf %d", &vrf_id))
9813         vrf_id_set = 1;
9814       else if (unformat (i, "ipv6"))
9815         is_ipv6 = 1;
9816       else
9817         {
9818           clib_warning ("parse error '%U'", format_unformat_error, i);
9819           return -99;
9820         }
9821     }
9822
9823   if (vrf_id_set == 0)
9824     {
9825       errmsg ("missing vrf id");
9826       return -99;
9827     }
9828
9829   M (RESET_FIB, mp);
9830
9831   mp->vrf_id = ntohl (vrf_id);
9832   mp->is_ipv6 = is_ipv6;
9833
9834   S (mp);
9835   W (ret);
9836   return ret;
9837 }
9838
9839 static int
9840 api_dhcp_proxy_config (vat_main_t * vam)
9841 {
9842   unformat_input_t *i = vam->input;
9843   vl_api_dhcp_proxy_config_t *mp;
9844   u32 rx_vrf_id = 0;
9845   u32 server_vrf_id = 0;
9846   u8 is_add = 1;
9847   u8 v4_address_set = 0;
9848   u8 v6_address_set = 0;
9849   ip4_address_t v4address;
9850   ip6_address_t v6address;
9851   u8 v4_src_address_set = 0;
9852   u8 v6_src_address_set = 0;
9853   ip4_address_t v4srcaddress;
9854   ip6_address_t v6srcaddress;
9855   int ret;
9856
9857   /* Parse args required to build the message */
9858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9859     {
9860       if (unformat (i, "del"))
9861         is_add = 0;
9862       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9863         ;
9864       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9865         ;
9866       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9867         v4_address_set = 1;
9868       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9869         v6_address_set = 1;
9870       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9871         v4_src_address_set = 1;
9872       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9873         v6_src_address_set = 1;
9874       else
9875         break;
9876     }
9877
9878   if (v4_address_set && v6_address_set)
9879     {
9880       errmsg ("both v4 and v6 server addresses set");
9881       return -99;
9882     }
9883   if (!v4_address_set && !v6_address_set)
9884     {
9885       errmsg ("no server addresses set");
9886       return -99;
9887     }
9888
9889   if (v4_src_address_set && v6_src_address_set)
9890     {
9891       errmsg ("both v4 and v6  src addresses set");
9892       return -99;
9893     }
9894   if (!v4_src_address_set && !v6_src_address_set)
9895     {
9896       errmsg ("no src addresses set");
9897       return -99;
9898     }
9899
9900   if (!(v4_src_address_set && v4_address_set) &&
9901       !(v6_src_address_set && v6_address_set))
9902     {
9903       errmsg ("no matching server and src addresses set");
9904       return -99;
9905     }
9906
9907   /* Construct the API message */
9908   M (DHCP_PROXY_CONFIG, mp);
9909
9910   mp->is_add = is_add;
9911   mp->rx_vrf_id = ntohl (rx_vrf_id);
9912   mp->server_vrf_id = ntohl (server_vrf_id);
9913   if (v6_address_set)
9914     {
9915       mp->is_ipv6 = 1;
9916       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9917       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9918     }
9919   else
9920     {
9921       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9922       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9923     }
9924
9925   /* send it... */
9926   S (mp);
9927
9928   /* Wait for a reply, return good/bad news  */
9929   W (ret);
9930   return ret;
9931 }
9932
9933 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9934 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9935
9936 static void
9937 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9938 {
9939   vat_main_t *vam = &vat_main;
9940   u32 i, count = mp->count;
9941   vl_api_dhcp_server_t *s;
9942
9943   if (mp->is_ipv6)
9944     print (vam->ofp,
9945            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9946            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9947            ntohl (mp->rx_vrf_id),
9948            format_ip6_address, mp->dhcp_src_address,
9949            mp->vss_type, mp->vss_vpn_ascii_id,
9950            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9951   else
9952     print (vam->ofp,
9953            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9954            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9955            ntohl (mp->rx_vrf_id),
9956            format_ip4_address, mp->dhcp_src_address,
9957            mp->vss_type, mp->vss_vpn_ascii_id,
9958            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9959
9960   for (i = 0; i < count; i++)
9961     {
9962       s = &mp->servers[i];
9963
9964       if (mp->is_ipv6)
9965         print (vam->ofp,
9966                " Server Table-ID %d, Server Address %U",
9967                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9968       else
9969         print (vam->ofp,
9970                " Server Table-ID %d, Server Address %U",
9971                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9972     }
9973 }
9974
9975 static void vl_api_dhcp_proxy_details_t_handler_json
9976   (vl_api_dhcp_proxy_details_t * mp)
9977 {
9978   vat_main_t *vam = &vat_main;
9979   vat_json_node_t *node = NULL;
9980   u32 i, count = mp->count;
9981   struct in_addr ip4;
9982   struct in6_addr ip6;
9983   vl_api_dhcp_server_t *s;
9984
9985   if (VAT_JSON_ARRAY != vam->json_tree.type)
9986     {
9987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9988       vat_json_init_array (&vam->json_tree);
9989     }
9990   node = vat_json_array_add (&vam->json_tree);
9991
9992   vat_json_init_object (node);
9993   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9994   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9995                              sizeof (mp->vss_type));
9996   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9997                                    mp->vss_vpn_ascii_id);
9998   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9999   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10000
10001   if (mp->is_ipv6)
10002     {
10003       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10004       vat_json_object_add_ip6 (node, "src_address", ip6);
10005     }
10006   else
10007     {
10008       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10009       vat_json_object_add_ip4 (node, "src_address", ip4);
10010     }
10011
10012   for (i = 0; i < count; i++)
10013     {
10014       s = &mp->servers[i];
10015
10016       vat_json_object_add_uint (node, "server-table-id",
10017                                 ntohl (s->server_vrf_id));
10018
10019       if (mp->is_ipv6)
10020         {
10021           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10022           vat_json_object_add_ip4 (node, "src_address", ip4);
10023         }
10024       else
10025         {
10026           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10027           vat_json_object_add_ip6 (node, "server_address", ip6);
10028         }
10029     }
10030 }
10031
10032 static int
10033 api_dhcp_proxy_dump (vat_main_t * vam)
10034 {
10035   unformat_input_t *i = vam->input;
10036   vl_api_control_ping_t *mp_ping;
10037   vl_api_dhcp_proxy_dump_t *mp;
10038   u8 is_ipv6 = 0;
10039   int ret;
10040
10041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10042     {
10043       if (unformat (i, "ipv6"))
10044         is_ipv6 = 1;
10045       else
10046         {
10047           clib_warning ("parse error '%U'", format_unformat_error, i);
10048           return -99;
10049         }
10050     }
10051
10052   M (DHCP_PROXY_DUMP, mp);
10053
10054   mp->is_ip6 = is_ipv6;
10055   S (mp);
10056
10057   /* Use a control ping for synchronization */
10058   MPING (CONTROL_PING, mp_ping);
10059   S (mp_ping);
10060
10061   W (ret);
10062   return ret;
10063 }
10064
10065 static int
10066 api_dhcp_proxy_set_vss (vat_main_t * vam)
10067 {
10068   unformat_input_t *i = vam->input;
10069   vl_api_dhcp_proxy_set_vss_t *mp;
10070   u8 is_ipv6 = 0;
10071   u8 is_add = 1;
10072   u32 tbl_id = ~0;
10073   u8 vss_type = VSS_TYPE_DEFAULT;
10074   u8 *vpn_ascii_id = 0;
10075   u32 oui = 0;
10076   u32 fib_id = 0;
10077   int ret;
10078
10079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10080     {
10081       if (unformat (i, "tbl_id %d", &tbl_id))
10082         ;
10083       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10084         vss_type = VSS_TYPE_ASCII;
10085       else if (unformat (i, "fib_id %d", &fib_id))
10086         vss_type = VSS_TYPE_VPN_ID;
10087       else if (unformat (i, "oui %d", &oui))
10088         vss_type = VSS_TYPE_VPN_ID;
10089       else if (unformat (i, "ipv6"))
10090         is_ipv6 = 1;
10091       else if (unformat (i, "del"))
10092         is_add = 0;
10093       else
10094         break;
10095     }
10096
10097   if (tbl_id == ~0)
10098     {
10099       errmsg ("missing tbl_id ");
10100       vec_free (vpn_ascii_id);
10101       return -99;
10102     }
10103
10104   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10105     {
10106       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10107       vec_free (vpn_ascii_id);
10108       return -99;
10109     }
10110
10111   M (DHCP_PROXY_SET_VSS, mp);
10112   mp->tbl_id = ntohl (tbl_id);
10113   mp->vss_type = vss_type;
10114   if (vpn_ascii_id)
10115     {
10116       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10117       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10118     }
10119   mp->vpn_index = ntohl (fib_id);
10120   mp->oui = ntohl (oui);
10121   mp->is_ipv6 = is_ipv6;
10122   mp->is_add = is_add;
10123
10124   S (mp);
10125   W (ret);
10126
10127   vec_free (vpn_ascii_id);
10128   return ret;
10129 }
10130
10131 static int
10132 api_dhcp_client_config (vat_main_t * vam)
10133 {
10134   unformat_input_t *i = vam->input;
10135   vl_api_dhcp_client_config_t *mp;
10136   u32 sw_if_index;
10137   u8 sw_if_index_set = 0;
10138   u8 is_add = 1;
10139   u8 *hostname = 0;
10140   u8 disable_event = 0;
10141   int ret;
10142
10143   /* Parse args required to build the message */
10144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10145     {
10146       if (unformat (i, "del"))
10147         is_add = 0;
10148       else
10149         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10150         sw_if_index_set = 1;
10151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10152         sw_if_index_set = 1;
10153       else if (unformat (i, "hostname %s", &hostname))
10154         ;
10155       else if (unformat (i, "disable_event"))
10156         disable_event = 1;
10157       else
10158         break;
10159     }
10160
10161   if (sw_if_index_set == 0)
10162     {
10163       errmsg ("missing interface name or sw_if_index");
10164       return -99;
10165     }
10166
10167   if (vec_len (hostname) > 63)
10168     {
10169       errmsg ("hostname too long");
10170     }
10171   vec_add1 (hostname, 0);
10172
10173   /* Construct the API message */
10174   M (DHCP_CLIENT_CONFIG, mp);
10175
10176   mp->is_add = is_add;
10177   mp->client.sw_if_index = htonl (sw_if_index);
10178   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10179   vec_free (hostname);
10180   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10181   mp->client.pid = htonl (getpid ());
10182
10183   /* send it... */
10184   S (mp);
10185
10186   /* Wait for a reply, return good/bad news  */
10187   W (ret);
10188   return ret;
10189 }
10190
10191 static int
10192 api_set_ip_flow_hash (vat_main_t * vam)
10193 {
10194   unformat_input_t *i = vam->input;
10195   vl_api_set_ip_flow_hash_t *mp;
10196   u32 vrf_id = 0;
10197   u8 is_ipv6 = 0;
10198   u8 vrf_id_set = 0;
10199   u8 src = 0;
10200   u8 dst = 0;
10201   u8 sport = 0;
10202   u8 dport = 0;
10203   u8 proto = 0;
10204   u8 reverse = 0;
10205   int ret;
10206
10207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10208     {
10209       if (unformat (i, "vrf %d", &vrf_id))
10210         vrf_id_set = 1;
10211       else if (unformat (i, "ipv6"))
10212         is_ipv6 = 1;
10213       else if (unformat (i, "src"))
10214         src = 1;
10215       else if (unformat (i, "dst"))
10216         dst = 1;
10217       else if (unformat (i, "sport"))
10218         sport = 1;
10219       else if (unformat (i, "dport"))
10220         dport = 1;
10221       else if (unformat (i, "proto"))
10222         proto = 1;
10223       else if (unformat (i, "reverse"))
10224         reverse = 1;
10225
10226       else
10227         {
10228           clib_warning ("parse error '%U'", format_unformat_error, i);
10229           return -99;
10230         }
10231     }
10232
10233   if (vrf_id_set == 0)
10234     {
10235       errmsg ("missing vrf id");
10236       return -99;
10237     }
10238
10239   M (SET_IP_FLOW_HASH, mp);
10240   mp->src = src;
10241   mp->dst = dst;
10242   mp->sport = sport;
10243   mp->dport = dport;
10244   mp->proto = proto;
10245   mp->reverse = reverse;
10246   mp->vrf_id = ntohl (vrf_id);
10247   mp->is_ipv6 = is_ipv6;
10248
10249   S (mp);
10250   W (ret);
10251   return ret;
10252 }
10253
10254 static int
10255 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10256 {
10257   unformat_input_t *i = vam->input;
10258   vl_api_sw_interface_ip6_enable_disable_t *mp;
10259   u32 sw_if_index;
10260   u8 sw_if_index_set = 0;
10261   u8 enable = 0;
10262   int ret;
10263
10264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10265     {
10266       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10267         sw_if_index_set = 1;
10268       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10269         sw_if_index_set = 1;
10270       else if (unformat (i, "enable"))
10271         enable = 1;
10272       else if (unformat (i, "disable"))
10273         enable = 0;
10274       else
10275         {
10276           clib_warning ("parse error '%U'", format_unformat_error, i);
10277           return -99;
10278         }
10279     }
10280
10281   if (sw_if_index_set == 0)
10282     {
10283       errmsg ("missing interface name or sw_if_index");
10284       return -99;
10285     }
10286
10287   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10288
10289   mp->sw_if_index = ntohl (sw_if_index);
10290   mp->enable = enable;
10291
10292   S (mp);
10293   W (ret);
10294   return ret;
10295 }
10296
10297 static int
10298 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10299 {
10300   unformat_input_t *i = vam->input;
10301   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10302   u32 sw_if_index;
10303   u8 sw_if_index_set = 0;
10304   u8 v6_address_set = 0;
10305   ip6_address_t v6address;
10306   int ret;
10307
10308   /* Parse args required to build the message */
10309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10310     {
10311       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10312         sw_if_index_set = 1;
10313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10314         sw_if_index_set = 1;
10315       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10316         v6_address_set = 1;
10317       else
10318         break;
10319     }
10320
10321   if (sw_if_index_set == 0)
10322     {
10323       errmsg ("missing interface name or sw_if_index");
10324       return -99;
10325     }
10326   if (!v6_address_set)
10327     {
10328       errmsg ("no address set");
10329       return -99;
10330     }
10331
10332   /* Construct the API message */
10333   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10334
10335   mp->sw_if_index = ntohl (sw_if_index);
10336   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10337
10338   /* send it... */
10339   S (mp);
10340
10341   /* Wait for a reply, return good/bad news  */
10342   W (ret);
10343   return ret;
10344 }
10345
10346 static int
10347 api_ip6nd_proxy_add_del (vat_main_t * vam)
10348 {
10349   unformat_input_t *i = vam->input;
10350   vl_api_ip6nd_proxy_add_del_t *mp;
10351   u32 sw_if_index = ~0;
10352   u8 v6_address_set = 0;
10353   ip6_address_t v6address;
10354   u8 is_del = 0;
10355   int ret;
10356
10357   /* Parse args required to build the message */
10358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10359     {
10360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10361         ;
10362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10363         ;
10364       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10365         v6_address_set = 1;
10366       if (unformat (i, "del"))
10367         is_del = 1;
10368       else
10369         {
10370           clib_warning ("parse error '%U'", format_unformat_error, i);
10371           return -99;
10372         }
10373     }
10374
10375   if (sw_if_index == ~0)
10376     {
10377       errmsg ("missing interface name or sw_if_index");
10378       return -99;
10379     }
10380   if (!v6_address_set)
10381     {
10382       errmsg ("no address set");
10383       return -99;
10384     }
10385
10386   /* Construct the API message */
10387   M (IP6ND_PROXY_ADD_DEL, mp);
10388
10389   mp->is_del = is_del;
10390   mp->sw_if_index = ntohl (sw_if_index);
10391   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10392
10393   /* send it... */
10394   S (mp);
10395
10396   /* Wait for a reply, return good/bad news  */
10397   W (ret);
10398   return ret;
10399 }
10400
10401 static int
10402 api_ip6nd_proxy_dump (vat_main_t * vam)
10403 {
10404   vl_api_ip6nd_proxy_dump_t *mp;
10405   vl_api_control_ping_t *mp_ping;
10406   int ret;
10407
10408   M (IP6ND_PROXY_DUMP, mp);
10409
10410   S (mp);
10411
10412   /* Use a control ping for synchronization */
10413   MPING (CONTROL_PING, mp_ping);
10414   S (mp_ping);
10415
10416   W (ret);
10417   return ret;
10418 }
10419
10420 static void vl_api_ip6nd_proxy_details_t_handler
10421   (vl_api_ip6nd_proxy_details_t * mp)
10422 {
10423   vat_main_t *vam = &vat_main;
10424
10425   print (vam->ofp, "host %U sw_if_index %d",
10426          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10427 }
10428
10429 static void vl_api_ip6nd_proxy_details_t_handler_json
10430   (vl_api_ip6nd_proxy_details_t * mp)
10431 {
10432   vat_main_t *vam = &vat_main;
10433   struct in6_addr ip6;
10434   vat_json_node_t *node = NULL;
10435
10436   if (VAT_JSON_ARRAY != vam->json_tree.type)
10437     {
10438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10439       vat_json_init_array (&vam->json_tree);
10440     }
10441   node = vat_json_array_add (&vam->json_tree);
10442
10443   vat_json_init_object (node);
10444   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10445
10446   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10447   vat_json_object_add_ip6 (node, "host", ip6);
10448 }
10449
10450 static int
10451 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10452 {
10453   unformat_input_t *i = vam->input;
10454   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10455   u32 sw_if_index;
10456   u8 sw_if_index_set = 0;
10457   u32 address_length = 0;
10458   u8 v6_address_set = 0;
10459   ip6_address_t v6address;
10460   u8 use_default = 0;
10461   u8 no_advertise = 0;
10462   u8 off_link = 0;
10463   u8 no_autoconfig = 0;
10464   u8 no_onlink = 0;
10465   u8 is_no = 0;
10466   u32 val_lifetime = 0;
10467   u32 pref_lifetime = 0;
10468   int ret;
10469
10470   /* Parse args required to build the message */
10471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10472     {
10473       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10474         sw_if_index_set = 1;
10475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10476         sw_if_index_set = 1;
10477       else if (unformat (i, "%U/%d",
10478                          unformat_ip6_address, &v6address, &address_length))
10479         v6_address_set = 1;
10480       else if (unformat (i, "val_life %d", &val_lifetime))
10481         ;
10482       else if (unformat (i, "pref_life %d", &pref_lifetime))
10483         ;
10484       else if (unformat (i, "def"))
10485         use_default = 1;
10486       else if (unformat (i, "noadv"))
10487         no_advertise = 1;
10488       else if (unformat (i, "offl"))
10489         off_link = 1;
10490       else if (unformat (i, "noauto"))
10491         no_autoconfig = 1;
10492       else if (unformat (i, "nolink"))
10493         no_onlink = 1;
10494       else if (unformat (i, "isno"))
10495         is_no = 1;
10496       else
10497         {
10498           clib_warning ("parse error '%U'", format_unformat_error, i);
10499           return -99;
10500         }
10501     }
10502
10503   if (sw_if_index_set == 0)
10504     {
10505       errmsg ("missing interface name or sw_if_index");
10506       return -99;
10507     }
10508   if (!v6_address_set)
10509     {
10510       errmsg ("no address set");
10511       return -99;
10512     }
10513
10514   /* Construct the API message */
10515   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10516
10517   mp->sw_if_index = ntohl (sw_if_index);
10518   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10519   mp->address_length = address_length;
10520   mp->use_default = use_default;
10521   mp->no_advertise = no_advertise;
10522   mp->off_link = off_link;
10523   mp->no_autoconfig = no_autoconfig;
10524   mp->no_onlink = no_onlink;
10525   mp->is_no = is_no;
10526   mp->val_lifetime = ntohl (val_lifetime);
10527   mp->pref_lifetime = ntohl (pref_lifetime);
10528
10529   /* send it... */
10530   S (mp);
10531
10532   /* Wait for a reply, return good/bad news  */
10533   W (ret);
10534   return ret;
10535 }
10536
10537 static int
10538 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10539 {
10540   unformat_input_t *i = vam->input;
10541   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10542   u32 sw_if_index;
10543   u8 sw_if_index_set = 0;
10544   u8 suppress = 0;
10545   u8 managed = 0;
10546   u8 other = 0;
10547   u8 ll_option = 0;
10548   u8 send_unicast = 0;
10549   u8 cease = 0;
10550   u8 is_no = 0;
10551   u8 default_router = 0;
10552   u32 max_interval = 0;
10553   u32 min_interval = 0;
10554   u32 lifetime = 0;
10555   u32 initial_count = 0;
10556   u32 initial_interval = 0;
10557   int ret;
10558
10559
10560   /* Parse args required to build the message */
10561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10562     {
10563       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10564         sw_if_index_set = 1;
10565       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10566         sw_if_index_set = 1;
10567       else if (unformat (i, "maxint %d", &max_interval))
10568         ;
10569       else if (unformat (i, "minint %d", &min_interval))
10570         ;
10571       else if (unformat (i, "life %d", &lifetime))
10572         ;
10573       else if (unformat (i, "count %d", &initial_count))
10574         ;
10575       else if (unformat (i, "interval %d", &initial_interval))
10576         ;
10577       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10578         suppress = 1;
10579       else if (unformat (i, "managed"))
10580         managed = 1;
10581       else if (unformat (i, "other"))
10582         other = 1;
10583       else if (unformat (i, "ll"))
10584         ll_option = 1;
10585       else if (unformat (i, "send"))
10586         send_unicast = 1;
10587       else if (unformat (i, "cease"))
10588         cease = 1;
10589       else if (unformat (i, "isno"))
10590         is_no = 1;
10591       else if (unformat (i, "def"))
10592         default_router = 1;
10593       else
10594         {
10595           clib_warning ("parse error '%U'", format_unformat_error, i);
10596           return -99;
10597         }
10598     }
10599
10600   if (sw_if_index_set == 0)
10601     {
10602       errmsg ("missing interface name or sw_if_index");
10603       return -99;
10604     }
10605
10606   /* Construct the API message */
10607   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10608
10609   mp->sw_if_index = ntohl (sw_if_index);
10610   mp->max_interval = ntohl (max_interval);
10611   mp->min_interval = ntohl (min_interval);
10612   mp->lifetime = ntohl (lifetime);
10613   mp->initial_count = ntohl (initial_count);
10614   mp->initial_interval = ntohl (initial_interval);
10615   mp->suppress = suppress;
10616   mp->managed = managed;
10617   mp->other = other;
10618   mp->ll_option = ll_option;
10619   mp->send_unicast = send_unicast;
10620   mp->cease = cease;
10621   mp->is_no = is_no;
10622   mp->default_router = default_router;
10623
10624   /* send it... */
10625   S (mp);
10626
10627   /* Wait for a reply, return good/bad news  */
10628   W (ret);
10629   return ret;
10630 }
10631
10632 static int
10633 api_set_arp_neighbor_limit (vat_main_t * vam)
10634 {
10635   unformat_input_t *i = vam->input;
10636   vl_api_set_arp_neighbor_limit_t *mp;
10637   u32 arp_nbr_limit;
10638   u8 limit_set = 0;
10639   u8 is_ipv6 = 0;
10640   int ret;
10641
10642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10643     {
10644       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10645         limit_set = 1;
10646       else if (unformat (i, "ipv6"))
10647         is_ipv6 = 1;
10648       else
10649         {
10650           clib_warning ("parse error '%U'", format_unformat_error, i);
10651           return -99;
10652         }
10653     }
10654
10655   if (limit_set == 0)
10656     {
10657       errmsg ("missing limit value");
10658       return -99;
10659     }
10660
10661   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10662
10663   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10664   mp->is_ipv6 = is_ipv6;
10665
10666   S (mp);
10667   W (ret);
10668   return ret;
10669 }
10670
10671 static int
10672 api_l2_patch_add_del (vat_main_t * vam)
10673 {
10674   unformat_input_t *i = vam->input;
10675   vl_api_l2_patch_add_del_t *mp;
10676   u32 rx_sw_if_index;
10677   u8 rx_sw_if_index_set = 0;
10678   u32 tx_sw_if_index;
10679   u8 tx_sw_if_index_set = 0;
10680   u8 is_add = 1;
10681   int ret;
10682
10683   /* Parse args required to build the message */
10684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10685     {
10686       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10687         rx_sw_if_index_set = 1;
10688       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10689         tx_sw_if_index_set = 1;
10690       else if (unformat (i, "rx"))
10691         {
10692           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10693             {
10694               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10695                             &rx_sw_if_index))
10696                 rx_sw_if_index_set = 1;
10697             }
10698           else
10699             break;
10700         }
10701       else if (unformat (i, "tx"))
10702         {
10703           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10704             {
10705               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10706                             &tx_sw_if_index))
10707                 tx_sw_if_index_set = 1;
10708             }
10709           else
10710             break;
10711         }
10712       else if (unformat (i, "del"))
10713         is_add = 0;
10714       else
10715         break;
10716     }
10717
10718   if (rx_sw_if_index_set == 0)
10719     {
10720       errmsg ("missing rx interface name or rx_sw_if_index");
10721       return -99;
10722     }
10723
10724   if (tx_sw_if_index_set == 0)
10725     {
10726       errmsg ("missing tx interface name or tx_sw_if_index");
10727       return -99;
10728     }
10729
10730   M (L2_PATCH_ADD_DEL, mp);
10731
10732   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10733   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10734   mp->is_add = is_add;
10735
10736   S (mp);
10737   W (ret);
10738   return ret;
10739 }
10740
10741 u8 is_del;
10742 u8 localsid_addr[16];
10743 u8 end_psp;
10744 u8 behavior;
10745 u32 sw_if_index;
10746 u32 vlan_index;
10747 u32 fib_table;
10748 u8 nh_addr[16];
10749
10750 static int
10751 api_sr_localsid_add_del (vat_main_t * vam)
10752 {
10753   unformat_input_t *i = vam->input;
10754   vl_api_sr_localsid_add_del_t *mp;
10755
10756   u8 is_del;
10757   ip6_address_t localsid;
10758   u8 end_psp = 0;
10759   u8 behavior = ~0;
10760   u32 sw_if_index;
10761   u32 fib_table = ~(u32) 0;
10762   ip6_address_t next_hop;
10763
10764   bool nexthop_set = 0;
10765
10766   int ret;
10767
10768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10769     {
10770       if (unformat (i, "del"))
10771         is_del = 1;
10772       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10773       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10774         nexthop_set = 1;
10775       else if (unformat (i, "behavior %u", &behavior));
10776       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10777       else if (unformat (i, "fib-table %u", &fib_table));
10778       else if (unformat (i, "end.psp %u", &behavior));
10779       else
10780         break;
10781     }
10782
10783   M (SR_LOCALSID_ADD_DEL, mp);
10784
10785   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10786   if (nexthop_set)
10787     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10788   mp->behavior = behavior;
10789   mp->sw_if_index = ntohl (sw_if_index);
10790   mp->fib_table = ntohl (fib_table);
10791   mp->end_psp = end_psp;
10792   mp->is_del = is_del;
10793
10794   S (mp);
10795   W (ret);
10796   return ret;
10797 }
10798
10799 static int
10800 api_ioam_enable (vat_main_t * vam)
10801 {
10802   unformat_input_t *input = vam->input;
10803   vl_api_ioam_enable_t *mp;
10804   u32 id = 0;
10805   int has_trace_option = 0;
10806   int has_pot_option = 0;
10807   int has_seqno_option = 0;
10808   int has_analyse_option = 0;
10809   int ret;
10810
10811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10812     {
10813       if (unformat (input, "trace"))
10814         has_trace_option = 1;
10815       else if (unformat (input, "pot"))
10816         has_pot_option = 1;
10817       else if (unformat (input, "seqno"))
10818         has_seqno_option = 1;
10819       else if (unformat (input, "analyse"))
10820         has_analyse_option = 1;
10821       else
10822         break;
10823     }
10824   M (IOAM_ENABLE, mp);
10825   mp->id = htons (id);
10826   mp->seqno = has_seqno_option;
10827   mp->analyse = has_analyse_option;
10828   mp->pot_enable = has_pot_option;
10829   mp->trace_enable = has_trace_option;
10830
10831   S (mp);
10832   W (ret);
10833   return ret;
10834 }
10835
10836
10837 static int
10838 api_ioam_disable (vat_main_t * vam)
10839 {
10840   vl_api_ioam_disable_t *mp;
10841   int ret;
10842
10843   M (IOAM_DISABLE, mp);
10844   S (mp);
10845   W (ret);
10846   return ret;
10847 }
10848
10849 #define foreach_tcp_proto_field                 \
10850 _(src_port)                                     \
10851 _(dst_port)
10852
10853 #define foreach_udp_proto_field                 \
10854 _(src_port)                                     \
10855 _(dst_port)
10856
10857 #define foreach_ip4_proto_field                 \
10858 _(src_address)                                  \
10859 _(dst_address)                                  \
10860 _(tos)                                          \
10861 _(length)                                       \
10862 _(fragment_id)                                  \
10863 _(ttl)                                          \
10864 _(protocol)                                     \
10865 _(checksum)
10866
10867 typedef struct
10868 {
10869   u16 src_port, dst_port;
10870 } tcpudp_header_t;
10871
10872 #if VPP_API_TEST_BUILTIN == 0
10873 uword
10874 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10875 {
10876   u8 **maskp = va_arg (*args, u8 **);
10877   u8 *mask = 0;
10878   u8 found_something = 0;
10879   tcp_header_t *tcp;
10880
10881 #define _(a) u8 a=0;
10882   foreach_tcp_proto_field;
10883 #undef _
10884
10885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10886     {
10887       if (0);
10888 #define _(a) else if (unformat (input, #a)) a=1;
10889       foreach_tcp_proto_field
10890 #undef _
10891         else
10892         break;
10893     }
10894
10895 #define _(a) found_something += a;
10896   foreach_tcp_proto_field;
10897 #undef _
10898
10899   if (found_something == 0)
10900     return 0;
10901
10902   vec_validate (mask, sizeof (*tcp) - 1);
10903
10904   tcp = (tcp_header_t *) mask;
10905
10906 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10907   foreach_tcp_proto_field;
10908 #undef _
10909
10910   *maskp = mask;
10911   return 1;
10912 }
10913
10914 uword
10915 unformat_udp_mask (unformat_input_t * input, va_list * args)
10916 {
10917   u8 **maskp = va_arg (*args, u8 **);
10918   u8 *mask = 0;
10919   u8 found_something = 0;
10920   udp_header_t *udp;
10921
10922 #define _(a) u8 a=0;
10923   foreach_udp_proto_field;
10924 #undef _
10925
10926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10927     {
10928       if (0);
10929 #define _(a) else if (unformat (input, #a)) a=1;
10930       foreach_udp_proto_field
10931 #undef _
10932         else
10933         break;
10934     }
10935
10936 #define _(a) found_something += a;
10937   foreach_udp_proto_field;
10938 #undef _
10939
10940   if (found_something == 0)
10941     return 0;
10942
10943   vec_validate (mask, sizeof (*udp) - 1);
10944
10945   udp = (udp_header_t *) mask;
10946
10947 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10948   foreach_udp_proto_field;
10949 #undef _
10950
10951   *maskp = mask;
10952   return 1;
10953 }
10954
10955 uword
10956 unformat_l4_mask (unformat_input_t * input, va_list * args)
10957 {
10958   u8 **maskp = va_arg (*args, u8 **);
10959   u16 src_port = 0, dst_port = 0;
10960   tcpudp_header_t *tcpudp;
10961
10962   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10963     {
10964       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10965         return 1;
10966       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10967         return 1;
10968       else if (unformat (input, "src_port"))
10969         src_port = 0xFFFF;
10970       else if (unformat (input, "dst_port"))
10971         dst_port = 0xFFFF;
10972       else
10973         return 0;
10974     }
10975
10976   if (!src_port && !dst_port)
10977     return 0;
10978
10979   u8 *mask = 0;
10980   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10981
10982   tcpudp = (tcpudp_header_t *) mask;
10983   tcpudp->src_port = src_port;
10984   tcpudp->dst_port = dst_port;
10985
10986   *maskp = mask;
10987
10988   return 1;
10989 }
10990
10991 uword
10992 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10993 {
10994   u8 **maskp = va_arg (*args, u8 **);
10995   u8 *mask = 0;
10996   u8 found_something = 0;
10997   ip4_header_t *ip;
10998
10999 #define _(a) u8 a=0;
11000   foreach_ip4_proto_field;
11001 #undef _
11002   u8 version = 0;
11003   u8 hdr_length = 0;
11004
11005
11006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11007     {
11008       if (unformat (input, "version"))
11009         version = 1;
11010       else if (unformat (input, "hdr_length"))
11011         hdr_length = 1;
11012       else if (unformat (input, "src"))
11013         src_address = 1;
11014       else if (unformat (input, "dst"))
11015         dst_address = 1;
11016       else if (unformat (input, "proto"))
11017         protocol = 1;
11018
11019 #define _(a) else if (unformat (input, #a)) a=1;
11020       foreach_ip4_proto_field
11021 #undef _
11022         else
11023         break;
11024     }
11025
11026 #define _(a) found_something += a;
11027   foreach_ip4_proto_field;
11028 #undef _
11029
11030   if (found_something == 0)
11031     return 0;
11032
11033   vec_validate (mask, sizeof (*ip) - 1);
11034
11035   ip = (ip4_header_t *) mask;
11036
11037 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11038   foreach_ip4_proto_field;
11039 #undef _
11040
11041   ip->ip_version_and_header_length = 0;
11042
11043   if (version)
11044     ip->ip_version_and_header_length |= 0xF0;
11045
11046   if (hdr_length)
11047     ip->ip_version_and_header_length |= 0x0F;
11048
11049   *maskp = mask;
11050   return 1;
11051 }
11052
11053 #define foreach_ip6_proto_field                 \
11054 _(src_address)                                  \
11055 _(dst_address)                                  \
11056 _(payload_length)                               \
11057 _(hop_limit)                                    \
11058 _(protocol)
11059
11060 uword
11061 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11062 {
11063   u8 **maskp = va_arg (*args, u8 **);
11064   u8 *mask = 0;
11065   u8 found_something = 0;
11066   ip6_header_t *ip;
11067   u32 ip_version_traffic_class_and_flow_label;
11068
11069 #define _(a) u8 a=0;
11070   foreach_ip6_proto_field;
11071 #undef _
11072   u8 version = 0;
11073   u8 traffic_class = 0;
11074   u8 flow_label = 0;
11075
11076   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11077     {
11078       if (unformat (input, "version"))
11079         version = 1;
11080       else if (unformat (input, "traffic-class"))
11081         traffic_class = 1;
11082       else if (unformat (input, "flow-label"))
11083         flow_label = 1;
11084       else if (unformat (input, "src"))
11085         src_address = 1;
11086       else if (unformat (input, "dst"))
11087         dst_address = 1;
11088       else if (unformat (input, "proto"))
11089         protocol = 1;
11090
11091 #define _(a) else if (unformat (input, #a)) a=1;
11092       foreach_ip6_proto_field
11093 #undef _
11094         else
11095         break;
11096     }
11097
11098 #define _(a) found_something += a;
11099   foreach_ip6_proto_field;
11100 #undef _
11101
11102   if (found_something == 0)
11103     return 0;
11104
11105   vec_validate (mask, sizeof (*ip) - 1);
11106
11107   ip = (ip6_header_t *) mask;
11108
11109 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11110   foreach_ip6_proto_field;
11111 #undef _
11112
11113   ip_version_traffic_class_and_flow_label = 0;
11114
11115   if (version)
11116     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11117
11118   if (traffic_class)
11119     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11120
11121   if (flow_label)
11122     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11123
11124   ip->ip_version_traffic_class_and_flow_label =
11125     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11126
11127   *maskp = mask;
11128   return 1;
11129 }
11130
11131 uword
11132 unformat_l3_mask (unformat_input_t * input, va_list * args)
11133 {
11134   u8 **maskp = va_arg (*args, u8 **);
11135
11136   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11137     {
11138       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11139         return 1;
11140       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11141         return 1;
11142       else
11143         break;
11144     }
11145   return 0;
11146 }
11147
11148 uword
11149 unformat_l2_mask (unformat_input_t * input, va_list * args)
11150 {
11151   u8 **maskp = va_arg (*args, u8 **);
11152   u8 *mask = 0;
11153   u8 src = 0;
11154   u8 dst = 0;
11155   u8 proto = 0;
11156   u8 tag1 = 0;
11157   u8 tag2 = 0;
11158   u8 ignore_tag1 = 0;
11159   u8 ignore_tag2 = 0;
11160   u8 cos1 = 0;
11161   u8 cos2 = 0;
11162   u8 dot1q = 0;
11163   u8 dot1ad = 0;
11164   int len = 14;
11165
11166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11167     {
11168       if (unformat (input, "src"))
11169         src = 1;
11170       else if (unformat (input, "dst"))
11171         dst = 1;
11172       else if (unformat (input, "proto"))
11173         proto = 1;
11174       else if (unformat (input, "tag1"))
11175         tag1 = 1;
11176       else if (unformat (input, "tag2"))
11177         tag2 = 1;
11178       else if (unformat (input, "ignore-tag1"))
11179         ignore_tag1 = 1;
11180       else if (unformat (input, "ignore-tag2"))
11181         ignore_tag2 = 1;
11182       else if (unformat (input, "cos1"))
11183         cos1 = 1;
11184       else if (unformat (input, "cos2"))
11185         cos2 = 1;
11186       else if (unformat (input, "dot1q"))
11187         dot1q = 1;
11188       else if (unformat (input, "dot1ad"))
11189         dot1ad = 1;
11190       else
11191         break;
11192     }
11193   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11194        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11195     return 0;
11196
11197   if (tag1 || ignore_tag1 || cos1 || dot1q)
11198     len = 18;
11199   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11200     len = 22;
11201
11202   vec_validate (mask, len - 1);
11203
11204   if (dst)
11205     memset (mask, 0xff, 6);
11206
11207   if (src)
11208     memset (mask + 6, 0xff, 6);
11209
11210   if (tag2 || dot1ad)
11211     {
11212       /* inner vlan tag */
11213       if (tag2)
11214         {
11215           mask[19] = 0xff;
11216           mask[18] = 0x0f;
11217         }
11218       if (cos2)
11219         mask[18] |= 0xe0;
11220       if (proto)
11221         mask[21] = mask[20] = 0xff;
11222       if (tag1)
11223         {
11224           mask[15] = 0xff;
11225           mask[14] = 0x0f;
11226         }
11227       if (cos1)
11228         mask[14] |= 0xe0;
11229       *maskp = mask;
11230       return 1;
11231     }
11232   if (tag1 | dot1q)
11233     {
11234       if (tag1)
11235         {
11236           mask[15] = 0xff;
11237           mask[14] = 0x0f;
11238         }
11239       if (cos1)
11240         mask[14] |= 0xe0;
11241       if (proto)
11242         mask[16] = mask[17] = 0xff;
11243
11244       *maskp = mask;
11245       return 1;
11246     }
11247   if (cos2)
11248     mask[18] |= 0xe0;
11249   if (cos1)
11250     mask[14] |= 0xe0;
11251   if (proto)
11252     mask[12] = mask[13] = 0xff;
11253
11254   *maskp = mask;
11255   return 1;
11256 }
11257
11258 uword
11259 unformat_classify_mask (unformat_input_t * input, va_list * args)
11260 {
11261   u8 **maskp = va_arg (*args, u8 **);
11262   u32 *skipp = va_arg (*args, u32 *);
11263   u32 *matchp = va_arg (*args, u32 *);
11264   u32 match;
11265   u8 *mask = 0;
11266   u8 *l2 = 0;
11267   u8 *l3 = 0;
11268   u8 *l4 = 0;
11269   int i;
11270
11271   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11272     {
11273       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11274         ;
11275       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11276         ;
11277       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11278         ;
11279       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11280         ;
11281       else
11282         break;
11283     }
11284
11285   if (l4 && !l3)
11286     {
11287       vec_free (mask);
11288       vec_free (l2);
11289       vec_free (l4);
11290       return 0;
11291     }
11292
11293   if (mask || l2 || l3 || l4)
11294     {
11295       if (l2 || l3 || l4)
11296         {
11297           /* "With a free Ethernet header in every package" */
11298           if (l2 == 0)
11299             vec_validate (l2, 13);
11300           mask = l2;
11301           if (vec_len (l3))
11302             {
11303               vec_append (mask, l3);
11304               vec_free (l3);
11305             }
11306           if (vec_len (l4))
11307             {
11308               vec_append (mask, l4);
11309               vec_free (l4);
11310             }
11311         }
11312
11313       /* Scan forward looking for the first significant mask octet */
11314       for (i = 0; i < vec_len (mask); i++)
11315         if (mask[i])
11316           break;
11317
11318       /* compute (skip, match) params */
11319       *skipp = i / sizeof (u32x4);
11320       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11321
11322       /* Pad mask to an even multiple of the vector size */
11323       while (vec_len (mask) % sizeof (u32x4))
11324         vec_add1 (mask, 0);
11325
11326       match = vec_len (mask) / sizeof (u32x4);
11327
11328       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11329         {
11330           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11331           if (*tmp || *(tmp + 1))
11332             break;
11333           match--;
11334         }
11335       if (match == 0)
11336         clib_warning ("BUG: match 0");
11337
11338       _vec_len (mask) = match * sizeof (u32x4);
11339
11340       *matchp = match;
11341       *maskp = mask;
11342
11343       return 1;
11344     }
11345
11346   return 0;
11347 }
11348 #endif /* VPP_API_TEST_BUILTIN */
11349
11350 #define foreach_l2_next                         \
11351 _(drop, DROP)                                   \
11352 _(ethernet, ETHERNET_INPUT)                     \
11353 _(ip4, IP4_INPUT)                               \
11354 _(ip6, IP6_INPUT)
11355
11356 uword
11357 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11358 {
11359   u32 *miss_next_indexp = va_arg (*args, u32 *);
11360   u32 next_index = 0;
11361   u32 tmp;
11362
11363 #define _(n,N) \
11364   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11365   foreach_l2_next;
11366 #undef _
11367
11368   if (unformat (input, "%d", &tmp))
11369     {
11370       next_index = tmp;
11371       goto out;
11372     }
11373
11374   return 0;
11375
11376 out:
11377   *miss_next_indexp = next_index;
11378   return 1;
11379 }
11380
11381 #define foreach_ip_next                         \
11382 _(drop, DROP)                                   \
11383 _(local, LOCAL)                                 \
11384 _(rewrite, REWRITE)
11385
11386 uword
11387 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11388 {
11389   u32 *miss_next_indexp = va_arg (*args, u32 *);
11390   u32 next_index = 0;
11391   u32 tmp;
11392
11393 #define _(n,N) \
11394   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11395   foreach_ip_next;
11396 #undef _
11397
11398   if (unformat (input, "%d", &tmp))
11399     {
11400       next_index = tmp;
11401       goto out;
11402     }
11403
11404   return 0;
11405
11406 out:
11407   *miss_next_indexp = next_index;
11408   return 1;
11409 }
11410
11411 #define foreach_acl_next                        \
11412 _(deny, DENY)
11413
11414 uword
11415 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11416 {
11417   u32 *miss_next_indexp = va_arg (*args, u32 *);
11418   u32 next_index = 0;
11419   u32 tmp;
11420
11421 #define _(n,N) \
11422   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11423   foreach_acl_next;
11424 #undef _
11425
11426   if (unformat (input, "permit"))
11427     {
11428       next_index = ~0;
11429       goto out;
11430     }
11431   else if (unformat (input, "%d", &tmp))
11432     {
11433       next_index = tmp;
11434       goto out;
11435     }
11436
11437   return 0;
11438
11439 out:
11440   *miss_next_indexp = next_index;
11441   return 1;
11442 }
11443
11444 uword
11445 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11446 {
11447   u32 *r = va_arg (*args, u32 *);
11448
11449   if (unformat (input, "conform-color"))
11450     *r = POLICE_CONFORM;
11451   else if (unformat (input, "exceed-color"))
11452     *r = POLICE_EXCEED;
11453   else
11454     return 0;
11455
11456   return 1;
11457 }
11458
11459 static int
11460 api_classify_add_del_table (vat_main_t * vam)
11461 {
11462   unformat_input_t *i = vam->input;
11463   vl_api_classify_add_del_table_t *mp;
11464
11465   u32 nbuckets = 2;
11466   u32 skip = ~0;
11467   u32 match = ~0;
11468   int is_add = 1;
11469   int del_chain = 0;
11470   u32 table_index = ~0;
11471   u32 next_table_index = ~0;
11472   u32 miss_next_index = ~0;
11473   u32 memory_size = 32 << 20;
11474   u8 *mask = 0;
11475   u32 current_data_flag = 0;
11476   int current_data_offset = 0;
11477   int ret;
11478
11479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11480     {
11481       if (unformat (i, "del"))
11482         is_add = 0;
11483       else if (unformat (i, "del-chain"))
11484         {
11485           is_add = 0;
11486           del_chain = 1;
11487         }
11488       else if (unformat (i, "buckets %d", &nbuckets))
11489         ;
11490       else if (unformat (i, "memory_size %d", &memory_size))
11491         ;
11492       else if (unformat (i, "skip %d", &skip))
11493         ;
11494       else if (unformat (i, "match %d", &match))
11495         ;
11496       else if (unformat (i, "table %d", &table_index))
11497         ;
11498       else if (unformat (i, "mask %U", unformat_classify_mask,
11499                          &mask, &skip, &match))
11500         ;
11501       else if (unformat (i, "next-table %d", &next_table_index))
11502         ;
11503       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11504                          &miss_next_index))
11505         ;
11506       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11507                          &miss_next_index))
11508         ;
11509       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11510                          &miss_next_index))
11511         ;
11512       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11513         ;
11514       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11515         ;
11516       else
11517         break;
11518     }
11519
11520   if (is_add && mask == 0)
11521     {
11522       errmsg ("Mask required");
11523       return -99;
11524     }
11525
11526   if (is_add && skip == ~0)
11527     {
11528       errmsg ("skip count required");
11529       return -99;
11530     }
11531
11532   if (is_add && match == ~0)
11533     {
11534       errmsg ("match count required");
11535       return -99;
11536     }
11537
11538   if (!is_add && table_index == ~0)
11539     {
11540       errmsg ("table index required for delete");
11541       return -99;
11542     }
11543
11544   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11545
11546   mp->is_add = is_add;
11547   mp->del_chain = del_chain;
11548   mp->table_index = ntohl (table_index);
11549   mp->nbuckets = ntohl (nbuckets);
11550   mp->memory_size = ntohl (memory_size);
11551   mp->skip_n_vectors = ntohl (skip);
11552   mp->match_n_vectors = ntohl (match);
11553   mp->next_table_index = ntohl (next_table_index);
11554   mp->miss_next_index = ntohl (miss_next_index);
11555   mp->current_data_flag = ntohl (current_data_flag);
11556   mp->current_data_offset = ntohl (current_data_offset);
11557   clib_memcpy (mp->mask, mask, vec_len (mask));
11558
11559   vec_free (mask);
11560
11561   S (mp);
11562   W (ret);
11563   return ret;
11564 }
11565
11566 #if VPP_API_TEST_BUILTIN == 0
11567 uword
11568 unformat_l4_match (unformat_input_t * input, va_list * args)
11569 {
11570   u8 **matchp = va_arg (*args, u8 **);
11571
11572   u8 *proto_header = 0;
11573   int src_port = 0;
11574   int dst_port = 0;
11575
11576   tcpudp_header_t h;
11577
11578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11579     {
11580       if (unformat (input, "src_port %d", &src_port))
11581         ;
11582       else if (unformat (input, "dst_port %d", &dst_port))
11583         ;
11584       else
11585         return 0;
11586     }
11587
11588   h.src_port = clib_host_to_net_u16 (src_port);
11589   h.dst_port = clib_host_to_net_u16 (dst_port);
11590   vec_validate (proto_header, sizeof (h) - 1);
11591   memcpy (proto_header, &h, sizeof (h));
11592
11593   *matchp = proto_header;
11594
11595   return 1;
11596 }
11597
11598 uword
11599 unformat_ip4_match (unformat_input_t * input, va_list * args)
11600 {
11601   u8 **matchp = va_arg (*args, u8 **);
11602   u8 *match = 0;
11603   ip4_header_t *ip;
11604   int version = 0;
11605   u32 version_val;
11606   int hdr_length = 0;
11607   u32 hdr_length_val;
11608   int src = 0, dst = 0;
11609   ip4_address_t src_val, dst_val;
11610   int proto = 0;
11611   u32 proto_val;
11612   int tos = 0;
11613   u32 tos_val;
11614   int length = 0;
11615   u32 length_val;
11616   int fragment_id = 0;
11617   u32 fragment_id_val;
11618   int ttl = 0;
11619   int ttl_val;
11620   int checksum = 0;
11621   u32 checksum_val;
11622
11623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11624     {
11625       if (unformat (input, "version %d", &version_val))
11626         version = 1;
11627       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11628         hdr_length = 1;
11629       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11630         src = 1;
11631       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11632         dst = 1;
11633       else if (unformat (input, "proto %d", &proto_val))
11634         proto = 1;
11635       else if (unformat (input, "tos %d", &tos_val))
11636         tos = 1;
11637       else if (unformat (input, "length %d", &length_val))
11638         length = 1;
11639       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11640         fragment_id = 1;
11641       else if (unformat (input, "ttl %d", &ttl_val))
11642         ttl = 1;
11643       else if (unformat (input, "checksum %d", &checksum_val))
11644         checksum = 1;
11645       else
11646         break;
11647     }
11648
11649   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11650       + ttl + checksum == 0)
11651     return 0;
11652
11653   /*
11654    * Aligned because we use the real comparison functions
11655    */
11656   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11657
11658   ip = (ip4_header_t *) match;
11659
11660   /* These are realistically matched in practice */
11661   if (src)
11662     ip->src_address.as_u32 = src_val.as_u32;
11663
11664   if (dst)
11665     ip->dst_address.as_u32 = dst_val.as_u32;
11666
11667   if (proto)
11668     ip->protocol = proto_val;
11669
11670
11671   /* These are not, but they're included for completeness */
11672   if (version)
11673     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11674
11675   if (hdr_length)
11676     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11677
11678   if (tos)
11679     ip->tos = tos_val;
11680
11681   if (length)
11682     ip->length = clib_host_to_net_u16 (length_val);
11683
11684   if (ttl)
11685     ip->ttl = ttl_val;
11686
11687   if (checksum)
11688     ip->checksum = clib_host_to_net_u16 (checksum_val);
11689
11690   *matchp = match;
11691   return 1;
11692 }
11693
11694 uword
11695 unformat_ip6_match (unformat_input_t * input, va_list * args)
11696 {
11697   u8 **matchp = va_arg (*args, u8 **);
11698   u8 *match = 0;
11699   ip6_header_t *ip;
11700   int version = 0;
11701   u32 version_val;
11702   u8 traffic_class = 0;
11703   u32 traffic_class_val = 0;
11704   u8 flow_label = 0;
11705   u8 flow_label_val;
11706   int src = 0, dst = 0;
11707   ip6_address_t src_val, dst_val;
11708   int proto = 0;
11709   u32 proto_val;
11710   int payload_length = 0;
11711   u32 payload_length_val;
11712   int hop_limit = 0;
11713   int hop_limit_val;
11714   u32 ip_version_traffic_class_and_flow_label;
11715
11716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11717     {
11718       if (unformat (input, "version %d", &version_val))
11719         version = 1;
11720       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11721         traffic_class = 1;
11722       else if (unformat (input, "flow_label %d", &flow_label_val))
11723         flow_label = 1;
11724       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11725         src = 1;
11726       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11727         dst = 1;
11728       else if (unformat (input, "proto %d", &proto_val))
11729         proto = 1;
11730       else if (unformat (input, "payload_length %d", &payload_length_val))
11731         payload_length = 1;
11732       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11733         hop_limit = 1;
11734       else
11735         break;
11736     }
11737
11738   if (version + traffic_class + flow_label + src + dst + proto +
11739       payload_length + hop_limit == 0)
11740     return 0;
11741
11742   /*
11743    * Aligned because we use the real comparison functions
11744    */
11745   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11746
11747   ip = (ip6_header_t *) match;
11748
11749   if (src)
11750     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11751
11752   if (dst)
11753     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11754
11755   if (proto)
11756     ip->protocol = proto_val;
11757
11758   ip_version_traffic_class_and_flow_label = 0;
11759
11760   if (version)
11761     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11762
11763   if (traffic_class)
11764     ip_version_traffic_class_and_flow_label |=
11765       (traffic_class_val & 0xFF) << 20;
11766
11767   if (flow_label)
11768     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11769
11770   ip->ip_version_traffic_class_and_flow_label =
11771     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11772
11773   if (payload_length)
11774     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11775
11776   if (hop_limit)
11777     ip->hop_limit = hop_limit_val;
11778
11779   *matchp = match;
11780   return 1;
11781 }
11782
11783 uword
11784 unformat_l3_match (unformat_input_t * input, va_list * args)
11785 {
11786   u8 **matchp = va_arg (*args, u8 **);
11787
11788   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11789     {
11790       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11791         return 1;
11792       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11793         return 1;
11794       else
11795         break;
11796     }
11797   return 0;
11798 }
11799
11800 uword
11801 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11802 {
11803   u8 *tagp = va_arg (*args, u8 *);
11804   u32 tag;
11805
11806   if (unformat (input, "%d", &tag))
11807     {
11808       tagp[0] = (tag >> 8) & 0x0F;
11809       tagp[1] = tag & 0xFF;
11810       return 1;
11811     }
11812
11813   return 0;
11814 }
11815
11816 uword
11817 unformat_l2_match (unformat_input_t * input, va_list * args)
11818 {
11819   u8 **matchp = va_arg (*args, u8 **);
11820   u8 *match = 0;
11821   u8 src = 0;
11822   u8 src_val[6];
11823   u8 dst = 0;
11824   u8 dst_val[6];
11825   u8 proto = 0;
11826   u16 proto_val;
11827   u8 tag1 = 0;
11828   u8 tag1_val[2];
11829   u8 tag2 = 0;
11830   u8 tag2_val[2];
11831   int len = 14;
11832   u8 ignore_tag1 = 0;
11833   u8 ignore_tag2 = 0;
11834   u8 cos1 = 0;
11835   u8 cos2 = 0;
11836   u32 cos1_val = 0;
11837   u32 cos2_val = 0;
11838
11839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11840     {
11841       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11842         src = 1;
11843       else
11844         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11845         dst = 1;
11846       else if (unformat (input, "proto %U",
11847                          unformat_ethernet_type_host_byte_order, &proto_val))
11848         proto = 1;
11849       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11850         tag1 = 1;
11851       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11852         tag2 = 1;
11853       else if (unformat (input, "ignore-tag1"))
11854         ignore_tag1 = 1;
11855       else if (unformat (input, "ignore-tag2"))
11856         ignore_tag2 = 1;
11857       else if (unformat (input, "cos1 %d", &cos1_val))
11858         cos1 = 1;
11859       else if (unformat (input, "cos2 %d", &cos2_val))
11860         cos2 = 1;
11861       else
11862         break;
11863     }
11864   if ((src + dst + proto + tag1 + tag2 +
11865        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11866     return 0;
11867
11868   if (tag1 || ignore_tag1 || cos1)
11869     len = 18;
11870   if (tag2 || ignore_tag2 || cos2)
11871     len = 22;
11872
11873   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11874
11875   if (dst)
11876     clib_memcpy (match, dst_val, 6);
11877
11878   if (src)
11879     clib_memcpy (match + 6, src_val, 6);
11880
11881   if (tag2)
11882     {
11883       /* inner vlan tag */
11884       match[19] = tag2_val[1];
11885       match[18] = tag2_val[0];
11886       if (cos2)
11887         match[18] |= (cos2_val & 0x7) << 5;
11888       if (proto)
11889         {
11890           match[21] = proto_val & 0xff;
11891           match[20] = proto_val >> 8;
11892         }
11893       if (tag1)
11894         {
11895           match[15] = tag1_val[1];
11896           match[14] = tag1_val[0];
11897         }
11898       if (cos1)
11899         match[14] |= (cos1_val & 0x7) << 5;
11900       *matchp = match;
11901       return 1;
11902     }
11903   if (tag1)
11904     {
11905       match[15] = tag1_val[1];
11906       match[14] = tag1_val[0];
11907       if (proto)
11908         {
11909           match[17] = proto_val & 0xff;
11910           match[16] = proto_val >> 8;
11911         }
11912       if (cos1)
11913         match[14] |= (cos1_val & 0x7) << 5;
11914
11915       *matchp = match;
11916       return 1;
11917     }
11918   if (cos2)
11919     match[18] |= (cos2_val & 0x7) << 5;
11920   if (cos1)
11921     match[14] |= (cos1_val & 0x7) << 5;
11922   if (proto)
11923     {
11924       match[13] = proto_val & 0xff;
11925       match[12] = proto_val >> 8;
11926     }
11927
11928   *matchp = match;
11929   return 1;
11930 }
11931
11932 uword
11933 unformat_qos_source (unformat_input_t * input, va_list * args)
11934 {
11935   int *qs = va_arg (*args, int *);
11936
11937   if (unformat (input, "ip"))
11938     *qs = QOS_SOURCE_IP;
11939   else if (unformat (input, "mpls"))
11940     *qs = QOS_SOURCE_MPLS;
11941   else if (unformat (input, "ext"))
11942     *qs = QOS_SOURCE_EXT;
11943   else if (unformat (input, "vlan"))
11944     *qs = QOS_SOURCE_VLAN;
11945   else
11946     return 0;
11947
11948   return 1;
11949 }
11950 #endif
11951
11952 uword
11953 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11954 {
11955   u8 **matchp = va_arg (*args, u8 **);
11956   u32 skip_n_vectors = va_arg (*args, u32);
11957   u32 match_n_vectors = va_arg (*args, u32);
11958
11959   u8 *match = 0;
11960   u8 *l2 = 0;
11961   u8 *l3 = 0;
11962   u8 *l4 = 0;
11963
11964   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11965     {
11966       if (unformat (input, "hex %U", unformat_hex_string, &match))
11967         ;
11968       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11969         ;
11970       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11971         ;
11972       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11973         ;
11974       else
11975         break;
11976     }
11977
11978   if (l4 && !l3)
11979     {
11980       vec_free (match);
11981       vec_free (l2);
11982       vec_free (l4);
11983       return 0;
11984     }
11985
11986   if (match || l2 || l3 || l4)
11987     {
11988       if (l2 || l3 || l4)
11989         {
11990           /* "Win a free Ethernet header in every packet" */
11991           if (l2 == 0)
11992             vec_validate_aligned (l2, 13, sizeof (u32x4));
11993           match = l2;
11994           if (vec_len (l3))
11995             {
11996               vec_append_aligned (match, l3, sizeof (u32x4));
11997               vec_free (l3);
11998             }
11999           if (vec_len (l4))
12000             {
12001               vec_append_aligned (match, l4, sizeof (u32x4));
12002               vec_free (l4);
12003             }
12004         }
12005
12006       /* Make sure the vector is big enough even if key is all 0's */
12007       vec_validate_aligned
12008         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12009          sizeof (u32x4));
12010
12011       /* Set size, include skipped vectors */
12012       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12013
12014       *matchp = match;
12015
12016       return 1;
12017     }
12018
12019   return 0;
12020 }
12021
12022 static int
12023 api_classify_add_del_session (vat_main_t * vam)
12024 {
12025   unformat_input_t *i = vam->input;
12026   vl_api_classify_add_del_session_t *mp;
12027   int is_add = 1;
12028   u32 table_index = ~0;
12029   u32 hit_next_index = ~0;
12030   u32 opaque_index = ~0;
12031   u8 *match = 0;
12032   i32 advance = 0;
12033   u32 skip_n_vectors = 0;
12034   u32 match_n_vectors = 0;
12035   u32 action = 0;
12036   u32 metadata = 0;
12037   int ret;
12038
12039   /*
12040    * Warning: you have to supply skip_n and match_n
12041    * because the API client cant simply look at the classify
12042    * table object.
12043    */
12044
12045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12046     {
12047       if (unformat (i, "del"))
12048         is_add = 0;
12049       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12050                          &hit_next_index))
12051         ;
12052       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12053                          &hit_next_index))
12054         ;
12055       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12056                          &hit_next_index))
12057         ;
12058       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12059         ;
12060       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12061         ;
12062       else if (unformat (i, "opaque-index %d", &opaque_index))
12063         ;
12064       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12065         ;
12066       else if (unformat (i, "match_n %d", &match_n_vectors))
12067         ;
12068       else if (unformat (i, "match %U", api_unformat_classify_match,
12069                          &match, skip_n_vectors, match_n_vectors))
12070         ;
12071       else if (unformat (i, "advance %d", &advance))
12072         ;
12073       else if (unformat (i, "table-index %d", &table_index))
12074         ;
12075       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12076         action = 1;
12077       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12078         action = 2;
12079       else if (unformat (i, "action %d", &action))
12080         ;
12081       else if (unformat (i, "metadata %d", &metadata))
12082         ;
12083       else
12084         break;
12085     }
12086
12087   if (table_index == ~0)
12088     {
12089       errmsg ("Table index required");
12090       return -99;
12091     }
12092
12093   if (is_add && match == 0)
12094     {
12095       errmsg ("Match value required");
12096       return -99;
12097     }
12098
12099   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12100
12101   mp->is_add = is_add;
12102   mp->table_index = ntohl (table_index);
12103   mp->hit_next_index = ntohl (hit_next_index);
12104   mp->opaque_index = ntohl (opaque_index);
12105   mp->advance = ntohl (advance);
12106   mp->action = action;
12107   mp->metadata = ntohl (metadata);
12108   clib_memcpy (mp->match, match, vec_len (match));
12109   vec_free (match);
12110
12111   S (mp);
12112   W (ret);
12113   return ret;
12114 }
12115
12116 static int
12117 api_classify_set_interface_ip_table (vat_main_t * vam)
12118 {
12119   unformat_input_t *i = vam->input;
12120   vl_api_classify_set_interface_ip_table_t *mp;
12121   u32 sw_if_index;
12122   int sw_if_index_set;
12123   u32 table_index = ~0;
12124   u8 is_ipv6 = 0;
12125   int ret;
12126
12127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12128     {
12129       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12130         sw_if_index_set = 1;
12131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12132         sw_if_index_set = 1;
12133       else if (unformat (i, "table %d", &table_index))
12134         ;
12135       else
12136         {
12137           clib_warning ("parse error '%U'", format_unformat_error, i);
12138           return -99;
12139         }
12140     }
12141
12142   if (sw_if_index_set == 0)
12143     {
12144       errmsg ("missing interface name or sw_if_index");
12145       return -99;
12146     }
12147
12148
12149   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12150
12151   mp->sw_if_index = ntohl (sw_if_index);
12152   mp->table_index = ntohl (table_index);
12153   mp->is_ipv6 = is_ipv6;
12154
12155   S (mp);
12156   W (ret);
12157   return ret;
12158 }
12159
12160 static int
12161 api_classify_set_interface_l2_tables (vat_main_t * vam)
12162 {
12163   unformat_input_t *i = vam->input;
12164   vl_api_classify_set_interface_l2_tables_t *mp;
12165   u32 sw_if_index;
12166   int sw_if_index_set;
12167   u32 ip4_table_index = ~0;
12168   u32 ip6_table_index = ~0;
12169   u32 other_table_index = ~0;
12170   u32 is_input = 1;
12171   int ret;
12172
12173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12174     {
12175       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12176         sw_if_index_set = 1;
12177       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12178         sw_if_index_set = 1;
12179       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12180         ;
12181       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12182         ;
12183       else if (unformat (i, "other-table %d", &other_table_index))
12184         ;
12185       else if (unformat (i, "is-input %d", &is_input))
12186         ;
12187       else
12188         {
12189           clib_warning ("parse error '%U'", format_unformat_error, i);
12190           return -99;
12191         }
12192     }
12193
12194   if (sw_if_index_set == 0)
12195     {
12196       errmsg ("missing interface name or sw_if_index");
12197       return -99;
12198     }
12199
12200
12201   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12202
12203   mp->sw_if_index = ntohl (sw_if_index);
12204   mp->ip4_table_index = ntohl (ip4_table_index);
12205   mp->ip6_table_index = ntohl (ip6_table_index);
12206   mp->other_table_index = ntohl (other_table_index);
12207   mp->is_input = (u8) is_input;
12208
12209   S (mp);
12210   W (ret);
12211   return ret;
12212 }
12213
12214 static int
12215 api_set_ipfix_exporter (vat_main_t * vam)
12216 {
12217   unformat_input_t *i = vam->input;
12218   vl_api_set_ipfix_exporter_t *mp;
12219   ip4_address_t collector_address;
12220   u8 collector_address_set = 0;
12221   u32 collector_port = ~0;
12222   ip4_address_t src_address;
12223   u8 src_address_set = 0;
12224   u32 vrf_id = ~0;
12225   u32 path_mtu = ~0;
12226   u32 template_interval = ~0;
12227   u8 udp_checksum = 0;
12228   int ret;
12229
12230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12231     {
12232       if (unformat (i, "collector_address %U", unformat_ip4_address,
12233                     &collector_address))
12234         collector_address_set = 1;
12235       else if (unformat (i, "collector_port %d", &collector_port))
12236         ;
12237       else if (unformat (i, "src_address %U", unformat_ip4_address,
12238                          &src_address))
12239         src_address_set = 1;
12240       else if (unformat (i, "vrf_id %d", &vrf_id))
12241         ;
12242       else if (unformat (i, "path_mtu %d", &path_mtu))
12243         ;
12244       else if (unformat (i, "template_interval %d", &template_interval))
12245         ;
12246       else if (unformat (i, "udp_checksum"))
12247         udp_checksum = 1;
12248       else
12249         break;
12250     }
12251
12252   if (collector_address_set == 0)
12253     {
12254       errmsg ("collector_address required");
12255       return -99;
12256     }
12257
12258   if (src_address_set == 0)
12259     {
12260       errmsg ("src_address required");
12261       return -99;
12262     }
12263
12264   M (SET_IPFIX_EXPORTER, mp);
12265
12266   memcpy (mp->collector_address, collector_address.data,
12267           sizeof (collector_address.data));
12268   mp->collector_port = htons ((u16) collector_port);
12269   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12270   mp->vrf_id = htonl (vrf_id);
12271   mp->path_mtu = htonl (path_mtu);
12272   mp->template_interval = htonl (template_interval);
12273   mp->udp_checksum = udp_checksum;
12274
12275   S (mp);
12276   W (ret);
12277   return ret;
12278 }
12279
12280 static int
12281 api_set_ipfix_classify_stream (vat_main_t * vam)
12282 {
12283   unformat_input_t *i = vam->input;
12284   vl_api_set_ipfix_classify_stream_t *mp;
12285   u32 domain_id = 0;
12286   u32 src_port = UDP_DST_PORT_ipfix;
12287   int ret;
12288
12289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12290     {
12291       if (unformat (i, "domain %d", &domain_id))
12292         ;
12293       else if (unformat (i, "src_port %d", &src_port))
12294         ;
12295       else
12296         {
12297           errmsg ("unknown input `%U'", format_unformat_error, i);
12298           return -99;
12299         }
12300     }
12301
12302   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12303
12304   mp->domain_id = htonl (domain_id);
12305   mp->src_port = htons ((u16) src_port);
12306
12307   S (mp);
12308   W (ret);
12309   return ret;
12310 }
12311
12312 static int
12313 api_ipfix_classify_table_add_del (vat_main_t * vam)
12314 {
12315   unformat_input_t *i = vam->input;
12316   vl_api_ipfix_classify_table_add_del_t *mp;
12317   int is_add = -1;
12318   u32 classify_table_index = ~0;
12319   u8 ip_version = 0;
12320   u8 transport_protocol = 255;
12321   int ret;
12322
12323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12324     {
12325       if (unformat (i, "add"))
12326         is_add = 1;
12327       else if (unformat (i, "del"))
12328         is_add = 0;
12329       else if (unformat (i, "table %d", &classify_table_index))
12330         ;
12331       else if (unformat (i, "ip4"))
12332         ip_version = 4;
12333       else if (unformat (i, "ip6"))
12334         ip_version = 6;
12335       else if (unformat (i, "tcp"))
12336         transport_protocol = 6;
12337       else if (unformat (i, "udp"))
12338         transport_protocol = 17;
12339       else
12340         {
12341           errmsg ("unknown input `%U'", format_unformat_error, i);
12342           return -99;
12343         }
12344     }
12345
12346   if (is_add == -1)
12347     {
12348       errmsg ("expecting: add|del");
12349       return -99;
12350     }
12351   if (classify_table_index == ~0)
12352     {
12353       errmsg ("classifier table not specified");
12354       return -99;
12355     }
12356   if (ip_version == 0)
12357     {
12358       errmsg ("IP version not specified");
12359       return -99;
12360     }
12361
12362   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12363
12364   mp->is_add = is_add;
12365   mp->table_id = htonl (classify_table_index);
12366   mp->ip_version = ip_version;
12367   mp->transport_protocol = transport_protocol;
12368
12369   S (mp);
12370   W (ret);
12371   return ret;
12372 }
12373
12374 static int
12375 api_get_node_index (vat_main_t * vam)
12376 {
12377   unformat_input_t *i = vam->input;
12378   vl_api_get_node_index_t *mp;
12379   u8 *name = 0;
12380   int ret;
12381
12382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12383     {
12384       if (unformat (i, "node %s", &name))
12385         ;
12386       else
12387         break;
12388     }
12389   if (name == 0)
12390     {
12391       errmsg ("node name required");
12392       return -99;
12393     }
12394   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12395     {
12396       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12397       return -99;
12398     }
12399
12400   M (GET_NODE_INDEX, mp);
12401   clib_memcpy (mp->node_name, name, vec_len (name));
12402   vec_free (name);
12403
12404   S (mp);
12405   W (ret);
12406   return ret;
12407 }
12408
12409 static int
12410 api_get_next_index (vat_main_t * vam)
12411 {
12412   unformat_input_t *i = vam->input;
12413   vl_api_get_next_index_t *mp;
12414   u8 *node_name = 0, *next_node_name = 0;
12415   int ret;
12416
12417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12418     {
12419       if (unformat (i, "node-name %s", &node_name))
12420         ;
12421       else if (unformat (i, "next-node-name %s", &next_node_name))
12422         break;
12423     }
12424
12425   if (node_name == 0)
12426     {
12427       errmsg ("node name required");
12428       return -99;
12429     }
12430   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12431     {
12432       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12433       return -99;
12434     }
12435
12436   if (next_node_name == 0)
12437     {
12438       errmsg ("next node name required");
12439       return -99;
12440     }
12441   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12442     {
12443       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12444       return -99;
12445     }
12446
12447   M (GET_NEXT_INDEX, mp);
12448   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12449   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12450   vec_free (node_name);
12451   vec_free (next_node_name);
12452
12453   S (mp);
12454   W (ret);
12455   return ret;
12456 }
12457
12458 static int
12459 api_add_node_next (vat_main_t * vam)
12460 {
12461   unformat_input_t *i = vam->input;
12462   vl_api_add_node_next_t *mp;
12463   u8 *name = 0;
12464   u8 *next = 0;
12465   int ret;
12466
12467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12468     {
12469       if (unformat (i, "node %s", &name))
12470         ;
12471       else if (unformat (i, "next %s", &next))
12472         ;
12473       else
12474         break;
12475     }
12476   if (name == 0)
12477     {
12478       errmsg ("node name required");
12479       return -99;
12480     }
12481   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12482     {
12483       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12484       return -99;
12485     }
12486   if (next == 0)
12487     {
12488       errmsg ("next node required");
12489       return -99;
12490     }
12491   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12492     {
12493       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12494       return -99;
12495     }
12496
12497   M (ADD_NODE_NEXT, mp);
12498   clib_memcpy (mp->node_name, name, vec_len (name));
12499   clib_memcpy (mp->next_name, next, vec_len (next));
12500   vec_free (name);
12501   vec_free (next);
12502
12503   S (mp);
12504   W (ret);
12505   return ret;
12506 }
12507
12508 static int
12509 api_l2tpv3_create_tunnel (vat_main_t * vam)
12510 {
12511   unformat_input_t *i = vam->input;
12512   ip6_address_t client_address, our_address;
12513   int client_address_set = 0;
12514   int our_address_set = 0;
12515   u32 local_session_id = 0;
12516   u32 remote_session_id = 0;
12517   u64 local_cookie = 0;
12518   u64 remote_cookie = 0;
12519   u8 l2_sublayer_present = 0;
12520   vl_api_l2tpv3_create_tunnel_t *mp;
12521   int ret;
12522
12523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12524     {
12525       if (unformat (i, "client_address %U", unformat_ip6_address,
12526                     &client_address))
12527         client_address_set = 1;
12528       else if (unformat (i, "our_address %U", unformat_ip6_address,
12529                          &our_address))
12530         our_address_set = 1;
12531       else if (unformat (i, "local_session_id %d", &local_session_id))
12532         ;
12533       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12534         ;
12535       else if (unformat (i, "local_cookie %lld", &local_cookie))
12536         ;
12537       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12538         ;
12539       else if (unformat (i, "l2-sublayer-present"))
12540         l2_sublayer_present = 1;
12541       else
12542         break;
12543     }
12544
12545   if (client_address_set == 0)
12546     {
12547       errmsg ("client_address required");
12548       return -99;
12549     }
12550
12551   if (our_address_set == 0)
12552     {
12553       errmsg ("our_address required");
12554       return -99;
12555     }
12556
12557   M (L2TPV3_CREATE_TUNNEL, mp);
12558
12559   clib_memcpy (mp->client_address, client_address.as_u8,
12560                sizeof (mp->client_address));
12561
12562   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12563
12564   mp->local_session_id = ntohl (local_session_id);
12565   mp->remote_session_id = ntohl (remote_session_id);
12566   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12567   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12568   mp->l2_sublayer_present = l2_sublayer_present;
12569   mp->is_ipv6 = 1;
12570
12571   S (mp);
12572   W (ret);
12573   return ret;
12574 }
12575
12576 static int
12577 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12578 {
12579   unformat_input_t *i = vam->input;
12580   u32 sw_if_index;
12581   u8 sw_if_index_set = 0;
12582   u64 new_local_cookie = 0;
12583   u64 new_remote_cookie = 0;
12584   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12585   int ret;
12586
12587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12588     {
12589       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12590         sw_if_index_set = 1;
12591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12592         sw_if_index_set = 1;
12593       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12594         ;
12595       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12596         ;
12597       else
12598         break;
12599     }
12600
12601   if (sw_if_index_set == 0)
12602     {
12603       errmsg ("missing interface name or sw_if_index");
12604       return -99;
12605     }
12606
12607   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12608
12609   mp->sw_if_index = ntohl (sw_if_index);
12610   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12611   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12612
12613   S (mp);
12614   W (ret);
12615   return ret;
12616 }
12617
12618 static int
12619 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12620 {
12621   unformat_input_t *i = vam->input;
12622   vl_api_l2tpv3_interface_enable_disable_t *mp;
12623   u32 sw_if_index;
12624   u8 sw_if_index_set = 0;
12625   u8 enable_disable = 1;
12626   int ret;
12627
12628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12629     {
12630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12631         sw_if_index_set = 1;
12632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12633         sw_if_index_set = 1;
12634       else if (unformat (i, "enable"))
12635         enable_disable = 1;
12636       else if (unformat (i, "disable"))
12637         enable_disable = 0;
12638       else
12639         break;
12640     }
12641
12642   if (sw_if_index_set == 0)
12643     {
12644       errmsg ("missing interface name or sw_if_index");
12645       return -99;
12646     }
12647
12648   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12649
12650   mp->sw_if_index = ntohl (sw_if_index);
12651   mp->enable_disable = enable_disable;
12652
12653   S (mp);
12654   W (ret);
12655   return ret;
12656 }
12657
12658 static int
12659 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12660 {
12661   unformat_input_t *i = vam->input;
12662   vl_api_l2tpv3_set_lookup_key_t *mp;
12663   u8 key = ~0;
12664   int ret;
12665
12666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12667     {
12668       if (unformat (i, "lookup_v6_src"))
12669         key = L2T_LOOKUP_SRC_ADDRESS;
12670       else if (unformat (i, "lookup_v6_dst"))
12671         key = L2T_LOOKUP_DST_ADDRESS;
12672       else if (unformat (i, "lookup_session_id"))
12673         key = L2T_LOOKUP_SESSION_ID;
12674       else
12675         break;
12676     }
12677
12678   if (key == (u8) ~ 0)
12679     {
12680       errmsg ("l2tp session lookup key unset");
12681       return -99;
12682     }
12683
12684   M (L2TPV3_SET_LOOKUP_KEY, mp);
12685
12686   mp->key = key;
12687
12688   S (mp);
12689   W (ret);
12690   return ret;
12691 }
12692
12693 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12694   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12695 {
12696   vat_main_t *vam = &vat_main;
12697
12698   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12699          format_ip6_address, mp->our_address,
12700          format_ip6_address, mp->client_address,
12701          clib_net_to_host_u32 (mp->sw_if_index));
12702
12703   print (vam->ofp,
12704          "   local cookies %016llx %016llx remote cookie %016llx",
12705          clib_net_to_host_u64 (mp->local_cookie[0]),
12706          clib_net_to_host_u64 (mp->local_cookie[1]),
12707          clib_net_to_host_u64 (mp->remote_cookie));
12708
12709   print (vam->ofp, "   local session-id %d remote session-id %d",
12710          clib_net_to_host_u32 (mp->local_session_id),
12711          clib_net_to_host_u32 (mp->remote_session_id));
12712
12713   print (vam->ofp, "   l2 specific sublayer %s\n",
12714          mp->l2_sublayer_present ? "preset" : "absent");
12715
12716 }
12717
12718 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12719   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12720 {
12721   vat_main_t *vam = &vat_main;
12722   vat_json_node_t *node = NULL;
12723   struct in6_addr addr;
12724
12725   if (VAT_JSON_ARRAY != vam->json_tree.type)
12726     {
12727       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12728       vat_json_init_array (&vam->json_tree);
12729     }
12730   node = vat_json_array_add (&vam->json_tree);
12731
12732   vat_json_init_object (node);
12733
12734   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12735   vat_json_object_add_ip6 (node, "our_address", addr);
12736   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12737   vat_json_object_add_ip6 (node, "client_address", addr);
12738
12739   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12740   vat_json_init_array (lc);
12741   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12742   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12743   vat_json_object_add_uint (node, "remote_cookie",
12744                             clib_net_to_host_u64 (mp->remote_cookie));
12745
12746   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12747   vat_json_object_add_uint (node, "local_session_id",
12748                             clib_net_to_host_u32 (mp->local_session_id));
12749   vat_json_object_add_uint (node, "remote_session_id",
12750                             clib_net_to_host_u32 (mp->remote_session_id));
12751   vat_json_object_add_string_copy (node, "l2_sublayer",
12752                                    mp->l2_sublayer_present ? (u8 *) "present"
12753                                    : (u8 *) "absent");
12754 }
12755
12756 static int
12757 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12758 {
12759   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12760   vl_api_control_ping_t *mp_ping;
12761   int ret;
12762
12763   /* Get list of l2tpv3-tunnel interfaces */
12764   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12765   S (mp);
12766
12767   /* Use a control ping for synchronization */
12768   MPING (CONTROL_PING, mp_ping);
12769   S (mp_ping);
12770
12771   W (ret);
12772   return ret;
12773 }
12774
12775
12776 static void vl_api_sw_interface_tap_details_t_handler
12777   (vl_api_sw_interface_tap_details_t * mp)
12778 {
12779   vat_main_t *vam = &vat_main;
12780
12781   print (vam->ofp, "%-16s %d",
12782          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12783 }
12784
12785 static void vl_api_sw_interface_tap_details_t_handler_json
12786   (vl_api_sw_interface_tap_details_t * mp)
12787 {
12788   vat_main_t *vam = &vat_main;
12789   vat_json_node_t *node = NULL;
12790
12791   if (VAT_JSON_ARRAY != vam->json_tree.type)
12792     {
12793       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12794       vat_json_init_array (&vam->json_tree);
12795     }
12796   node = vat_json_array_add (&vam->json_tree);
12797
12798   vat_json_init_object (node);
12799   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12800   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12801 }
12802
12803 static int
12804 api_sw_interface_tap_dump (vat_main_t * vam)
12805 {
12806   vl_api_sw_interface_tap_dump_t *mp;
12807   vl_api_control_ping_t *mp_ping;
12808   int ret;
12809
12810   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12811   /* Get list of tap interfaces */
12812   M (SW_INTERFACE_TAP_DUMP, mp);
12813   S (mp);
12814
12815   /* Use a control ping for synchronization */
12816   MPING (CONTROL_PING, mp_ping);
12817   S (mp_ping);
12818
12819   W (ret);
12820   return ret;
12821 }
12822
12823 static void vl_api_sw_interface_tap_v2_details_t_handler
12824   (vl_api_sw_interface_tap_v2_details_t * mp)
12825 {
12826   vat_main_t *vam = &vat_main;
12827
12828   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12829                     mp->host_ip4_prefix_len);
12830   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12831                     mp->host_ip6_prefix_len);
12832
12833   print (vam->ofp,
12834          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12835          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12836          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12837          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12838          mp->host_bridge, ip4, ip6);
12839
12840   vec_free (ip4);
12841   vec_free (ip6);
12842 }
12843
12844 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12845   (vl_api_sw_interface_tap_v2_details_t * mp)
12846 {
12847   vat_main_t *vam = &vat_main;
12848   vat_json_node_t *node = NULL;
12849
12850   if (VAT_JSON_ARRAY != vam->json_tree.type)
12851     {
12852       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12853       vat_json_init_array (&vam->json_tree);
12854     }
12855   node = vat_json_array_add (&vam->json_tree);
12856
12857   vat_json_init_object (node);
12858   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12859   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12860   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12861   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12862   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12863   vat_json_object_add_string_copy (node, "host_mac_addr",
12864                                    format (0, "%U", format_ethernet_address,
12865                                            &mp->host_mac_addr));
12866   vat_json_object_add_string_copy (node, "host_namespace",
12867                                    mp->host_namespace);
12868   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12869   vat_json_object_add_string_copy (node, "host_ip4_addr",
12870                                    format (0, "%U/%d", format_ip4_address,
12871                                            mp->host_ip4_addr,
12872                                            mp->host_ip4_prefix_len));
12873   vat_json_object_add_string_copy (node, "host_ip6_addr",
12874                                    format (0, "%U/%d", format_ip6_address,
12875                                            mp->host_ip6_addr,
12876                                            mp->host_ip6_prefix_len));
12877
12878 }
12879
12880 static int
12881 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12882 {
12883   vl_api_sw_interface_tap_v2_dump_t *mp;
12884   vl_api_control_ping_t *mp_ping;
12885   int ret;
12886
12887   print (vam->ofp,
12888          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12889          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12890          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12891          "host_ip6_addr");
12892
12893   /* Get list of tap interfaces */
12894   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12895   S (mp);
12896
12897   /* Use a control ping for synchronization */
12898   MPING (CONTROL_PING, mp_ping);
12899   S (mp_ping);
12900
12901   W (ret);
12902   return ret;
12903 }
12904
12905 static int
12906 api_vxlan_offload_rx (vat_main_t * vam)
12907 {
12908   unformat_input_t *line_input = vam->input;
12909   vl_api_vxlan_offload_rx_t *mp;
12910   u32 hw_if_index = ~0, rx_if_index = ~0;
12911   u8 is_add = 1;
12912   int ret;
12913
12914   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12915     {
12916       if (unformat (line_input, "del"))
12917         is_add = 0;
12918       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12919                          &hw_if_index))
12920         ;
12921       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12922         ;
12923       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12924                          &rx_if_index))
12925         ;
12926       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12927         ;
12928       else
12929         {
12930           errmsg ("parse error '%U'", format_unformat_error, line_input);
12931           return -99;
12932         }
12933     }
12934
12935   if (hw_if_index == ~0)
12936     {
12937       errmsg ("no hw interface");
12938       return -99;
12939     }
12940
12941   if (rx_if_index == ~0)
12942     {
12943       errmsg ("no rx tunnel");
12944       return -99;
12945     }
12946
12947   M (VXLAN_OFFLOAD_RX, mp);
12948
12949   mp->hw_if_index = ntohl (hw_if_index);
12950   mp->sw_if_index = ntohl (rx_if_index);
12951   mp->enable = is_add;
12952
12953   S (mp);
12954   W (ret);
12955   return ret;
12956 }
12957
12958 static uword unformat_vxlan_decap_next
12959   (unformat_input_t * input, va_list * args)
12960 {
12961   u32 *result = va_arg (*args, u32 *);
12962   u32 tmp;
12963
12964   if (unformat (input, "l2"))
12965     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12966   else if (unformat (input, "%d", &tmp))
12967     *result = tmp;
12968   else
12969     return 0;
12970   return 1;
12971 }
12972
12973 static int
12974 api_vxlan_add_del_tunnel (vat_main_t * vam)
12975 {
12976   unformat_input_t *line_input = vam->input;
12977   vl_api_vxlan_add_del_tunnel_t *mp;
12978   ip46_address_t src, dst;
12979   u8 is_add = 1;
12980   u8 ipv4_set = 0, ipv6_set = 0;
12981   u8 src_set = 0;
12982   u8 dst_set = 0;
12983   u8 grp_set = 0;
12984   u32 instance = ~0;
12985   u32 mcast_sw_if_index = ~0;
12986   u32 encap_vrf_id = 0;
12987   u32 decap_next_index = ~0;
12988   u32 vni = 0;
12989   int ret;
12990
12991   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12992   memset (&src, 0, sizeof src);
12993   memset (&dst, 0, sizeof dst);
12994
12995   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12996     {
12997       if (unformat (line_input, "del"))
12998         is_add = 0;
12999       else if (unformat (line_input, "instance %d", &instance))
13000         ;
13001       else
13002         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13003         {
13004           ipv4_set = 1;
13005           src_set = 1;
13006         }
13007       else
13008         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13009         {
13010           ipv4_set = 1;
13011           dst_set = 1;
13012         }
13013       else
13014         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13015         {
13016           ipv6_set = 1;
13017           src_set = 1;
13018         }
13019       else
13020         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13021         {
13022           ipv6_set = 1;
13023           dst_set = 1;
13024         }
13025       else if (unformat (line_input, "group %U %U",
13026                          unformat_ip4_address, &dst.ip4,
13027                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13028         {
13029           grp_set = dst_set = 1;
13030           ipv4_set = 1;
13031         }
13032       else if (unformat (line_input, "group %U",
13033                          unformat_ip4_address, &dst.ip4))
13034         {
13035           grp_set = dst_set = 1;
13036           ipv4_set = 1;
13037         }
13038       else if (unformat (line_input, "group %U %U",
13039                          unformat_ip6_address, &dst.ip6,
13040                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13041         {
13042           grp_set = dst_set = 1;
13043           ipv6_set = 1;
13044         }
13045       else if (unformat (line_input, "group %U",
13046                          unformat_ip6_address, &dst.ip6))
13047         {
13048           grp_set = dst_set = 1;
13049           ipv6_set = 1;
13050         }
13051       else
13052         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13053         ;
13054       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13055         ;
13056       else if (unformat (line_input, "decap-next %U",
13057                          unformat_vxlan_decap_next, &decap_next_index))
13058         ;
13059       else if (unformat (line_input, "vni %d", &vni))
13060         ;
13061       else
13062         {
13063           errmsg ("parse error '%U'", format_unformat_error, line_input);
13064           return -99;
13065         }
13066     }
13067
13068   if (src_set == 0)
13069     {
13070       errmsg ("tunnel src address not specified");
13071       return -99;
13072     }
13073   if (dst_set == 0)
13074     {
13075       errmsg ("tunnel dst address not specified");
13076       return -99;
13077     }
13078
13079   if (grp_set && !ip46_address_is_multicast (&dst))
13080     {
13081       errmsg ("tunnel group address not multicast");
13082       return -99;
13083     }
13084   if (grp_set && mcast_sw_if_index == ~0)
13085     {
13086       errmsg ("tunnel nonexistent multicast device");
13087       return -99;
13088     }
13089   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13090     {
13091       errmsg ("tunnel dst address must be unicast");
13092       return -99;
13093     }
13094
13095
13096   if (ipv4_set && ipv6_set)
13097     {
13098       errmsg ("both IPv4 and IPv6 addresses specified");
13099       return -99;
13100     }
13101
13102   if ((vni == 0) || (vni >> 24))
13103     {
13104       errmsg ("vni not specified or out of range");
13105       return -99;
13106     }
13107
13108   M (VXLAN_ADD_DEL_TUNNEL, mp);
13109
13110   if (ipv6_set)
13111     {
13112       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13113       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13114     }
13115   else
13116     {
13117       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13118       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13119     }
13120
13121   mp->instance = htonl (instance);
13122   mp->encap_vrf_id = ntohl (encap_vrf_id);
13123   mp->decap_next_index = ntohl (decap_next_index);
13124   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13125   mp->vni = ntohl (vni);
13126   mp->is_add = is_add;
13127   mp->is_ipv6 = ipv6_set;
13128
13129   S (mp);
13130   W (ret);
13131   return ret;
13132 }
13133
13134 static void vl_api_vxlan_tunnel_details_t_handler
13135   (vl_api_vxlan_tunnel_details_t * mp)
13136 {
13137   vat_main_t *vam = &vat_main;
13138   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13139   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13140
13141   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13142          ntohl (mp->sw_if_index),
13143          ntohl (mp->instance),
13144          format_ip46_address, &src, IP46_TYPE_ANY,
13145          format_ip46_address, &dst, IP46_TYPE_ANY,
13146          ntohl (mp->encap_vrf_id),
13147          ntohl (mp->decap_next_index), ntohl (mp->vni),
13148          ntohl (mp->mcast_sw_if_index));
13149 }
13150
13151 static void vl_api_vxlan_tunnel_details_t_handler_json
13152   (vl_api_vxlan_tunnel_details_t * mp)
13153 {
13154   vat_main_t *vam = &vat_main;
13155   vat_json_node_t *node = NULL;
13156
13157   if (VAT_JSON_ARRAY != vam->json_tree.type)
13158     {
13159       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13160       vat_json_init_array (&vam->json_tree);
13161     }
13162   node = vat_json_array_add (&vam->json_tree);
13163
13164   vat_json_init_object (node);
13165   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13166
13167   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13168
13169   if (mp->is_ipv6)
13170     {
13171       struct in6_addr ip6;
13172
13173       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13174       vat_json_object_add_ip6 (node, "src_address", ip6);
13175       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13176       vat_json_object_add_ip6 (node, "dst_address", ip6);
13177     }
13178   else
13179     {
13180       struct in_addr ip4;
13181
13182       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13183       vat_json_object_add_ip4 (node, "src_address", ip4);
13184       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13185       vat_json_object_add_ip4 (node, "dst_address", ip4);
13186     }
13187   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13188   vat_json_object_add_uint (node, "decap_next_index",
13189                             ntohl (mp->decap_next_index));
13190   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13191   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13192   vat_json_object_add_uint (node, "mcast_sw_if_index",
13193                             ntohl (mp->mcast_sw_if_index));
13194 }
13195
13196 static int
13197 api_vxlan_tunnel_dump (vat_main_t * vam)
13198 {
13199   unformat_input_t *i = vam->input;
13200   vl_api_vxlan_tunnel_dump_t *mp;
13201   vl_api_control_ping_t *mp_ping;
13202   u32 sw_if_index;
13203   u8 sw_if_index_set = 0;
13204   int ret;
13205
13206   /* Parse args required to build the message */
13207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13208     {
13209       if (unformat (i, "sw_if_index %d", &sw_if_index))
13210         sw_if_index_set = 1;
13211       else
13212         break;
13213     }
13214
13215   if (sw_if_index_set == 0)
13216     {
13217       sw_if_index = ~0;
13218     }
13219
13220   if (!vam->json_output)
13221     {
13222       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13223              "sw_if_index", "instance", "src_address", "dst_address",
13224              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13225     }
13226
13227   /* Get list of vxlan-tunnel interfaces */
13228   M (VXLAN_TUNNEL_DUMP, mp);
13229
13230   mp->sw_if_index = htonl (sw_if_index);
13231
13232   S (mp);
13233
13234   /* Use a control ping for synchronization */
13235   MPING (CONTROL_PING, mp_ping);
13236   S (mp_ping);
13237
13238   W (ret);
13239   return ret;
13240 }
13241
13242 static uword unformat_geneve_decap_next
13243   (unformat_input_t * input, va_list * args)
13244 {
13245   u32 *result = va_arg (*args, u32 *);
13246   u32 tmp;
13247
13248   if (unformat (input, "l2"))
13249     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13250   else if (unformat (input, "%d", &tmp))
13251     *result = tmp;
13252   else
13253     return 0;
13254   return 1;
13255 }
13256
13257 static int
13258 api_geneve_add_del_tunnel (vat_main_t * vam)
13259 {
13260   unformat_input_t *line_input = vam->input;
13261   vl_api_geneve_add_del_tunnel_t *mp;
13262   ip46_address_t src, dst;
13263   u8 is_add = 1;
13264   u8 ipv4_set = 0, ipv6_set = 0;
13265   u8 src_set = 0;
13266   u8 dst_set = 0;
13267   u8 grp_set = 0;
13268   u32 mcast_sw_if_index = ~0;
13269   u32 encap_vrf_id = 0;
13270   u32 decap_next_index = ~0;
13271   u32 vni = 0;
13272   int ret;
13273
13274   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13275   memset (&src, 0, sizeof src);
13276   memset (&dst, 0, sizeof dst);
13277
13278   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13279     {
13280       if (unformat (line_input, "del"))
13281         is_add = 0;
13282       else
13283         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13284         {
13285           ipv4_set = 1;
13286           src_set = 1;
13287         }
13288       else
13289         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13290         {
13291           ipv4_set = 1;
13292           dst_set = 1;
13293         }
13294       else
13295         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13296         {
13297           ipv6_set = 1;
13298           src_set = 1;
13299         }
13300       else
13301         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13302         {
13303           ipv6_set = 1;
13304           dst_set = 1;
13305         }
13306       else if (unformat (line_input, "group %U %U",
13307                          unformat_ip4_address, &dst.ip4,
13308                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13309         {
13310           grp_set = dst_set = 1;
13311           ipv4_set = 1;
13312         }
13313       else if (unformat (line_input, "group %U",
13314                          unformat_ip4_address, &dst.ip4))
13315         {
13316           grp_set = dst_set = 1;
13317           ipv4_set = 1;
13318         }
13319       else if (unformat (line_input, "group %U %U",
13320                          unformat_ip6_address, &dst.ip6,
13321                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13322         {
13323           grp_set = dst_set = 1;
13324           ipv6_set = 1;
13325         }
13326       else if (unformat (line_input, "group %U",
13327                          unformat_ip6_address, &dst.ip6))
13328         {
13329           grp_set = dst_set = 1;
13330           ipv6_set = 1;
13331         }
13332       else
13333         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13334         ;
13335       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13336         ;
13337       else if (unformat (line_input, "decap-next %U",
13338                          unformat_geneve_decap_next, &decap_next_index))
13339         ;
13340       else if (unformat (line_input, "vni %d", &vni))
13341         ;
13342       else
13343         {
13344           errmsg ("parse error '%U'", format_unformat_error, line_input);
13345           return -99;
13346         }
13347     }
13348
13349   if (src_set == 0)
13350     {
13351       errmsg ("tunnel src address not specified");
13352       return -99;
13353     }
13354   if (dst_set == 0)
13355     {
13356       errmsg ("tunnel dst address not specified");
13357       return -99;
13358     }
13359
13360   if (grp_set && !ip46_address_is_multicast (&dst))
13361     {
13362       errmsg ("tunnel group address not multicast");
13363       return -99;
13364     }
13365   if (grp_set && mcast_sw_if_index == ~0)
13366     {
13367       errmsg ("tunnel nonexistent multicast device");
13368       return -99;
13369     }
13370   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13371     {
13372       errmsg ("tunnel dst address must be unicast");
13373       return -99;
13374     }
13375
13376
13377   if (ipv4_set && ipv6_set)
13378     {
13379       errmsg ("both IPv4 and IPv6 addresses specified");
13380       return -99;
13381     }
13382
13383   if ((vni == 0) || (vni >> 24))
13384     {
13385       errmsg ("vni not specified or out of range");
13386       return -99;
13387     }
13388
13389   M (GENEVE_ADD_DEL_TUNNEL, mp);
13390
13391   if (ipv6_set)
13392     {
13393       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13394       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13395     }
13396   else
13397     {
13398       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13399       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13400     }
13401   mp->encap_vrf_id = ntohl (encap_vrf_id);
13402   mp->decap_next_index = ntohl (decap_next_index);
13403   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13404   mp->vni = ntohl (vni);
13405   mp->is_add = is_add;
13406   mp->is_ipv6 = ipv6_set;
13407
13408   S (mp);
13409   W (ret);
13410   return ret;
13411 }
13412
13413 static void vl_api_geneve_tunnel_details_t_handler
13414   (vl_api_geneve_tunnel_details_t * mp)
13415 {
13416   vat_main_t *vam = &vat_main;
13417   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13418   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13419
13420   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13421          ntohl (mp->sw_if_index),
13422          format_ip46_address, &src, IP46_TYPE_ANY,
13423          format_ip46_address, &dst, IP46_TYPE_ANY,
13424          ntohl (mp->encap_vrf_id),
13425          ntohl (mp->decap_next_index), ntohl (mp->vni),
13426          ntohl (mp->mcast_sw_if_index));
13427 }
13428
13429 static void vl_api_geneve_tunnel_details_t_handler_json
13430   (vl_api_geneve_tunnel_details_t * mp)
13431 {
13432   vat_main_t *vam = &vat_main;
13433   vat_json_node_t *node = NULL;
13434
13435   if (VAT_JSON_ARRAY != vam->json_tree.type)
13436     {
13437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13438       vat_json_init_array (&vam->json_tree);
13439     }
13440   node = vat_json_array_add (&vam->json_tree);
13441
13442   vat_json_init_object (node);
13443   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13444   if (mp->is_ipv6)
13445     {
13446       struct in6_addr ip6;
13447
13448       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13449       vat_json_object_add_ip6 (node, "src_address", ip6);
13450       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13451       vat_json_object_add_ip6 (node, "dst_address", ip6);
13452     }
13453   else
13454     {
13455       struct in_addr ip4;
13456
13457       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13458       vat_json_object_add_ip4 (node, "src_address", ip4);
13459       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13460       vat_json_object_add_ip4 (node, "dst_address", ip4);
13461     }
13462   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13463   vat_json_object_add_uint (node, "decap_next_index",
13464                             ntohl (mp->decap_next_index));
13465   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13466   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13467   vat_json_object_add_uint (node, "mcast_sw_if_index",
13468                             ntohl (mp->mcast_sw_if_index));
13469 }
13470
13471 static int
13472 api_geneve_tunnel_dump (vat_main_t * vam)
13473 {
13474   unformat_input_t *i = vam->input;
13475   vl_api_geneve_tunnel_dump_t *mp;
13476   vl_api_control_ping_t *mp_ping;
13477   u32 sw_if_index;
13478   u8 sw_if_index_set = 0;
13479   int ret;
13480
13481   /* Parse args required to build the message */
13482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13483     {
13484       if (unformat (i, "sw_if_index %d", &sw_if_index))
13485         sw_if_index_set = 1;
13486       else
13487         break;
13488     }
13489
13490   if (sw_if_index_set == 0)
13491     {
13492       sw_if_index = ~0;
13493     }
13494
13495   if (!vam->json_output)
13496     {
13497       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13498              "sw_if_index", "local_address", "remote_address",
13499              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13500     }
13501
13502   /* Get list of geneve-tunnel interfaces */
13503   M (GENEVE_TUNNEL_DUMP, mp);
13504
13505   mp->sw_if_index = htonl (sw_if_index);
13506
13507   S (mp);
13508
13509   /* Use a control ping for synchronization */
13510   M (CONTROL_PING, mp_ping);
13511   S (mp_ping);
13512
13513   W (ret);
13514   return ret;
13515 }
13516
13517 static int
13518 api_gre_add_del_tunnel (vat_main_t * vam)
13519 {
13520   unformat_input_t *line_input = vam->input;
13521   vl_api_gre_add_del_tunnel_t *mp;
13522   ip4_address_t src4, dst4;
13523   ip6_address_t src6, dst6;
13524   u8 is_add = 1;
13525   u8 ipv4_set = 0;
13526   u8 ipv6_set = 0;
13527   u8 t_type = GRE_TUNNEL_TYPE_L3;
13528   u8 src_set = 0;
13529   u8 dst_set = 0;
13530   u32 outer_fib_id = 0;
13531   u32 session_id = 0;
13532   u32 instance = ~0;
13533   int ret;
13534
13535   memset (&src4, 0, sizeof src4);
13536   memset (&dst4, 0, sizeof dst4);
13537   memset (&src6, 0, sizeof src6);
13538   memset (&dst6, 0, sizeof dst6);
13539
13540   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13541     {
13542       if (unformat (line_input, "del"))
13543         is_add = 0;
13544       else if (unformat (line_input, "instance %d", &instance))
13545         ;
13546       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13547         {
13548           src_set = 1;
13549           ipv4_set = 1;
13550         }
13551       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13552         {
13553           dst_set = 1;
13554           ipv4_set = 1;
13555         }
13556       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13557         {
13558           src_set = 1;
13559           ipv6_set = 1;
13560         }
13561       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13562         {
13563           dst_set = 1;
13564           ipv6_set = 1;
13565         }
13566       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13567         ;
13568       else if (unformat (line_input, "teb"))
13569         t_type = GRE_TUNNEL_TYPE_TEB;
13570       else if (unformat (line_input, "erspan %d", &session_id))
13571         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13572       else
13573         {
13574           errmsg ("parse error '%U'", format_unformat_error, line_input);
13575           return -99;
13576         }
13577     }
13578
13579   if (src_set == 0)
13580     {
13581       errmsg ("tunnel src address not specified");
13582       return -99;
13583     }
13584   if (dst_set == 0)
13585     {
13586       errmsg ("tunnel dst address not specified");
13587       return -99;
13588     }
13589   if (ipv4_set && ipv6_set)
13590     {
13591       errmsg ("both IPv4 and IPv6 addresses specified");
13592       return -99;
13593     }
13594
13595
13596   M (GRE_ADD_DEL_TUNNEL, mp);
13597
13598   if (ipv4_set)
13599     {
13600       clib_memcpy (&mp->src_address, &src4, 4);
13601       clib_memcpy (&mp->dst_address, &dst4, 4);
13602     }
13603   else
13604     {
13605       clib_memcpy (&mp->src_address, &src6, 16);
13606       clib_memcpy (&mp->dst_address, &dst6, 16);
13607     }
13608   mp->instance = htonl (instance);
13609   mp->outer_fib_id = htonl (outer_fib_id);
13610   mp->is_add = is_add;
13611   mp->session_id = htons ((u16) session_id);
13612   mp->tunnel_type = t_type;
13613   mp->is_ipv6 = ipv6_set;
13614
13615   S (mp);
13616   W (ret);
13617   return ret;
13618 }
13619
13620 static void vl_api_gre_tunnel_details_t_handler
13621   (vl_api_gre_tunnel_details_t * mp)
13622 {
13623   vat_main_t *vam = &vat_main;
13624   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13625   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13626
13627   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13628          ntohl (mp->sw_if_index),
13629          ntohl (mp->instance),
13630          format_ip46_address, &src, IP46_TYPE_ANY,
13631          format_ip46_address, &dst, IP46_TYPE_ANY,
13632          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13633 }
13634
13635 static void vl_api_gre_tunnel_details_t_handler_json
13636   (vl_api_gre_tunnel_details_t * mp)
13637 {
13638   vat_main_t *vam = &vat_main;
13639   vat_json_node_t *node = NULL;
13640   struct in_addr ip4;
13641   struct in6_addr ip6;
13642
13643   if (VAT_JSON_ARRAY != vam->json_tree.type)
13644     {
13645       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13646       vat_json_init_array (&vam->json_tree);
13647     }
13648   node = vat_json_array_add (&vam->json_tree);
13649
13650   vat_json_init_object (node);
13651   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13652   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13653   if (!mp->is_ipv6)
13654     {
13655       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13656       vat_json_object_add_ip4 (node, "src_address", ip4);
13657       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13658       vat_json_object_add_ip4 (node, "dst_address", ip4);
13659     }
13660   else
13661     {
13662       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13663       vat_json_object_add_ip6 (node, "src_address", ip6);
13664       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13665       vat_json_object_add_ip6 (node, "dst_address", ip6);
13666     }
13667   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13668   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13669   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13670   vat_json_object_add_uint (node, "session_id", mp->session_id);
13671 }
13672
13673 static int
13674 api_gre_tunnel_dump (vat_main_t * vam)
13675 {
13676   unformat_input_t *i = vam->input;
13677   vl_api_gre_tunnel_dump_t *mp;
13678   vl_api_control_ping_t *mp_ping;
13679   u32 sw_if_index;
13680   u8 sw_if_index_set = 0;
13681   int ret;
13682
13683   /* Parse args required to build the message */
13684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13685     {
13686       if (unformat (i, "sw_if_index %d", &sw_if_index))
13687         sw_if_index_set = 1;
13688       else
13689         break;
13690     }
13691
13692   if (sw_if_index_set == 0)
13693     {
13694       sw_if_index = ~0;
13695     }
13696
13697   if (!vam->json_output)
13698     {
13699       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13700              "sw_if_index", "instance", "src_address", "dst_address",
13701              "tunnel_type", "outer_fib_id", "session_id");
13702     }
13703
13704   /* Get list of gre-tunnel interfaces */
13705   M (GRE_TUNNEL_DUMP, mp);
13706
13707   mp->sw_if_index = htonl (sw_if_index);
13708
13709   S (mp);
13710
13711   /* Use a control ping for synchronization */
13712   MPING (CONTROL_PING, mp_ping);
13713   S (mp_ping);
13714
13715   W (ret);
13716   return ret;
13717 }
13718
13719 static int
13720 api_l2_fib_clear_table (vat_main_t * vam)
13721 {
13722 //  unformat_input_t * i = vam->input;
13723   vl_api_l2_fib_clear_table_t *mp;
13724   int ret;
13725
13726   M (L2_FIB_CLEAR_TABLE, mp);
13727
13728   S (mp);
13729   W (ret);
13730   return ret;
13731 }
13732
13733 static int
13734 api_l2_interface_efp_filter (vat_main_t * vam)
13735 {
13736   unformat_input_t *i = vam->input;
13737   vl_api_l2_interface_efp_filter_t *mp;
13738   u32 sw_if_index;
13739   u8 enable = 1;
13740   u8 sw_if_index_set = 0;
13741   int ret;
13742
13743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13744     {
13745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13746         sw_if_index_set = 1;
13747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13748         sw_if_index_set = 1;
13749       else if (unformat (i, "enable"))
13750         enable = 1;
13751       else if (unformat (i, "disable"))
13752         enable = 0;
13753       else
13754         {
13755           clib_warning ("parse error '%U'", format_unformat_error, i);
13756           return -99;
13757         }
13758     }
13759
13760   if (sw_if_index_set == 0)
13761     {
13762       errmsg ("missing sw_if_index");
13763       return -99;
13764     }
13765
13766   M (L2_INTERFACE_EFP_FILTER, mp);
13767
13768   mp->sw_if_index = ntohl (sw_if_index);
13769   mp->enable_disable = enable;
13770
13771   S (mp);
13772   W (ret);
13773   return ret;
13774 }
13775
13776 #define foreach_vtr_op                          \
13777 _("disable",  L2_VTR_DISABLED)                  \
13778 _("push-1",  L2_VTR_PUSH_1)                     \
13779 _("push-2",  L2_VTR_PUSH_2)                     \
13780 _("pop-1",  L2_VTR_POP_1)                       \
13781 _("pop-2",  L2_VTR_POP_2)                       \
13782 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13783 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13784 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13785 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13786
13787 static int
13788 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13789 {
13790   unformat_input_t *i = vam->input;
13791   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13792   u32 sw_if_index;
13793   u8 sw_if_index_set = 0;
13794   u8 vtr_op_set = 0;
13795   u32 vtr_op = 0;
13796   u32 push_dot1q = 1;
13797   u32 tag1 = ~0;
13798   u32 tag2 = ~0;
13799   int ret;
13800
13801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13802     {
13803       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13804         sw_if_index_set = 1;
13805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13806         sw_if_index_set = 1;
13807       else if (unformat (i, "vtr_op %d", &vtr_op))
13808         vtr_op_set = 1;
13809 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13810       foreach_vtr_op
13811 #undef _
13812         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13813         ;
13814       else if (unformat (i, "tag1 %d", &tag1))
13815         ;
13816       else if (unformat (i, "tag2 %d", &tag2))
13817         ;
13818       else
13819         {
13820           clib_warning ("parse error '%U'", format_unformat_error, i);
13821           return -99;
13822         }
13823     }
13824
13825   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13826     {
13827       errmsg ("missing vtr operation or sw_if_index");
13828       return -99;
13829     }
13830
13831   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13832   mp->sw_if_index = ntohl (sw_if_index);
13833   mp->vtr_op = ntohl (vtr_op);
13834   mp->push_dot1q = ntohl (push_dot1q);
13835   mp->tag1 = ntohl (tag1);
13836   mp->tag2 = ntohl (tag2);
13837
13838   S (mp);
13839   W (ret);
13840   return ret;
13841 }
13842
13843 static int
13844 api_create_vhost_user_if (vat_main_t * vam)
13845 {
13846   unformat_input_t *i = vam->input;
13847   vl_api_create_vhost_user_if_t *mp;
13848   u8 *file_name;
13849   u8 is_server = 0;
13850   u8 file_name_set = 0;
13851   u32 custom_dev_instance = ~0;
13852   u8 hwaddr[6];
13853   u8 use_custom_mac = 0;
13854   u8 *tag = 0;
13855   int ret;
13856
13857   /* Shut up coverity */
13858   memset (hwaddr, 0, sizeof (hwaddr));
13859
13860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13861     {
13862       if (unformat (i, "socket %s", &file_name))
13863         {
13864           file_name_set = 1;
13865         }
13866       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13867         ;
13868       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13869         use_custom_mac = 1;
13870       else if (unformat (i, "server"))
13871         is_server = 1;
13872       else if (unformat (i, "tag %s", &tag))
13873         ;
13874       else
13875         break;
13876     }
13877
13878   if (file_name_set == 0)
13879     {
13880       errmsg ("missing socket file name");
13881       return -99;
13882     }
13883
13884   if (vec_len (file_name) > 255)
13885     {
13886       errmsg ("socket file name too long");
13887       return -99;
13888     }
13889   vec_add1 (file_name, 0);
13890
13891   M (CREATE_VHOST_USER_IF, mp);
13892
13893   mp->is_server = is_server;
13894   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13895   vec_free (file_name);
13896   if (custom_dev_instance != ~0)
13897     {
13898       mp->renumber = 1;
13899       mp->custom_dev_instance = ntohl (custom_dev_instance);
13900     }
13901   mp->use_custom_mac = use_custom_mac;
13902   clib_memcpy (mp->mac_address, hwaddr, 6);
13903   if (tag)
13904     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13905   vec_free (tag);
13906
13907   S (mp);
13908   W (ret);
13909   return ret;
13910 }
13911
13912 static int
13913 api_modify_vhost_user_if (vat_main_t * vam)
13914 {
13915   unformat_input_t *i = vam->input;
13916   vl_api_modify_vhost_user_if_t *mp;
13917   u8 *file_name;
13918   u8 is_server = 0;
13919   u8 file_name_set = 0;
13920   u32 custom_dev_instance = ~0;
13921   u8 sw_if_index_set = 0;
13922   u32 sw_if_index = (u32) ~ 0;
13923   int ret;
13924
13925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13926     {
13927       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13928         sw_if_index_set = 1;
13929       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13930         sw_if_index_set = 1;
13931       else if (unformat (i, "socket %s", &file_name))
13932         {
13933           file_name_set = 1;
13934         }
13935       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13936         ;
13937       else if (unformat (i, "server"))
13938         is_server = 1;
13939       else
13940         break;
13941     }
13942
13943   if (sw_if_index_set == 0)
13944     {
13945       errmsg ("missing sw_if_index or interface name");
13946       return -99;
13947     }
13948
13949   if (file_name_set == 0)
13950     {
13951       errmsg ("missing socket file name");
13952       return -99;
13953     }
13954
13955   if (vec_len (file_name) > 255)
13956     {
13957       errmsg ("socket file name too long");
13958       return -99;
13959     }
13960   vec_add1 (file_name, 0);
13961
13962   M (MODIFY_VHOST_USER_IF, mp);
13963
13964   mp->sw_if_index = ntohl (sw_if_index);
13965   mp->is_server = is_server;
13966   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13967   vec_free (file_name);
13968   if (custom_dev_instance != ~0)
13969     {
13970       mp->renumber = 1;
13971       mp->custom_dev_instance = ntohl (custom_dev_instance);
13972     }
13973
13974   S (mp);
13975   W (ret);
13976   return ret;
13977 }
13978
13979 static int
13980 api_delete_vhost_user_if (vat_main_t * vam)
13981 {
13982   unformat_input_t *i = vam->input;
13983   vl_api_delete_vhost_user_if_t *mp;
13984   u32 sw_if_index = ~0;
13985   u8 sw_if_index_set = 0;
13986   int ret;
13987
13988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13989     {
13990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13991         sw_if_index_set = 1;
13992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13993         sw_if_index_set = 1;
13994       else
13995         break;
13996     }
13997
13998   if (sw_if_index_set == 0)
13999     {
14000       errmsg ("missing sw_if_index or interface name");
14001       return -99;
14002     }
14003
14004
14005   M (DELETE_VHOST_USER_IF, mp);
14006
14007   mp->sw_if_index = ntohl (sw_if_index);
14008
14009   S (mp);
14010   W (ret);
14011   return ret;
14012 }
14013
14014 static void vl_api_sw_interface_vhost_user_details_t_handler
14015   (vl_api_sw_interface_vhost_user_details_t * mp)
14016 {
14017   vat_main_t *vam = &vat_main;
14018
14019   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14020          (char *) mp->interface_name,
14021          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14022          clib_net_to_host_u64 (mp->features), mp->is_server,
14023          ntohl (mp->num_regions), (char *) mp->sock_filename);
14024   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14025 }
14026
14027 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14028   (vl_api_sw_interface_vhost_user_details_t * mp)
14029 {
14030   vat_main_t *vam = &vat_main;
14031   vat_json_node_t *node = NULL;
14032
14033   if (VAT_JSON_ARRAY != vam->json_tree.type)
14034     {
14035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14036       vat_json_init_array (&vam->json_tree);
14037     }
14038   node = vat_json_array_add (&vam->json_tree);
14039
14040   vat_json_init_object (node);
14041   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14042   vat_json_object_add_string_copy (node, "interface_name",
14043                                    mp->interface_name);
14044   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14045                             ntohl (mp->virtio_net_hdr_sz));
14046   vat_json_object_add_uint (node, "features",
14047                             clib_net_to_host_u64 (mp->features));
14048   vat_json_object_add_uint (node, "is_server", mp->is_server);
14049   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14050   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14051   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14052 }
14053
14054 static int
14055 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14056 {
14057   vl_api_sw_interface_vhost_user_dump_t *mp;
14058   vl_api_control_ping_t *mp_ping;
14059   int ret;
14060   print (vam->ofp,
14061          "Interface name            idx hdr_sz features server regions filename");
14062
14063   /* Get list of vhost-user interfaces */
14064   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14065   S (mp);
14066
14067   /* Use a control ping for synchronization */
14068   MPING (CONTROL_PING, mp_ping);
14069   S (mp_ping);
14070
14071   W (ret);
14072   return ret;
14073 }
14074
14075 static int
14076 api_show_version (vat_main_t * vam)
14077 {
14078   vl_api_show_version_t *mp;
14079   int ret;
14080
14081   M (SHOW_VERSION, mp);
14082
14083   S (mp);
14084   W (ret);
14085   return ret;
14086 }
14087
14088
14089 static int
14090 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14091 {
14092   unformat_input_t *line_input = vam->input;
14093   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14094   ip4_address_t local4, remote4;
14095   ip6_address_t local6, remote6;
14096   u8 is_add = 1;
14097   u8 ipv4_set = 0, ipv6_set = 0;
14098   u8 local_set = 0;
14099   u8 remote_set = 0;
14100   u8 grp_set = 0;
14101   u32 mcast_sw_if_index = ~0;
14102   u32 encap_vrf_id = 0;
14103   u32 decap_vrf_id = 0;
14104   u8 protocol = ~0;
14105   u32 vni;
14106   u8 vni_set = 0;
14107   int ret;
14108
14109   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14110   memset (&local4, 0, sizeof local4);
14111   memset (&remote4, 0, sizeof remote4);
14112   memset (&local6, 0, sizeof local6);
14113   memset (&remote6, 0, sizeof remote6);
14114
14115   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14116     {
14117       if (unformat (line_input, "del"))
14118         is_add = 0;
14119       else if (unformat (line_input, "local %U",
14120                          unformat_ip4_address, &local4))
14121         {
14122           local_set = 1;
14123           ipv4_set = 1;
14124         }
14125       else if (unformat (line_input, "remote %U",
14126                          unformat_ip4_address, &remote4))
14127         {
14128           remote_set = 1;
14129           ipv4_set = 1;
14130         }
14131       else if (unformat (line_input, "local %U",
14132                          unformat_ip6_address, &local6))
14133         {
14134           local_set = 1;
14135           ipv6_set = 1;
14136         }
14137       else if (unformat (line_input, "remote %U",
14138                          unformat_ip6_address, &remote6))
14139         {
14140           remote_set = 1;
14141           ipv6_set = 1;
14142         }
14143       else if (unformat (line_input, "group %U %U",
14144                          unformat_ip4_address, &remote4,
14145                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14146         {
14147           grp_set = remote_set = 1;
14148           ipv4_set = 1;
14149         }
14150       else if (unformat (line_input, "group %U",
14151                          unformat_ip4_address, &remote4))
14152         {
14153           grp_set = remote_set = 1;
14154           ipv4_set = 1;
14155         }
14156       else if (unformat (line_input, "group %U %U",
14157                          unformat_ip6_address, &remote6,
14158                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14159         {
14160           grp_set = remote_set = 1;
14161           ipv6_set = 1;
14162         }
14163       else if (unformat (line_input, "group %U",
14164                          unformat_ip6_address, &remote6))
14165         {
14166           grp_set = remote_set = 1;
14167           ipv6_set = 1;
14168         }
14169       else
14170         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14171         ;
14172       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14173         ;
14174       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14175         ;
14176       else if (unformat (line_input, "vni %d", &vni))
14177         vni_set = 1;
14178       else if (unformat (line_input, "next-ip4"))
14179         protocol = 1;
14180       else if (unformat (line_input, "next-ip6"))
14181         protocol = 2;
14182       else if (unformat (line_input, "next-ethernet"))
14183         protocol = 3;
14184       else if (unformat (line_input, "next-nsh"))
14185         protocol = 4;
14186       else
14187         {
14188           errmsg ("parse error '%U'", format_unformat_error, line_input);
14189           return -99;
14190         }
14191     }
14192
14193   if (local_set == 0)
14194     {
14195       errmsg ("tunnel local address not specified");
14196       return -99;
14197     }
14198   if (remote_set == 0)
14199     {
14200       errmsg ("tunnel remote address not specified");
14201       return -99;
14202     }
14203   if (grp_set && mcast_sw_if_index == ~0)
14204     {
14205       errmsg ("tunnel nonexistent multicast device");
14206       return -99;
14207     }
14208   if (ipv4_set && ipv6_set)
14209     {
14210       errmsg ("both IPv4 and IPv6 addresses specified");
14211       return -99;
14212     }
14213
14214   if (vni_set == 0)
14215     {
14216       errmsg ("vni not specified");
14217       return -99;
14218     }
14219
14220   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14221
14222
14223   if (ipv6_set)
14224     {
14225       clib_memcpy (&mp->local, &local6, sizeof (local6));
14226       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14227     }
14228   else
14229     {
14230       clib_memcpy (&mp->local, &local4, sizeof (local4));
14231       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14232     }
14233
14234   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14235   mp->encap_vrf_id = ntohl (encap_vrf_id);
14236   mp->decap_vrf_id = ntohl (decap_vrf_id);
14237   mp->protocol = protocol;
14238   mp->vni = ntohl (vni);
14239   mp->is_add = is_add;
14240   mp->is_ipv6 = ipv6_set;
14241
14242   S (mp);
14243   W (ret);
14244   return ret;
14245 }
14246
14247 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14248   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14249 {
14250   vat_main_t *vam = &vat_main;
14251   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14252   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14253
14254   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14255          ntohl (mp->sw_if_index),
14256          format_ip46_address, &local, IP46_TYPE_ANY,
14257          format_ip46_address, &remote, IP46_TYPE_ANY,
14258          ntohl (mp->vni), mp->protocol,
14259          ntohl (mp->mcast_sw_if_index),
14260          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14261 }
14262
14263
14264 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14265   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14266 {
14267   vat_main_t *vam = &vat_main;
14268   vat_json_node_t *node = NULL;
14269   struct in_addr ip4;
14270   struct in6_addr ip6;
14271
14272   if (VAT_JSON_ARRAY != vam->json_tree.type)
14273     {
14274       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14275       vat_json_init_array (&vam->json_tree);
14276     }
14277   node = vat_json_array_add (&vam->json_tree);
14278
14279   vat_json_init_object (node);
14280   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14281   if (mp->is_ipv6)
14282     {
14283       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14284       vat_json_object_add_ip6 (node, "local", ip6);
14285       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14286       vat_json_object_add_ip6 (node, "remote", ip6);
14287     }
14288   else
14289     {
14290       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14291       vat_json_object_add_ip4 (node, "local", ip4);
14292       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14293       vat_json_object_add_ip4 (node, "remote", ip4);
14294     }
14295   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14296   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14297   vat_json_object_add_uint (node, "mcast_sw_if_index",
14298                             ntohl (mp->mcast_sw_if_index));
14299   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14300   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14301   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14302 }
14303
14304 static int
14305 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14306 {
14307   unformat_input_t *i = vam->input;
14308   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14309   vl_api_control_ping_t *mp_ping;
14310   u32 sw_if_index;
14311   u8 sw_if_index_set = 0;
14312   int ret;
14313
14314   /* Parse args required to build the message */
14315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14316     {
14317       if (unformat (i, "sw_if_index %d", &sw_if_index))
14318         sw_if_index_set = 1;
14319       else
14320         break;
14321     }
14322
14323   if (sw_if_index_set == 0)
14324     {
14325       sw_if_index = ~0;
14326     }
14327
14328   if (!vam->json_output)
14329     {
14330       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14331              "sw_if_index", "local", "remote", "vni",
14332              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14333     }
14334
14335   /* Get list of vxlan-tunnel interfaces */
14336   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14337
14338   mp->sw_if_index = htonl (sw_if_index);
14339
14340   S (mp);
14341
14342   /* Use a control ping for synchronization */
14343   MPING (CONTROL_PING, mp_ping);
14344   S (mp_ping);
14345
14346   W (ret);
14347   return ret;
14348 }
14349
14350 static void vl_api_l2_fib_table_details_t_handler
14351   (vl_api_l2_fib_table_details_t * mp)
14352 {
14353   vat_main_t *vam = &vat_main;
14354
14355   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14356          "       %d       %d     %d",
14357          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14358          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14359          mp->bvi_mac);
14360 }
14361
14362 static void vl_api_l2_fib_table_details_t_handler_json
14363   (vl_api_l2_fib_table_details_t * mp)
14364 {
14365   vat_main_t *vam = &vat_main;
14366   vat_json_node_t *node = NULL;
14367
14368   if (VAT_JSON_ARRAY != vam->json_tree.type)
14369     {
14370       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14371       vat_json_init_array (&vam->json_tree);
14372     }
14373   node = vat_json_array_add (&vam->json_tree);
14374
14375   vat_json_init_object (node);
14376   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14377   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14378   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14379   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14380   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14381   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14382 }
14383
14384 static int
14385 api_l2_fib_table_dump (vat_main_t * vam)
14386 {
14387   unformat_input_t *i = vam->input;
14388   vl_api_l2_fib_table_dump_t *mp;
14389   vl_api_control_ping_t *mp_ping;
14390   u32 bd_id;
14391   u8 bd_id_set = 0;
14392   int ret;
14393
14394   /* Parse args required to build the message */
14395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14396     {
14397       if (unformat (i, "bd_id %d", &bd_id))
14398         bd_id_set = 1;
14399       else
14400         break;
14401     }
14402
14403   if (bd_id_set == 0)
14404     {
14405       errmsg ("missing bridge domain");
14406       return -99;
14407     }
14408
14409   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14410
14411   /* Get list of l2 fib entries */
14412   M (L2_FIB_TABLE_DUMP, mp);
14413
14414   mp->bd_id = ntohl (bd_id);
14415   S (mp);
14416
14417   /* Use a control ping for synchronization */
14418   MPING (CONTROL_PING, mp_ping);
14419   S (mp_ping);
14420
14421   W (ret);
14422   return ret;
14423 }
14424
14425
14426 static int
14427 api_interface_name_renumber (vat_main_t * vam)
14428 {
14429   unformat_input_t *line_input = vam->input;
14430   vl_api_interface_name_renumber_t *mp;
14431   u32 sw_if_index = ~0;
14432   u32 new_show_dev_instance = ~0;
14433   int ret;
14434
14435   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14436     {
14437       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14438                     &sw_if_index))
14439         ;
14440       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14441         ;
14442       else if (unformat (line_input, "new_show_dev_instance %d",
14443                          &new_show_dev_instance))
14444         ;
14445       else
14446         break;
14447     }
14448
14449   if (sw_if_index == ~0)
14450     {
14451       errmsg ("missing interface name or sw_if_index");
14452       return -99;
14453     }
14454
14455   if (new_show_dev_instance == ~0)
14456     {
14457       errmsg ("missing new_show_dev_instance");
14458       return -99;
14459     }
14460
14461   M (INTERFACE_NAME_RENUMBER, mp);
14462
14463   mp->sw_if_index = ntohl (sw_if_index);
14464   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14465
14466   S (mp);
14467   W (ret);
14468   return ret;
14469 }
14470
14471 static int
14472 api_ip_probe_neighbor (vat_main_t * vam)
14473 {
14474   unformat_input_t *i = vam->input;
14475   vl_api_ip_probe_neighbor_t *mp;
14476   u8 int_set = 0;
14477   u8 adr_set = 0;
14478   u8 is_ipv6 = 0;
14479   u8 dst_adr[16];
14480   u32 sw_if_index;
14481   int ret;
14482
14483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14484     {
14485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14486         int_set = 1;
14487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14488         int_set = 1;
14489       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14490         adr_set = 1;
14491       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14492         {
14493           adr_set = 1;
14494           is_ipv6 = 1;
14495         }
14496       else
14497         break;
14498     }
14499
14500   if (int_set == 0)
14501     {
14502       errmsg ("missing interface");
14503       return -99;
14504     }
14505
14506   if (adr_set == 0)
14507     {
14508       errmsg ("missing addresses");
14509       return -99;
14510     }
14511
14512   M (IP_PROBE_NEIGHBOR, mp);
14513
14514   mp->sw_if_index = ntohl (sw_if_index);
14515   mp->is_ipv6 = is_ipv6;
14516   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14517
14518   S (mp);
14519   W (ret);
14520   return ret;
14521 }
14522
14523 static int
14524 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14525 {
14526   unformat_input_t *i = vam->input;
14527   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14528   u8 mode = IP_SCAN_V46_NEIGHBORS;
14529   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14530   int ret;
14531
14532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14533     {
14534       if (unformat (i, "ip4"))
14535         mode = IP_SCAN_V4_NEIGHBORS;
14536       else if (unformat (i, "ip6"))
14537         mode = IP_SCAN_V6_NEIGHBORS;
14538       if (unformat (i, "both"))
14539         mode = IP_SCAN_V46_NEIGHBORS;
14540       else if (unformat (i, "disable"))
14541         mode = IP_SCAN_DISABLED;
14542       else if (unformat (i, "interval %d", &interval))
14543         ;
14544       else if (unformat (i, "max-time %d", &time))
14545         ;
14546       else if (unformat (i, "max-update %d", &update))
14547         ;
14548       else if (unformat (i, "delay %d", &delay))
14549         ;
14550       else if (unformat (i, "stale %d", &stale))
14551         ;
14552       else
14553         break;
14554     }
14555
14556   if (interval > 255)
14557     {
14558       errmsg ("interval cannot exceed 255 minutes.");
14559       return -99;
14560     }
14561   if (time > 255)
14562     {
14563       errmsg ("max-time cannot exceed 255 usec.");
14564       return -99;
14565     }
14566   if (update > 255)
14567     {
14568       errmsg ("max-update cannot exceed 255.");
14569       return -99;
14570     }
14571   if (delay > 255)
14572     {
14573       errmsg ("delay cannot exceed 255 msec.");
14574       return -99;
14575     }
14576   if (stale > 255)
14577     {
14578       errmsg ("stale cannot exceed 255 minutes.");
14579       return -99;
14580     }
14581
14582   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14583   mp->mode = mode;
14584   mp->scan_interval = interval;
14585   mp->max_proc_time = time;
14586   mp->max_update = update;
14587   mp->scan_int_delay = delay;
14588   mp->stale_threshold = stale;
14589
14590   S (mp);
14591   W (ret);
14592   return ret;
14593 }
14594
14595 static int
14596 api_want_ip4_arp_events (vat_main_t * vam)
14597 {
14598   unformat_input_t *line_input = vam->input;
14599   vl_api_want_ip4_arp_events_t *mp;
14600   ip4_address_t address;
14601   int address_set = 0;
14602   u32 enable_disable = 1;
14603   int ret;
14604
14605   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14606     {
14607       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14608         address_set = 1;
14609       else if (unformat (line_input, "del"))
14610         enable_disable = 0;
14611       else
14612         break;
14613     }
14614
14615   if (address_set == 0)
14616     {
14617       errmsg ("missing addresses");
14618       return -99;
14619     }
14620
14621   M (WANT_IP4_ARP_EVENTS, mp);
14622   mp->enable_disable = enable_disable;
14623   mp->pid = htonl (getpid ());
14624   mp->address = address.as_u32;
14625
14626   S (mp);
14627   W (ret);
14628   return ret;
14629 }
14630
14631 static int
14632 api_want_ip6_nd_events (vat_main_t * vam)
14633 {
14634   unformat_input_t *line_input = vam->input;
14635   vl_api_want_ip6_nd_events_t *mp;
14636   ip6_address_t address;
14637   int address_set = 0;
14638   u32 enable_disable = 1;
14639   int ret;
14640
14641   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14642     {
14643       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14644         address_set = 1;
14645       else if (unformat (line_input, "del"))
14646         enable_disable = 0;
14647       else
14648         break;
14649     }
14650
14651   if (address_set == 0)
14652     {
14653       errmsg ("missing addresses");
14654       return -99;
14655     }
14656
14657   M (WANT_IP6_ND_EVENTS, mp);
14658   mp->enable_disable = enable_disable;
14659   mp->pid = htonl (getpid ());
14660   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14661
14662   S (mp);
14663   W (ret);
14664   return ret;
14665 }
14666
14667 static int
14668 api_want_l2_macs_events (vat_main_t * vam)
14669 {
14670   unformat_input_t *line_input = vam->input;
14671   vl_api_want_l2_macs_events_t *mp;
14672   u8 enable_disable = 1;
14673   u32 scan_delay = 0;
14674   u32 max_macs_in_event = 0;
14675   u32 learn_limit = 0;
14676   int ret;
14677
14678   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (line_input, "learn-limit %d", &learn_limit))
14681         ;
14682       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14683         ;
14684       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14685         ;
14686       else if (unformat (line_input, "disable"))
14687         enable_disable = 0;
14688       else
14689         break;
14690     }
14691
14692   M (WANT_L2_MACS_EVENTS, mp);
14693   mp->enable_disable = enable_disable;
14694   mp->pid = htonl (getpid ());
14695   mp->learn_limit = htonl (learn_limit);
14696   mp->scan_delay = (u8) scan_delay;
14697   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14698   S (mp);
14699   W (ret);
14700   return ret;
14701 }
14702
14703 static int
14704 api_input_acl_set_interface (vat_main_t * vam)
14705 {
14706   unformat_input_t *i = vam->input;
14707   vl_api_input_acl_set_interface_t *mp;
14708   u32 sw_if_index;
14709   int sw_if_index_set;
14710   u32 ip4_table_index = ~0;
14711   u32 ip6_table_index = ~0;
14712   u32 l2_table_index = ~0;
14713   u8 is_add = 1;
14714   int ret;
14715
14716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14717     {
14718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14719         sw_if_index_set = 1;
14720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14721         sw_if_index_set = 1;
14722       else if (unformat (i, "del"))
14723         is_add = 0;
14724       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14725         ;
14726       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14727         ;
14728       else if (unformat (i, "l2-table %d", &l2_table_index))
14729         ;
14730       else
14731         {
14732           clib_warning ("parse error '%U'", format_unformat_error, i);
14733           return -99;
14734         }
14735     }
14736
14737   if (sw_if_index_set == 0)
14738     {
14739       errmsg ("missing interface name or sw_if_index");
14740       return -99;
14741     }
14742
14743   M (INPUT_ACL_SET_INTERFACE, mp);
14744
14745   mp->sw_if_index = ntohl (sw_if_index);
14746   mp->ip4_table_index = ntohl (ip4_table_index);
14747   mp->ip6_table_index = ntohl (ip6_table_index);
14748   mp->l2_table_index = ntohl (l2_table_index);
14749   mp->is_add = is_add;
14750
14751   S (mp);
14752   W (ret);
14753   return ret;
14754 }
14755
14756 static int
14757 api_output_acl_set_interface (vat_main_t * vam)
14758 {
14759   unformat_input_t *i = vam->input;
14760   vl_api_output_acl_set_interface_t *mp;
14761   u32 sw_if_index;
14762   int sw_if_index_set;
14763   u32 ip4_table_index = ~0;
14764   u32 ip6_table_index = ~0;
14765   u32 l2_table_index = ~0;
14766   u8 is_add = 1;
14767   int ret;
14768
14769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14770     {
14771       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14772         sw_if_index_set = 1;
14773       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14774         sw_if_index_set = 1;
14775       else if (unformat (i, "del"))
14776         is_add = 0;
14777       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14778         ;
14779       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14780         ;
14781       else if (unformat (i, "l2-table %d", &l2_table_index))
14782         ;
14783       else
14784         {
14785           clib_warning ("parse error '%U'", format_unformat_error, i);
14786           return -99;
14787         }
14788     }
14789
14790   if (sw_if_index_set == 0)
14791     {
14792       errmsg ("missing interface name or sw_if_index");
14793       return -99;
14794     }
14795
14796   M (OUTPUT_ACL_SET_INTERFACE, mp);
14797
14798   mp->sw_if_index = ntohl (sw_if_index);
14799   mp->ip4_table_index = ntohl (ip4_table_index);
14800   mp->ip6_table_index = ntohl (ip6_table_index);
14801   mp->l2_table_index = ntohl (l2_table_index);
14802   mp->is_add = is_add;
14803
14804   S (mp);
14805   W (ret);
14806   return ret;
14807 }
14808
14809 static int
14810 api_ip_address_dump (vat_main_t * vam)
14811 {
14812   unformat_input_t *i = vam->input;
14813   vl_api_ip_address_dump_t *mp;
14814   vl_api_control_ping_t *mp_ping;
14815   u32 sw_if_index = ~0;
14816   u8 sw_if_index_set = 0;
14817   u8 ipv4_set = 0;
14818   u8 ipv6_set = 0;
14819   int ret;
14820
14821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14822     {
14823       if (unformat (i, "sw_if_index %d", &sw_if_index))
14824         sw_if_index_set = 1;
14825       else
14826         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14827         sw_if_index_set = 1;
14828       else if (unformat (i, "ipv4"))
14829         ipv4_set = 1;
14830       else if (unformat (i, "ipv6"))
14831         ipv6_set = 1;
14832       else
14833         break;
14834     }
14835
14836   if (ipv4_set && ipv6_set)
14837     {
14838       errmsg ("ipv4 and ipv6 flags cannot be both set");
14839       return -99;
14840     }
14841
14842   if ((!ipv4_set) && (!ipv6_set))
14843     {
14844       errmsg ("no ipv4 nor ipv6 flag set");
14845       return -99;
14846     }
14847
14848   if (sw_if_index_set == 0)
14849     {
14850       errmsg ("missing interface name or sw_if_index");
14851       return -99;
14852     }
14853
14854   vam->current_sw_if_index = sw_if_index;
14855   vam->is_ipv6 = ipv6_set;
14856
14857   M (IP_ADDRESS_DUMP, mp);
14858   mp->sw_if_index = ntohl (sw_if_index);
14859   mp->is_ipv6 = ipv6_set;
14860   S (mp);
14861
14862   /* Use a control ping for synchronization */
14863   MPING (CONTROL_PING, mp_ping);
14864   S (mp_ping);
14865
14866   W (ret);
14867   return ret;
14868 }
14869
14870 static int
14871 api_ip_dump (vat_main_t * vam)
14872 {
14873   vl_api_ip_dump_t *mp;
14874   vl_api_control_ping_t *mp_ping;
14875   unformat_input_t *in = vam->input;
14876   int ipv4_set = 0;
14877   int ipv6_set = 0;
14878   int is_ipv6;
14879   int i;
14880   int ret;
14881
14882   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14883     {
14884       if (unformat (in, "ipv4"))
14885         ipv4_set = 1;
14886       else if (unformat (in, "ipv6"))
14887         ipv6_set = 1;
14888       else
14889         break;
14890     }
14891
14892   if (ipv4_set && ipv6_set)
14893     {
14894       errmsg ("ipv4 and ipv6 flags cannot be both set");
14895       return -99;
14896     }
14897
14898   if ((!ipv4_set) && (!ipv6_set))
14899     {
14900       errmsg ("no ipv4 nor ipv6 flag set");
14901       return -99;
14902     }
14903
14904   is_ipv6 = ipv6_set;
14905   vam->is_ipv6 = is_ipv6;
14906
14907   /* free old data */
14908   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14909     {
14910       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14911     }
14912   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14913
14914   M (IP_DUMP, mp);
14915   mp->is_ipv6 = ipv6_set;
14916   S (mp);
14917
14918   /* Use a control ping for synchronization */
14919   MPING (CONTROL_PING, mp_ping);
14920   S (mp_ping);
14921
14922   W (ret);
14923   return ret;
14924 }
14925
14926 static int
14927 api_ipsec_spd_add_del (vat_main_t * vam)
14928 {
14929   unformat_input_t *i = vam->input;
14930   vl_api_ipsec_spd_add_del_t *mp;
14931   u32 spd_id = ~0;
14932   u8 is_add = 1;
14933   int ret;
14934
14935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14936     {
14937       if (unformat (i, "spd_id %d", &spd_id))
14938         ;
14939       else if (unformat (i, "del"))
14940         is_add = 0;
14941       else
14942         {
14943           clib_warning ("parse error '%U'", format_unformat_error, i);
14944           return -99;
14945         }
14946     }
14947   if (spd_id == ~0)
14948     {
14949       errmsg ("spd_id must be set");
14950       return -99;
14951     }
14952
14953   M (IPSEC_SPD_ADD_DEL, mp);
14954
14955   mp->spd_id = ntohl (spd_id);
14956   mp->is_add = is_add;
14957
14958   S (mp);
14959   W (ret);
14960   return ret;
14961 }
14962
14963 static int
14964 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14965 {
14966   unformat_input_t *i = vam->input;
14967   vl_api_ipsec_interface_add_del_spd_t *mp;
14968   u32 sw_if_index;
14969   u8 sw_if_index_set = 0;
14970   u32 spd_id = (u32) ~ 0;
14971   u8 is_add = 1;
14972   int ret;
14973
14974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14975     {
14976       if (unformat (i, "del"))
14977         is_add = 0;
14978       else if (unformat (i, "spd_id %d", &spd_id))
14979         ;
14980       else
14981         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14982         sw_if_index_set = 1;
14983       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14984         sw_if_index_set = 1;
14985       else
14986         {
14987           clib_warning ("parse error '%U'", format_unformat_error, i);
14988           return -99;
14989         }
14990
14991     }
14992
14993   if (spd_id == (u32) ~ 0)
14994     {
14995       errmsg ("spd_id must be set");
14996       return -99;
14997     }
14998
14999   if (sw_if_index_set == 0)
15000     {
15001       errmsg ("missing interface name or sw_if_index");
15002       return -99;
15003     }
15004
15005   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15006
15007   mp->spd_id = ntohl (spd_id);
15008   mp->sw_if_index = ntohl (sw_if_index);
15009   mp->is_add = is_add;
15010
15011   S (mp);
15012   W (ret);
15013   return ret;
15014 }
15015
15016 static int
15017 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15018 {
15019   unformat_input_t *i = vam->input;
15020   vl_api_ipsec_spd_add_del_entry_t *mp;
15021   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15022   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15023   i32 priority = 0;
15024   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15025   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15026   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15027   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15028   int ret;
15029
15030   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15031   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15032   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15033   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15034   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15035   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15036
15037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15038     {
15039       if (unformat (i, "del"))
15040         is_add = 0;
15041       if (unformat (i, "outbound"))
15042         is_outbound = 1;
15043       if (unformat (i, "inbound"))
15044         is_outbound = 0;
15045       else if (unformat (i, "spd_id %d", &spd_id))
15046         ;
15047       else if (unformat (i, "sa_id %d", &sa_id))
15048         ;
15049       else if (unformat (i, "priority %d", &priority))
15050         ;
15051       else if (unformat (i, "protocol %d", &protocol))
15052         ;
15053       else if (unformat (i, "lport_start %d", &lport_start))
15054         ;
15055       else if (unformat (i, "lport_stop %d", &lport_stop))
15056         ;
15057       else if (unformat (i, "rport_start %d", &rport_start))
15058         ;
15059       else if (unformat (i, "rport_stop %d", &rport_stop))
15060         ;
15061       else
15062         if (unformat
15063             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15064         {
15065           is_ipv6 = 0;
15066           is_ip_any = 0;
15067         }
15068       else
15069         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15070         {
15071           is_ipv6 = 0;
15072           is_ip_any = 0;
15073         }
15074       else
15075         if (unformat
15076             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15077         {
15078           is_ipv6 = 0;
15079           is_ip_any = 0;
15080         }
15081       else
15082         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15083         {
15084           is_ipv6 = 0;
15085           is_ip_any = 0;
15086         }
15087       else
15088         if (unformat
15089             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15090         {
15091           is_ipv6 = 1;
15092           is_ip_any = 0;
15093         }
15094       else
15095         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15096         {
15097           is_ipv6 = 1;
15098           is_ip_any = 0;
15099         }
15100       else
15101         if (unformat
15102             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15103         {
15104           is_ipv6 = 1;
15105           is_ip_any = 0;
15106         }
15107       else
15108         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15109         {
15110           is_ipv6 = 1;
15111           is_ip_any = 0;
15112         }
15113       else
15114         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15115         {
15116           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15117             {
15118               clib_warning ("unsupported action: 'resolve'");
15119               return -99;
15120             }
15121         }
15122       else
15123         {
15124           clib_warning ("parse error '%U'", format_unformat_error, i);
15125           return -99;
15126         }
15127
15128     }
15129
15130   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15131
15132   mp->spd_id = ntohl (spd_id);
15133   mp->priority = ntohl (priority);
15134   mp->is_outbound = is_outbound;
15135
15136   mp->is_ipv6 = is_ipv6;
15137   if (is_ipv6 || is_ip_any)
15138     {
15139       clib_memcpy (mp->remote_address_start, &raddr6_start,
15140                    sizeof (ip6_address_t));
15141       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15142                    sizeof (ip6_address_t));
15143       clib_memcpy (mp->local_address_start, &laddr6_start,
15144                    sizeof (ip6_address_t));
15145       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15146                    sizeof (ip6_address_t));
15147     }
15148   else
15149     {
15150       clib_memcpy (mp->remote_address_start, &raddr4_start,
15151                    sizeof (ip4_address_t));
15152       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15153                    sizeof (ip4_address_t));
15154       clib_memcpy (mp->local_address_start, &laddr4_start,
15155                    sizeof (ip4_address_t));
15156       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15157                    sizeof (ip4_address_t));
15158     }
15159   mp->protocol = (u8) protocol;
15160   mp->local_port_start = ntohs ((u16) lport_start);
15161   mp->local_port_stop = ntohs ((u16) lport_stop);
15162   mp->remote_port_start = ntohs ((u16) rport_start);
15163   mp->remote_port_stop = ntohs ((u16) rport_stop);
15164   mp->policy = (u8) policy;
15165   mp->sa_id = ntohl (sa_id);
15166   mp->is_add = is_add;
15167   mp->is_ip_any = is_ip_any;
15168   S (mp);
15169   W (ret);
15170   return ret;
15171 }
15172
15173 static int
15174 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15175 {
15176   unformat_input_t *i = vam->input;
15177   vl_api_ipsec_sad_add_del_entry_t *mp;
15178   u32 sad_id = 0, spi = 0;
15179   u8 *ck = 0, *ik = 0;
15180   u8 is_add = 1;
15181
15182   u8 protocol = IPSEC_PROTOCOL_AH;
15183   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15184   u32 crypto_alg = 0, integ_alg = 0;
15185   ip4_address_t tun_src4;
15186   ip4_address_t tun_dst4;
15187   ip6_address_t tun_src6;
15188   ip6_address_t tun_dst6;
15189   int ret;
15190
15191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15192     {
15193       if (unformat (i, "del"))
15194         is_add = 0;
15195       else if (unformat (i, "sad_id %d", &sad_id))
15196         ;
15197       else if (unformat (i, "spi %d", &spi))
15198         ;
15199       else if (unformat (i, "esp"))
15200         protocol = IPSEC_PROTOCOL_ESP;
15201       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15202         {
15203           is_tunnel = 1;
15204           is_tunnel_ipv6 = 0;
15205         }
15206       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15207         {
15208           is_tunnel = 1;
15209           is_tunnel_ipv6 = 0;
15210         }
15211       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15212         {
15213           is_tunnel = 1;
15214           is_tunnel_ipv6 = 1;
15215         }
15216       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15217         {
15218           is_tunnel = 1;
15219           is_tunnel_ipv6 = 1;
15220         }
15221       else
15222         if (unformat
15223             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15224         {
15225           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15226               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15227             {
15228               clib_warning ("unsupported crypto-alg: '%U'",
15229                             format_ipsec_crypto_alg, crypto_alg);
15230               return -99;
15231             }
15232         }
15233       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15234         ;
15235       else
15236         if (unformat
15237             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15238         {
15239           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15240               integ_alg >= IPSEC_INTEG_N_ALG)
15241             {
15242               clib_warning ("unsupported integ-alg: '%U'",
15243                             format_ipsec_integ_alg, integ_alg);
15244               return -99;
15245             }
15246         }
15247       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15248         ;
15249       else
15250         {
15251           clib_warning ("parse error '%U'", format_unformat_error, i);
15252           return -99;
15253         }
15254
15255     }
15256
15257   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15258
15259   mp->sad_id = ntohl (sad_id);
15260   mp->is_add = is_add;
15261   mp->protocol = protocol;
15262   mp->spi = ntohl (spi);
15263   mp->is_tunnel = is_tunnel;
15264   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15265   mp->crypto_algorithm = crypto_alg;
15266   mp->integrity_algorithm = integ_alg;
15267   mp->crypto_key_length = vec_len (ck);
15268   mp->integrity_key_length = vec_len (ik);
15269
15270   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15271     mp->crypto_key_length = sizeof (mp->crypto_key);
15272
15273   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15274     mp->integrity_key_length = sizeof (mp->integrity_key);
15275
15276   if (ck)
15277     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15278   if (ik)
15279     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15280
15281   if (is_tunnel)
15282     {
15283       if (is_tunnel_ipv6)
15284         {
15285           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15286                        sizeof (ip6_address_t));
15287           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15288                        sizeof (ip6_address_t));
15289         }
15290       else
15291         {
15292           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15293                        sizeof (ip4_address_t));
15294           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15295                        sizeof (ip4_address_t));
15296         }
15297     }
15298
15299   S (mp);
15300   W (ret);
15301   return ret;
15302 }
15303
15304 static int
15305 api_ipsec_sa_set_key (vat_main_t * vam)
15306 {
15307   unformat_input_t *i = vam->input;
15308   vl_api_ipsec_sa_set_key_t *mp;
15309   u32 sa_id;
15310   u8 *ck = 0, *ik = 0;
15311   int ret;
15312
15313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15314     {
15315       if (unformat (i, "sa_id %d", &sa_id))
15316         ;
15317       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15318         ;
15319       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15320         ;
15321       else
15322         {
15323           clib_warning ("parse error '%U'", format_unformat_error, i);
15324           return -99;
15325         }
15326     }
15327
15328   M (IPSEC_SA_SET_KEY, mp);
15329
15330   mp->sa_id = ntohl (sa_id);
15331   mp->crypto_key_length = vec_len (ck);
15332   mp->integrity_key_length = vec_len (ik);
15333
15334   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15335     mp->crypto_key_length = sizeof (mp->crypto_key);
15336
15337   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15338     mp->integrity_key_length = sizeof (mp->integrity_key);
15339
15340   if (ck)
15341     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15342   if (ik)
15343     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15344
15345   S (mp);
15346   W (ret);
15347   return ret;
15348 }
15349
15350 static int
15351 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15352 {
15353   unformat_input_t *i = vam->input;
15354   vl_api_ipsec_tunnel_if_add_del_t *mp;
15355   u32 local_spi = 0, remote_spi = 0;
15356   u32 crypto_alg = 0, integ_alg = 0;
15357   u8 *lck = NULL, *rck = NULL;
15358   u8 *lik = NULL, *rik = NULL;
15359   ip4_address_t local_ip = { {0} };
15360   ip4_address_t remote_ip = { {0} };
15361   u8 is_add = 1;
15362   u8 esn = 0;
15363   u8 anti_replay = 0;
15364   u8 renumber = 0;
15365   u32 instance = ~0;
15366   int ret;
15367
15368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15369     {
15370       if (unformat (i, "del"))
15371         is_add = 0;
15372       else if (unformat (i, "esn"))
15373         esn = 1;
15374       else if (unformat (i, "anti_replay"))
15375         anti_replay = 1;
15376       else if (unformat (i, "local_spi %d", &local_spi))
15377         ;
15378       else if (unformat (i, "remote_spi %d", &remote_spi))
15379         ;
15380       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15381         ;
15382       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15383         ;
15384       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15385         ;
15386       else
15387         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15388         ;
15389       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15390         ;
15391       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15392         ;
15393       else
15394         if (unformat
15395             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15396         {
15397           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15398               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_ALG_NONE ||
15410               integ_alg >= IPSEC_INTEG_N_ALG)
15411             {
15412               errmsg ("unsupported integ-alg: '%U'\n",
15413                       format_ipsec_integ_alg, integ_alg);
15414               return -99;
15415             }
15416         }
15417       else if (unformat (i, "instance %u", &instance))
15418         renumber = 1;
15419       else
15420         {
15421           errmsg ("parse error '%U'\n", format_unformat_error, i);
15422           return -99;
15423         }
15424     }
15425
15426   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15427
15428   mp->is_add = is_add;
15429   mp->esn = esn;
15430   mp->anti_replay = anti_replay;
15431
15432   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15433   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15434
15435   mp->local_spi = htonl (local_spi);
15436   mp->remote_spi = htonl (remote_spi);
15437   mp->crypto_alg = (u8) crypto_alg;
15438
15439   mp->local_crypto_key_len = 0;
15440   if (lck)
15441     {
15442       mp->local_crypto_key_len = vec_len (lck);
15443       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15444         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15445       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15446     }
15447
15448   mp->remote_crypto_key_len = 0;
15449   if (rck)
15450     {
15451       mp->remote_crypto_key_len = vec_len (rck);
15452       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15453         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15454       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15455     }
15456
15457   mp->integ_alg = (u8) integ_alg;
15458
15459   mp->local_integ_key_len = 0;
15460   if (lik)
15461     {
15462       mp->local_integ_key_len = vec_len (lik);
15463       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15464         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15465       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15466     }
15467
15468   mp->remote_integ_key_len = 0;
15469   if (rik)
15470     {
15471       mp->remote_integ_key_len = vec_len (rik);
15472       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15473         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15474       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15475     }
15476
15477   if (renumber)
15478     {
15479       mp->renumber = renumber;
15480       mp->show_instance = ntohl (instance);
15481     }
15482
15483   S (mp);
15484   W (ret);
15485   return ret;
15486 }
15487
15488 static void
15489 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15490 {
15491   vat_main_t *vam = &vat_main;
15492
15493   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15494          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15495          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15496          "tunnel_src_addr %U tunnel_dst_addr %U "
15497          "salt %u seq_outbound %lu last_seq_inbound %lu "
15498          "replay_window %lu total_data_size %lu\n",
15499          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15500          mp->protocol,
15501          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15502          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15503          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15504          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15505          mp->tunnel_src_addr,
15506          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15507          mp->tunnel_dst_addr,
15508          ntohl (mp->salt),
15509          clib_net_to_host_u64 (mp->seq_outbound),
15510          clib_net_to_host_u64 (mp->last_seq_inbound),
15511          clib_net_to_host_u64 (mp->replay_window),
15512          clib_net_to_host_u64 (mp->total_data_size));
15513 }
15514
15515 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15516 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15517
15518 static void vl_api_ipsec_sa_details_t_handler_json
15519   (vl_api_ipsec_sa_details_t * mp)
15520 {
15521   vat_main_t *vam = &vat_main;
15522   vat_json_node_t *node = NULL;
15523   struct in_addr src_ip4, dst_ip4;
15524   struct in6_addr src_ip6, dst_ip6;
15525
15526   if (VAT_JSON_ARRAY != vam->json_tree.type)
15527     {
15528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15529       vat_json_init_array (&vam->json_tree);
15530     }
15531   node = vat_json_array_add (&vam->json_tree);
15532
15533   vat_json_init_object (node);
15534   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15535   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15536   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15537   vat_json_object_add_uint (node, "proto", mp->protocol);
15538   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15539   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15540   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15541   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15542   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15543   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15544   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15545                              mp->crypto_key_len);
15546   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15547                              mp->integ_key_len);
15548   if (mp->is_tunnel_ip6)
15549     {
15550       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15551       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15552       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15553       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15554     }
15555   else
15556     {
15557       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15558       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15559       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15560       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15561     }
15562   vat_json_object_add_uint (node, "replay_window",
15563                             clib_net_to_host_u64 (mp->replay_window));
15564   vat_json_object_add_uint (node, "total_data_size",
15565                             clib_net_to_host_u64 (mp->total_data_size));
15566
15567 }
15568
15569 static int
15570 api_ipsec_sa_dump (vat_main_t * vam)
15571 {
15572   unformat_input_t *i = vam->input;
15573   vl_api_ipsec_sa_dump_t *mp;
15574   vl_api_control_ping_t *mp_ping;
15575   u32 sa_id = ~0;
15576   int ret;
15577
15578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15579     {
15580       if (unformat (i, "sa_id %d", &sa_id))
15581         ;
15582       else
15583         {
15584           clib_warning ("parse error '%U'", format_unformat_error, i);
15585           return -99;
15586         }
15587     }
15588
15589   M (IPSEC_SA_DUMP, mp);
15590
15591   mp->sa_id = ntohl (sa_id);
15592
15593   S (mp);
15594
15595   /* Use a control ping for synchronization */
15596   M (CONTROL_PING, mp_ping);
15597   S (mp_ping);
15598
15599   W (ret);
15600   return ret;
15601 }
15602
15603 static int
15604 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15605 {
15606   unformat_input_t *i = vam->input;
15607   vl_api_ipsec_tunnel_if_set_key_t *mp;
15608   u32 sw_if_index = ~0;
15609   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15610   u8 *key = 0;
15611   u32 alg = ~0;
15612   int ret;
15613
15614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15615     {
15616       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15617         ;
15618       else
15619         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15620         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15621       else
15622         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15623         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15624       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15625         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15626       else
15627         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15628         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15629       else if (unformat (i, "%U", unformat_hex_string, &key))
15630         ;
15631       else
15632         {
15633           clib_warning ("parse error '%U'", format_unformat_error, i);
15634           return -99;
15635         }
15636     }
15637
15638   if (sw_if_index == ~0)
15639     {
15640       errmsg ("interface must be specified");
15641       return -99;
15642     }
15643
15644   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15645     {
15646       errmsg ("key type must be specified");
15647       return -99;
15648     }
15649
15650   if (alg == ~0)
15651     {
15652       errmsg ("algorithm must be specified");
15653       return -99;
15654     }
15655
15656   if (vec_len (key) == 0)
15657     {
15658       errmsg ("key must be specified");
15659       return -99;
15660     }
15661
15662   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15663
15664   mp->sw_if_index = htonl (sw_if_index);
15665   mp->alg = alg;
15666   mp->key_type = key_type;
15667   mp->key_len = vec_len (key);
15668   clib_memcpy (mp->key, key, vec_len (key));
15669
15670   S (mp);
15671   W (ret);
15672
15673   return ret;
15674 }
15675
15676 static int
15677 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15678 {
15679   unformat_input_t *i = vam->input;
15680   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15681   u32 sw_if_index = ~0;
15682   u32 sa_id = ~0;
15683   u8 is_outbound = (u8) ~ 0;
15684   int ret;
15685
15686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15687     {
15688       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15689         ;
15690       else if (unformat (i, "sa_id %d", &sa_id))
15691         ;
15692       else if (unformat (i, "outbound"))
15693         is_outbound = 1;
15694       else if (unformat (i, "inbound"))
15695         is_outbound = 0;
15696       else
15697         {
15698           clib_warning ("parse error '%U'", format_unformat_error, i);
15699           return -99;
15700         }
15701     }
15702
15703   if (sw_if_index == ~0)
15704     {
15705       errmsg ("interface must be specified");
15706       return -99;
15707     }
15708
15709   if (sa_id == ~0)
15710     {
15711       errmsg ("SA ID must be specified");
15712       return -99;
15713     }
15714
15715   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15716
15717   mp->sw_if_index = htonl (sw_if_index);
15718   mp->sa_id = htonl (sa_id);
15719   mp->is_outbound = is_outbound;
15720
15721   S (mp);
15722   W (ret);
15723
15724   return ret;
15725 }
15726
15727 static int
15728 api_ikev2_profile_add_del (vat_main_t * vam)
15729 {
15730   unformat_input_t *i = vam->input;
15731   vl_api_ikev2_profile_add_del_t *mp;
15732   u8 is_add = 1;
15733   u8 *name = 0;
15734   int ret;
15735
15736   const char *valid_chars = "a-zA-Z0-9_";
15737
15738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15739     {
15740       if (unformat (i, "del"))
15741         is_add = 0;
15742       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15743         vec_add1 (name, 0);
15744       else
15745         {
15746           errmsg ("parse error '%U'", format_unformat_error, i);
15747           return -99;
15748         }
15749     }
15750
15751   if (!vec_len (name))
15752     {
15753       errmsg ("profile name must be specified");
15754       return -99;
15755     }
15756
15757   if (vec_len (name) > 64)
15758     {
15759       errmsg ("profile name too long");
15760       return -99;
15761     }
15762
15763   M (IKEV2_PROFILE_ADD_DEL, mp);
15764
15765   clib_memcpy (mp->name, name, vec_len (name));
15766   mp->is_add = is_add;
15767   vec_free (name);
15768
15769   S (mp);
15770   W (ret);
15771   return ret;
15772 }
15773
15774 static int
15775 api_ikev2_profile_set_auth (vat_main_t * vam)
15776 {
15777   unformat_input_t *i = vam->input;
15778   vl_api_ikev2_profile_set_auth_t *mp;
15779   u8 *name = 0;
15780   u8 *data = 0;
15781   u32 auth_method = 0;
15782   u8 is_hex = 0;
15783   int ret;
15784
15785   const char *valid_chars = "a-zA-Z0-9_";
15786
15787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15788     {
15789       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15790         vec_add1 (name, 0);
15791       else if (unformat (i, "auth_method %U",
15792                          unformat_ikev2_auth_method, &auth_method))
15793         ;
15794       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15795         is_hex = 1;
15796       else if (unformat (i, "auth_data %v", &data))
15797         ;
15798       else
15799         {
15800           errmsg ("parse error '%U'", format_unformat_error, i);
15801           return -99;
15802         }
15803     }
15804
15805   if (!vec_len (name))
15806     {
15807       errmsg ("profile name must be specified");
15808       return -99;
15809     }
15810
15811   if (vec_len (name) > 64)
15812     {
15813       errmsg ("profile name too long");
15814       return -99;
15815     }
15816
15817   if (!vec_len (data))
15818     {
15819       errmsg ("auth_data must be specified");
15820       return -99;
15821     }
15822
15823   if (!auth_method)
15824     {
15825       errmsg ("auth_method must be specified");
15826       return -99;
15827     }
15828
15829   M (IKEV2_PROFILE_SET_AUTH, mp);
15830
15831   mp->is_hex = is_hex;
15832   mp->auth_method = (u8) auth_method;
15833   mp->data_len = vec_len (data);
15834   clib_memcpy (mp->name, name, vec_len (name));
15835   clib_memcpy (mp->data, data, vec_len (data));
15836   vec_free (name);
15837   vec_free (data);
15838
15839   S (mp);
15840   W (ret);
15841   return ret;
15842 }
15843
15844 static int
15845 api_ikev2_profile_set_id (vat_main_t * vam)
15846 {
15847   unformat_input_t *i = vam->input;
15848   vl_api_ikev2_profile_set_id_t *mp;
15849   u8 *name = 0;
15850   u8 *data = 0;
15851   u8 is_local = 0;
15852   u32 id_type = 0;
15853   ip4_address_t ip4;
15854   int ret;
15855
15856   const char *valid_chars = "a-zA-Z0-9_";
15857
15858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15859     {
15860       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15861         vec_add1 (name, 0);
15862       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15863         ;
15864       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15865         {
15866           data = vec_new (u8, 4);
15867           clib_memcpy (data, ip4.as_u8, 4);
15868         }
15869       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15870         ;
15871       else if (unformat (i, "id_data %v", &data))
15872         ;
15873       else if (unformat (i, "local"))
15874         is_local = 1;
15875       else if (unformat (i, "remote"))
15876         is_local = 0;
15877       else
15878         {
15879           errmsg ("parse error '%U'", format_unformat_error, i);
15880           return -99;
15881         }
15882     }
15883
15884   if (!vec_len (name))
15885     {
15886       errmsg ("profile name must be specified");
15887       return -99;
15888     }
15889
15890   if (vec_len (name) > 64)
15891     {
15892       errmsg ("profile name too long");
15893       return -99;
15894     }
15895
15896   if (!vec_len (data))
15897     {
15898       errmsg ("id_data must be specified");
15899       return -99;
15900     }
15901
15902   if (!id_type)
15903     {
15904       errmsg ("id_type must be specified");
15905       return -99;
15906     }
15907
15908   M (IKEV2_PROFILE_SET_ID, mp);
15909
15910   mp->is_local = is_local;
15911   mp->id_type = (u8) id_type;
15912   mp->data_len = vec_len (data);
15913   clib_memcpy (mp->name, name, vec_len (name));
15914   clib_memcpy (mp->data, data, vec_len (data));
15915   vec_free (name);
15916   vec_free (data);
15917
15918   S (mp);
15919   W (ret);
15920   return ret;
15921 }
15922
15923 static int
15924 api_ikev2_profile_set_ts (vat_main_t * vam)
15925 {
15926   unformat_input_t *i = vam->input;
15927   vl_api_ikev2_profile_set_ts_t *mp;
15928   u8 *name = 0;
15929   u8 is_local = 0;
15930   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15931   ip4_address_t start_addr, end_addr;
15932
15933   const char *valid_chars = "a-zA-Z0-9_";
15934   int ret;
15935
15936   start_addr.as_u32 = 0;
15937   end_addr.as_u32 = (u32) ~ 0;
15938
15939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15940     {
15941       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15942         vec_add1 (name, 0);
15943       else if (unformat (i, "protocol %d", &proto))
15944         ;
15945       else if (unformat (i, "start_port %d", &start_port))
15946         ;
15947       else if (unformat (i, "end_port %d", &end_port))
15948         ;
15949       else
15950         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15951         ;
15952       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15953         ;
15954       else if (unformat (i, "local"))
15955         is_local = 1;
15956       else if (unformat (i, "remote"))
15957         is_local = 0;
15958       else
15959         {
15960           errmsg ("parse error '%U'", format_unformat_error, i);
15961           return -99;
15962         }
15963     }
15964
15965   if (!vec_len (name))
15966     {
15967       errmsg ("profile name must be specified");
15968       return -99;
15969     }
15970
15971   if (vec_len (name) > 64)
15972     {
15973       errmsg ("profile name too long");
15974       return -99;
15975     }
15976
15977   M (IKEV2_PROFILE_SET_TS, mp);
15978
15979   mp->is_local = is_local;
15980   mp->proto = (u8) proto;
15981   mp->start_port = (u16) start_port;
15982   mp->end_port = (u16) end_port;
15983   mp->start_addr = start_addr.as_u32;
15984   mp->end_addr = end_addr.as_u32;
15985   clib_memcpy (mp->name, name, vec_len (name));
15986   vec_free (name);
15987
15988   S (mp);
15989   W (ret);
15990   return ret;
15991 }
15992
15993 static int
15994 api_ikev2_set_local_key (vat_main_t * vam)
15995 {
15996   unformat_input_t *i = vam->input;
15997   vl_api_ikev2_set_local_key_t *mp;
15998   u8 *file = 0;
15999   int ret;
16000
16001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16002     {
16003       if (unformat (i, "file %v", &file))
16004         vec_add1 (file, 0);
16005       else
16006         {
16007           errmsg ("parse error '%U'", format_unformat_error, i);
16008           return -99;
16009         }
16010     }
16011
16012   if (!vec_len (file))
16013     {
16014       errmsg ("RSA key file must be specified");
16015       return -99;
16016     }
16017
16018   if (vec_len (file) > 256)
16019     {
16020       errmsg ("file name too long");
16021       return -99;
16022     }
16023
16024   M (IKEV2_SET_LOCAL_KEY, mp);
16025
16026   clib_memcpy (mp->key_file, file, vec_len (file));
16027   vec_free (file);
16028
16029   S (mp);
16030   W (ret);
16031   return ret;
16032 }
16033
16034 static int
16035 api_ikev2_set_responder (vat_main_t * vam)
16036 {
16037   unformat_input_t *i = vam->input;
16038   vl_api_ikev2_set_responder_t *mp;
16039   int ret;
16040   u8 *name = 0;
16041   u32 sw_if_index = ~0;
16042   ip4_address_t address;
16043
16044   const char *valid_chars = "a-zA-Z0-9_";
16045
16046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16047     {
16048       if (unformat
16049           (i, "%U interface %d address %U", unformat_token, valid_chars,
16050            &name, &sw_if_index, unformat_ip4_address, &address))
16051         vec_add1 (name, 0);
16052       else
16053         {
16054           errmsg ("parse error '%U'", format_unformat_error, i);
16055           return -99;
16056         }
16057     }
16058
16059   if (!vec_len (name))
16060     {
16061       errmsg ("profile name must be specified");
16062       return -99;
16063     }
16064
16065   if (vec_len (name) > 64)
16066     {
16067       errmsg ("profile name too long");
16068       return -99;
16069     }
16070
16071   M (IKEV2_SET_RESPONDER, mp);
16072
16073   clib_memcpy (mp->name, name, vec_len (name));
16074   vec_free (name);
16075
16076   mp->sw_if_index = sw_if_index;
16077   clib_memcpy (mp->address, &address, sizeof (address));
16078
16079   S (mp);
16080   W (ret);
16081   return ret;
16082 }
16083
16084 static int
16085 api_ikev2_set_ike_transforms (vat_main_t * vam)
16086 {
16087   unformat_input_t *i = vam->input;
16088   vl_api_ikev2_set_ike_transforms_t *mp;
16089   int ret;
16090   u8 *name = 0;
16091   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16092
16093   const char *valid_chars = "a-zA-Z0-9_";
16094
16095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16096     {
16097       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16098                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16099         vec_add1 (name, 0);
16100       else
16101         {
16102           errmsg ("parse error '%U'", format_unformat_error, i);
16103           return -99;
16104         }
16105     }
16106
16107   if (!vec_len (name))
16108     {
16109       errmsg ("profile name must be specified");
16110       return -99;
16111     }
16112
16113   if (vec_len (name) > 64)
16114     {
16115       errmsg ("profile name too long");
16116       return -99;
16117     }
16118
16119   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16120
16121   clib_memcpy (mp->name, name, vec_len (name));
16122   vec_free (name);
16123   mp->crypto_alg = crypto_alg;
16124   mp->crypto_key_size = crypto_key_size;
16125   mp->integ_alg = integ_alg;
16126   mp->dh_group = dh_group;
16127
16128   S (mp);
16129   W (ret);
16130   return ret;
16131 }
16132
16133
16134 static int
16135 api_ikev2_set_esp_transforms (vat_main_t * vam)
16136 {
16137   unformat_input_t *i = vam->input;
16138   vl_api_ikev2_set_esp_transforms_t *mp;
16139   int ret;
16140   u8 *name = 0;
16141   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16142
16143   const char *valid_chars = "a-zA-Z0-9_";
16144
16145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16146     {
16147       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16148                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16149         vec_add1 (name, 0);
16150       else
16151         {
16152           errmsg ("parse error '%U'", format_unformat_error, i);
16153           return -99;
16154         }
16155     }
16156
16157   if (!vec_len (name))
16158     {
16159       errmsg ("profile name must be specified");
16160       return -99;
16161     }
16162
16163   if (vec_len (name) > 64)
16164     {
16165       errmsg ("profile name too long");
16166       return -99;
16167     }
16168
16169   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16170
16171   clib_memcpy (mp->name, name, vec_len (name));
16172   vec_free (name);
16173   mp->crypto_alg = crypto_alg;
16174   mp->crypto_key_size = crypto_key_size;
16175   mp->integ_alg = integ_alg;
16176   mp->dh_group = dh_group;
16177
16178   S (mp);
16179   W (ret);
16180   return ret;
16181 }
16182
16183 static int
16184 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16185 {
16186   unformat_input_t *i = vam->input;
16187   vl_api_ikev2_set_sa_lifetime_t *mp;
16188   int ret;
16189   u8 *name = 0;
16190   u64 lifetime, lifetime_maxdata;
16191   u32 lifetime_jitter, handover;
16192
16193   const char *valid_chars = "a-zA-Z0-9_";
16194
16195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16196     {
16197       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16198                     &lifetime, &lifetime_jitter, &handover,
16199                     &lifetime_maxdata))
16200         vec_add1 (name, 0);
16201       else
16202         {
16203           errmsg ("parse error '%U'", format_unformat_error, i);
16204           return -99;
16205         }
16206     }
16207
16208   if (!vec_len (name))
16209     {
16210       errmsg ("profile name must be specified");
16211       return -99;
16212     }
16213
16214   if (vec_len (name) > 64)
16215     {
16216       errmsg ("profile name too long");
16217       return -99;
16218     }
16219
16220   M (IKEV2_SET_SA_LIFETIME, mp);
16221
16222   clib_memcpy (mp->name, name, vec_len (name));
16223   vec_free (name);
16224   mp->lifetime = lifetime;
16225   mp->lifetime_jitter = lifetime_jitter;
16226   mp->handover = handover;
16227   mp->lifetime_maxdata = lifetime_maxdata;
16228
16229   S (mp);
16230   W (ret);
16231   return ret;
16232 }
16233
16234 static int
16235 api_ikev2_initiate_sa_init (vat_main_t * vam)
16236 {
16237   unformat_input_t *i = vam->input;
16238   vl_api_ikev2_initiate_sa_init_t *mp;
16239   int ret;
16240   u8 *name = 0;
16241
16242   const char *valid_chars = "a-zA-Z0-9_";
16243
16244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16247         vec_add1 (name, 0);
16248       else
16249         {
16250           errmsg ("parse error '%U'", format_unformat_error, i);
16251           return -99;
16252         }
16253     }
16254
16255   if (!vec_len (name))
16256     {
16257       errmsg ("profile name must be specified");
16258       return -99;
16259     }
16260
16261   if (vec_len (name) > 64)
16262     {
16263       errmsg ("profile name too long");
16264       return -99;
16265     }
16266
16267   M (IKEV2_INITIATE_SA_INIT, mp);
16268
16269   clib_memcpy (mp->name, name, vec_len (name));
16270   vec_free (name);
16271
16272   S (mp);
16273   W (ret);
16274   return ret;
16275 }
16276
16277 static int
16278 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16279 {
16280   unformat_input_t *i = vam->input;
16281   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16282   int ret;
16283   u64 ispi;
16284
16285
16286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16287     {
16288       if (unformat (i, "%lx", &ispi))
16289         ;
16290       else
16291         {
16292           errmsg ("parse error '%U'", format_unformat_error, i);
16293           return -99;
16294         }
16295     }
16296
16297   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16298
16299   mp->ispi = ispi;
16300
16301   S (mp);
16302   W (ret);
16303   return ret;
16304 }
16305
16306 static int
16307 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16308 {
16309   unformat_input_t *i = vam->input;
16310   vl_api_ikev2_initiate_del_child_sa_t *mp;
16311   int ret;
16312   u32 ispi;
16313
16314
16315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16316     {
16317       if (unformat (i, "%x", &ispi))
16318         ;
16319       else
16320         {
16321           errmsg ("parse error '%U'", format_unformat_error, i);
16322           return -99;
16323         }
16324     }
16325
16326   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16327
16328   mp->ispi = ispi;
16329
16330   S (mp);
16331   W (ret);
16332   return ret;
16333 }
16334
16335 static int
16336 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16337 {
16338   unformat_input_t *i = vam->input;
16339   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16340   int ret;
16341   u32 ispi;
16342
16343
16344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16345     {
16346       if (unformat (i, "%x", &ispi))
16347         ;
16348       else
16349         {
16350           errmsg ("parse error '%U'", format_unformat_error, i);
16351           return -99;
16352         }
16353     }
16354
16355   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16356
16357   mp->ispi = ispi;
16358
16359   S (mp);
16360   W (ret);
16361   return ret;
16362 }
16363
16364 /*
16365  * MAP
16366  */
16367 static int
16368 api_map_add_domain (vat_main_t * vam)
16369 {
16370   unformat_input_t *i = vam->input;
16371   vl_api_map_add_domain_t *mp;
16372
16373   ip4_address_t ip4_prefix;
16374   ip6_address_t ip6_prefix;
16375   ip6_address_t ip6_src;
16376   u32 num_m_args = 0;
16377   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16378     0, psid_length = 0;
16379   u8 is_translation = 0;
16380   u32 mtu = 0;
16381   u32 ip6_src_len = 128;
16382   int ret;
16383
16384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16385     {
16386       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16387                     &ip4_prefix, &ip4_prefix_len))
16388         num_m_args++;
16389       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16390                          &ip6_prefix, &ip6_prefix_len))
16391         num_m_args++;
16392       else
16393         if (unformat
16394             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16395              &ip6_src_len))
16396         num_m_args++;
16397       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16398         num_m_args++;
16399       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16400         num_m_args++;
16401       else if (unformat (i, "psid-offset %d", &psid_offset))
16402         num_m_args++;
16403       else if (unformat (i, "psid-len %d", &psid_length))
16404         num_m_args++;
16405       else if (unformat (i, "mtu %d", &mtu))
16406         num_m_args++;
16407       else if (unformat (i, "map-t"))
16408         is_translation = 1;
16409       else
16410         {
16411           clib_warning ("parse error '%U'", format_unformat_error, i);
16412           return -99;
16413         }
16414     }
16415
16416   if (num_m_args < 3)
16417     {
16418       errmsg ("mandatory argument(s) missing");
16419       return -99;
16420     }
16421
16422   /* Construct the API message */
16423   M (MAP_ADD_DOMAIN, mp);
16424
16425   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16426   mp->ip4_prefix_len = ip4_prefix_len;
16427
16428   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16429   mp->ip6_prefix_len = ip6_prefix_len;
16430
16431   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16432   mp->ip6_src_prefix_len = ip6_src_len;
16433
16434   mp->ea_bits_len = ea_bits_len;
16435   mp->psid_offset = psid_offset;
16436   mp->psid_length = psid_length;
16437   mp->is_translation = is_translation;
16438   mp->mtu = htons (mtu);
16439
16440   /* send it... */
16441   S (mp);
16442
16443   /* Wait for a reply, return good/bad news  */
16444   W (ret);
16445   return ret;
16446 }
16447
16448 static int
16449 api_map_del_domain (vat_main_t * vam)
16450 {
16451   unformat_input_t *i = vam->input;
16452   vl_api_map_del_domain_t *mp;
16453
16454   u32 num_m_args = 0;
16455   u32 index;
16456   int ret;
16457
16458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16459     {
16460       if (unformat (i, "index %d", &index))
16461         num_m_args++;
16462       else
16463         {
16464           clib_warning ("parse error '%U'", format_unformat_error, i);
16465           return -99;
16466         }
16467     }
16468
16469   if (num_m_args != 1)
16470     {
16471       errmsg ("mandatory argument(s) missing");
16472       return -99;
16473     }
16474
16475   /* Construct the API message */
16476   M (MAP_DEL_DOMAIN, mp);
16477
16478   mp->index = ntohl (index);
16479
16480   /* send it... */
16481   S (mp);
16482
16483   /* Wait for a reply, return good/bad news  */
16484   W (ret);
16485   return ret;
16486 }
16487
16488 static int
16489 api_map_add_del_rule (vat_main_t * vam)
16490 {
16491   unformat_input_t *i = vam->input;
16492   vl_api_map_add_del_rule_t *mp;
16493   u8 is_add = 1;
16494   ip6_address_t ip6_dst;
16495   u32 num_m_args = 0, index, psid = 0;
16496   int ret;
16497
16498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16499     {
16500       if (unformat (i, "index %d", &index))
16501         num_m_args++;
16502       else if (unformat (i, "psid %d", &psid))
16503         num_m_args++;
16504       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16505         num_m_args++;
16506       else if (unformat (i, "del"))
16507         {
16508           is_add = 0;
16509         }
16510       else
16511         {
16512           clib_warning ("parse error '%U'", format_unformat_error, i);
16513           return -99;
16514         }
16515     }
16516
16517   /* Construct the API message */
16518   M (MAP_ADD_DEL_RULE, mp);
16519
16520   mp->index = ntohl (index);
16521   mp->is_add = is_add;
16522   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16523   mp->psid = ntohs (psid);
16524
16525   /* send it... */
16526   S (mp);
16527
16528   /* Wait for a reply, return good/bad news  */
16529   W (ret);
16530   return ret;
16531 }
16532
16533 static int
16534 api_map_domain_dump (vat_main_t * vam)
16535 {
16536   vl_api_map_domain_dump_t *mp;
16537   vl_api_control_ping_t *mp_ping;
16538   int ret;
16539
16540   /* Construct the API message */
16541   M (MAP_DOMAIN_DUMP, mp);
16542
16543   /* send it... */
16544   S (mp);
16545
16546   /* Use a control ping for synchronization */
16547   MPING (CONTROL_PING, mp_ping);
16548   S (mp_ping);
16549
16550   W (ret);
16551   return ret;
16552 }
16553
16554 static int
16555 api_map_rule_dump (vat_main_t * vam)
16556 {
16557   unformat_input_t *i = vam->input;
16558   vl_api_map_rule_dump_t *mp;
16559   vl_api_control_ping_t *mp_ping;
16560   u32 domain_index = ~0;
16561   int ret;
16562
16563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16564     {
16565       if (unformat (i, "index %u", &domain_index))
16566         ;
16567       else
16568         break;
16569     }
16570
16571   if (domain_index == ~0)
16572     {
16573       clib_warning ("parse error: domain index expected");
16574       return -99;
16575     }
16576
16577   /* Construct the API message */
16578   M (MAP_RULE_DUMP, mp);
16579
16580   mp->domain_index = htonl (domain_index);
16581
16582   /* send it... */
16583   S (mp);
16584
16585   /* Use a control ping for synchronization */
16586   MPING (CONTROL_PING, mp_ping);
16587   S (mp_ping);
16588
16589   W (ret);
16590   return ret;
16591 }
16592
16593 static void vl_api_map_add_domain_reply_t_handler
16594   (vl_api_map_add_domain_reply_t * mp)
16595 {
16596   vat_main_t *vam = &vat_main;
16597   i32 retval = ntohl (mp->retval);
16598
16599   if (vam->async_mode)
16600     {
16601       vam->async_errors += (retval < 0);
16602     }
16603   else
16604     {
16605       vam->retval = retval;
16606       vam->result_ready = 1;
16607     }
16608 }
16609
16610 static void vl_api_map_add_domain_reply_t_handler_json
16611   (vl_api_map_add_domain_reply_t * mp)
16612 {
16613   vat_main_t *vam = &vat_main;
16614   vat_json_node_t node;
16615
16616   vat_json_init_object (&node);
16617   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16618   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16619
16620   vat_json_print (vam->ofp, &node);
16621   vat_json_free (&node);
16622
16623   vam->retval = ntohl (mp->retval);
16624   vam->result_ready = 1;
16625 }
16626
16627 static int
16628 api_get_first_msg_id (vat_main_t * vam)
16629 {
16630   vl_api_get_first_msg_id_t *mp;
16631   unformat_input_t *i = vam->input;
16632   u8 *name;
16633   u8 name_set = 0;
16634   int ret;
16635
16636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16637     {
16638       if (unformat (i, "client %s", &name))
16639         name_set = 1;
16640       else
16641         break;
16642     }
16643
16644   if (name_set == 0)
16645     {
16646       errmsg ("missing client name");
16647       return -99;
16648     }
16649   vec_add1 (name, 0);
16650
16651   if (vec_len (name) > 63)
16652     {
16653       errmsg ("client name too long");
16654       return -99;
16655     }
16656
16657   M (GET_FIRST_MSG_ID, mp);
16658   clib_memcpy (mp->name, name, vec_len (name));
16659   S (mp);
16660   W (ret);
16661   return ret;
16662 }
16663
16664 static int
16665 api_cop_interface_enable_disable (vat_main_t * vam)
16666 {
16667   unformat_input_t *line_input = vam->input;
16668   vl_api_cop_interface_enable_disable_t *mp;
16669   u32 sw_if_index = ~0;
16670   u8 enable_disable = 1;
16671   int ret;
16672
16673   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16674     {
16675       if (unformat (line_input, "disable"))
16676         enable_disable = 0;
16677       if (unformat (line_input, "enable"))
16678         enable_disable = 1;
16679       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16680                          vam, &sw_if_index))
16681         ;
16682       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16683         ;
16684       else
16685         break;
16686     }
16687
16688   if (sw_if_index == ~0)
16689     {
16690       errmsg ("missing interface name or sw_if_index");
16691       return -99;
16692     }
16693
16694   /* Construct the API message */
16695   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16696   mp->sw_if_index = ntohl (sw_if_index);
16697   mp->enable_disable = enable_disable;
16698
16699   /* send it... */
16700   S (mp);
16701   /* Wait for the reply */
16702   W (ret);
16703   return ret;
16704 }
16705
16706 static int
16707 api_cop_whitelist_enable_disable (vat_main_t * vam)
16708 {
16709   unformat_input_t *line_input = vam->input;
16710   vl_api_cop_whitelist_enable_disable_t *mp;
16711   u32 sw_if_index = ~0;
16712   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16713   u32 fib_id = 0;
16714   int ret;
16715
16716   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16717     {
16718       if (unformat (line_input, "ip4"))
16719         ip4 = 1;
16720       else if (unformat (line_input, "ip6"))
16721         ip6 = 1;
16722       else if (unformat (line_input, "default"))
16723         default_cop = 1;
16724       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16725                          vam, &sw_if_index))
16726         ;
16727       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16728         ;
16729       else if (unformat (line_input, "fib-id %d", &fib_id))
16730         ;
16731       else
16732         break;
16733     }
16734
16735   if (sw_if_index == ~0)
16736     {
16737       errmsg ("missing interface name or sw_if_index");
16738       return -99;
16739     }
16740
16741   /* Construct the API message */
16742   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16743   mp->sw_if_index = ntohl (sw_if_index);
16744   mp->fib_id = ntohl (fib_id);
16745   mp->ip4 = ip4;
16746   mp->ip6 = ip6;
16747   mp->default_cop = default_cop;
16748
16749   /* send it... */
16750   S (mp);
16751   /* Wait for the reply */
16752   W (ret);
16753   return ret;
16754 }
16755
16756 static int
16757 api_get_node_graph (vat_main_t * vam)
16758 {
16759   vl_api_get_node_graph_t *mp;
16760   int ret;
16761
16762   M (GET_NODE_GRAPH, mp);
16763
16764   /* send it... */
16765   S (mp);
16766   /* Wait for the reply */
16767   W (ret);
16768   return ret;
16769 }
16770
16771 /* *INDENT-OFF* */
16772 /** Used for parsing LISP eids */
16773 typedef CLIB_PACKED(struct{
16774   u8 addr[16];   /**< eid address */
16775   u32 len;       /**< prefix length if IP */
16776   u8 type;      /**< type of eid */
16777 }) lisp_eid_vat_t;
16778 /* *INDENT-ON* */
16779
16780 static uword
16781 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16782 {
16783   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16784
16785   memset (a, 0, sizeof (a[0]));
16786
16787   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16788     {
16789       a->type = 0;              /* ipv4 type */
16790     }
16791   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16792     {
16793       a->type = 1;              /* ipv6 type */
16794     }
16795   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16796     {
16797       a->type = 2;              /* mac type */
16798     }
16799   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16800     {
16801       a->type = 3;              /* NSH type */
16802       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16803       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16804     }
16805   else
16806     {
16807       return 0;
16808     }
16809
16810   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16811     {
16812       return 0;
16813     }
16814
16815   return 1;
16816 }
16817
16818 static int
16819 lisp_eid_size_vat (u8 type)
16820 {
16821   switch (type)
16822     {
16823     case 0:
16824       return 4;
16825     case 1:
16826       return 16;
16827     case 2:
16828       return 6;
16829     case 3:
16830       return 5;
16831     }
16832   return 0;
16833 }
16834
16835 static void
16836 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16837 {
16838   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16839 }
16840
16841 static int
16842 api_one_add_del_locator_set (vat_main_t * vam)
16843 {
16844   unformat_input_t *input = vam->input;
16845   vl_api_one_add_del_locator_set_t *mp;
16846   u8 is_add = 1;
16847   u8 *locator_set_name = NULL;
16848   u8 locator_set_name_set = 0;
16849   vl_api_local_locator_t locator, *locators = 0;
16850   u32 sw_if_index, priority, weight;
16851   u32 data_len = 0;
16852
16853   int ret;
16854   /* Parse args required to build the message */
16855   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16856     {
16857       if (unformat (input, "del"))
16858         {
16859           is_add = 0;
16860         }
16861       else if (unformat (input, "locator-set %s", &locator_set_name))
16862         {
16863           locator_set_name_set = 1;
16864         }
16865       else if (unformat (input, "sw_if_index %u p %u w %u",
16866                          &sw_if_index, &priority, &weight))
16867         {
16868           locator.sw_if_index = htonl (sw_if_index);
16869           locator.priority = priority;
16870           locator.weight = weight;
16871           vec_add1 (locators, locator);
16872         }
16873       else
16874         if (unformat
16875             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16876              &sw_if_index, &priority, &weight))
16877         {
16878           locator.sw_if_index = htonl (sw_if_index);
16879           locator.priority = priority;
16880           locator.weight = weight;
16881           vec_add1 (locators, locator);
16882         }
16883       else
16884         break;
16885     }
16886
16887   if (locator_set_name_set == 0)
16888     {
16889       errmsg ("missing locator-set name");
16890       vec_free (locators);
16891       return -99;
16892     }
16893
16894   if (vec_len (locator_set_name) > 64)
16895     {
16896       errmsg ("locator-set name too long");
16897       vec_free (locator_set_name);
16898       vec_free (locators);
16899       return -99;
16900     }
16901   vec_add1 (locator_set_name, 0);
16902
16903   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16904
16905   /* Construct the API message */
16906   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16907
16908   mp->is_add = is_add;
16909   clib_memcpy (mp->locator_set_name, locator_set_name,
16910                vec_len (locator_set_name));
16911   vec_free (locator_set_name);
16912
16913   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16914   if (locators)
16915     clib_memcpy (mp->locators, locators, data_len);
16916   vec_free (locators);
16917
16918   /* send it... */
16919   S (mp);
16920
16921   /* Wait for a reply... */
16922   W (ret);
16923   return ret;
16924 }
16925
16926 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16927
16928 static int
16929 api_one_add_del_locator (vat_main_t * vam)
16930 {
16931   unformat_input_t *input = vam->input;
16932   vl_api_one_add_del_locator_t *mp;
16933   u32 tmp_if_index = ~0;
16934   u32 sw_if_index = ~0;
16935   u8 sw_if_index_set = 0;
16936   u8 sw_if_index_if_name_set = 0;
16937   u32 priority = ~0;
16938   u8 priority_set = 0;
16939   u32 weight = ~0;
16940   u8 weight_set = 0;
16941   u8 is_add = 1;
16942   u8 *locator_set_name = NULL;
16943   u8 locator_set_name_set = 0;
16944   int ret;
16945
16946   /* Parse args required to build the message */
16947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16948     {
16949       if (unformat (input, "del"))
16950         {
16951           is_add = 0;
16952         }
16953       else if (unformat (input, "locator-set %s", &locator_set_name))
16954         {
16955           locator_set_name_set = 1;
16956         }
16957       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16958                          &tmp_if_index))
16959         {
16960           sw_if_index_if_name_set = 1;
16961           sw_if_index = tmp_if_index;
16962         }
16963       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16964         {
16965           sw_if_index_set = 1;
16966           sw_if_index = tmp_if_index;
16967         }
16968       else if (unformat (input, "p %d", &priority))
16969         {
16970           priority_set = 1;
16971         }
16972       else if (unformat (input, "w %d", &weight))
16973         {
16974           weight_set = 1;
16975         }
16976       else
16977         break;
16978     }
16979
16980   if (locator_set_name_set == 0)
16981     {
16982       errmsg ("missing locator-set name");
16983       return -99;
16984     }
16985
16986   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16987     {
16988       errmsg ("missing sw_if_index");
16989       vec_free (locator_set_name);
16990       return -99;
16991     }
16992
16993   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16994     {
16995       errmsg ("cannot use both params interface name and sw_if_index");
16996       vec_free (locator_set_name);
16997       return -99;
16998     }
16999
17000   if (priority_set == 0)
17001     {
17002       errmsg ("missing locator-set priority");
17003       vec_free (locator_set_name);
17004       return -99;
17005     }
17006
17007   if (weight_set == 0)
17008     {
17009       errmsg ("missing locator-set weight");
17010       vec_free (locator_set_name);
17011       return -99;
17012     }
17013
17014   if (vec_len (locator_set_name) > 64)
17015     {
17016       errmsg ("locator-set name too long");
17017       vec_free (locator_set_name);
17018       return -99;
17019     }
17020   vec_add1 (locator_set_name, 0);
17021
17022   /* Construct the API message */
17023   M (ONE_ADD_DEL_LOCATOR, mp);
17024
17025   mp->is_add = is_add;
17026   mp->sw_if_index = ntohl (sw_if_index);
17027   mp->priority = priority;
17028   mp->weight = weight;
17029   clib_memcpy (mp->locator_set_name, locator_set_name,
17030                vec_len (locator_set_name));
17031   vec_free (locator_set_name);
17032
17033   /* send it... */
17034   S (mp);
17035
17036   /* Wait for a reply... */
17037   W (ret);
17038   return ret;
17039 }
17040
17041 #define api_lisp_add_del_locator api_one_add_del_locator
17042
17043 uword
17044 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17045 {
17046   u32 *key_id = va_arg (*args, u32 *);
17047   u8 *s = 0;
17048
17049   if (unformat (input, "%s", &s))
17050     {
17051       if (!strcmp ((char *) s, "sha1"))
17052         key_id[0] = HMAC_SHA_1_96;
17053       else if (!strcmp ((char *) s, "sha256"))
17054         key_id[0] = HMAC_SHA_256_128;
17055       else
17056         {
17057           clib_warning ("invalid key_id: '%s'", s);
17058           key_id[0] = HMAC_NO_KEY;
17059         }
17060     }
17061   else
17062     return 0;
17063
17064   vec_free (s);
17065   return 1;
17066 }
17067
17068 static int
17069 api_one_add_del_local_eid (vat_main_t * vam)
17070 {
17071   unformat_input_t *input = vam->input;
17072   vl_api_one_add_del_local_eid_t *mp;
17073   u8 is_add = 1;
17074   u8 eid_set = 0;
17075   lisp_eid_vat_t _eid, *eid = &_eid;
17076   u8 *locator_set_name = 0;
17077   u8 locator_set_name_set = 0;
17078   u32 vni = 0;
17079   u16 key_id = 0;
17080   u8 *key = 0;
17081   int ret;
17082
17083   /* Parse args required to build the message */
17084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17085     {
17086       if (unformat (input, "del"))
17087         {
17088           is_add = 0;
17089         }
17090       else if (unformat (input, "vni %d", &vni))
17091         {
17092           ;
17093         }
17094       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17095         {
17096           eid_set = 1;
17097         }
17098       else if (unformat (input, "locator-set %s", &locator_set_name))
17099         {
17100           locator_set_name_set = 1;
17101         }
17102       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17103         ;
17104       else if (unformat (input, "secret-key %_%v%_", &key))
17105         ;
17106       else
17107         break;
17108     }
17109
17110   if (locator_set_name_set == 0)
17111     {
17112       errmsg ("missing locator-set name");
17113       return -99;
17114     }
17115
17116   if (0 == eid_set)
17117     {
17118       errmsg ("EID address not set!");
17119       vec_free (locator_set_name);
17120       return -99;
17121     }
17122
17123   if (key && (0 == key_id))
17124     {
17125       errmsg ("invalid key_id!");
17126       return -99;
17127     }
17128
17129   if (vec_len (key) > 64)
17130     {
17131       errmsg ("key too long");
17132       vec_free (key);
17133       return -99;
17134     }
17135
17136   if (vec_len (locator_set_name) > 64)
17137     {
17138       errmsg ("locator-set name too long");
17139       vec_free (locator_set_name);
17140       return -99;
17141     }
17142   vec_add1 (locator_set_name, 0);
17143
17144   /* Construct the API message */
17145   M (ONE_ADD_DEL_LOCAL_EID, mp);
17146
17147   mp->is_add = is_add;
17148   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17149   mp->eid_type = eid->type;
17150   mp->prefix_len = eid->len;
17151   mp->vni = clib_host_to_net_u32 (vni);
17152   mp->key_id = clib_host_to_net_u16 (key_id);
17153   clib_memcpy (mp->locator_set_name, locator_set_name,
17154                vec_len (locator_set_name));
17155   clib_memcpy (mp->key, key, vec_len (key));
17156
17157   vec_free (locator_set_name);
17158   vec_free (key);
17159
17160   /* send it... */
17161   S (mp);
17162
17163   /* Wait for a reply... */
17164   W (ret);
17165   return ret;
17166 }
17167
17168 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17169
17170 static int
17171 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17172 {
17173   u32 dp_table = 0, vni = 0;;
17174   unformat_input_t *input = vam->input;
17175   vl_api_gpe_add_del_fwd_entry_t *mp;
17176   u8 is_add = 1;
17177   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17178   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17179   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17180   u32 action = ~0, w;
17181   ip4_address_t rmt_rloc4, lcl_rloc4;
17182   ip6_address_t rmt_rloc6, lcl_rloc6;
17183   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17184   int ret;
17185
17186   memset (&rloc, 0, sizeof (rloc));
17187
17188   /* Parse args required to build the message */
17189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17190     {
17191       if (unformat (input, "del"))
17192         is_add = 0;
17193       else if (unformat (input, "add"))
17194         is_add = 1;
17195       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17196         {
17197           rmt_eid_set = 1;
17198         }
17199       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17200         {
17201           lcl_eid_set = 1;
17202         }
17203       else if (unformat (input, "vrf %d", &dp_table))
17204         ;
17205       else if (unformat (input, "bd %d", &dp_table))
17206         ;
17207       else if (unformat (input, "vni %d", &vni))
17208         ;
17209       else if (unformat (input, "w %d", &w))
17210         {
17211           if (!curr_rloc)
17212             {
17213               errmsg ("No RLOC configured for setting priority/weight!");
17214               return -99;
17215             }
17216           curr_rloc->weight = w;
17217         }
17218       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17219                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17220         {
17221           rloc.is_ip4 = 1;
17222
17223           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17224           rloc.weight = 0;
17225           vec_add1 (lcl_locs, rloc);
17226
17227           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17228           vec_add1 (rmt_locs, rloc);
17229           /* weight saved in rmt loc */
17230           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17231         }
17232       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17233                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17234         {
17235           rloc.is_ip4 = 0;
17236           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17237           rloc.weight = 0;
17238           vec_add1 (lcl_locs, rloc);
17239
17240           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17241           vec_add1 (rmt_locs, rloc);
17242           /* weight saved in rmt loc */
17243           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17244         }
17245       else if (unformat (input, "action %d", &action))
17246         {
17247           ;
17248         }
17249       else
17250         {
17251           clib_warning ("parse error '%U'", format_unformat_error, input);
17252           return -99;
17253         }
17254     }
17255
17256   if (!rmt_eid_set)
17257     {
17258       errmsg ("remote eid addresses not set");
17259       return -99;
17260     }
17261
17262   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17263     {
17264       errmsg ("eid types don't match");
17265       return -99;
17266     }
17267
17268   if (0 == rmt_locs && (u32) ~ 0 == action)
17269     {
17270       errmsg ("action not set for negative mapping");
17271       return -99;
17272     }
17273
17274   /* Construct the API message */
17275   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17276       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17277
17278   mp->is_add = is_add;
17279   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17280   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17281   mp->eid_type = rmt_eid->type;
17282   mp->dp_table = clib_host_to_net_u32 (dp_table);
17283   mp->vni = clib_host_to_net_u32 (vni);
17284   mp->rmt_len = rmt_eid->len;
17285   mp->lcl_len = lcl_eid->len;
17286   mp->action = action;
17287
17288   if (0 != rmt_locs && 0 != lcl_locs)
17289     {
17290       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17291       clib_memcpy (mp->locs, lcl_locs,
17292                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17293
17294       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17295       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17296                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17297     }
17298   vec_free (lcl_locs);
17299   vec_free (rmt_locs);
17300
17301   /* send it... */
17302   S (mp);
17303
17304   /* Wait for a reply... */
17305   W (ret);
17306   return ret;
17307 }
17308
17309 static int
17310 api_one_add_del_map_server (vat_main_t * vam)
17311 {
17312   unformat_input_t *input = vam->input;
17313   vl_api_one_add_del_map_server_t *mp;
17314   u8 is_add = 1;
17315   u8 ipv4_set = 0;
17316   u8 ipv6_set = 0;
17317   ip4_address_t ipv4;
17318   ip6_address_t ipv6;
17319   int ret;
17320
17321   /* Parse args required to build the message */
17322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17323     {
17324       if (unformat (input, "del"))
17325         {
17326           is_add = 0;
17327         }
17328       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17329         {
17330           ipv4_set = 1;
17331         }
17332       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17333         {
17334           ipv6_set = 1;
17335         }
17336       else
17337         break;
17338     }
17339
17340   if (ipv4_set && ipv6_set)
17341     {
17342       errmsg ("both eid v4 and v6 addresses set");
17343       return -99;
17344     }
17345
17346   if (!ipv4_set && !ipv6_set)
17347     {
17348       errmsg ("eid addresses not set");
17349       return -99;
17350     }
17351
17352   /* Construct the API message */
17353   M (ONE_ADD_DEL_MAP_SERVER, mp);
17354
17355   mp->is_add = is_add;
17356   if (ipv6_set)
17357     {
17358       mp->is_ipv6 = 1;
17359       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17360     }
17361   else
17362     {
17363       mp->is_ipv6 = 0;
17364       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17365     }
17366
17367   /* send it... */
17368   S (mp);
17369
17370   /* Wait for a reply... */
17371   W (ret);
17372   return ret;
17373 }
17374
17375 #define api_lisp_add_del_map_server api_one_add_del_map_server
17376
17377 static int
17378 api_one_add_del_map_resolver (vat_main_t * vam)
17379 {
17380   unformat_input_t *input = vam->input;
17381   vl_api_one_add_del_map_resolver_t *mp;
17382   u8 is_add = 1;
17383   u8 ipv4_set = 0;
17384   u8 ipv6_set = 0;
17385   ip4_address_t ipv4;
17386   ip6_address_t ipv6;
17387   int ret;
17388
17389   /* Parse args required to build the message */
17390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17391     {
17392       if (unformat (input, "del"))
17393         {
17394           is_add = 0;
17395         }
17396       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17397         {
17398           ipv4_set = 1;
17399         }
17400       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17401         {
17402           ipv6_set = 1;
17403         }
17404       else
17405         break;
17406     }
17407
17408   if (ipv4_set && ipv6_set)
17409     {
17410       errmsg ("both eid v4 and v6 addresses set");
17411       return -99;
17412     }
17413
17414   if (!ipv4_set && !ipv6_set)
17415     {
17416       errmsg ("eid addresses not set");
17417       return -99;
17418     }
17419
17420   /* Construct the API message */
17421   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17422
17423   mp->is_add = is_add;
17424   if (ipv6_set)
17425     {
17426       mp->is_ipv6 = 1;
17427       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17428     }
17429   else
17430     {
17431       mp->is_ipv6 = 0;
17432       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17433     }
17434
17435   /* send it... */
17436   S (mp);
17437
17438   /* Wait for a reply... */
17439   W (ret);
17440   return ret;
17441 }
17442
17443 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17444
17445 static int
17446 api_lisp_gpe_enable_disable (vat_main_t * vam)
17447 {
17448   unformat_input_t *input = vam->input;
17449   vl_api_gpe_enable_disable_t *mp;
17450   u8 is_set = 0;
17451   u8 is_en = 1;
17452   int ret;
17453
17454   /* Parse args required to build the message */
17455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17456     {
17457       if (unformat (input, "enable"))
17458         {
17459           is_set = 1;
17460           is_en = 1;
17461         }
17462       else if (unformat (input, "disable"))
17463         {
17464           is_set = 1;
17465           is_en = 0;
17466         }
17467       else
17468         break;
17469     }
17470
17471   if (is_set == 0)
17472     {
17473       errmsg ("Value not set");
17474       return -99;
17475     }
17476
17477   /* Construct the API message */
17478   M (GPE_ENABLE_DISABLE, mp);
17479
17480   mp->is_en = is_en;
17481
17482   /* send it... */
17483   S (mp);
17484
17485   /* Wait for a reply... */
17486   W (ret);
17487   return ret;
17488 }
17489
17490 static int
17491 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17492 {
17493   unformat_input_t *input = vam->input;
17494   vl_api_one_rloc_probe_enable_disable_t *mp;
17495   u8 is_set = 0;
17496   u8 is_en = 0;
17497   int ret;
17498
17499   /* Parse args required to build the message */
17500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17501     {
17502       if (unformat (input, "enable"))
17503         {
17504           is_set = 1;
17505           is_en = 1;
17506         }
17507       else if (unformat (input, "disable"))
17508         is_set = 1;
17509       else
17510         break;
17511     }
17512
17513   if (!is_set)
17514     {
17515       errmsg ("Value not set");
17516       return -99;
17517     }
17518
17519   /* Construct the API message */
17520   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17521
17522   mp->is_enabled = is_en;
17523
17524   /* send it... */
17525   S (mp);
17526
17527   /* Wait for a reply... */
17528   W (ret);
17529   return ret;
17530 }
17531
17532 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17533
17534 static int
17535 api_one_map_register_enable_disable (vat_main_t * vam)
17536 {
17537   unformat_input_t *input = vam->input;
17538   vl_api_one_map_register_enable_disable_t *mp;
17539   u8 is_set = 0;
17540   u8 is_en = 0;
17541   int ret;
17542
17543   /* Parse args required to build the message */
17544   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17545     {
17546       if (unformat (input, "enable"))
17547         {
17548           is_set = 1;
17549           is_en = 1;
17550         }
17551       else if (unformat (input, "disable"))
17552         is_set = 1;
17553       else
17554         break;
17555     }
17556
17557   if (!is_set)
17558     {
17559       errmsg ("Value not set");
17560       return -99;
17561     }
17562
17563   /* Construct the API message */
17564   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17565
17566   mp->is_enabled = is_en;
17567
17568   /* send it... */
17569   S (mp);
17570
17571   /* Wait for a reply... */
17572   W (ret);
17573   return ret;
17574 }
17575
17576 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17577
17578 static int
17579 api_one_enable_disable (vat_main_t * vam)
17580 {
17581   unformat_input_t *input = vam->input;
17582   vl_api_one_enable_disable_t *mp;
17583   u8 is_set = 0;
17584   u8 is_en = 0;
17585   int ret;
17586
17587   /* Parse args required to build the message */
17588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17589     {
17590       if (unformat (input, "enable"))
17591         {
17592           is_set = 1;
17593           is_en = 1;
17594         }
17595       else if (unformat (input, "disable"))
17596         {
17597           is_set = 1;
17598         }
17599       else
17600         break;
17601     }
17602
17603   if (!is_set)
17604     {
17605       errmsg ("Value not set");
17606       return -99;
17607     }
17608
17609   /* Construct the API message */
17610   M (ONE_ENABLE_DISABLE, mp);
17611
17612   mp->is_en = is_en;
17613
17614   /* send it... */
17615   S (mp);
17616
17617   /* Wait for a reply... */
17618   W (ret);
17619   return ret;
17620 }
17621
17622 #define api_lisp_enable_disable api_one_enable_disable
17623
17624 static int
17625 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17626 {
17627   unformat_input_t *input = vam->input;
17628   vl_api_one_enable_disable_xtr_mode_t *mp;
17629   u8 is_set = 0;
17630   u8 is_en = 0;
17631   int ret;
17632
17633   /* Parse args required to build the message */
17634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17635     {
17636       if (unformat (input, "enable"))
17637         {
17638           is_set = 1;
17639           is_en = 1;
17640         }
17641       else if (unformat (input, "disable"))
17642         {
17643           is_set = 1;
17644         }
17645       else
17646         break;
17647     }
17648
17649   if (!is_set)
17650     {
17651       errmsg ("Value not set");
17652       return -99;
17653     }
17654
17655   /* Construct the API message */
17656   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17657
17658   mp->is_en = is_en;
17659
17660   /* send it... */
17661   S (mp);
17662
17663   /* Wait for a reply... */
17664   W (ret);
17665   return ret;
17666 }
17667
17668 static int
17669 api_one_show_xtr_mode (vat_main_t * vam)
17670 {
17671   vl_api_one_show_xtr_mode_t *mp;
17672   int ret;
17673
17674   /* Construct the API message */
17675   M (ONE_SHOW_XTR_MODE, mp);
17676
17677   /* send it... */
17678   S (mp);
17679
17680   /* Wait for a reply... */
17681   W (ret);
17682   return ret;
17683 }
17684
17685 static int
17686 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17687 {
17688   unformat_input_t *input = vam->input;
17689   vl_api_one_enable_disable_pitr_mode_t *mp;
17690   u8 is_set = 0;
17691   u8 is_en = 0;
17692   int ret;
17693
17694   /* Parse args required to build the message */
17695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17696     {
17697       if (unformat (input, "enable"))
17698         {
17699           is_set = 1;
17700           is_en = 1;
17701         }
17702       else if (unformat (input, "disable"))
17703         {
17704           is_set = 1;
17705         }
17706       else
17707         break;
17708     }
17709
17710   if (!is_set)
17711     {
17712       errmsg ("Value not set");
17713       return -99;
17714     }
17715
17716   /* Construct the API message */
17717   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17718
17719   mp->is_en = is_en;
17720
17721   /* send it... */
17722   S (mp);
17723
17724   /* Wait for a reply... */
17725   W (ret);
17726   return ret;
17727 }
17728
17729 static int
17730 api_one_show_pitr_mode (vat_main_t * vam)
17731 {
17732   vl_api_one_show_pitr_mode_t *mp;
17733   int ret;
17734
17735   /* Construct the API message */
17736   M (ONE_SHOW_PITR_MODE, mp);
17737
17738   /* send it... */
17739   S (mp);
17740
17741   /* Wait for a reply... */
17742   W (ret);
17743   return ret;
17744 }
17745
17746 static int
17747 api_one_enable_disable_petr_mode (vat_main_t * vam)
17748 {
17749   unformat_input_t *input = vam->input;
17750   vl_api_one_enable_disable_petr_mode_t *mp;
17751   u8 is_set = 0;
17752   u8 is_en = 0;
17753   int ret;
17754
17755   /* Parse args required to build the message */
17756   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17757     {
17758       if (unformat (input, "enable"))
17759         {
17760           is_set = 1;
17761           is_en = 1;
17762         }
17763       else if (unformat (input, "disable"))
17764         {
17765           is_set = 1;
17766         }
17767       else
17768         break;
17769     }
17770
17771   if (!is_set)
17772     {
17773       errmsg ("Value not set");
17774       return -99;
17775     }
17776
17777   /* Construct the API message */
17778   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17779
17780   mp->is_en = is_en;
17781
17782   /* send it... */
17783   S (mp);
17784
17785   /* Wait for a reply... */
17786   W (ret);
17787   return ret;
17788 }
17789
17790 static int
17791 api_one_show_petr_mode (vat_main_t * vam)
17792 {
17793   vl_api_one_show_petr_mode_t *mp;
17794   int ret;
17795
17796   /* Construct the API message */
17797   M (ONE_SHOW_PETR_MODE, mp);
17798
17799   /* send it... */
17800   S (mp);
17801
17802   /* Wait for a reply... */
17803   W (ret);
17804   return ret;
17805 }
17806
17807 static int
17808 api_show_one_map_register_state (vat_main_t * vam)
17809 {
17810   vl_api_show_one_map_register_state_t *mp;
17811   int ret;
17812
17813   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17814
17815   /* send */
17816   S (mp);
17817
17818   /* wait for reply */
17819   W (ret);
17820   return ret;
17821 }
17822
17823 #define api_show_lisp_map_register_state api_show_one_map_register_state
17824
17825 static int
17826 api_show_one_rloc_probe_state (vat_main_t * vam)
17827 {
17828   vl_api_show_one_rloc_probe_state_t *mp;
17829   int ret;
17830
17831   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17832
17833   /* send */
17834   S (mp);
17835
17836   /* wait for reply */
17837   W (ret);
17838   return ret;
17839 }
17840
17841 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17842
17843 static int
17844 api_one_add_del_ndp_entry (vat_main_t * vam)
17845 {
17846   vl_api_one_add_del_ndp_entry_t *mp;
17847   unformat_input_t *input = vam->input;
17848   u8 is_add = 1;
17849   u8 mac_set = 0;
17850   u8 bd_set = 0;
17851   u8 ip_set = 0;
17852   u8 mac[6] = { 0, };
17853   u8 ip6[16] = { 0, };
17854   u32 bd = ~0;
17855   int ret;
17856
17857   /* Parse args required to build the message */
17858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17859     {
17860       if (unformat (input, "del"))
17861         is_add = 0;
17862       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17863         mac_set = 1;
17864       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17865         ip_set = 1;
17866       else if (unformat (input, "bd %d", &bd))
17867         bd_set = 1;
17868       else
17869         {
17870           errmsg ("parse error '%U'", format_unformat_error, input);
17871           return -99;
17872         }
17873     }
17874
17875   if (!bd_set || !ip_set || (!mac_set && is_add))
17876     {
17877       errmsg ("Missing BD, IP or MAC!");
17878       return -99;
17879     }
17880
17881   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17882   mp->is_add = is_add;
17883   clib_memcpy (mp->mac, mac, 6);
17884   mp->bd = clib_host_to_net_u32 (bd);
17885   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17886
17887   /* send */
17888   S (mp);
17889
17890   /* wait for reply */
17891   W (ret);
17892   return ret;
17893 }
17894
17895 static int
17896 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17897 {
17898   vl_api_one_add_del_l2_arp_entry_t *mp;
17899   unformat_input_t *input = vam->input;
17900   u8 is_add = 1;
17901   u8 mac_set = 0;
17902   u8 bd_set = 0;
17903   u8 ip_set = 0;
17904   u8 mac[6] = { 0, };
17905   u32 ip4 = 0, bd = ~0;
17906   int ret;
17907
17908   /* Parse args required to build the message */
17909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17910     {
17911       if (unformat (input, "del"))
17912         is_add = 0;
17913       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17914         mac_set = 1;
17915       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17916         ip_set = 1;
17917       else if (unformat (input, "bd %d", &bd))
17918         bd_set = 1;
17919       else
17920         {
17921           errmsg ("parse error '%U'", format_unformat_error, input);
17922           return -99;
17923         }
17924     }
17925
17926   if (!bd_set || !ip_set || (!mac_set && is_add))
17927     {
17928       errmsg ("Missing BD, IP or MAC!");
17929       return -99;
17930     }
17931
17932   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17933   mp->is_add = is_add;
17934   clib_memcpy (mp->mac, mac, 6);
17935   mp->bd = clib_host_to_net_u32 (bd);
17936   mp->ip4 = ip4;
17937
17938   /* send */
17939   S (mp);
17940
17941   /* wait for reply */
17942   W (ret);
17943   return ret;
17944 }
17945
17946 static int
17947 api_one_ndp_bd_get (vat_main_t * vam)
17948 {
17949   vl_api_one_ndp_bd_get_t *mp;
17950   int ret;
17951
17952   M (ONE_NDP_BD_GET, mp);
17953
17954   /* send */
17955   S (mp);
17956
17957   /* wait for reply */
17958   W (ret);
17959   return ret;
17960 }
17961
17962 static int
17963 api_one_ndp_entries_get (vat_main_t * vam)
17964 {
17965   vl_api_one_ndp_entries_get_t *mp;
17966   unformat_input_t *input = vam->input;
17967   u8 bd_set = 0;
17968   u32 bd = ~0;
17969   int ret;
17970
17971   /* Parse args required to build the message */
17972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17973     {
17974       if (unformat (input, "bd %d", &bd))
17975         bd_set = 1;
17976       else
17977         {
17978           errmsg ("parse error '%U'", format_unformat_error, input);
17979           return -99;
17980         }
17981     }
17982
17983   if (!bd_set)
17984     {
17985       errmsg ("Expected bridge domain!");
17986       return -99;
17987     }
17988
17989   M (ONE_NDP_ENTRIES_GET, mp);
17990   mp->bd = clib_host_to_net_u32 (bd);
17991
17992   /* send */
17993   S (mp);
17994
17995   /* wait for reply */
17996   W (ret);
17997   return ret;
17998 }
17999
18000 static int
18001 api_one_l2_arp_bd_get (vat_main_t * vam)
18002 {
18003   vl_api_one_l2_arp_bd_get_t *mp;
18004   int ret;
18005
18006   M (ONE_L2_ARP_BD_GET, mp);
18007
18008   /* send */
18009   S (mp);
18010
18011   /* wait for reply */
18012   W (ret);
18013   return ret;
18014 }
18015
18016 static int
18017 api_one_l2_arp_entries_get (vat_main_t * vam)
18018 {
18019   vl_api_one_l2_arp_entries_get_t *mp;
18020   unformat_input_t *input = vam->input;
18021   u8 bd_set = 0;
18022   u32 bd = ~0;
18023   int ret;
18024
18025   /* Parse args required to build the message */
18026   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18027     {
18028       if (unformat (input, "bd %d", &bd))
18029         bd_set = 1;
18030       else
18031         {
18032           errmsg ("parse error '%U'", format_unformat_error, input);
18033           return -99;
18034         }
18035     }
18036
18037   if (!bd_set)
18038     {
18039       errmsg ("Expected bridge domain!");
18040       return -99;
18041     }
18042
18043   M (ONE_L2_ARP_ENTRIES_GET, mp);
18044   mp->bd = clib_host_to_net_u32 (bd);
18045
18046   /* send */
18047   S (mp);
18048
18049   /* wait for reply */
18050   W (ret);
18051   return ret;
18052 }
18053
18054 static int
18055 api_one_stats_enable_disable (vat_main_t * vam)
18056 {
18057   vl_api_one_stats_enable_disable_t *mp;
18058   unformat_input_t *input = vam->input;
18059   u8 is_set = 0;
18060   u8 is_en = 0;
18061   int ret;
18062
18063   /* Parse args required to build the message */
18064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18065     {
18066       if (unformat (input, "enable"))
18067         {
18068           is_set = 1;
18069           is_en = 1;
18070         }
18071       else if (unformat (input, "disable"))
18072         {
18073           is_set = 1;
18074         }
18075       else
18076         break;
18077     }
18078
18079   if (!is_set)
18080     {
18081       errmsg ("Value not set");
18082       return -99;
18083     }
18084
18085   M (ONE_STATS_ENABLE_DISABLE, mp);
18086   mp->is_en = is_en;
18087
18088   /* send */
18089   S (mp);
18090
18091   /* wait for reply */
18092   W (ret);
18093   return ret;
18094 }
18095
18096 static int
18097 api_show_one_stats_enable_disable (vat_main_t * vam)
18098 {
18099   vl_api_show_one_stats_enable_disable_t *mp;
18100   int ret;
18101
18102   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18103
18104   /* send */
18105   S (mp);
18106
18107   /* wait for reply */
18108   W (ret);
18109   return ret;
18110 }
18111
18112 static int
18113 api_show_one_map_request_mode (vat_main_t * vam)
18114 {
18115   vl_api_show_one_map_request_mode_t *mp;
18116   int ret;
18117
18118   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18119
18120   /* send */
18121   S (mp);
18122
18123   /* wait for reply */
18124   W (ret);
18125   return ret;
18126 }
18127
18128 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18129
18130 static int
18131 api_one_map_request_mode (vat_main_t * vam)
18132 {
18133   unformat_input_t *input = vam->input;
18134   vl_api_one_map_request_mode_t *mp;
18135   u8 mode = 0;
18136   int ret;
18137
18138   /* Parse args required to build the message */
18139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18140     {
18141       if (unformat (input, "dst-only"))
18142         mode = 0;
18143       else if (unformat (input, "src-dst"))
18144         mode = 1;
18145       else
18146         {
18147           errmsg ("parse error '%U'", format_unformat_error, input);
18148           return -99;
18149         }
18150     }
18151
18152   M (ONE_MAP_REQUEST_MODE, mp);
18153
18154   mp->mode = mode;
18155
18156   /* send */
18157   S (mp);
18158
18159   /* wait for reply */
18160   W (ret);
18161   return ret;
18162 }
18163
18164 #define api_lisp_map_request_mode api_one_map_request_mode
18165
18166 /**
18167  * Enable/disable ONE proxy ITR.
18168  *
18169  * @param vam vpp API test context
18170  * @return return code
18171  */
18172 static int
18173 api_one_pitr_set_locator_set (vat_main_t * vam)
18174 {
18175   u8 ls_name_set = 0;
18176   unformat_input_t *input = vam->input;
18177   vl_api_one_pitr_set_locator_set_t *mp;
18178   u8 is_add = 1;
18179   u8 *ls_name = 0;
18180   int ret;
18181
18182   /* Parse args required to build the message */
18183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18184     {
18185       if (unformat (input, "del"))
18186         is_add = 0;
18187       else if (unformat (input, "locator-set %s", &ls_name))
18188         ls_name_set = 1;
18189       else
18190         {
18191           errmsg ("parse error '%U'", format_unformat_error, input);
18192           return -99;
18193         }
18194     }
18195
18196   if (!ls_name_set)
18197     {
18198       errmsg ("locator-set name not set!");
18199       return -99;
18200     }
18201
18202   M (ONE_PITR_SET_LOCATOR_SET, mp);
18203
18204   mp->is_add = is_add;
18205   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18206   vec_free (ls_name);
18207
18208   /* send */
18209   S (mp);
18210
18211   /* wait for reply */
18212   W (ret);
18213   return ret;
18214 }
18215
18216 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18217
18218 static int
18219 api_one_nsh_set_locator_set (vat_main_t * vam)
18220 {
18221   u8 ls_name_set = 0;
18222   unformat_input_t *input = vam->input;
18223   vl_api_one_nsh_set_locator_set_t *mp;
18224   u8 is_add = 1;
18225   u8 *ls_name = 0;
18226   int ret;
18227
18228   /* Parse args required to build the message */
18229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18230     {
18231       if (unformat (input, "del"))
18232         is_add = 0;
18233       else if (unformat (input, "ls %s", &ls_name))
18234         ls_name_set = 1;
18235       else
18236         {
18237           errmsg ("parse error '%U'", format_unformat_error, input);
18238           return -99;
18239         }
18240     }
18241
18242   if (!ls_name_set && is_add)
18243     {
18244       errmsg ("locator-set name not set!");
18245       return -99;
18246     }
18247
18248   M (ONE_NSH_SET_LOCATOR_SET, mp);
18249
18250   mp->is_add = is_add;
18251   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18252   vec_free (ls_name);
18253
18254   /* send */
18255   S (mp);
18256
18257   /* wait for reply */
18258   W (ret);
18259   return ret;
18260 }
18261
18262 static int
18263 api_show_one_pitr (vat_main_t * vam)
18264 {
18265   vl_api_show_one_pitr_t *mp;
18266   int ret;
18267
18268   if (!vam->json_output)
18269     {
18270       print (vam->ofp, "%=20s", "lisp status:");
18271     }
18272
18273   M (SHOW_ONE_PITR, mp);
18274   /* send it... */
18275   S (mp);
18276
18277   /* Wait for a reply... */
18278   W (ret);
18279   return ret;
18280 }
18281
18282 #define api_show_lisp_pitr api_show_one_pitr
18283
18284 static int
18285 api_one_use_petr (vat_main_t * vam)
18286 {
18287   unformat_input_t *input = vam->input;
18288   vl_api_one_use_petr_t *mp;
18289   u8 is_add = 0;
18290   ip_address_t ip;
18291   int ret;
18292
18293   memset (&ip, 0, sizeof (ip));
18294
18295   /* Parse args required to build the message */
18296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18297     {
18298       if (unformat (input, "disable"))
18299         is_add = 0;
18300       else
18301         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18302         {
18303           is_add = 1;
18304           ip_addr_version (&ip) = IP4;
18305         }
18306       else
18307         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18308         {
18309           is_add = 1;
18310           ip_addr_version (&ip) = IP6;
18311         }
18312       else
18313         {
18314           errmsg ("parse error '%U'", format_unformat_error, input);
18315           return -99;
18316         }
18317     }
18318
18319   M (ONE_USE_PETR, mp);
18320
18321   mp->is_add = is_add;
18322   if (is_add)
18323     {
18324       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18325       if (mp->is_ip4)
18326         clib_memcpy (mp->address, &ip, 4);
18327       else
18328         clib_memcpy (mp->address, &ip, 16);
18329     }
18330
18331   /* send */
18332   S (mp);
18333
18334   /* wait for reply */
18335   W (ret);
18336   return ret;
18337 }
18338
18339 #define api_lisp_use_petr api_one_use_petr
18340
18341 static int
18342 api_show_one_nsh_mapping (vat_main_t * vam)
18343 {
18344   vl_api_show_one_use_petr_t *mp;
18345   int ret;
18346
18347   if (!vam->json_output)
18348     {
18349       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18350     }
18351
18352   M (SHOW_ONE_NSH_MAPPING, mp);
18353   /* send it... */
18354   S (mp);
18355
18356   /* Wait for a reply... */
18357   W (ret);
18358   return ret;
18359 }
18360
18361 static int
18362 api_show_one_use_petr (vat_main_t * vam)
18363 {
18364   vl_api_show_one_use_petr_t *mp;
18365   int ret;
18366
18367   if (!vam->json_output)
18368     {
18369       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18370     }
18371
18372   M (SHOW_ONE_USE_PETR, mp);
18373   /* send it... */
18374   S (mp);
18375
18376   /* Wait for a reply... */
18377   W (ret);
18378   return ret;
18379 }
18380
18381 #define api_show_lisp_use_petr api_show_one_use_petr
18382
18383 /**
18384  * Add/delete mapping between vni and vrf
18385  */
18386 static int
18387 api_one_eid_table_add_del_map (vat_main_t * vam)
18388 {
18389   unformat_input_t *input = vam->input;
18390   vl_api_one_eid_table_add_del_map_t *mp;
18391   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18392   u32 vni, vrf, bd_index;
18393   int ret;
18394
18395   /* Parse args required to build the message */
18396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18397     {
18398       if (unformat (input, "del"))
18399         is_add = 0;
18400       else if (unformat (input, "vrf %d", &vrf))
18401         vrf_set = 1;
18402       else if (unformat (input, "bd_index %d", &bd_index))
18403         bd_index_set = 1;
18404       else if (unformat (input, "vni %d", &vni))
18405         vni_set = 1;
18406       else
18407         break;
18408     }
18409
18410   if (!vni_set || (!vrf_set && !bd_index_set))
18411     {
18412       errmsg ("missing arguments!");
18413       return -99;
18414     }
18415
18416   if (vrf_set && bd_index_set)
18417     {
18418       errmsg ("error: both vrf and bd entered!");
18419       return -99;
18420     }
18421
18422   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18423
18424   mp->is_add = is_add;
18425   mp->vni = htonl (vni);
18426   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18427   mp->is_l2 = bd_index_set;
18428
18429   /* send */
18430   S (mp);
18431
18432   /* wait for reply */
18433   W (ret);
18434   return ret;
18435 }
18436
18437 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18438
18439 uword
18440 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18441 {
18442   u32 *action = va_arg (*args, u32 *);
18443   u8 *s = 0;
18444
18445   if (unformat (input, "%s", &s))
18446     {
18447       if (!strcmp ((char *) s, "no-action"))
18448         action[0] = 0;
18449       else if (!strcmp ((char *) s, "natively-forward"))
18450         action[0] = 1;
18451       else if (!strcmp ((char *) s, "send-map-request"))
18452         action[0] = 2;
18453       else if (!strcmp ((char *) s, "drop"))
18454         action[0] = 3;
18455       else
18456         {
18457           clib_warning ("invalid action: '%s'", s);
18458           action[0] = 3;
18459         }
18460     }
18461   else
18462     return 0;
18463
18464   vec_free (s);
18465   return 1;
18466 }
18467
18468 /**
18469  * Add/del remote mapping to/from ONE control plane
18470  *
18471  * @param vam vpp API test context
18472  * @return return code
18473  */
18474 static int
18475 api_one_add_del_remote_mapping (vat_main_t * vam)
18476 {
18477   unformat_input_t *input = vam->input;
18478   vl_api_one_add_del_remote_mapping_t *mp;
18479   u32 vni = 0;
18480   lisp_eid_vat_t _eid, *eid = &_eid;
18481   lisp_eid_vat_t _seid, *seid = &_seid;
18482   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18483   u32 action = ~0, p, w, data_len;
18484   ip4_address_t rloc4;
18485   ip6_address_t rloc6;
18486   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18487   int ret;
18488
18489   memset (&rloc, 0, sizeof (rloc));
18490
18491   /* Parse args required to build the message */
18492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18493     {
18494       if (unformat (input, "del-all"))
18495         {
18496           del_all = 1;
18497         }
18498       else if (unformat (input, "del"))
18499         {
18500           is_add = 0;
18501         }
18502       else if (unformat (input, "add"))
18503         {
18504           is_add = 1;
18505         }
18506       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18507         {
18508           eid_set = 1;
18509         }
18510       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18511         {
18512           seid_set = 1;
18513         }
18514       else if (unformat (input, "vni %d", &vni))
18515         {
18516           ;
18517         }
18518       else if (unformat (input, "p %d w %d", &p, &w))
18519         {
18520           if (!curr_rloc)
18521             {
18522               errmsg ("No RLOC configured for setting priority/weight!");
18523               return -99;
18524             }
18525           curr_rloc->priority = p;
18526           curr_rloc->weight = w;
18527         }
18528       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18529         {
18530           rloc.is_ip4 = 1;
18531           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18532           vec_add1 (rlocs, rloc);
18533           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18534         }
18535       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18536         {
18537           rloc.is_ip4 = 0;
18538           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18539           vec_add1 (rlocs, rloc);
18540           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18541         }
18542       else if (unformat (input, "action %U",
18543                          unformat_negative_mapping_action, &action))
18544         {
18545           ;
18546         }
18547       else
18548         {
18549           clib_warning ("parse error '%U'", format_unformat_error, input);
18550           return -99;
18551         }
18552     }
18553
18554   if (0 == eid_set)
18555     {
18556       errmsg ("missing params!");
18557       return -99;
18558     }
18559
18560   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18561     {
18562       errmsg ("no action set for negative map-reply!");
18563       return -99;
18564     }
18565
18566   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18567
18568   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18569   mp->is_add = is_add;
18570   mp->vni = htonl (vni);
18571   mp->action = (u8) action;
18572   mp->is_src_dst = seid_set;
18573   mp->eid_len = eid->len;
18574   mp->seid_len = seid->len;
18575   mp->del_all = del_all;
18576   mp->eid_type = eid->type;
18577   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18578   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18579
18580   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18581   clib_memcpy (mp->rlocs, rlocs, data_len);
18582   vec_free (rlocs);
18583
18584   /* send it... */
18585   S (mp);
18586
18587   /* Wait for a reply... */
18588   W (ret);
18589   return ret;
18590 }
18591
18592 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18593
18594 /**
18595  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18596  * forwarding entries in data-plane accordingly.
18597  *
18598  * @param vam vpp API test context
18599  * @return return code
18600  */
18601 static int
18602 api_one_add_del_adjacency (vat_main_t * vam)
18603 {
18604   unformat_input_t *input = vam->input;
18605   vl_api_one_add_del_adjacency_t *mp;
18606   u32 vni = 0;
18607   ip4_address_t leid4, reid4;
18608   ip6_address_t leid6, reid6;
18609   u8 reid_mac[6] = { 0 };
18610   u8 leid_mac[6] = { 0 };
18611   u8 reid_type, leid_type;
18612   u32 leid_len = 0, reid_len = 0, len;
18613   u8 is_add = 1;
18614   int ret;
18615
18616   leid_type = reid_type = (u8) ~ 0;
18617
18618   /* Parse args required to build the message */
18619   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18620     {
18621       if (unformat (input, "del"))
18622         {
18623           is_add = 0;
18624         }
18625       else if (unformat (input, "add"))
18626         {
18627           is_add = 1;
18628         }
18629       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18630                          &reid4, &len))
18631         {
18632           reid_type = 0;        /* ipv4 */
18633           reid_len = len;
18634         }
18635       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18636                          &reid6, &len))
18637         {
18638           reid_type = 1;        /* ipv6 */
18639           reid_len = len;
18640         }
18641       else if (unformat (input, "reid %U", unformat_ethernet_address,
18642                          reid_mac))
18643         {
18644           reid_type = 2;        /* mac */
18645         }
18646       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18647                          &leid4, &len))
18648         {
18649           leid_type = 0;        /* ipv4 */
18650           leid_len = len;
18651         }
18652       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18653                          &leid6, &len))
18654         {
18655           leid_type = 1;        /* ipv6 */
18656           leid_len = len;
18657         }
18658       else if (unformat (input, "leid %U", unformat_ethernet_address,
18659                          leid_mac))
18660         {
18661           leid_type = 2;        /* mac */
18662         }
18663       else if (unformat (input, "vni %d", &vni))
18664         {
18665           ;
18666         }
18667       else
18668         {
18669           errmsg ("parse error '%U'", format_unformat_error, input);
18670           return -99;
18671         }
18672     }
18673
18674   if ((u8) ~ 0 == reid_type)
18675     {
18676       errmsg ("missing params!");
18677       return -99;
18678     }
18679
18680   if (leid_type != reid_type)
18681     {
18682       errmsg ("remote and local EIDs are of different types!");
18683       return -99;
18684     }
18685
18686   M (ONE_ADD_DEL_ADJACENCY, mp);
18687   mp->is_add = is_add;
18688   mp->vni = htonl (vni);
18689   mp->leid_len = leid_len;
18690   mp->reid_len = reid_len;
18691   mp->eid_type = reid_type;
18692
18693   switch (mp->eid_type)
18694     {
18695     case 0:
18696       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18697       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18698       break;
18699     case 1:
18700       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18701       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18702       break;
18703     case 2:
18704       clib_memcpy (mp->leid, leid_mac, 6);
18705       clib_memcpy (mp->reid, reid_mac, 6);
18706       break;
18707     default:
18708       errmsg ("unknown EID type %d!", mp->eid_type);
18709       return 0;
18710     }
18711
18712   /* send it... */
18713   S (mp);
18714
18715   /* Wait for a reply... */
18716   W (ret);
18717   return ret;
18718 }
18719
18720 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18721
18722 uword
18723 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18724 {
18725   u32 *mode = va_arg (*args, u32 *);
18726
18727   if (unformat (input, "lisp"))
18728     *mode = 0;
18729   else if (unformat (input, "vxlan"))
18730     *mode = 1;
18731   else
18732     return 0;
18733
18734   return 1;
18735 }
18736
18737 static int
18738 api_gpe_get_encap_mode (vat_main_t * vam)
18739 {
18740   vl_api_gpe_get_encap_mode_t *mp;
18741   int ret;
18742
18743   /* Construct the API message */
18744   M (GPE_GET_ENCAP_MODE, mp);
18745
18746   /* send it... */
18747   S (mp);
18748
18749   /* Wait for a reply... */
18750   W (ret);
18751   return ret;
18752 }
18753
18754 static int
18755 api_gpe_set_encap_mode (vat_main_t * vam)
18756 {
18757   unformat_input_t *input = vam->input;
18758   vl_api_gpe_set_encap_mode_t *mp;
18759   int ret;
18760   u32 mode = 0;
18761
18762   /* Parse args required to build the message */
18763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18764     {
18765       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18766         ;
18767       else
18768         break;
18769     }
18770
18771   /* Construct the API message */
18772   M (GPE_SET_ENCAP_MODE, mp);
18773
18774   mp->mode = mode;
18775
18776   /* send it... */
18777   S (mp);
18778
18779   /* Wait for a reply... */
18780   W (ret);
18781   return ret;
18782 }
18783
18784 static int
18785 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18786 {
18787   unformat_input_t *input = vam->input;
18788   vl_api_gpe_add_del_iface_t *mp;
18789   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18790   u32 dp_table = 0, vni = 0;
18791   int ret;
18792
18793   /* Parse args required to build the message */
18794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18795     {
18796       if (unformat (input, "up"))
18797         {
18798           action_set = 1;
18799           is_add = 1;
18800         }
18801       else if (unformat (input, "down"))
18802         {
18803           action_set = 1;
18804           is_add = 0;
18805         }
18806       else if (unformat (input, "table_id %d", &dp_table))
18807         {
18808           dp_table_set = 1;
18809         }
18810       else if (unformat (input, "bd_id %d", &dp_table))
18811         {
18812           dp_table_set = 1;
18813           is_l2 = 1;
18814         }
18815       else if (unformat (input, "vni %d", &vni))
18816         {
18817           vni_set = 1;
18818         }
18819       else
18820         break;
18821     }
18822
18823   if (action_set == 0)
18824     {
18825       errmsg ("Action not set");
18826       return -99;
18827     }
18828   if (dp_table_set == 0 || vni_set == 0)
18829     {
18830       errmsg ("vni and dp_table must be set");
18831       return -99;
18832     }
18833
18834   /* Construct the API message */
18835   M (GPE_ADD_DEL_IFACE, mp);
18836
18837   mp->is_add = is_add;
18838   mp->dp_table = clib_host_to_net_u32 (dp_table);
18839   mp->is_l2 = is_l2;
18840   mp->vni = clib_host_to_net_u32 (vni);
18841
18842   /* send it... */
18843   S (mp);
18844
18845   /* Wait for a reply... */
18846   W (ret);
18847   return ret;
18848 }
18849
18850 static int
18851 api_one_map_register_fallback_threshold (vat_main_t * vam)
18852 {
18853   unformat_input_t *input = vam->input;
18854   vl_api_one_map_register_fallback_threshold_t *mp;
18855   u32 value = 0;
18856   u8 is_set = 0;
18857   int ret;
18858
18859   /* Parse args required to build the message */
18860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18861     {
18862       if (unformat (input, "%u", &value))
18863         is_set = 1;
18864       else
18865         {
18866           clib_warning ("parse error '%U'", format_unformat_error, input);
18867           return -99;
18868         }
18869     }
18870
18871   if (!is_set)
18872     {
18873       errmsg ("fallback threshold value is missing!");
18874       return -99;
18875     }
18876
18877   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18878   mp->value = clib_host_to_net_u32 (value);
18879
18880   /* send it... */
18881   S (mp);
18882
18883   /* Wait for a reply... */
18884   W (ret);
18885   return ret;
18886 }
18887
18888 static int
18889 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18890 {
18891   vl_api_show_one_map_register_fallback_threshold_t *mp;
18892   int ret;
18893
18894   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18895
18896   /* send it... */
18897   S (mp);
18898
18899   /* Wait for a reply... */
18900   W (ret);
18901   return ret;
18902 }
18903
18904 uword
18905 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18906 {
18907   u32 *proto = va_arg (*args, u32 *);
18908
18909   if (unformat (input, "udp"))
18910     *proto = 1;
18911   else if (unformat (input, "api"))
18912     *proto = 2;
18913   else
18914     return 0;
18915
18916   return 1;
18917 }
18918
18919 static int
18920 api_one_set_transport_protocol (vat_main_t * vam)
18921 {
18922   unformat_input_t *input = vam->input;
18923   vl_api_one_set_transport_protocol_t *mp;
18924   u8 is_set = 0;
18925   u32 protocol = 0;
18926   int ret;
18927
18928   /* Parse args required to build the message */
18929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18930     {
18931       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18932         is_set = 1;
18933       else
18934         {
18935           clib_warning ("parse error '%U'", format_unformat_error, input);
18936           return -99;
18937         }
18938     }
18939
18940   if (!is_set)
18941     {
18942       errmsg ("Transport protocol missing!");
18943       return -99;
18944     }
18945
18946   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18947   mp->protocol = (u8) protocol;
18948
18949   /* send it... */
18950   S (mp);
18951
18952   /* Wait for a reply... */
18953   W (ret);
18954   return ret;
18955 }
18956
18957 static int
18958 api_one_get_transport_protocol (vat_main_t * vam)
18959 {
18960   vl_api_one_get_transport_protocol_t *mp;
18961   int ret;
18962
18963   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18964
18965   /* send it... */
18966   S (mp);
18967
18968   /* Wait for a reply... */
18969   W (ret);
18970   return ret;
18971 }
18972
18973 static int
18974 api_one_map_register_set_ttl (vat_main_t * vam)
18975 {
18976   unformat_input_t *input = vam->input;
18977   vl_api_one_map_register_set_ttl_t *mp;
18978   u32 ttl = 0;
18979   u8 is_set = 0;
18980   int ret;
18981
18982   /* Parse args required to build the message */
18983   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18984     {
18985       if (unformat (input, "%u", &ttl))
18986         is_set = 1;
18987       else
18988         {
18989           clib_warning ("parse error '%U'", format_unformat_error, input);
18990           return -99;
18991         }
18992     }
18993
18994   if (!is_set)
18995     {
18996       errmsg ("TTL value missing!");
18997       return -99;
18998     }
18999
19000   M (ONE_MAP_REGISTER_SET_TTL, mp);
19001   mp->ttl = clib_host_to_net_u32 (ttl);
19002
19003   /* send it... */
19004   S (mp);
19005
19006   /* Wait for a reply... */
19007   W (ret);
19008   return ret;
19009 }
19010
19011 static int
19012 api_show_one_map_register_ttl (vat_main_t * vam)
19013 {
19014   vl_api_show_one_map_register_ttl_t *mp;
19015   int ret;
19016
19017   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19018
19019   /* send it... */
19020   S (mp);
19021
19022   /* Wait for a reply... */
19023   W (ret);
19024   return ret;
19025 }
19026
19027 /**
19028  * Add/del map request itr rlocs from ONE control plane and updates
19029  *
19030  * @param vam vpp API test context
19031  * @return return code
19032  */
19033 static int
19034 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19035 {
19036   unformat_input_t *input = vam->input;
19037   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19038   u8 *locator_set_name = 0;
19039   u8 locator_set_name_set = 0;
19040   u8 is_add = 1;
19041   int ret;
19042
19043   /* Parse args required to build the message */
19044   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19045     {
19046       if (unformat (input, "del"))
19047         {
19048           is_add = 0;
19049         }
19050       else if (unformat (input, "%_%v%_", &locator_set_name))
19051         {
19052           locator_set_name_set = 1;
19053         }
19054       else
19055         {
19056           clib_warning ("parse error '%U'", format_unformat_error, input);
19057           return -99;
19058         }
19059     }
19060
19061   if (is_add && !locator_set_name_set)
19062     {
19063       errmsg ("itr-rloc is not set!");
19064       return -99;
19065     }
19066
19067   if (is_add && vec_len (locator_set_name) > 64)
19068     {
19069       errmsg ("itr-rloc locator-set name too long");
19070       vec_free (locator_set_name);
19071       return -99;
19072     }
19073
19074   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19075   mp->is_add = is_add;
19076   if (is_add)
19077     {
19078       clib_memcpy (mp->locator_set_name, locator_set_name,
19079                    vec_len (locator_set_name));
19080     }
19081   else
19082     {
19083       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19084     }
19085   vec_free (locator_set_name);
19086
19087   /* send it... */
19088   S (mp);
19089
19090   /* Wait for a reply... */
19091   W (ret);
19092   return ret;
19093 }
19094
19095 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19096
19097 static int
19098 api_one_locator_dump (vat_main_t * vam)
19099 {
19100   unformat_input_t *input = vam->input;
19101   vl_api_one_locator_dump_t *mp;
19102   vl_api_control_ping_t *mp_ping;
19103   u8 is_index_set = 0, is_name_set = 0;
19104   u8 *ls_name = 0;
19105   u32 ls_index = ~0;
19106   int ret;
19107
19108   /* Parse args required to build the message */
19109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19110     {
19111       if (unformat (input, "ls_name %_%v%_", &ls_name))
19112         {
19113           is_name_set = 1;
19114         }
19115       else if (unformat (input, "ls_index %d", &ls_index))
19116         {
19117           is_index_set = 1;
19118         }
19119       else
19120         {
19121           errmsg ("parse error '%U'", format_unformat_error, input);
19122           return -99;
19123         }
19124     }
19125
19126   if (!is_index_set && !is_name_set)
19127     {
19128       errmsg ("error: expected one of index or name!");
19129       return -99;
19130     }
19131
19132   if (is_index_set && is_name_set)
19133     {
19134       errmsg ("error: only one param expected!");
19135       return -99;
19136     }
19137
19138   if (vec_len (ls_name) > 62)
19139     {
19140       errmsg ("error: locator set name too long!");
19141       return -99;
19142     }
19143
19144   if (!vam->json_output)
19145     {
19146       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19147     }
19148
19149   M (ONE_LOCATOR_DUMP, mp);
19150   mp->is_index_set = is_index_set;
19151
19152   if (is_index_set)
19153     mp->ls_index = clib_host_to_net_u32 (ls_index);
19154   else
19155     {
19156       vec_add1 (ls_name, 0);
19157       strncpy ((char *) mp->ls_name, (char *) ls_name,
19158                sizeof (mp->ls_name) - 1);
19159     }
19160
19161   /* send it... */
19162   S (mp);
19163
19164   /* Use a control ping for synchronization */
19165   MPING (CONTROL_PING, mp_ping);
19166   S (mp_ping);
19167
19168   /* Wait for a reply... */
19169   W (ret);
19170   return ret;
19171 }
19172
19173 #define api_lisp_locator_dump api_one_locator_dump
19174
19175 static int
19176 api_one_locator_set_dump (vat_main_t * vam)
19177 {
19178   vl_api_one_locator_set_dump_t *mp;
19179   vl_api_control_ping_t *mp_ping;
19180   unformat_input_t *input = vam->input;
19181   u8 filter = 0;
19182   int ret;
19183
19184   /* Parse args required to build the message */
19185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19186     {
19187       if (unformat (input, "local"))
19188         {
19189           filter = 1;
19190         }
19191       else if (unformat (input, "remote"))
19192         {
19193           filter = 2;
19194         }
19195       else
19196         {
19197           errmsg ("parse error '%U'", format_unformat_error, input);
19198           return -99;
19199         }
19200     }
19201
19202   if (!vam->json_output)
19203     {
19204       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19205     }
19206
19207   M (ONE_LOCATOR_SET_DUMP, mp);
19208
19209   mp->filter = filter;
19210
19211   /* send it... */
19212   S (mp);
19213
19214   /* Use a control ping for synchronization */
19215   MPING (CONTROL_PING, mp_ping);
19216   S (mp_ping);
19217
19218   /* Wait for a reply... */
19219   W (ret);
19220   return ret;
19221 }
19222
19223 #define api_lisp_locator_set_dump api_one_locator_set_dump
19224
19225 static int
19226 api_one_eid_table_map_dump (vat_main_t * vam)
19227 {
19228   u8 is_l2 = 0;
19229   u8 mode_set = 0;
19230   unformat_input_t *input = vam->input;
19231   vl_api_one_eid_table_map_dump_t *mp;
19232   vl_api_control_ping_t *mp_ping;
19233   int ret;
19234
19235   /* Parse args required to build the message */
19236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19237     {
19238       if (unformat (input, "l2"))
19239         {
19240           is_l2 = 1;
19241           mode_set = 1;
19242         }
19243       else if (unformat (input, "l3"))
19244         {
19245           is_l2 = 0;
19246           mode_set = 1;
19247         }
19248       else
19249         {
19250           errmsg ("parse error '%U'", format_unformat_error, input);
19251           return -99;
19252         }
19253     }
19254
19255   if (!mode_set)
19256     {
19257       errmsg ("expected one of 'l2' or 'l3' parameter!");
19258       return -99;
19259     }
19260
19261   if (!vam->json_output)
19262     {
19263       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19264     }
19265
19266   M (ONE_EID_TABLE_MAP_DUMP, mp);
19267   mp->is_l2 = is_l2;
19268
19269   /* send it... */
19270   S (mp);
19271
19272   /* Use a control ping for synchronization */
19273   MPING (CONTROL_PING, mp_ping);
19274   S (mp_ping);
19275
19276   /* Wait for a reply... */
19277   W (ret);
19278   return ret;
19279 }
19280
19281 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19282
19283 static int
19284 api_one_eid_table_vni_dump (vat_main_t * vam)
19285 {
19286   vl_api_one_eid_table_vni_dump_t *mp;
19287   vl_api_control_ping_t *mp_ping;
19288   int ret;
19289
19290   if (!vam->json_output)
19291     {
19292       print (vam->ofp, "VNI");
19293     }
19294
19295   M (ONE_EID_TABLE_VNI_DUMP, mp);
19296
19297   /* send it... */
19298   S (mp);
19299
19300   /* Use a control ping for synchronization */
19301   MPING (CONTROL_PING, mp_ping);
19302   S (mp_ping);
19303
19304   /* Wait for a reply... */
19305   W (ret);
19306   return ret;
19307 }
19308
19309 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19310
19311 static int
19312 api_one_eid_table_dump (vat_main_t * vam)
19313 {
19314   unformat_input_t *i = vam->input;
19315   vl_api_one_eid_table_dump_t *mp;
19316   vl_api_control_ping_t *mp_ping;
19317   struct in_addr ip4;
19318   struct in6_addr ip6;
19319   u8 mac[6];
19320   u8 eid_type = ~0, eid_set = 0;
19321   u32 prefix_length = ~0, t, vni = 0;
19322   u8 filter = 0;
19323   int ret;
19324   lisp_nsh_api_t nsh;
19325
19326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19327     {
19328       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19329         {
19330           eid_set = 1;
19331           eid_type = 0;
19332           prefix_length = t;
19333         }
19334       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19335         {
19336           eid_set = 1;
19337           eid_type = 1;
19338           prefix_length = t;
19339         }
19340       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19341         {
19342           eid_set = 1;
19343           eid_type = 2;
19344         }
19345       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19346         {
19347           eid_set = 1;
19348           eid_type = 3;
19349         }
19350       else if (unformat (i, "vni %d", &t))
19351         {
19352           vni = t;
19353         }
19354       else if (unformat (i, "local"))
19355         {
19356           filter = 1;
19357         }
19358       else if (unformat (i, "remote"))
19359         {
19360           filter = 2;
19361         }
19362       else
19363         {
19364           errmsg ("parse error '%U'", format_unformat_error, i);
19365           return -99;
19366         }
19367     }
19368
19369   if (!vam->json_output)
19370     {
19371       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19372              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19373     }
19374
19375   M (ONE_EID_TABLE_DUMP, mp);
19376
19377   mp->filter = filter;
19378   if (eid_set)
19379     {
19380       mp->eid_set = 1;
19381       mp->vni = htonl (vni);
19382       mp->eid_type = eid_type;
19383       switch (eid_type)
19384         {
19385         case 0:
19386           mp->prefix_length = prefix_length;
19387           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19388           break;
19389         case 1:
19390           mp->prefix_length = prefix_length;
19391           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19392           break;
19393         case 2:
19394           clib_memcpy (mp->eid, mac, sizeof (mac));
19395           break;
19396         case 3:
19397           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19398           break;
19399         default:
19400           errmsg ("unknown EID type %d!", eid_type);
19401           return -99;
19402         }
19403     }
19404
19405   /* send it... */
19406   S (mp);
19407
19408   /* Use a control ping for synchronization */
19409   MPING (CONTROL_PING, mp_ping);
19410   S (mp_ping);
19411
19412   /* Wait for a reply... */
19413   W (ret);
19414   return ret;
19415 }
19416
19417 #define api_lisp_eid_table_dump api_one_eid_table_dump
19418
19419 static int
19420 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19421 {
19422   unformat_input_t *i = vam->input;
19423   vl_api_gpe_fwd_entries_get_t *mp;
19424   u8 vni_set = 0;
19425   u32 vni = ~0;
19426   int ret;
19427
19428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19429     {
19430       if (unformat (i, "vni %d", &vni))
19431         {
19432           vni_set = 1;
19433         }
19434       else
19435         {
19436           errmsg ("parse error '%U'", format_unformat_error, i);
19437           return -99;
19438         }
19439     }
19440
19441   if (!vni_set)
19442     {
19443       errmsg ("vni not set!");
19444       return -99;
19445     }
19446
19447   if (!vam->json_output)
19448     {
19449       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19450              "leid", "reid");
19451     }
19452
19453   M (GPE_FWD_ENTRIES_GET, mp);
19454   mp->vni = clib_host_to_net_u32 (vni);
19455
19456   /* send it... */
19457   S (mp);
19458
19459   /* Wait for a reply... */
19460   W (ret);
19461   return ret;
19462 }
19463
19464 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19465 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19466 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19467 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19468 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19469 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19470 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19471 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19472
19473 static int
19474 api_one_adjacencies_get (vat_main_t * vam)
19475 {
19476   unformat_input_t *i = vam->input;
19477   vl_api_one_adjacencies_get_t *mp;
19478   u8 vni_set = 0;
19479   u32 vni = ~0;
19480   int ret;
19481
19482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19483     {
19484       if (unformat (i, "vni %d", &vni))
19485         {
19486           vni_set = 1;
19487         }
19488       else
19489         {
19490           errmsg ("parse error '%U'", format_unformat_error, i);
19491           return -99;
19492         }
19493     }
19494
19495   if (!vni_set)
19496     {
19497       errmsg ("vni not set!");
19498       return -99;
19499     }
19500
19501   if (!vam->json_output)
19502     {
19503       print (vam->ofp, "%s %40s", "leid", "reid");
19504     }
19505
19506   M (ONE_ADJACENCIES_GET, mp);
19507   mp->vni = clib_host_to_net_u32 (vni);
19508
19509   /* send it... */
19510   S (mp);
19511
19512   /* Wait for a reply... */
19513   W (ret);
19514   return ret;
19515 }
19516
19517 #define api_lisp_adjacencies_get api_one_adjacencies_get
19518
19519 static int
19520 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19521 {
19522   unformat_input_t *i = vam->input;
19523   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19524   int ret;
19525   u8 ip_family_set = 0, is_ip4 = 1;
19526
19527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19528     {
19529       if (unformat (i, "ip4"))
19530         {
19531           ip_family_set = 1;
19532           is_ip4 = 1;
19533         }
19534       else if (unformat (i, "ip6"))
19535         {
19536           ip_family_set = 1;
19537           is_ip4 = 0;
19538         }
19539       else
19540         {
19541           errmsg ("parse error '%U'", format_unformat_error, i);
19542           return -99;
19543         }
19544     }
19545
19546   if (!ip_family_set)
19547     {
19548       errmsg ("ip family not set!");
19549       return -99;
19550     }
19551
19552   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19553   mp->is_ip4 = is_ip4;
19554
19555   /* send it... */
19556   S (mp);
19557
19558   /* Wait for a reply... */
19559   W (ret);
19560   return ret;
19561 }
19562
19563 static int
19564 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19565 {
19566   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19567   int ret;
19568
19569   if (!vam->json_output)
19570     {
19571       print (vam->ofp, "VNIs");
19572     }
19573
19574   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19575
19576   /* send it... */
19577   S (mp);
19578
19579   /* Wait for a reply... */
19580   W (ret);
19581   return ret;
19582 }
19583
19584 static int
19585 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19586 {
19587   unformat_input_t *i = vam->input;
19588   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19589   int ret = 0;
19590   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19591   struct in_addr ip4;
19592   struct in6_addr ip6;
19593   u32 table_id = 0, nh_sw_if_index = ~0;
19594
19595   memset (&ip4, 0, sizeof (ip4));
19596   memset (&ip6, 0, sizeof (ip6));
19597
19598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19599     {
19600       if (unformat (i, "del"))
19601         is_add = 0;
19602       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19603                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19604         {
19605           ip_set = 1;
19606           is_ip4 = 1;
19607         }
19608       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19609                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19610         {
19611           ip_set = 1;
19612           is_ip4 = 0;
19613         }
19614       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19615         {
19616           ip_set = 1;
19617           is_ip4 = 1;
19618           nh_sw_if_index = ~0;
19619         }
19620       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19621         {
19622           ip_set = 1;
19623           is_ip4 = 0;
19624           nh_sw_if_index = ~0;
19625         }
19626       else if (unformat (i, "table %d", &table_id))
19627         ;
19628       else
19629         {
19630           errmsg ("parse error '%U'", format_unformat_error, i);
19631           return -99;
19632         }
19633     }
19634
19635   if (!ip_set)
19636     {
19637       errmsg ("nh addr not set!");
19638       return -99;
19639     }
19640
19641   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19642   mp->is_add = is_add;
19643   mp->table_id = clib_host_to_net_u32 (table_id);
19644   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19645   mp->is_ip4 = is_ip4;
19646   if (is_ip4)
19647     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19648   else
19649     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19650
19651   /* send it... */
19652   S (mp);
19653
19654   /* Wait for a reply... */
19655   W (ret);
19656   return ret;
19657 }
19658
19659 static int
19660 api_one_map_server_dump (vat_main_t * vam)
19661 {
19662   vl_api_one_map_server_dump_t *mp;
19663   vl_api_control_ping_t *mp_ping;
19664   int ret;
19665
19666   if (!vam->json_output)
19667     {
19668       print (vam->ofp, "%=20s", "Map server");
19669     }
19670
19671   M (ONE_MAP_SERVER_DUMP, mp);
19672   /* send it... */
19673   S (mp);
19674
19675   /* Use a control ping for synchronization */
19676   MPING (CONTROL_PING, mp_ping);
19677   S (mp_ping);
19678
19679   /* Wait for a reply... */
19680   W (ret);
19681   return ret;
19682 }
19683
19684 #define api_lisp_map_server_dump api_one_map_server_dump
19685
19686 static int
19687 api_one_map_resolver_dump (vat_main_t * vam)
19688 {
19689   vl_api_one_map_resolver_dump_t *mp;
19690   vl_api_control_ping_t *mp_ping;
19691   int ret;
19692
19693   if (!vam->json_output)
19694     {
19695       print (vam->ofp, "%=20s", "Map resolver");
19696     }
19697
19698   M (ONE_MAP_RESOLVER_DUMP, mp);
19699   /* send it... */
19700   S (mp);
19701
19702   /* Use a control ping for synchronization */
19703   MPING (CONTROL_PING, mp_ping);
19704   S (mp_ping);
19705
19706   /* Wait for a reply... */
19707   W (ret);
19708   return ret;
19709 }
19710
19711 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19712
19713 static int
19714 api_one_stats_flush (vat_main_t * vam)
19715 {
19716   vl_api_one_stats_flush_t *mp;
19717   int ret = 0;
19718
19719   M (ONE_STATS_FLUSH, mp);
19720   S (mp);
19721   W (ret);
19722   return ret;
19723 }
19724
19725 static int
19726 api_one_stats_dump (vat_main_t * vam)
19727 {
19728   vl_api_one_stats_dump_t *mp;
19729   vl_api_control_ping_t *mp_ping;
19730   int ret;
19731
19732   M (ONE_STATS_DUMP, mp);
19733   /* send it... */
19734   S (mp);
19735
19736   /* Use a control ping for synchronization */
19737   MPING (CONTROL_PING, mp_ping);
19738   S (mp_ping);
19739
19740   /* Wait for a reply... */
19741   W (ret);
19742   return ret;
19743 }
19744
19745 static int
19746 api_show_one_status (vat_main_t * vam)
19747 {
19748   vl_api_show_one_status_t *mp;
19749   int ret;
19750
19751   if (!vam->json_output)
19752     {
19753       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19754     }
19755
19756   M (SHOW_ONE_STATUS, mp);
19757   /* send it... */
19758   S (mp);
19759   /* Wait for a reply... */
19760   W (ret);
19761   return ret;
19762 }
19763
19764 #define api_show_lisp_status api_show_one_status
19765
19766 static int
19767 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19768 {
19769   vl_api_gpe_fwd_entry_path_dump_t *mp;
19770   vl_api_control_ping_t *mp_ping;
19771   unformat_input_t *i = vam->input;
19772   u32 fwd_entry_index = ~0;
19773   int ret;
19774
19775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19776     {
19777       if (unformat (i, "index %d", &fwd_entry_index))
19778         ;
19779       else
19780         break;
19781     }
19782
19783   if (~0 == fwd_entry_index)
19784     {
19785       errmsg ("no index specified!");
19786       return -99;
19787     }
19788
19789   if (!vam->json_output)
19790     {
19791       print (vam->ofp, "first line");
19792     }
19793
19794   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19795
19796   /* send it... */
19797   S (mp);
19798   /* Use a control ping for synchronization */
19799   MPING (CONTROL_PING, mp_ping);
19800   S (mp_ping);
19801
19802   /* Wait for a reply... */
19803   W (ret);
19804   return ret;
19805 }
19806
19807 static int
19808 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19809 {
19810   vl_api_one_get_map_request_itr_rlocs_t *mp;
19811   int ret;
19812
19813   if (!vam->json_output)
19814     {
19815       print (vam->ofp, "%=20s", "itr-rlocs:");
19816     }
19817
19818   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19819   /* send it... */
19820   S (mp);
19821   /* Wait for a reply... */
19822   W (ret);
19823   return ret;
19824 }
19825
19826 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19827
19828 static int
19829 api_af_packet_create (vat_main_t * vam)
19830 {
19831   unformat_input_t *i = vam->input;
19832   vl_api_af_packet_create_t *mp;
19833   u8 *host_if_name = 0;
19834   u8 hw_addr[6];
19835   u8 random_hw_addr = 1;
19836   int ret;
19837
19838   memset (hw_addr, 0, sizeof (hw_addr));
19839
19840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19841     {
19842       if (unformat (i, "name %s", &host_if_name))
19843         vec_add1 (host_if_name, 0);
19844       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19845         random_hw_addr = 0;
19846       else
19847         break;
19848     }
19849
19850   if (!vec_len (host_if_name))
19851     {
19852       errmsg ("host-interface name must be specified");
19853       return -99;
19854     }
19855
19856   if (vec_len (host_if_name) > 64)
19857     {
19858       errmsg ("host-interface name too long");
19859       return -99;
19860     }
19861
19862   M (AF_PACKET_CREATE, mp);
19863
19864   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19865   clib_memcpy (mp->hw_addr, hw_addr, 6);
19866   mp->use_random_hw_addr = random_hw_addr;
19867   vec_free (host_if_name);
19868
19869   S (mp);
19870
19871   /* *INDENT-OFF* */
19872   W2 (ret,
19873       ({
19874         if (ret == 0)
19875           fprintf (vam->ofp ? vam->ofp : stderr,
19876                    " new sw_if_index = %d\n", vam->sw_if_index);
19877       }));
19878   /* *INDENT-ON* */
19879   return ret;
19880 }
19881
19882 static int
19883 api_af_packet_delete (vat_main_t * vam)
19884 {
19885   unformat_input_t *i = vam->input;
19886   vl_api_af_packet_delete_t *mp;
19887   u8 *host_if_name = 0;
19888   int ret;
19889
19890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19891     {
19892       if (unformat (i, "name %s", &host_if_name))
19893         vec_add1 (host_if_name, 0);
19894       else
19895         break;
19896     }
19897
19898   if (!vec_len (host_if_name))
19899     {
19900       errmsg ("host-interface name must be specified");
19901       return -99;
19902     }
19903
19904   if (vec_len (host_if_name) > 64)
19905     {
19906       errmsg ("host-interface name too long");
19907       return -99;
19908     }
19909
19910   M (AF_PACKET_DELETE, mp);
19911
19912   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19913   vec_free (host_if_name);
19914
19915   S (mp);
19916   W (ret);
19917   return ret;
19918 }
19919
19920 static void vl_api_af_packet_details_t_handler
19921   (vl_api_af_packet_details_t * mp)
19922 {
19923   vat_main_t *vam = &vat_main;
19924
19925   print (vam->ofp, "%-16s %d",
19926          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19927 }
19928
19929 static void vl_api_af_packet_details_t_handler_json
19930   (vl_api_af_packet_details_t * mp)
19931 {
19932   vat_main_t *vam = &vat_main;
19933   vat_json_node_t *node = NULL;
19934
19935   if (VAT_JSON_ARRAY != vam->json_tree.type)
19936     {
19937       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19938       vat_json_init_array (&vam->json_tree);
19939     }
19940   node = vat_json_array_add (&vam->json_tree);
19941
19942   vat_json_init_object (node);
19943   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19944   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19945 }
19946
19947 static int
19948 api_af_packet_dump (vat_main_t * vam)
19949 {
19950   vl_api_af_packet_dump_t *mp;
19951   vl_api_control_ping_t *mp_ping;
19952   int ret;
19953
19954   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19955   /* Get list of tap interfaces */
19956   M (AF_PACKET_DUMP, mp);
19957   S (mp);
19958
19959   /* Use a control ping for synchronization */
19960   MPING (CONTROL_PING, mp_ping);
19961   S (mp_ping);
19962
19963   W (ret);
19964   return ret;
19965 }
19966
19967 static int
19968 api_policer_add_del (vat_main_t * vam)
19969 {
19970   unformat_input_t *i = vam->input;
19971   vl_api_policer_add_del_t *mp;
19972   u8 is_add = 1;
19973   u8 *name = 0;
19974   u32 cir = 0;
19975   u32 eir = 0;
19976   u64 cb = 0;
19977   u64 eb = 0;
19978   u8 rate_type = 0;
19979   u8 round_type = 0;
19980   u8 type = 0;
19981   u8 color_aware = 0;
19982   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19983   int ret;
19984
19985   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19986   conform_action.dscp = 0;
19987   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19988   exceed_action.dscp = 0;
19989   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19990   violate_action.dscp = 0;
19991
19992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19993     {
19994       if (unformat (i, "del"))
19995         is_add = 0;
19996       else if (unformat (i, "name %s", &name))
19997         vec_add1 (name, 0);
19998       else if (unformat (i, "cir %u", &cir))
19999         ;
20000       else if (unformat (i, "eir %u", &eir))
20001         ;
20002       else if (unformat (i, "cb %u", &cb))
20003         ;
20004       else if (unformat (i, "eb %u", &eb))
20005         ;
20006       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20007                          &rate_type))
20008         ;
20009       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20010                          &round_type))
20011         ;
20012       else if (unformat (i, "type %U", unformat_policer_type, &type))
20013         ;
20014       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20015                          &conform_action))
20016         ;
20017       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20018                          &exceed_action))
20019         ;
20020       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20021                          &violate_action))
20022         ;
20023       else if (unformat (i, "color-aware"))
20024         color_aware = 1;
20025       else
20026         break;
20027     }
20028
20029   if (!vec_len (name))
20030     {
20031       errmsg ("policer name must be specified");
20032       return -99;
20033     }
20034
20035   if (vec_len (name) > 64)
20036     {
20037       errmsg ("policer name too long");
20038       return -99;
20039     }
20040
20041   M (POLICER_ADD_DEL, mp);
20042
20043   clib_memcpy (mp->name, name, vec_len (name));
20044   vec_free (name);
20045   mp->is_add = is_add;
20046   mp->cir = ntohl (cir);
20047   mp->eir = ntohl (eir);
20048   mp->cb = clib_net_to_host_u64 (cb);
20049   mp->eb = clib_net_to_host_u64 (eb);
20050   mp->rate_type = rate_type;
20051   mp->round_type = round_type;
20052   mp->type = type;
20053   mp->conform_action_type = conform_action.action_type;
20054   mp->conform_dscp = conform_action.dscp;
20055   mp->exceed_action_type = exceed_action.action_type;
20056   mp->exceed_dscp = exceed_action.dscp;
20057   mp->violate_action_type = violate_action.action_type;
20058   mp->violate_dscp = violate_action.dscp;
20059   mp->color_aware = color_aware;
20060
20061   S (mp);
20062   W (ret);
20063   return ret;
20064 }
20065
20066 static int
20067 api_policer_dump (vat_main_t * vam)
20068 {
20069   unformat_input_t *i = vam->input;
20070   vl_api_policer_dump_t *mp;
20071   vl_api_control_ping_t *mp_ping;
20072   u8 *match_name = 0;
20073   u8 match_name_valid = 0;
20074   int ret;
20075
20076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20077     {
20078       if (unformat (i, "name %s", &match_name))
20079         {
20080           vec_add1 (match_name, 0);
20081           match_name_valid = 1;
20082         }
20083       else
20084         break;
20085     }
20086
20087   M (POLICER_DUMP, mp);
20088   mp->match_name_valid = match_name_valid;
20089   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20090   vec_free (match_name);
20091   /* send it... */
20092   S (mp);
20093
20094   /* Use a control ping for synchronization */
20095   MPING (CONTROL_PING, mp_ping);
20096   S (mp_ping);
20097
20098   /* Wait for a reply... */
20099   W (ret);
20100   return ret;
20101 }
20102
20103 static int
20104 api_policer_classify_set_interface (vat_main_t * vam)
20105 {
20106   unformat_input_t *i = vam->input;
20107   vl_api_policer_classify_set_interface_t *mp;
20108   u32 sw_if_index;
20109   int sw_if_index_set;
20110   u32 ip4_table_index = ~0;
20111   u32 ip6_table_index = ~0;
20112   u32 l2_table_index = ~0;
20113   u8 is_add = 1;
20114   int ret;
20115
20116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20117     {
20118       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20119         sw_if_index_set = 1;
20120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20121         sw_if_index_set = 1;
20122       else if (unformat (i, "del"))
20123         is_add = 0;
20124       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20125         ;
20126       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20127         ;
20128       else if (unformat (i, "l2-table %d", &l2_table_index))
20129         ;
20130       else
20131         {
20132           clib_warning ("parse error '%U'", format_unformat_error, i);
20133           return -99;
20134         }
20135     }
20136
20137   if (sw_if_index_set == 0)
20138     {
20139       errmsg ("missing interface name or sw_if_index");
20140       return -99;
20141     }
20142
20143   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20144
20145   mp->sw_if_index = ntohl (sw_if_index);
20146   mp->ip4_table_index = ntohl (ip4_table_index);
20147   mp->ip6_table_index = ntohl (ip6_table_index);
20148   mp->l2_table_index = ntohl (l2_table_index);
20149   mp->is_add = is_add;
20150
20151   S (mp);
20152   W (ret);
20153   return ret;
20154 }
20155
20156 static int
20157 api_policer_classify_dump (vat_main_t * vam)
20158 {
20159   unformat_input_t *i = vam->input;
20160   vl_api_policer_classify_dump_t *mp;
20161   vl_api_control_ping_t *mp_ping;
20162   u8 type = POLICER_CLASSIFY_N_TABLES;
20163   int ret;
20164
20165   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20166     ;
20167   else
20168     {
20169       errmsg ("classify table type must be specified");
20170       return -99;
20171     }
20172
20173   if (!vam->json_output)
20174     {
20175       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20176     }
20177
20178   M (POLICER_CLASSIFY_DUMP, mp);
20179   mp->type = type;
20180   /* send it... */
20181   S (mp);
20182
20183   /* Use a control ping for synchronization */
20184   MPING (CONTROL_PING, mp_ping);
20185   S (mp_ping);
20186
20187   /* Wait for a reply... */
20188   W (ret);
20189   return ret;
20190 }
20191
20192 static int
20193 api_netmap_create (vat_main_t * vam)
20194 {
20195   unformat_input_t *i = vam->input;
20196   vl_api_netmap_create_t *mp;
20197   u8 *if_name = 0;
20198   u8 hw_addr[6];
20199   u8 random_hw_addr = 1;
20200   u8 is_pipe = 0;
20201   u8 is_master = 0;
20202   int ret;
20203
20204   memset (hw_addr, 0, sizeof (hw_addr));
20205
20206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20207     {
20208       if (unformat (i, "name %s", &if_name))
20209         vec_add1 (if_name, 0);
20210       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20211         random_hw_addr = 0;
20212       else if (unformat (i, "pipe"))
20213         is_pipe = 1;
20214       else if (unformat (i, "master"))
20215         is_master = 1;
20216       else if (unformat (i, "slave"))
20217         is_master = 0;
20218       else
20219         break;
20220     }
20221
20222   if (!vec_len (if_name))
20223     {
20224       errmsg ("interface name must be specified");
20225       return -99;
20226     }
20227
20228   if (vec_len (if_name) > 64)
20229     {
20230       errmsg ("interface name too long");
20231       return -99;
20232     }
20233
20234   M (NETMAP_CREATE, mp);
20235
20236   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20237   clib_memcpy (mp->hw_addr, hw_addr, 6);
20238   mp->use_random_hw_addr = random_hw_addr;
20239   mp->is_pipe = is_pipe;
20240   mp->is_master = is_master;
20241   vec_free (if_name);
20242
20243   S (mp);
20244   W (ret);
20245   return ret;
20246 }
20247
20248 static int
20249 api_netmap_delete (vat_main_t * vam)
20250 {
20251   unformat_input_t *i = vam->input;
20252   vl_api_netmap_delete_t *mp;
20253   u8 *if_name = 0;
20254   int ret;
20255
20256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20257     {
20258       if (unformat (i, "name %s", &if_name))
20259         vec_add1 (if_name, 0);
20260       else
20261         break;
20262     }
20263
20264   if (!vec_len (if_name))
20265     {
20266       errmsg ("interface name must be specified");
20267       return -99;
20268     }
20269
20270   if (vec_len (if_name) > 64)
20271     {
20272       errmsg ("interface name too long");
20273       return -99;
20274     }
20275
20276   M (NETMAP_DELETE, mp);
20277
20278   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20279   vec_free (if_name);
20280
20281   S (mp);
20282   W (ret);
20283   return ret;
20284 }
20285
20286 static void
20287 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20288 {
20289   if (fp->afi == IP46_TYPE_IP6)
20290     print (vam->ofp,
20291            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20292            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20293            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20294            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20295            format_ip6_address, fp->next_hop);
20296   else if (fp->afi == IP46_TYPE_IP4)
20297     print (vam->ofp,
20298            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20299            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20300            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20301            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20302            format_ip4_address, fp->next_hop);
20303 }
20304
20305 static void
20306 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20307                                  vl_api_fib_path_t * fp)
20308 {
20309   struct in_addr ip4;
20310   struct in6_addr ip6;
20311
20312   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20313   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20314   vat_json_object_add_uint (node, "is_local", fp->is_local);
20315   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20316   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20317   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20318   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20319   if (fp->afi == IP46_TYPE_IP4)
20320     {
20321       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20322       vat_json_object_add_ip4 (node, "next_hop", ip4);
20323     }
20324   else if (fp->afi == IP46_TYPE_IP6)
20325     {
20326       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20327       vat_json_object_add_ip6 (node, "next_hop", ip6);
20328     }
20329 }
20330
20331 static void
20332 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20333 {
20334   vat_main_t *vam = &vat_main;
20335   int count = ntohl (mp->mt_count);
20336   vl_api_fib_path_t *fp;
20337   i32 i;
20338
20339   print (vam->ofp, "[%d]: sw_if_index %d via:",
20340          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20341   fp = mp->mt_paths;
20342   for (i = 0; i < count; i++)
20343     {
20344       vl_api_mpls_fib_path_print (vam, fp);
20345       fp++;
20346     }
20347
20348   print (vam->ofp, "");
20349 }
20350
20351 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20352 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20353
20354 static void
20355 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20356 {
20357   vat_main_t *vam = &vat_main;
20358   vat_json_node_t *node = NULL;
20359   int count = ntohl (mp->mt_count);
20360   vl_api_fib_path_t *fp;
20361   i32 i;
20362
20363   if (VAT_JSON_ARRAY != vam->json_tree.type)
20364     {
20365       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20366       vat_json_init_array (&vam->json_tree);
20367     }
20368   node = vat_json_array_add (&vam->json_tree);
20369
20370   vat_json_init_object (node);
20371   vat_json_object_add_uint (node, "tunnel_index",
20372                             ntohl (mp->mt_tunnel_index));
20373   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20374
20375   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20376
20377   fp = mp->mt_paths;
20378   for (i = 0; i < count; i++)
20379     {
20380       vl_api_mpls_fib_path_json_print (node, fp);
20381       fp++;
20382     }
20383 }
20384
20385 static int
20386 api_mpls_tunnel_dump (vat_main_t * vam)
20387 {
20388   vl_api_mpls_tunnel_dump_t *mp;
20389   vl_api_control_ping_t *mp_ping;
20390   i32 index = -1;
20391   int ret;
20392
20393   /* Parse args required to build the message */
20394   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20395     {
20396       if (!unformat (vam->input, "tunnel_index %d", &index))
20397         {
20398           index = -1;
20399           break;
20400         }
20401     }
20402
20403   print (vam->ofp, "  tunnel_index %d", index);
20404
20405   M (MPLS_TUNNEL_DUMP, mp);
20406   mp->tunnel_index = htonl (index);
20407   S (mp);
20408
20409   /* Use a control ping for synchronization */
20410   MPING (CONTROL_PING, mp_ping);
20411   S (mp_ping);
20412
20413   W (ret);
20414   return ret;
20415 }
20416
20417 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20418 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20419
20420
20421 static void
20422 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20423 {
20424   vat_main_t *vam = &vat_main;
20425   int count = ntohl (mp->count);
20426   vl_api_fib_path_t *fp;
20427   int i;
20428
20429   print (vam->ofp,
20430          "table-id %d, label %u, ess_bit %u",
20431          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20432   fp = mp->path;
20433   for (i = 0; i < count; i++)
20434     {
20435       vl_api_mpls_fib_path_print (vam, fp);
20436       fp++;
20437     }
20438 }
20439
20440 static void vl_api_mpls_fib_details_t_handler_json
20441   (vl_api_mpls_fib_details_t * mp)
20442 {
20443   vat_main_t *vam = &vat_main;
20444   int count = ntohl (mp->count);
20445   vat_json_node_t *node = NULL;
20446   vl_api_fib_path_t *fp;
20447   int i;
20448
20449   if (VAT_JSON_ARRAY != vam->json_tree.type)
20450     {
20451       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20452       vat_json_init_array (&vam->json_tree);
20453     }
20454   node = vat_json_array_add (&vam->json_tree);
20455
20456   vat_json_init_object (node);
20457   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20458   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20459   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20460   vat_json_object_add_uint (node, "path_count", count);
20461   fp = mp->path;
20462   for (i = 0; i < count; i++)
20463     {
20464       vl_api_mpls_fib_path_json_print (node, fp);
20465       fp++;
20466     }
20467 }
20468
20469 static int
20470 api_mpls_fib_dump (vat_main_t * vam)
20471 {
20472   vl_api_mpls_fib_dump_t *mp;
20473   vl_api_control_ping_t *mp_ping;
20474   int ret;
20475
20476   M (MPLS_FIB_DUMP, mp);
20477   S (mp);
20478
20479   /* Use a control ping for synchronization */
20480   MPING (CONTROL_PING, mp_ping);
20481   S (mp_ping);
20482
20483   W (ret);
20484   return ret;
20485 }
20486
20487 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20488 #define vl_api_ip_fib_details_t_print vl_noop_handler
20489
20490 static void
20491 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20492 {
20493   vat_main_t *vam = &vat_main;
20494   int count = ntohl (mp->count);
20495   vl_api_fib_path_t *fp;
20496   int i;
20497
20498   print (vam->ofp,
20499          "table-id %d, prefix %U/%d",
20500          ntohl (mp->table_id), format_ip4_address, mp->address,
20501          mp->address_length);
20502   fp = mp->path;
20503   for (i = 0; i < count; i++)
20504     {
20505       if (fp->afi == IP46_TYPE_IP6)
20506         print (vam->ofp,
20507                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20508                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20509                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20510                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20511                format_ip6_address, fp->next_hop);
20512       else if (fp->afi == IP46_TYPE_IP4)
20513         print (vam->ofp,
20514                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20515                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20516                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20517                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20518                format_ip4_address, fp->next_hop);
20519       fp++;
20520     }
20521 }
20522
20523 static void vl_api_ip_fib_details_t_handler_json
20524   (vl_api_ip_fib_details_t * mp)
20525 {
20526   vat_main_t *vam = &vat_main;
20527   int count = ntohl (mp->count);
20528   vat_json_node_t *node = NULL;
20529   struct in_addr ip4;
20530   struct in6_addr ip6;
20531   vl_api_fib_path_t *fp;
20532   int i;
20533
20534   if (VAT_JSON_ARRAY != vam->json_tree.type)
20535     {
20536       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20537       vat_json_init_array (&vam->json_tree);
20538     }
20539   node = vat_json_array_add (&vam->json_tree);
20540
20541   vat_json_init_object (node);
20542   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20543   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20544   vat_json_object_add_ip4 (node, "prefix", ip4);
20545   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20546   vat_json_object_add_uint (node, "path_count", count);
20547   fp = mp->path;
20548   for (i = 0; i < count; i++)
20549     {
20550       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20551       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20552       vat_json_object_add_uint (node, "is_local", fp->is_local);
20553       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20554       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20555       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20556       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20557       if (fp->afi == IP46_TYPE_IP4)
20558         {
20559           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20560           vat_json_object_add_ip4 (node, "next_hop", ip4);
20561         }
20562       else if (fp->afi == IP46_TYPE_IP6)
20563         {
20564           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20565           vat_json_object_add_ip6 (node, "next_hop", ip6);
20566         }
20567     }
20568 }
20569
20570 static int
20571 api_ip_fib_dump (vat_main_t * vam)
20572 {
20573   vl_api_ip_fib_dump_t *mp;
20574   vl_api_control_ping_t *mp_ping;
20575   int ret;
20576
20577   M (IP_FIB_DUMP, mp);
20578   S (mp);
20579
20580   /* Use a control ping for synchronization */
20581   MPING (CONTROL_PING, mp_ping);
20582   S (mp_ping);
20583
20584   W (ret);
20585   return ret;
20586 }
20587
20588 static int
20589 api_ip_mfib_dump (vat_main_t * vam)
20590 {
20591   vl_api_ip_mfib_dump_t *mp;
20592   vl_api_control_ping_t *mp_ping;
20593   int ret;
20594
20595   M (IP_MFIB_DUMP, mp);
20596   S (mp);
20597
20598   /* Use a control ping for synchronization */
20599   MPING (CONTROL_PING, mp_ping);
20600   S (mp_ping);
20601
20602   W (ret);
20603   return ret;
20604 }
20605
20606 static void vl_api_ip_neighbor_details_t_handler
20607   (vl_api_ip_neighbor_details_t * mp)
20608 {
20609   vat_main_t *vam = &vat_main;
20610
20611   print (vam->ofp, "%c %U %U",
20612          (mp->is_static) ? 'S' : 'D',
20613          format_ethernet_address, &mp->mac_address,
20614          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20615          &mp->ip_address);
20616 }
20617
20618 static void vl_api_ip_neighbor_details_t_handler_json
20619   (vl_api_ip_neighbor_details_t * mp)
20620 {
20621
20622   vat_main_t *vam = &vat_main;
20623   vat_json_node_t *node;
20624   struct in_addr ip4;
20625   struct in6_addr ip6;
20626
20627   if (VAT_JSON_ARRAY != vam->json_tree.type)
20628     {
20629       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20630       vat_json_init_array (&vam->json_tree);
20631     }
20632   node = vat_json_array_add (&vam->json_tree);
20633
20634   vat_json_init_object (node);
20635   vat_json_object_add_string_copy (node, "flag",
20636                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20637                                    "dynamic");
20638
20639   vat_json_object_add_string_copy (node, "link_layer",
20640                                    format (0, "%U", format_ethernet_address,
20641                                            &mp->mac_address));
20642
20643   if (mp->is_ipv6)
20644     {
20645       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20646       vat_json_object_add_ip6 (node, "ip_address", ip6);
20647     }
20648   else
20649     {
20650       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20651       vat_json_object_add_ip4 (node, "ip_address", ip4);
20652     }
20653 }
20654
20655 static int
20656 api_ip_neighbor_dump (vat_main_t * vam)
20657 {
20658   unformat_input_t *i = vam->input;
20659   vl_api_ip_neighbor_dump_t *mp;
20660   vl_api_control_ping_t *mp_ping;
20661   u8 is_ipv6 = 0;
20662   u32 sw_if_index = ~0;
20663   int ret;
20664
20665   /* Parse args required to build the message */
20666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20667     {
20668       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20669         ;
20670       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20671         ;
20672       else if (unformat (i, "ip6"))
20673         is_ipv6 = 1;
20674       else
20675         break;
20676     }
20677
20678   if (sw_if_index == ~0)
20679     {
20680       errmsg ("missing interface name or sw_if_index");
20681       return -99;
20682     }
20683
20684   M (IP_NEIGHBOR_DUMP, mp);
20685   mp->is_ipv6 = (u8) is_ipv6;
20686   mp->sw_if_index = ntohl (sw_if_index);
20687   S (mp);
20688
20689   /* Use a control ping for synchronization */
20690   MPING (CONTROL_PING, mp_ping);
20691   S (mp_ping);
20692
20693   W (ret);
20694   return ret;
20695 }
20696
20697 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20698 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20699
20700 static void
20701 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20702 {
20703   vat_main_t *vam = &vat_main;
20704   int count = ntohl (mp->count);
20705   vl_api_fib_path_t *fp;
20706   int i;
20707
20708   print (vam->ofp,
20709          "table-id %d, prefix %U/%d",
20710          ntohl (mp->table_id), format_ip6_address, mp->address,
20711          mp->address_length);
20712   fp = mp->path;
20713   for (i = 0; i < count; i++)
20714     {
20715       if (fp->afi == IP46_TYPE_IP6)
20716         print (vam->ofp,
20717                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20718                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20719                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20720                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20721                format_ip6_address, fp->next_hop);
20722       else if (fp->afi == IP46_TYPE_IP4)
20723         print (vam->ofp,
20724                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20725                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20726                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20727                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20728                format_ip4_address, fp->next_hop);
20729       fp++;
20730     }
20731 }
20732
20733 static void vl_api_ip6_fib_details_t_handler_json
20734   (vl_api_ip6_fib_details_t * mp)
20735 {
20736   vat_main_t *vam = &vat_main;
20737   int count = ntohl (mp->count);
20738   vat_json_node_t *node = NULL;
20739   struct in_addr ip4;
20740   struct in6_addr ip6;
20741   vl_api_fib_path_t *fp;
20742   int i;
20743
20744   if (VAT_JSON_ARRAY != vam->json_tree.type)
20745     {
20746       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20747       vat_json_init_array (&vam->json_tree);
20748     }
20749   node = vat_json_array_add (&vam->json_tree);
20750
20751   vat_json_init_object (node);
20752   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20753   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20754   vat_json_object_add_ip6 (node, "prefix", ip6);
20755   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20756   vat_json_object_add_uint (node, "path_count", count);
20757   fp = mp->path;
20758   for (i = 0; i < count; i++)
20759     {
20760       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20761       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20762       vat_json_object_add_uint (node, "is_local", fp->is_local);
20763       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20764       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20765       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20766       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20767       if (fp->afi == IP46_TYPE_IP4)
20768         {
20769           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20770           vat_json_object_add_ip4 (node, "next_hop", ip4);
20771         }
20772       else if (fp->afi == IP46_TYPE_IP6)
20773         {
20774           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20775           vat_json_object_add_ip6 (node, "next_hop", ip6);
20776         }
20777     }
20778 }
20779
20780 static int
20781 api_ip6_fib_dump (vat_main_t * vam)
20782 {
20783   vl_api_ip6_fib_dump_t *mp;
20784   vl_api_control_ping_t *mp_ping;
20785   int ret;
20786
20787   M (IP6_FIB_DUMP, mp);
20788   S (mp);
20789
20790   /* Use a control ping for synchronization */
20791   MPING (CONTROL_PING, mp_ping);
20792   S (mp_ping);
20793
20794   W (ret);
20795   return ret;
20796 }
20797
20798 static int
20799 api_ip6_mfib_dump (vat_main_t * vam)
20800 {
20801   vl_api_ip6_mfib_dump_t *mp;
20802   vl_api_control_ping_t *mp_ping;
20803   int ret;
20804
20805   M (IP6_MFIB_DUMP, mp);
20806   S (mp);
20807
20808   /* Use a control ping for synchronization */
20809   MPING (CONTROL_PING, mp_ping);
20810   S (mp_ping);
20811
20812   W (ret);
20813   return ret;
20814 }
20815
20816 int
20817 api_classify_table_ids (vat_main_t * vam)
20818 {
20819   vl_api_classify_table_ids_t *mp;
20820   int ret;
20821
20822   /* Construct the API message */
20823   M (CLASSIFY_TABLE_IDS, mp);
20824   mp->context = 0;
20825
20826   S (mp);
20827   W (ret);
20828   return ret;
20829 }
20830
20831 int
20832 api_classify_table_by_interface (vat_main_t * vam)
20833 {
20834   unformat_input_t *input = vam->input;
20835   vl_api_classify_table_by_interface_t *mp;
20836
20837   u32 sw_if_index = ~0;
20838   int ret;
20839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20840     {
20841       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20842         ;
20843       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20844         ;
20845       else
20846         break;
20847     }
20848   if (sw_if_index == ~0)
20849     {
20850       errmsg ("missing interface name or sw_if_index");
20851       return -99;
20852     }
20853
20854   /* Construct the API message */
20855   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20856   mp->context = 0;
20857   mp->sw_if_index = ntohl (sw_if_index);
20858
20859   S (mp);
20860   W (ret);
20861   return ret;
20862 }
20863
20864 int
20865 api_classify_table_info (vat_main_t * vam)
20866 {
20867   unformat_input_t *input = vam->input;
20868   vl_api_classify_table_info_t *mp;
20869
20870   u32 table_id = ~0;
20871   int ret;
20872   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20873     {
20874       if (unformat (input, "table_id %d", &table_id))
20875         ;
20876       else
20877         break;
20878     }
20879   if (table_id == ~0)
20880     {
20881       errmsg ("missing table id");
20882       return -99;
20883     }
20884
20885   /* Construct the API message */
20886   M (CLASSIFY_TABLE_INFO, mp);
20887   mp->context = 0;
20888   mp->table_id = ntohl (table_id);
20889
20890   S (mp);
20891   W (ret);
20892   return ret;
20893 }
20894
20895 int
20896 api_classify_session_dump (vat_main_t * vam)
20897 {
20898   unformat_input_t *input = vam->input;
20899   vl_api_classify_session_dump_t *mp;
20900   vl_api_control_ping_t *mp_ping;
20901
20902   u32 table_id = ~0;
20903   int ret;
20904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20905     {
20906       if (unformat (input, "table_id %d", &table_id))
20907         ;
20908       else
20909         break;
20910     }
20911   if (table_id == ~0)
20912     {
20913       errmsg ("missing table id");
20914       return -99;
20915     }
20916
20917   /* Construct the API message */
20918   M (CLASSIFY_SESSION_DUMP, mp);
20919   mp->context = 0;
20920   mp->table_id = ntohl (table_id);
20921   S (mp);
20922
20923   /* Use a control ping for synchronization */
20924   MPING (CONTROL_PING, mp_ping);
20925   S (mp_ping);
20926
20927   W (ret);
20928   return ret;
20929 }
20930
20931 static void
20932 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20933 {
20934   vat_main_t *vam = &vat_main;
20935
20936   print (vam->ofp, "collector_address %U, collector_port %d, "
20937          "src_address %U, vrf_id %d, path_mtu %u, "
20938          "template_interval %u, udp_checksum %d",
20939          format_ip4_address, mp->collector_address,
20940          ntohs (mp->collector_port),
20941          format_ip4_address, mp->src_address,
20942          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20943          ntohl (mp->template_interval), mp->udp_checksum);
20944
20945   vam->retval = 0;
20946   vam->result_ready = 1;
20947 }
20948
20949 static void
20950   vl_api_ipfix_exporter_details_t_handler_json
20951   (vl_api_ipfix_exporter_details_t * mp)
20952 {
20953   vat_main_t *vam = &vat_main;
20954   vat_json_node_t node;
20955   struct in_addr collector_address;
20956   struct in_addr src_address;
20957
20958   vat_json_init_object (&node);
20959   clib_memcpy (&collector_address, &mp->collector_address,
20960                sizeof (collector_address));
20961   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20962   vat_json_object_add_uint (&node, "collector_port",
20963                             ntohs (mp->collector_port));
20964   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20965   vat_json_object_add_ip4 (&node, "src_address", src_address);
20966   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20967   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20968   vat_json_object_add_uint (&node, "template_interval",
20969                             ntohl (mp->template_interval));
20970   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20971
20972   vat_json_print (vam->ofp, &node);
20973   vat_json_free (&node);
20974   vam->retval = 0;
20975   vam->result_ready = 1;
20976 }
20977
20978 int
20979 api_ipfix_exporter_dump (vat_main_t * vam)
20980 {
20981   vl_api_ipfix_exporter_dump_t *mp;
20982   int ret;
20983
20984   /* Construct the API message */
20985   M (IPFIX_EXPORTER_DUMP, mp);
20986   mp->context = 0;
20987
20988   S (mp);
20989   W (ret);
20990   return ret;
20991 }
20992
20993 static int
20994 api_ipfix_classify_stream_dump (vat_main_t * vam)
20995 {
20996   vl_api_ipfix_classify_stream_dump_t *mp;
20997   int ret;
20998
20999   /* Construct the API message */
21000   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21001   mp->context = 0;
21002
21003   S (mp);
21004   W (ret);
21005   return ret;
21006   /* NOTREACHED */
21007   return 0;
21008 }
21009
21010 static void
21011   vl_api_ipfix_classify_stream_details_t_handler
21012   (vl_api_ipfix_classify_stream_details_t * mp)
21013 {
21014   vat_main_t *vam = &vat_main;
21015   print (vam->ofp, "domain_id %d, src_port %d",
21016          ntohl (mp->domain_id), ntohs (mp->src_port));
21017   vam->retval = 0;
21018   vam->result_ready = 1;
21019 }
21020
21021 static void
21022   vl_api_ipfix_classify_stream_details_t_handler_json
21023   (vl_api_ipfix_classify_stream_details_t * mp)
21024 {
21025   vat_main_t *vam = &vat_main;
21026   vat_json_node_t node;
21027
21028   vat_json_init_object (&node);
21029   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21030   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21031
21032   vat_json_print (vam->ofp, &node);
21033   vat_json_free (&node);
21034   vam->retval = 0;
21035   vam->result_ready = 1;
21036 }
21037
21038 static int
21039 api_ipfix_classify_table_dump (vat_main_t * vam)
21040 {
21041   vl_api_ipfix_classify_table_dump_t *mp;
21042   vl_api_control_ping_t *mp_ping;
21043   int ret;
21044
21045   if (!vam->json_output)
21046     {
21047       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21048              "transport_protocol");
21049     }
21050
21051   /* Construct the API message */
21052   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21053
21054   /* send it... */
21055   S (mp);
21056
21057   /* Use a control ping for synchronization */
21058   MPING (CONTROL_PING, mp_ping);
21059   S (mp_ping);
21060
21061   W (ret);
21062   return ret;
21063 }
21064
21065 static void
21066   vl_api_ipfix_classify_table_details_t_handler
21067   (vl_api_ipfix_classify_table_details_t * mp)
21068 {
21069   vat_main_t *vam = &vat_main;
21070   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21071          mp->transport_protocol);
21072 }
21073
21074 static void
21075   vl_api_ipfix_classify_table_details_t_handler_json
21076   (vl_api_ipfix_classify_table_details_t * mp)
21077 {
21078   vat_json_node_t *node = NULL;
21079   vat_main_t *vam = &vat_main;
21080
21081   if (VAT_JSON_ARRAY != vam->json_tree.type)
21082     {
21083       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21084       vat_json_init_array (&vam->json_tree);
21085     }
21086
21087   node = vat_json_array_add (&vam->json_tree);
21088   vat_json_init_object (node);
21089
21090   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21091   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21092   vat_json_object_add_uint (node, "transport_protocol",
21093                             mp->transport_protocol);
21094 }
21095
21096 static int
21097 api_sw_interface_span_enable_disable (vat_main_t * vam)
21098 {
21099   unformat_input_t *i = vam->input;
21100   vl_api_sw_interface_span_enable_disable_t *mp;
21101   u32 src_sw_if_index = ~0;
21102   u32 dst_sw_if_index = ~0;
21103   u8 state = 3;
21104   int ret;
21105   u8 is_l2 = 0;
21106
21107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21108     {
21109       if (unformat
21110           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21111         ;
21112       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21113         ;
21114       else
21115         if (unformat
21116             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21117         ;
21118       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21119         ;
21120       else if (unformat (i, "disable"))
21121         state = 0;
21122       else if (unformat (i, "rx"))
21123         state = 1;
21124       else if (unformat (i, "tx"))
21125         state = 2;
21126       else if (unformat (i, "both"))
21127         state = 3;
21128       else if (unformat (i, "l2"))
21129         is_l2 = 1;
21130       else
21131         break;
21132     }
21133
21134   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21135
21136   mp->sw_if_index_from = htonl (src_sw_if_index);
21137   mp->sw_if_index_to = htonl (dst_sw_if_index);
21138   mp->state = state;
21139   mp->is_l2 = is_l2;
21140
21141   S (mp);
21142   W (ret);
21143   return ret;
21144 }
21145
21146 static void
21147 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21148                                             * mp)
21149 {
21150   vat_main_t *vam = &vat_main;
21151   u8 *sw_if_from_name = 0;
21152   u8 *sw_if_to_name = 0;
21153   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21154   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21155   char *states[] = { "none", "rx", "tx", "both" };
21156   hash_pair_t *p;
21157
21158   /* *INDENT-OFF* */
21159   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21160   ({
21161     if ((u32) p->value[0] == sw_if_index_from)
21162       {
21163         sw_if_from_name = (u8 *)(p->key);
21164         if (sw_if_to_name)
21165           break;
21166       }
21167     if ((u32) p->value[0] == sw_if_index_to)
21168       {
21169         sw_if_to_name = (u8 *)(p->key);
21170         if (sw_if_from_name)
21171           break;
21172       }
21173   }));
21174   /* *INDENT-ON* */
21175   print (vam->ofp, "%20s => %20s (%s) %s",
21176          sw_if_from_name, sw_if_to_name, states[mp->state],
21177          mp->is_l2 ? "l2" : "device");
21178 }
21179
21180 static void
21181   vl_api_sw_interface_span_details_t_handler_json
21182   (vl_api_sw_interface_span_details_t * mp)
21183 {
21184   vat_main_t *vam = &vat_main;
21185   vat_json_node_t *node = NULL;
21186   u8 *sw_if_from_name = 0;
21187   u8 *sw_if_to_name = 0;
21188   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21189   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21190   hash_pair_t *p;
21191
21192   /* *INDENT-OFF* */
21193   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21194   ({
21195     if ((u32) p->value[0] == sw_if_index_from)
21196       {
21197         sw_if_from_name = (u8 *)(p->key);
21198         if (sw_if_to_name)
21199           break;
21200       }
21201     if ((u32) p->value[0] == sw_if_index_to)
21202       {
21203         sw_if_to_name = (u8 *)(p->key);
21204         if (sw_if_from_name)
21205           break;
21206       }
21207   }));
21208   /* *INDENT-ON* */
21209
21210   if (VAT_JSON_ARRAY != vam->json_tree.type)
21211     {
21212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21213       vat_json_init_array (&vam->json_tree);
21214     }
21215   node = vat_json_array_add (&vam->json_tree);
21216
21217   vat_json_init_object (node);
21218   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21219   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21220   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21221   if (0 != sw_if_to_name)
21222     {
21223       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21224     }
21225   vat_json_object_add_uint (node, "state", mp->state);
21226   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21227 }
21228
21229 static int
21230 api_sw_interface_span_dump (vat_main_t * vam)
21231 {
21232   unformat_input_t *input = vam->input;
21233   vl_api_sw_interface_span_dump_t *mp;
21234   vl_api_control_ping_t *mp_ping;
21235   u8 is_l2 = 0;
21236   int ret;
21237
21238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21239     {
21240       if (unformat (input, "l2"))
21241         is_l2 = 1;
21242       else
21243         break;
21244     }
21245
21246   M (SW_INTERFACE_SPAN_DUMP, mp);
21247   mp->is_l2 = is_l2;
21248   S (mp);
21249
21250   /* Use a control ping for synchronization */
21251   MPING (CONTROL_PING, mp_ping);
21252   S (mp_ping);
21253
21254   W (ret);
21255   return ret;
21256 }
21257
21258 int
21259 api_pg_create_interface (vat_main_t * vam)
21260 {
21261   unformat_input_t *input = vam->input;
21262   vl_api_pg_create_interface_t *mp;
21263
21264   u32 if_id = ~0;
21265   int ret;
21266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21267     {
21268       if (unformat (input, "if_id %d", &if_id))
21269         ;
21270       else
21271         break;
21272     }
21273   if (if_id == ~0)
21274     {
21275       errmsg ("missing pg interface index");
21276       return -99;
21277     }
21278
21279   /* Construct the API message */
21280   M (PG_CREATE_INTERFACE, mp);
21281   mp->context = 0;
21282   mp->interface_id = ntohl (if_id);
21283
21284   S (mp);
21285   W (ret);
21286   return ret;
21287 }
21288
21289 int
21290 api_pg_capture (vat_main_t * vam)
21291 {
21292   unformat_input_t *input = vam->input;
21293   vl_api_pg_capture_t *mp;
21294
21295   u32 if_id = ~0;
21296   u8 enable = 1;
21297   u32 count = 1;
21298   u8 pcap_file_set = 0;
21299   u8 *pcap_file = 0;
21300   int ret;
21301   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21302     {
21303       if (unformat (input, "if_id %d", &if_id))
21304         ;
21305       else if (unformat (input, "pcap %s", &pcap_file))
21306         pcap_file_set = 1;
21307       else if (unformat (input, "count %d", &count))
21308         ;
21309       else if (unformat (input, "disable"))
21310         enable = 0;
21311       else
21312         break;
21313     }
21314   if (if_id == ~0)
21315     {
21316       errmsg ("missing pg interface index");
21317       return -99;
21318     }
21319   if (pcap_file_set > 0)
21320     {
21321       if (vec_len (pcap_file) > 255)
21322         {
21323           errmsg ("pcap file name is too long");
21324           return -99;
21325         }
21326     }
21327
21328   u32 name_len = vec_len (pcap_file);
21329   /* Construct the API message */
21330   M (PG_CAPTURE, mp);
21331   mp->context = 0;
21332   mp->interface_id = ntohl (if_id);
21333   mp->is_enabled = enable;
21334   mp->count = ntohl (count);
21335   mp->pcap_name_length = ntohl (name_len);
21336   if (pcap_file_set != 0)
21337     {
21338       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21339     }
21340   vec_free (pcap_file);
21341
21342   S (mp);
21343   W (ret);
21344   return ret;
21345 }
21346
21347 int
21348 api_pg_enable_disable (vat_main_t * vam)
21349 {
21350   unformat_input_t *input = vam->input;
21351   vl_api_pg_enable_disable_t *mp;
21352
21353   u8 enable = 1;
21354   u8 stream_name_set = 0;
21355   u8 *stream_name = 0;
21356   int ret;
21357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21358     {
21359       if (unformat (input, "stream %s", &stream_name))
21360         stream_name_set = 1;
21361       else if (unformat (input, "disable"))
21362         enable = 0;
21363       else
21364         break;
21365     }
21366
21367   if (stream_name_set > 0)
21368     {
21369       if (vec_len (stream_name) > 255)
21370         {
21371           errmsg ("stream name too long");
21372           return -99;
21373         }
21374     }
21375
21376   u32 name_len = vec_len (stream_name);
21377   /* Construct the API message */
21378   M (PG_ENABLE_DISABLE, mp);
21379   mp->context = 0;
21380   mp->is_enabled = enable;
21381   if (stream_name_set != 0)
21382     {
21383       mp->stream_name_length = ntohl (name_len);
21384       clib_memcpy (mp->stream_name, stream_name, name_len);
21385     }
21386   vec_free (stream_name);
21387
21388   S (mp);
21389   W (ret);
21390   return ret;
21391 }
21392
21393 int
21394 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21395 {
21396   unformat_input_t *input = vam->input;
21397   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21398
21399   u16 *low_ports = 0;
21400   u16 *high_ports = 0;
21401   u16 this_low;
21402   u16 this_hi;
21403   ip4_address_t ip4_addr;
21404   ip6_address_t ip6_addr;
21405   u32 length;
21406   u32 tmp, tmp2;
21407   u8 prefix_set = 0;
21408   u32 vrf_id = ~0;
21409   u8 is_add = 1;
21410   u8 is_ipv6 = 0;
21411   int ret;
21412
21413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21414     {
21415       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21416         {
21417           prefix_set = 1;
21418         }
21419       else
21420         if (unformat
21421             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21422         {
21423           prefix_set = 1;
21424           is_ipv6 = 1;
21425         }
21426       else if (unformat (input, "vrf %d", &vrf_id))
21427         ;
21428       else if (unformat (input, "del"))
21429         is_add = 0;
21430       else if (unformat (input, "port %d", &tmp))
21431         {
21432           if (tmp == 0 || tmp > 65535)
21433             {
21434               errmsg ("port %d out of range", tmp);
21435               return -99;
21436             }
21437           this_low = tmp;
21438           this_hi = this_low + 1;
21439           vec_add1 (low_ports, this_low);
21440           vec_add1 (high_ports, this_hi);
21441         }
21442       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21443         {
21444           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21445             {
21446               errmsg ("incorrect range parameters");
21447               return -99;
21448             }
21449           this_low = tmp;
21450           /* Note: in debug CLI +1 is added to high before
21451              passing to real fn that does "the work"
21452              (ip_source_and_port_range_check_add_del).
21453              This fn is a wrapper around the binary API fn a
21454              control plane will call, which expects this increment
21455              to have occurred. Hence letting the binary API control
21456              plane fn do the increment for consistency between VAT
21457              and other control planes.
21458            */
21459           this_hi = tmp2;
21460           vec_add1 (low_ports, this_low);
21461           vec_add1 (high_ports, this_hi);
21462         }
21463       else
21464         break;
21465     }
21466
21467   if (prefix_set == 0)
21468     {
21469       errmsg ("<address>/<mask> not specified");
21470       return -99;
21471     }
21472
21473   if (vrf_id == ~0)
21474     {
21475       errmsg ("VRF ID required, not specified");
21476       return -99;
21477     }
21478
21479   if (vrf_id == 0)
21480     {
21481       errmsg
21482         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21483       return -99;
21484     }
21485
21486   if (vec_len (low_ports) == 0)
21487     {
21488       errmsg ("At least one port or port range required");
21489       return -99;
21490     }
21491
21492   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21493
21494   mp->is_add = is_add;
21495
21496   if (is_ipv6)
21497     {
21498       mp->is_ipv6 = 1;
21499       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21500     }
21501   else
21502     {
21503       mp->is_ipv6 = 0;
21504       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21505     }
21506
21507   mp->mask_length = length;
21508   mp->number_of_ranges = vec_len (low_ports);
21509
21510   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21511   vec_free (low_ports);
21512
21513   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21514   vec_free (high_ports);
21515
21516   mp->vrf_id = ntohl (vrf_id);
21517
21518   S (mp);
21519   W (ret);
21520   return ret;
21521 }
21522
21523 int
21524 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21525 {
21526   unformat_input_t *input = vam->input;
21527   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21528   u32 sw_if_index = ~0;
21529   int vrf_set = 0;
21530   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21531   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21532   u8 is_add = 1;
21533   int ret;
21534
21535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21536     {
21537       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21538         ;
21539       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21540         ;
21541       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21542         vrf_set = 1;
21543       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21544         vrf_set = 1;
21545       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21546         vrf_set = 1;
21547       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21548         vrf_set = 1;
21549       else if (unformat (input, "del"))
21550         is_add = 0;
21551       else
21552         break;
21553     }
21554
21555   if (sw_if_index == ~0)
21556     {
21557       errmsg ("Interface required but not specified");
21558       return -99;
21559     }
21560
21561   if (vrf_set == 0)
21562     {
21563       errmsg ("VRF ID required but not specified");
21564       return -99;
21565     }
21566
21567   if (tcp_out_vrf_id == 0
21568       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21569     {
21570       errmsg
21571         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21572       return -99;
21573     }
21574
21575   /* Construct the API message */
21576   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21577
21578   mp->sw_if_index = ntohl (sw_if_index);
21579   mp->is_add = is_add;
21580   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21581   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21582   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21583   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21584
21585   /* send it... */
21586   S (mp);
21587
21588   /* Wait for a reply... */
21589   W (ret);
21590   return ret;
21591 }
21592
21593 static int
21594 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21595 {
21596   unformat_input_t *i = vam->input;
21597   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21598   u32 local_sa_id = 0;
21599   u32 remote_sa_id = 0;
21600   ip4_address_t src_address;
21601   ip4_address_t dst_address;
21602   u8 is_add = 1;
21603   int ret;
21604
21605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21606     {
21607       if (unformat (i, "local_sa %d", &local_sa_id))
21608         ;
21609       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21610         ;
21611       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21612         ;
21613       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21614         ;
21615       else if (unformat (i, "del"))
21616         is_add = 0;
21617       else
21618         {
21619           clib_warning ("parse error '%U'", format_unformat_error, i);
21620           return -99;
21621         }
21622     }
21623
21624   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21625
21626   mp->local_sa_id = ntohl (local_sa_id);
21627   mp->remote_sa_id = ntohl (remote_sa_id);
21628   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21629   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21630   mp->is_add = is_add;
21631
21632   S (mp);
21633   W (ret);
21634   return ret;
21635 }
21636
21637 static int
21638 api_punt (vat_main_t * vam)
21639 {
21640   unformat_input_t *i = vam->input;
21641   vl_api_punt_t *mp;
21642   u32 ipv = ~0;
21643   u32 protocol = ~0;
21644   u32 port = ~0;
21645   int is_add = 1;
21646   int ret;
21647
21648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21649     {
21650       if (unformat (i, "ip %d", &ipv))
21651         ;
21652       else if (unformat (i, "protocol %d", &protocol))
21653         ;
21654       else if (unformat (i, "port %d", &port))
21655         ;
21656       else if (unformat (i, "del"))
21657         is_add = 0;
21658       else
21659         {
21660           clib_warning ("parse error '%U'", format_unformat_error, i);
21661           return -99;
21662         }
21663     }
21664
21665   M (PUNT, mp);
21666
21667   mp->is_add = (u8) is_add;
21668   mp->ipv = (u8) ipv;
21669   mp->l4_protocol = (u8) protocol;
21670   mp->l4_port = htons ((u16) port);
21671
21672   S (mp);
21673   W (ret);
21674   return ret;
21675 }
21676
21677 static void vl_api_ipsec_gre_tunnel_details_t_handler
21678   (vl_api_ipsec_gre_tunnel_details_t * mp)
21679 {
21680   vat_main_t *vam = &vat_main;
21681
21682   print (vam->ofp, "%11d%15U%15U%14d%14d",
21683          ntohl (mp->sw_if_index),
21684          format_ip4_address, &mp->src_address,
21685          format_ip4_address, &mp->dst_address,
21686          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21687 }
21688
21689 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21690   (vl_api_ipsec_gre_tunnel_details_t * mp)
21691 {
21692   vat_main_t *vam = &vat_main;
21693   vat_json_node_t *node = NULL;
21694   struct in_addr ip4;
21695
21696   if (VAT_JSON_ARRAY != vam->json_tree.type)
21697     {
21698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21699       vat_json_init_array (&vam->json_tree);
21700     }
21701   node = vat_json_array_add (&vam->json_tree);
21702
21703   vat_json_init_object (node);
21704   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21705   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21706   vat_json_object_add_ip4 (node, "src_address", ip4);
21707   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21708   vat_json_object_add_ip4 (node, "dst_address", ip4);
21709   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21710   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21711 }
21712
21713 static int
21714 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21715 {
21716   unformat_input_t *i = vam->input;
21717   vl_api_ipsec_gre_tunnel_dump_t *mp;
21718   vl_api_control_ping_t *mp_ping;
21719   u32 sw_if_index;
21720   u8 sw_if_index_set = 0;
21721   int ret;
21722
21723   /* Parse args required to build the message */
21724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21725     {
21726       if (unformat (i, "sw_if_index %d", &sw_if_index))
21727         sw_if_index_set = 1;
21728       else
21729         break;
21730     }
21731
21732   if (sw_if_index_set == 0)
21733     {
21734       sw_if_index = ~0;
21735     }
21736
21737   if (!vam->json_output)
21738     {
21739       print (vam->ofp, "%11s%15s%15s%14s%14s",
21740              "sw_if_index", "src_address", "dst_address",
21741              "local_sa_id", "remote_sa_id");
21742     }
21743
21744   /* Get list of gre-tunnel interfaces */
21745   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21746
21747   mp->sw_if_index = htonl (sw_if_index);
21748
21749   S (mp);
21750
21751   /* Use a control ping for synchronization */
21752   MPING (CONTROL_PING, mp_ping);
21753   S (mp_ping);
21754
21755   W (ret);
21756   return ret;
21757 }
21758
21759 static int
21760 api_delete_subif (vat_main_t * vam)
21761 {
21762   unformat_input_t *i = vam->input;
21763   vl_api_delete_subif_t *mp;
21764   u32 sw_if_index = ~0;
21765   int ret;
21766
21767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21768     {
21769       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21770         ;
21771       if (unformat (i, "sw_if_index %d", &sw_if_index))
21772         ;
21773       else
21774         break;
21775     }
21776
21777   if (sw_if_index == ~0)
21778     {
21779       errmsg ("missing sw_if_index");
21780       return -99;
21781     }
21782
21783   /* Construct the API message */
21784   M (DELETE_SUBIF, mp);
21785   mp->sw_if_index = ntohl (sw_if_index);
21786
21787   S (mp);
21788   W (ret);
21789   return ret;
21790 }
21791
21792 #define foreach_pbb_vtr_op      \
21793 _("disable",  L2_VTR_DISABLED)  \
21794 _("pop",  L2_VTR_POP_2)         \
21795 _("push",  L2_VTR_PUSH_2)
21796
21797 static int
21798 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21799 {
21800   unformat_input_t *i = vam->input;
21801   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21802   u32 sw_if_index = ~0, vtr_op = ~0;
21803   u16 outer_tag = ~0;
21804   u8 dmac[6], smac[6];
21805   u8 dmac_set = 0, smac_set = 0;
21806   u16 vlanid = 0;
21807   u32 sid = ~0;
21808   u32 tmp;
21809   int ret;
21810
21811   /* Shut up coverity */
21812   memset (dmac, 0, sizeof (dmac));
21813   memset (smac, 0, sizeof (smac));
21814
21815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21816     {
21817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21818         ;
21819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21820         ;
21821       else if (unformat (i, "vtr_op %d", &vtr_op))
21822         ;
21823 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21824       foreach_pbb_vtr_op
21825 #undef _
21826         else if (unformat (i, "translate_pbb_stag"))
21827         {
21828           if (unformat (i, "%d", &tmp))
21829             {
21830               vtr_op = L2_VTR_TRANSLATE_2_1;
21831               outer_tag = tmp;
21832             }
21833           else
21834             {
21835               errmsg
21836                 ("translate_pbb_stag operation requires outer tag definition");
21837               return -99;
21838             }
21839         }
21840       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21841         dmac_set++;
21842       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21843         smac_set++;
21844       else if (unformat (i, "sid %d", &sid))
21845         ;
21846       else if (unformat (i, "vlanid %d", &tmp))
21847         vlanid = tmp;
21848       else
21849         {
21850           clib_warning ("parse error '%U'", format_unformat_error, i);
21851           return -99;
21852         }
21853     }
21854
21855   if ((sw_if_index == ~0) || (vtr_op == ~0))
21856     {
21857       errmsg ("missing sw_if_index or vtr operation");
21858       return -99;
21859     }
21860   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21861       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21862     {
21863       errmsg
21864         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21865       return -99;
21866     }
21867
21868   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21869   mp->sw_if_index = ntohl (sw_if_index);
21870   mp->vtr_op = ntohl (vtr_op);
21871   mp->outer_tag = ntohs (outer_tag);
21872   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21873   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21874   mp->b_vlanid = ntohs (vlanid);
21875   mp->i_sid = ntohl (sid);
21876
21877   S (mp);
21878   W (ret);
21879   return ret;
21880 }
21881
21882 static int
21883 api_flow_classify_set_interface (vat_main_t * vam)
21884 {
21885   unformat_input_t *i = vam->input;
21886   vl_api_flow_classify_set_interface_t *mp;
21887   u32 sw_if_index;
21888   int sw_if_index_set;
21889   u32 ip4_table_index = ~0;
21890   u32 ip6_table_index = ~0;
21891   u8 is_add = 1;
21892   int ret;
21893
21894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21895     {
21896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21897         sw_if_index_set = 1;
21898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21899         sw_if_index_set = 1;
21900       else if (unformat (i, "del"))
21901         is_add = 0;
21902       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21903         ;
21904       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21905         ;
21906       else
21907         {
21908           clib_warning ("parse error '%U'", format_unformat_error, i);
21909           return -99;
21910         }
21911     }
21912
21913   if (sw_if_index_set == 0)
21914     {
21915       errmsg ("missing interface name or sw_if_index");
21916       return -99;
21917     }
21918
21919   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21920
21921   mp->sw_if_index = ntohl (sw_if_index);
21922   mp->ip4_table_index = ntohl (ip4_table_index);
21923   mp->ip6_table_index = ntohl (ip6_table_index);
21924   mp->is_add = is_add;
21925
21926   S (mp);
21927   W (ret);
21928   return ret;
21929 }
21930
21931 static int
21932 api_flow_classify_dump (vat_main_t * vam)
21933 {
21934   unformat_input_t *i = vam->input;
21935   vl_api_flow_classify_dump_t *mp;
21936   vl_api_control_ping_t *mp_ping;
21937   u8 type = FLOW_CLASSIFY_N_TABLES;
21938   int ret;
21939
21940   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21941     ;
21942   else
21943     {
21944       errmsg ("classify table type must be specified");
21945       return -99;
21946     }
21947
21948   if (!vam->json_output)
21949     {
21950       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21951     }
21952
21953   M (FLOW_CLASSIFY_DUMP, mp);
21954   mp->type = type;
21955   /* send it... */
21956   S (mp);
21957
21958   /* Use a control ping for synchronization */
21959   MPING (CONTROL_PING, mp_ping);
21960   S (mp_ping);
21961
21962   /* Wait for a reply... */
21963   W (ret);
21964   return ret;
21965 }
21966
21967 static int
21968 api_feature_enable_disable (vat_main_t * vam)
21969 {
21970   unformat_input_t *i = vam->input;
21971   vl_api_feature_enable_disable_t *mp;
21972   u8 *arc_name = 0;
21973   u8 *feature_name = 0;
21974   u32 sw_if_index = ~0;
21975   u8 enable = 1;
21976   int ret;
21977
21978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21979     {
21980       if (unformat (i, "arc_name %s", &arc_name))
21981         ;
21982       else if (unformat (i, "feature_name %s", &feature_name))
21983         ;
21984       else
21985         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21986         ;
21987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21988         ;
21989       else if (unformat (i, "disable"))
21990         enable = 0;
21991       else
21992         break;
21993     }
21994
21995   if (arc_name == 0)
21996     {
21997       errmsg ("missing arc name");
21998       return -99;
21999     }
22000   if (vec_len (arc_name) > 63)
22001     {
22002       errmsg ("arc name too long");
22003     }
22004
22005   if (feature_name == 0)
22006     {
22007       errmsg ("missing feature name");
22008       return -99;
22009     }
22010   if (vec_len (feature_name) > 63)
22011     {
22012       errmsg ("feature name too long");
22013     }
22014
22015   if (sw_if_index == ~0)
22016     {
22017       errmsg ("missing interface name or sw_if_index");
22018       return -99;
22019     }
22020
22021   /* Construct the API message */
22022   M (FEATURE_ENABLE_DISABLE, mp);
22023   mp->sw_if_index = ntohl (sw_if_index);
22024   mp->enable = enable;
22025   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22026   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22027   vec_free (arc_name);
22028   vec_free (feature_name);
22029
22030   S (mp);
22031   W (ret);
22032   return ret;
22033 }
22034
22035 static int
22036 api_sw_interface_tag_add_del (vat_main_t * vam)
22037 {
22038   unformat_input_t *i = vam->input;
22039   vl_api_sw_interface_tag_add_del_t *mp;
22040   u32 sw_if_index = ~0;
22041   u8 *tag = 0;
22042   u8 enable = 1;
22043   int ret;
22044
22045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22046     {
22047       if (unformat (i, "tag %s", &tag))
22048         ;
22049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22050         ;
22051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22052         ;
22053       else if (unformat (i, "del"))
22054         enable = 0;
22055       else
22056         break;
22057     }
22058
22059   if (sw_if_index == ~0)
22060     {
22061       errmsg ("missing interface name or sw_if_index");
22062       return -99;
22063     }
22064
22065   if (enable && (tag == 0))
22066     {
22067       errmsg ("no tag specified");
22068       return -99;
22069     }
22070
22071   /* Construct the API message */
22072   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22073   mp->sw_if_index = ntohl (sw_if_index);
22074   mp->is_add = enable;
22075   if (enable)
22076     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22077   vec_free (tag);
22078
22079   S (mp);
22080   W (ret);
22081   return ret;
22082 }
22083
22084 static void vl_api_l2_xconnect_details_t_handler
22085   (vl_api_l2_xconnect_details_t * mp)
22086 {
22087   vat_main_t *vam = &vat_main;
22088
22089   print (vam->ofp, "%15d%15d",
22090          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22091 }
22092
22093 static void vl_api_l2_xconnect_details_t_handler_json
22094   (vl_api_l2_xconnect_details_t * mp)
22095 {
22096   vat_main_t *vam = &vat_main;
22097   vat_json_node_t *node = NULL;
22098
22099   if (VAT_JSON_ARRAY != vam->json_tree.type)
22100     {
22101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22102       vat_json_init_array (&vam->json_tree);
22103     }
22104   node = vat_json_array_add (&vam->json_tree);
22105
22106   vat_json_init_object (node);
22107   vat_json_object_add_uint (node, "rx_sw_if_index",
22108                             ntohl (mp->rx_sw_if_index));
22109   vat_json_object_add_uint (node, "tx_sw_if_index",
22110                             ntohl (mp->tx_sw_if_index));
22111 }
22112
22113 static int
22114 api_l2_xconnect_dump (vat_main_t * vam)
22115 {
22116   vl_api_l2_xconnect_dump_t *mp;
22117   vl_api_control_ping_t *mp_ping;
22118   int ret;
22119
22120   if (!vam->json_output)
22121     {
22122       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22123     }
22124
22125   M (L2_XCONNECT_DUMP, mp);
22126
22127   S (mp);
22128
22129   /* Use a control ping for synchronization */
22130   MPING (CONTROL_PING, mp_ping);
22131   S (mp_ping);
22132
22133   W (ret);
22134   return ret;
22135 }
22136
22137 static int
22138 api_hw_interface_set_mtu (vat_main_t * vam)
22139 {
22140   unformat_input_t *i = vam->input;
22141   vl_api_hw_interface_set_mtu_t *mp;
22142   u32 sw_if_index = ~0;
22143   u32 mtu = 0;
22144   int ret;
22145
22146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22147     {
22148       if (unformat (i, "mtu %d", &mtu))
22149         ;
22150       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22151         ;
22152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22153         ;
22154       else
22155         break;
22156     }
22157
22158   if (sw_if_index == ~0)
22159     {
22160       errmsg ("missing interface name or sw_if_index");
22161       return -99;
22162     }
22163
22164   if (mtu == 0)
22165     {
22166       errmsg ("no mtu specified");
22167       return -99;
22168     }
22169
22170   /* Construct the API message */
22171   M (HW_INTERFACE_SET_MTU, mp);
22172   mp->sw_if_index = ntohl (sw_if_index);
22173   mp->mtu = ntohs ((u16) mtu);
22174
22175   S (mp);
22176   W (ret);
22177   return ret;
22178 }
22179
22180 static int
22181 api_p2p_ethernet_add (vat_main_t * vam)
22182 {
22183   unformat_input_t *i = vam->input;
22184   vl_api_p2p_ethernet_add_t *mp;
22185   u32 parent_if_index = ~0;
22186   u32 sub_id = ~0;
22187   u8 remote_mac[6];
22188   u8 mac_set = 0;
22189   int ret;
22190
22191   memset (remote_mac, 0, sizeof (remote_mac));
22192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22193     {
22194       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22195         ;
22196       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22197         ;
22198       else
22199         if (unformat
22200             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22201         mac_set++;
22202       else if (unformat (i, "sub_id %d", &sub_id))
22203         ;
22204       else
22205         {
22206           clib_warning ("parse error '%U'", format_unformat_error, i);
22207           return -99;
22208         }
22209     }
22210
22211   if (parent_if_index == ~0)
22212     {
22213       errmsg ("missing interface name or sw_if_index");
22214       return -99;
22215     }
22216   if (mac_set == 0)
22217     {
22218       errmsg ("missing remote mac address");
22219       return -99;
22220     }
22221   if (sub_id == ~0)
22222     {
22223       errmsg ("missing sub-interface id");
22224       return -99;
22225     }
22226
22227   M (P2P_ETHERNET_ADD, mp);
22228   mp->parent_if_index = ntohl (parent_if_index);
22229   mp->subif_id = ntohl (sub_id);
22230   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22231
22232   S (mp);
22233   W (ret);
22234   return ret;
22235 }
22236
22237 static int
22238 api_p2p_ethernet_del (vat_main_t * vam)
22239 {
22240   unformat_input_t *i = vam->input;
22241   vl_api_p2p_ethernet_del_t *mp;
22242   u32 parent_if_index = ~0;
22243   u8 remote_mac[6];
22244   u8 mac_set = 0;
22245   int ret;
22246
22247   memset (remote_mac, 0, sizeof (remote_mac));
22248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22249     {
22250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22251         ;
22252       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22253         ;
22254       else
22255         if (unformat
22256             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22257         mac_set++;
22258       else
22259         {
22260           clib_warning ("parse error '%U'", format_unformat_error, i);
22261           return -99;
22262         }
22263     }
22264
22265   if (parent_if_index == ~0)
22266     {
22267       errmsg ("missing interface name or sw_if_index");
22268       return -99;
22269     }
22270   if (mac_set == 0)
22271     {
22272       errmsg ("missing remote mac address");
22273       return -99;
22274     }
22275
22276   M (P2P_ETHERNET_DEL, mp);
22277   mp->parent_if_index = ntohl (parent_if_index);
22278   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22279
22280   S (mp);
22281   W (ret);
22282   return ret;
22283 }
22284
22285 static int
22286 api_lldp_config (vat_main_t * vam)
22287 {
22288   unformat_input_t *i = vam->input;
22289   vl_api_lldp_config_t *mp;
22290   int tx_hold = 0;
22291   int tx_interval = 0;
22292   u8 *sys_name = NULL;
22293   int ret;
22294
22295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22296     {
22297       if (unformat (i, "system-name %s", &sys_name))
22298         ;
22299       else if (unformat (i, "tx-hold %d", &tx_hold))
22300         ;
22301       else if (unformat (i, "tx-interval %d", &tx_interval))
22302         ;
22303       else
22304         {
22305           clib_warning ("parse error '%U'", format_unformat_error, i);
22306           return -99;
22307         }
22308     }
22309
22310   vec_add1 (sys_name, 0);
22311
22312   M (LLDP_CONFIG, mp);
22313   mp->tx_hold = htonl (tx_hold);
22314   mp->tx_interval = htonl (tx_interval);
22315   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22316   vec_free (sys_name);
22317
22318   S (mp);
22319   W (ret);
22320   return ret;
22321 }
22322
22323 static int
22324 api_sw_interface_set_lldp (vat_main_t * vam)
22325 {
22326   unformat_input_t *i = vam->input;
22327   vl_api_sw_interface_set_lldp_t *mp;
22328   u32 sw_if_index = ~0;
22329   u32 enable = 1;
22330   u8 *port_desc = NULL, *mgmt_oid = NULL;
22331   ip4_address_t ip4_addr;
22332   ip6_address_t ip6_addr;
22333   int ret;
22334
22335   memset (&ip4_addr, 0, sizeof (ip4_addr));
22336   memset (&ip6_addr, 0, sizeof (ip6_addr));
22337
22338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22339     {
22340       if (unformat (i, "disable"))
22341         enable = 0;
22342       else
22343         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22344         ;
22345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22346         ;
22347       else if (unformat (i, "port-desc %s", &port_desc))
22348         ;
22349       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22350         ;
22351       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22352         ;
22353       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22354         ;
22355       else
22356         break;
22357     }
22358
22359   if (sw_if_index == ~0)
22360     {
22361       errmsg ("missing interface name or sw_if_index");
22362       return -99;
22363     }
22364
22365   /* Construct the API message */
22366   vec_add1 (port_desc, 0);
22367   vec_add1 (mgmt_oid, 0);
22368   M (SW_INTERFACE_SET_LLDP, mp);
22369   mp->sw_if_index = ntohl (sw_if_index);
22370   mp->enable = enable;
22371   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22372   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22373   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22374   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22375   vec_free (port_desc);
22376   vec_free (mgmt_oid);
22377
22378   S (mp);
22379   W (ret);
22380   return ret;
22381 }
22382
22383 static int
22384 api_tcp_configure_src_addresses (vat_main_t * vam)
22385 {
22386   vl_api_tcp_configure_src_addresses_t *mp;
22387   unformat_input_t *i = vam->input;
22388   ip4_address_t v4first, v4last;
22389   ip6_address_t v6first, v6last;
22390   u8 range_set = 0;
22391   u32 vrf_id = 0;
22392   int ret;
22393
22394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22395     {
22396       if (unformat (i, "%U - %U",
22397                     unformat_ip4_address, &v4first,
22398                     unformat_ip4_address, &v4last))
22399         {
22400           if (range_set)
22401             {
22402               errmsg ("one range per message (range already set)");
22403               return -99;
22404             }
22405           range_set = 1;
22406         }
22407       else if (unformat (i, "%U - %U",
22408                          unformat_ip6_address, &v6first,
22409                          unformat_ip6_address, &v6last))
22410         {
22411           if (range_set)
22412             {
22413               errmsg ("one range per message (range already set)");
22414               return -99;
22415             }
22416           range_set = 2;
22417         }
22418       else if (unformat (i, "vrf %d", &vrf_id))
22419         ;
22420       else
22421         break;
22422     }
22423
22424   if (range_set == 0)
22425     {
22426       errmsg ("address range not set");
22427       return -99;
22428     }
22429
22430   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22431   mp->vrf_id = ntohl (vrf_id);
22432   /* ipv6? */
22433   if (range_set == 2)
22434     {
22435       mp->is_ipv6 = 1;
22436       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22437       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22438     }
22439   else
22440     {
22441       mp->is_ipv6 = 0;
22442       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22443       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22444     }
22445   S (mp);
22446   W (ret);
22447   return ret;
22448 }
22449
22450 static void vl_api_app_namespace_add_del_reply_t_handler
22451   (vl_api_app_namespace_add_del_reply_t * mp)
22452 {
22453   vat_main_t *vam = &vat_main;
22454   i32 retval = ntohl (mp->retval);
22455   if (vam->async_mode)
22456     {
22457       vam->async_errors += (retval < 0);
22458     }
22459   else
22460     {
22461       vam->retval = retval;
22462       if (retval == 0)
22463         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22464       vam->result_ready = 1;
22465     }
22466 }
22467
22468 static void vl_api_app_namespace_add_del_reply_t_handler_json
22469   (vl_api_app_namespace_add_del_reply_t * mp)
22470 {
22471   vat_main_t *vam = &vat_main;
22472   vat_json_node_t node;
22473
22474   vat_json_init_object (&node);
22475   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22476   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22477
22478   vat_json_print (vam->ofp, &node);
22479   vat_json_free (&node);
22480
22481   vam->retval = ntohl (mp->retval);
22482   vam->result_ready = 1;
22483 }
22484
22485 static int
22486 api_app_namespace_add_del (vat_main_t * vam)
22487 {
22488   vl_api_app_namespace_add_del_t *mp;
22489   unformat_input_t *i = vam->input;
22490   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22491   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22492   u64 secret;
22493   int ret;
22494
22495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22496     {
22497       if (unformat (i, "id %_%v%_", &ns_id))
22498         ;
22499       else if (unformat (i, "secret %lu", &secret))
22500         secret_set = 1;
22501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22502         sw_if_index_set = 1;
22503       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22504         ;
22505       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22506         ;
22507       else
22508         break;
22509     }
22510   if (!ns_id || !secret_set || !sw_if_index_set)
22511     {
22512       errmsg ("namespace id, secret and sw_if_index must be set");
22513       return -99;
22514     }
22515   if (vec_len (ns_id) > 64)
22516     {
22517       errmsg ("namespace id too long");
22518       return -99;
22519     }
22520   M (APP_NAMESPACE_ADD_DEL, mp);
22521
22522   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22523   mp->namespace_id_len = vec_len (ns_id);
22524   mp->secret = clib_host_to_net_u64 (secret);
22525   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22526   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22527   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22528   vec_free (ns_id);
22529   S (mp);
22530   W (ret);
22531   return ret;
22532 }
22533
22534 static void vl_api_map_stats_segment_reply_t_handler
22535   (vl_api_map_stats_segment_reply_t * mp)
22536 {
22537 #if VPP_API_TEST_BUILTIN == 0
22538   vat_main_t *vam = &vat_main;
22539   ssvm_private_t *ssvmp = &vam->stat_segment;
22540   ssvm_shared_header_t *shared_header;
22541   socket_client_main_t *scm = vam->socket_client_main;
22542   int rv = ntohl (mp->retval);
22543   int my_fd, retval;
22544   clib_error_t *error;
22545
22546   vam->retval = rv;
22547
22548   if (rv != 0)
22549     {
22550       vam->result_ready = 1;
22551       return;
22552     }
22553
22554   /*
22555    * Check the socket for the magic fd
22556    */
22557   error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 5);
22558   if (error)
22559     {
22560       clib_error_report (error);
22561       vam->retval = -99;
22562       vam->result_ready = 1;
22563       return;
22564     }
22565
22566   memset (ssvmp, 0, sizeof (*ssvmp));
22567   ssvmp->fd = my_fd;
22568
22569   /* Note: this closes memfd.fd */
22570   retval = ssvm_slave_init_memfd (ssvmp);
22571   if (retval)
22572     {
22573       clib_warning ("WARNING: segment map returned %d", retval);
22574       vam->retval = -99;
22575       vam->result_ready = 1;
22576       return;
22577     }
22578   else
22579     errmsg ("stat segment mapped OK...");
22580
22581   ASSERT (ssvmp && ssvmp->sh);
22582
22583   /* Pick up the segment lock from the shared memory header */
22584   shared_header = ssvmp->sh;
22585   vam->stat_segment_lockp = (clib_spinlock_t *) (shared_header->opaque[0]);
22586   vam->retval = 0;
22587   vam->result_ready = 1;
22588 #endif
22589 }
22590
22591 static void vl_api_map_stats_segment_reply_t_handler_json
22592   (vl_api_map_stats_segment_reply_t * mp)
22593 {
22594 #if VPP_API_TEST_BUILTIN == 0
22595   vat_main_t *vam = &vat_main;
22596   clib_warning ("not implemented");
22597   vam->retval = -99;
22598   vam->result_ready = 1;
22599 #endif
22600 }
22601
22602 static int
22603 api_map_stats_segment (vat_main_t * vam)
22604 {
22605 #if VPP_API_TEST_BUILTIN == 0
22606   vl_api_map_stats_segment_t *mp;
22607   int ret;
22608
22609   M (MAP_STATS_SEGMENT, mp);
22610   S (mp);
22611   W (ret);
22612
22613   return ret;
22614 #else
22615   errmsg ("api unavailable");
22616   return -99;
22617 #endif
22618 }
22619
22620 static int
22621 api_sock_init_shm (vat_main_t * vam)
22622 {
22623 #if VPP_API_TEST_BUILTIN == 0
22624   unformat_input_t *i = vam->input;
22625   vl_api_shm_elem_config_t *config = 0;
22626   u64 size = 64 << 20;
22627   int rv;
22628
22629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22630     {
22631       if (unformat (i, "size %U", unformat_memory_size, &size))
22632         ;
22633       else
22634         break;
22635     }
22636
22637   /*
22638    * Canned custom ring allocator config.
22639    * Should probably parse all of this
22640    */
22641   vec_validate (config, 6);
22642   config[0].type = VL_API_VLIB_RING;
22643   config[0].size = 256;
22644   config[0].count = 32;
22645
22646   config[1].type = VL_API_VLIB_RING;
22647   config[1].size = 1024;
22648   config[1].count = 16;
22649
22650   config[2].type = VL_API_VLIB_RING;
22651   config[2].size = 4096;
22652   config[2].count = 2;
22653
22654   config[3].type = VL_API_CLIENT_RING;
22655   config[3].size = 256;
22656   config[3].count = 32;
22657
22658   config[4].type = VL_API_CLIENT_RING;
22659   config[4].size = 1024;
22660   config[4].count = 16;
22661
22662   config[5].type = VL_API_CLIENT_RING;
22663   config[5].size = 4096;
22664   config[5].count = 2;
22665
22666   config[6].type = VL_API_QUEUE;
22667   config[6].count = 128;
22668   config[6].size = sizeof (uword);
22669
22670   rv = vl_socket_client_init_shm (config);
22671   if (!rv)
22672     vam->client_index_invalid = 1;
22673   return rv;
22674 #else
22675   return -99;
22676 #endif
22677 }
22678
22679 static int
22680 api_dns_enable_disable (vat_main_t * vam)
22681 {
22682   unformat_input_t *line_input = vam->input;
22683   vl_api_dns_enable_disable_t *mp;
22684   u8 enable_disable = 1;
22685   int ret;
22686
22687   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22688     {
22689       if (unformat (line_input, "disable"))
22690         enable_disable = 0;
22691       if (unformat (line_input, "enable"))
22692         enable_disable = 1;
22693       else
22694         break;
22695     }
22696
22697   /* Construct the API message */
22698   M (DNS_ENABLE_DISABLE, mp);
22699   mp->enable = enable_disable;
22700
22701   /* send it... */
22702   S (mp);
22703   /* Wait for the reply */
22704   W (ret);
22705   return ret;
22706 }
22707
22708 static int
22709 api_dns_resolve_name (vat_main_t * vam)
22710 {
22711   unformat_input_t *line_input = vam->input;
22712   vl_api_dns_resolve_name_t *mp;
22713   u8 *name = 0;
22714   int ret;
22715
22716   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22717     {
22718       if (unformat (line_input, "%s", &name))
22719         ;
22720       else
22721         break;
22722     }
22723
22724   if (vec_len (name) > 127)
22725     {
22726       errmsg ("name too long");
22727       return -99;
22728     }
22729
22730   /* Construct the API message */
22731   M (DNS_RESOLVE_NAME, mp);
22732   memcpy (mp->name, name, vec_len (name));
22733   vec_free (name);
22734
22735   /* send it... */
22736   S (mp);
22737   /* Wait for the reply */
22738   W (ret);
22739   return ret;
22740 }
22741
22742 static int
22743 api_dns_resolve_ip (vat_main_t * vam)
22744 {
22745   unformat_input_t *line_input = vam->input;
22746   vl_api_dns_resolve_ip_t *mp;
22747   int is_ip6 = -1;
22748   ip4_address_t addr4;
22749   ip6_address_t addr6;
22750   int ret;
22751
22752   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22753     {
22754       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22755         is_ip6 = 1;
22756       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22757         is_ip6 = 0;
22758       else
22759         break;
22760     }
22761
22762   if (is_ip6 == -1)
22763     {
22764       errmsg ("missing address");
22765       return -99;
22766     }
22767
22768   /* Construct the API message */
22769   M (DNS_RESOLVE_IP, mp);
22770   mp->is_ip6 = is_ip6;
22771   if (is_ip6)
22772     memcpy (mp->address, &addr6, sizeof (addr6));
22773   else
22774     memcpy (mp->address, &addr4, sizeof (addr4));
22775
22776   /* send it... */
22777   S (mp);
22778   /* Wait for the reply */
22779   W (ret);
22780   return ret;
22781 }
22782
22783 static int
22784 api_dns_name_server_add_del (vat_main_t * vam)
22785 {
22786   unformat_input_t *i = vam->input;
22787   vl_api_dns_name_server_add_del_t *mp;
22788   u8 is_add = 1;
22789   ip6_address_t ip6_server;
22790   ip4_address_t ip4_server;
22791   int ip6_set = 0;
22792   int ip4_set = 0;
22793   int ret = 0;
22794
22795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22796     {
22797       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22798         ip6_set = 1;
22799       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22800         ip4_set = 1;
22801       else if (unformat (i, "del"))
22802         is_add = 0;
22803       else
22804         {
22805           clib_warning ("parse error '%U'", format_unformat_error, i);
22806           return -99;
22807         }
22808     }
22809
22810   if (ip4_set && ip6_set)
22811     {
22812       errmsg ("Only one server address allowed per message");
22813       return -99;
22814     }
22815   if ((ip4_set + ip6_set) == 0)
22816     {
22817       errmsg ("Server address required");
22818       return -99;
22819     }
22820
22821   /* Construct the API message */
22822   M (DNS_NAME_SERVER_ADD_DEL, mp);
22823
22824   if (ip6_set)
22825     {
22826       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22827       mp->is_ip6 = 1;
22828     }
22829   else
22830     {
22831       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22832       mp->is_ip6 = 0;
22833     }
22834
22835   mp->is_add = is_add;
22836
22837   /* send it... */
22838   S (mp);
22839
22840   /* Wait for a reply, return good/bad news  */
22841   W (ret);
22842   return ret;
22843 }
22844
22845 static void
22846 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22847 {
22848   vat_main_t *vam = &vat_main;
22849
22850   if (mp->is_ip4)
22851     {
22852       print (vam->ofp,
22853              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22854              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22855              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22856              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22857              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22858              clib_net_to_host_u32 (mp->action_index), mp->tag);
22859     }
22860   else
22861     {
22862       print (vam->ofp,
22863              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22864              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22865              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22866              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22867              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22868              clib_net_to_host_u32 (mp->action_index), mp->tag);
22869     }
22870 }
22871
22872 static void
22873 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22874                                              mp)
22875 {
22876   vat_main_t *vam = &vat_main;
22877   vat_json_node_t *node = NULL;
22878   struct in6_addr ip6;
22879   struct in_addr ip4;
22880
22881   if (VAT_JSON_ARRAY != vam->json_tree.type)
22882     {
22883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22884       vat_json_init_array (&vam->json_tree);
22885     }
22886   node = vat_json_array_add (&vam->json_tree);
22887   vat_json_init_object (node);
22888
22889   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22890   vat_json_object_add_uint (node, "appns_index",
22891                             clib_net_to_host_u32 (mp->appns_index));
22892   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22893   vat_json_object_add_uint (node, "scope", mp->scope);
22894   vat_json_object_add_uint (node, "action_index",
22895                             clib_net_to_host_u32 (mp->action_index));
22896   vat_json_object_add_uint (node, "lcl_port",
22897                             clib_net_to_host_u16 (mp->lcl_port));
22898   vat_json_object_add_uint (node, "rmt_port",
22899                             clib_net_to_host_u16 (mp->rmt_port));
22900   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22901   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22902   vat_json_object_add_string_copy (node, "tag", mp->tag);
22903   if (mp->is_ip4)
22904     {
22905       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22906       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22907       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22908       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22909     }
22910   else
22911     {
22912       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22913       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22914       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22915       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22916     }
22917 }
22918
22919 static int
22920 api_session_rule_add_del (vat_main_t * vam)
22921 {
22922   vl_api_session_rule_add_del_t *mp;
22923   unformat_input_t *i = vam->input;
22924   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22925   u32 appns_index = 0, scope = 0;
22926   ip4_address_t lcl_ip4, rmt_ip4;
22927   ip6_address_t lcl_ip6, rmt_ip6;
22928   u8 is_ip4 = 1, conn_set = 0;
22929   u8 is_add = 1, *tag = 0;
22930   int ret;
22931
22932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22933     {
22934       if (unformat (i, "del"))
22935         is_add = 0;
22936       else if (unformat (i, "add"))
22937         ;
22938       else if (unformat (i, "proto tcp"))
22939         proto = 0;
22940       else if (unformat (i, "proto udp"))
22941         proto = 1;
22942       else if (unformat (i, "appns %d", &appns_index))
22943         ;
22944       else if (unformat (i, "scope %d", &scope))
22945         ;
22946       else if (unformat (i, "tag %_%v%_", &tag))
22947         ;
22948       else
22949         if (unformat
22950             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22951              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22952              &rmt_port))
22953         {
22954           is_ip4 = 1;
22955           conn_set = 1;
22956         }
22957       else
22958         if (unformat
22959             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22960              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22961              &rmt_port))
22962         {
22963           is_ip4 = 0;
22964           conn_set = 1;
22965         }
22966       else if (unformat (i, "action %d", &action))
22967         ;
22968       else
22969         break;
22970     }
22971   if (proto == ~0 || !conn_set || action == ~0)
22972     {
22973       errmsg ("transport proto, connection and action must be set");
22974       return -99;
22975     }
22976
22977   if (scope > 3)
22978     {
22979       errmsg ("scope should be 0-3");
22980       return -99;
22981     }
22982
22983   M (SESSION_RULE_ADD_DEL, mp);
22984
22985   mp->is_ip4 = is_ip4;
22986   mp->transport_proto = proto;
22987   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22988   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22989   mp->lcl_plen = lcl_plen;
22990   mp->rmt_plen = rmt_plen;
22991   mp->action_index = clib_host_to_net_u32 (action);
22992   mp->appns_index = clib_host_to_net_u32 (appns_index);
22993   mp->scope = scope;
22994   mp->is_add = is_add;
22995   if (is_ip4)
22996     {
22997       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22998       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22999     }
23000   else
23001     {
23002       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23003       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23004     }
23005   if (tag)
23006     {
23007       clib_memcpy (mp->tag, tag, vec_len (tag));
23008       vec_free (tag);
23009     }
23010
23011   S (mp);
23012   W (ret);
23013   return ret;
23014 }
23015
23016 static int
23017 api_session_rules_dump (vat_main_t * vam)
23018 {
23019   vl_api_session_rules_dump_t *mp;
23020   vl_api_control_ping_t *mp_ping;
23021   int ret;
23022
23023   if (!vam->json_output)
23024     {
23025       print (vam->ofp, "%=20s", "Session Rules");
23026     }
23027
23028   M (SESSION_RULES_DUMP, mp);
23029   /* send it... */
23030   S (mp);
23031
23032   /* Use a control ping for synchronization */
23033   MPING (CONTROL_PING, mp_ping);
23034   S (mp_ping);
23035
23036   /* Wait for a reply... */
23037   W (ret);
23038   return ret;
23039 }
23040
23041 static int
23042 api_ip_container_proxy_add_del (vat_main_t * vam)
23043 {
23044   vl_api_ip_container_proxy_add_del_t *mp;
23045   unformat_input_t *i = vam->input;
23046   u32 plen = ~0, sw_if_index = ~0;
23047   ip4_address_t ip4;
23048   ip6_address_t ip6;
23049   u8 is_ip4 = 1;
23050   u8 is_add = 1;
23051   int ret;
23052
23053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23054     {
23055       if (unformat (i, "del"))
23056         is_add = 0;
23057       else if (unformat (i, "add"))
23058         ;
23059       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23060         {
23061           is_ip4 = 1;
23062           plen = 32;
23063         }
23064       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23065         {
23066           is_ip4 = 0;
23067           plen = 128;
23068         }
23069       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23070         ;
23071       else
23072         break;
23073     }
23074   if (sw_if_index == ~0 || plen == ~0)
23075     {
23076       errmsg ("address and sw_if_index must be set");
23077       return -99;
23078     }
23079
23080   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23081
23082   mp->is_ip4 = is_ip4;
23083   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23084   mp->plen = plen;
23085   mp->is_add = is_add;
23086   if (is_ip4)
23087     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23088   else
23089     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23090
23091   S (mp);
23092   W (ret);
23093   return ret;
23094 }
23095
23096 static int
23097 api_qos_record_enable_disable (vat_main_t * vam)
23098 {
23099   unformat_input_t *i = vam->input;
23100   vl_api_qos_record_enable_disable_t *mp;
23101   u32 sw_if_index, qs = 0xff;
23102   u8 sw_if_index_set = 0;
23103   u8 enable = 1;
23104   int ret;
23105
23106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23107     {
23108       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23109         sw_if_index_set = 1;
23110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23111         sw_if_index_set = 1;
23112       else if (unformat (i, "%U", unformat_qos_source, &qs))
23113         ;
23114       else if (unformat (i, "disable"))
23115         enable = 0;
23116       else
23117         {
23118           clib_warning ("parse error '%U'", format_unformat_error, i);
23119           return -99;
23120         }
23121     }
23122
23123   if (sw_if_index_set == 0)
23124     {
23125       errmsg ("missing interface name or sw_if_index");
23126       return -99;
23127     }
23128   if (qs == 0xff)
23129     {
23130       errmsg ("input location must be specified");
23131       return -99;
23132     }
23133
23134   M (QOS_RECORD_ENABLE_DISABLE, mp);
23135
23136   mp->sw_if_index = ntohl (sw_if_index);
23137   mp->input_source = qs;
23138   mp->enable = enable;
23139
23140   S (mp);
23141   W (ret);
23142   return ret;
23143 }
23144
23145
23146 static int
23147 q_or_quit (vat_main_t * vam)
23148 {
23149 #if VPP_API_TEST_BUILTIN == 0
23150   longjmp (vam->jump_buf, 1);
23151 #endif
23152   return 0;                     /* not so much */
23153 }
23154
23155 static int
23156 q (vat_main_t * vam)
23157 {
23158   return q_or_quit (vam);
23159 }
23160
23161 static int
23162 quit (vat_main_t * vam)
23163 {
23164   return q_or_quit (vam);
23165 }
23166
23167 static int
23168 comment (vat_main_t * vam)
23169 {
23170   return 0;
23171 }
23172
23173 static int
23174 statseg (vat_main_t * vam)
23175 {
23176   ssvm_private_t *ssvmp = &vam->stat_segment;
23177   ssvm_shared_header_t *shared_header = ssvmp->sh;
23178   vlib_counter_t **counters;
23179   u64 thread0_index1_packets;
23180   u64 thread0_index1_bytes;
23181   f64 vector_rate, input_rate;
23182   uword *p;
23183
23184   uword *counter_vector_by_name;
23185   if (vam->stat_segment_lockp == 0)
23186     {
23187       errmsg ("Stat segment not mapped...");
23188       return -99;
23189     }
23190
23191   /* look up "/if/rx for sw_if_index 1 as a test */
23192
23193   clib_spinlock_lock (vam->stat_segment_lockp);
23194
23195   counter_vector_by_name = (uword *) shared_header->opaque[1];
23196
23197   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23198   if (p == 0)
23199     {
23200       clib_spinlock_unlock (vam->stat_segment_lockp);
23201       errmsg ("/if/tx not found?");
23202       return -99;
23203     }
23204
23205   /* Fish per-thread vector of combined counters from shared memory */
23206   counters = (vlib_counter_t **) p[0];
23207
23208   if (vec_len (counters[0]) < 2)
23209     {
23210       clib_spinlock_unlock (vam->stat_segment_lockp);
23211       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23212       return -99;
23213     }
23214
23215   /* Read thread 0 sw_if_index 1 counter */
23216   thread0_index1_packets = counters[0][1].packets;
23217   thread0_index1_bytes = counters[0][1].bytes;
23218
23219   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23220   if (p == 0)
23221     {
23222       clib_spinlock_unlock (vam->stat_segment_lockp);
23223       errmsg ("vector_rate not found?");
23224       return -99;
23225     }
23226
23227   vector_rate = *(f64 *) (p[0]);
23228   p = hash_get_mem (counter_vector_by_name, "input_rate");
23229   if (p == 0)
23230     {
23231       clib_spinlock_unlock (vam->stat_segment_lockp);
23232       errmsg ("input_rate not found?");
23233       return -99;
23234     }
23235   input_rate = *(f64 *) (p[0]);
23236
23237   clib_spinlock_unlock (vam->stat_segment_lockp);
23238
23239   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23240          vector_rate, input_rate);
23241   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23242          thread0_index1_packets, thread0_index1_bytes);
23243
23244   return 0;
23245 }
23246
23247 static int
23248 cmd_cmp (void *a1, void *a2)
23249 {
23250   u8 **c1 = a1;
23251   u8 **c2 = a2;
23252
23253   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23254 }
23255
23256 static int
23257 help (vat_main_t * vam)
23258 {
23259   u8 **cmds = 0;
23260   u8 *name = 0;
23261   hash_pair_t *p;
23262   unformat_input_t *i = vam->input;
23263   int j;
23264
23265   if (unformat (i, "%s", &name))
23266     {
23267       uword *hs;
23268
23269       vec_add1 (name, 0);
23270
23271       hs = hash_get_mem (vam->help_by_name, name);
23272       if (hs)
23273         print (vam->ofp, "usage: %s %s", name, hs[0]);
23274       else
23275         print (vam->ofp, "No such msg / command '%s'", name);
23276       vec_free (name);
23277       return 0;
23278     }
23279
23280   print (vam->ofp, "Help is available for the following:");
23281
23282     /* *INDENT-OFF* */
23283     hash_foreach_pair (p, vam->function_by_name,
23284     ({
23285       vec_add1 (cmds, (u8 *)(p->key));
23286     }));
23287     /* *INDENT-ON* */
23288
23289   vec_sort_with_function (cmds, cmd_cmp);
23290
23291   for (j = 0; j < vec_len (cmds); j++)
23292     print (vam->ofp, "%s", cmds[j]);
23293
23294   vec_free (cmds);
23295   return 0;
23296 }
23297
23298 static int
23299 set (vat_main_t * vam)
23300 {
23301   u8 *name = 0, *value = 0;
23302   unformat_input_t *i = vam->input;
23303
23304   if (unformat (i, "%s", &name))
23305     {
23306       /* The input buffer is a vector, not a string. */
23307       value = vec_dup (i->buffer);
23308       vec_delete (value, i->index, 0);
23309       /* Almost certainly has a trailing newline */
23310       if (value[vec_len (value) - 1] == '\n')
23311         value[vec_len (value) - 1] = 0;
23312       /* Make sure it's a proper string, one way or the other */
23313       vec_add1 (value, 0);
23314       (void) clib_macro_set_value (&vam->macro_main,
23315                                    (char *) name, (char *) value);
23316     }
23317   else
23318     errmsg ("usage: set <name> <value>");
23319
23320   vec_free (name);
23321   vec_free (value);
23322   return 0;
23323 }
23324
23325 static int
23326 unset (vat_main_t * vam)
23327 {
23328   u8 *name = 0;
23329
23330   if (unformat (vam->input, "%s", &name))
23331     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23332       errmsg ("unset: %s wasn't set", name);
23333   vec_free (name);
23334   return 0;
23335 }
23336
23337 typedef struct
23338 {
23339   u8 *name;
23340   u8 *value;
23341 } macro_sort_t;
23342
23343
23344 static int
23345 macro_sort_cmp (void *a1, void *a2)
23346 {
23347   macro_sort_t *s1 = a1;
23348   macro_sort_t *s2 = a2;
23349
23350   return strcmp ((char *) (s1->name), (char *) (s2->name));
23351 }
23352
23353 static int
23354 dump_macro_table (vat_main_t * vam)
23355 {
23356   macro_sort_t *sort_me = 0, *sm;
23357   int i;
23358   hash_pair_t *p;
23359
23360     /* *INDENT-OFF* */
23361     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23362     ({
23363       vec_add2 (sort_me, sm, 1);
23364       sm->name = (u8 *)(p->key);
23365       sm->value = (u8 *) (p->value[0]);
23366     }));
23367     /* *INDENT-ON* */
23368
23369   vec_sort_with_function (sort_me, macro_sort_cmp);
23370
23371   if (vec_len (sort_me))
23372     print (vam->ofp, "%-15s%s", "Name", "Value");
23373   else
23374     print (vam->ofp, "The macro table is empty...");
23375
23376   for (i = 0; i < vec_len (sort_me); i++)
23377     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23378   return 0;
23379 }
23380
23381 static int
23382 dump_node_table (vat_main_t * vam)
23383 {
23384   int i, j;
23385   vlib_node_t *node, *next_node;
23386
23387   if (vec_len (vam->graph_nodes) == 0)
23388     {
23389       print (vam->ofp, "Node table empty, issue get_node_graph...");
23390       return 0;
23391     }
23392
23393   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23394     {
23395       node = vam->graph_nodes[0][i];
23396       print (vam->ofp, "[%d] %s", i, node->name);
23397       for (j = 0; j < vec_len (node->next_nodes); j++)
23398         {
23399           if (node->next_nodes[j] != ~0)
23400             {
23401               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23402               print (vam->ofp, "  [%d] %s", j, next_node->name);
23403             }
23404         }
23405     }
23406   return 0;
23407 }
23408
23409 static int
23410 value_sort_cmp (void *a1, void *a2)
23411 {
23412   name_sort_t *n1 = a1;
23413   name_sort_t *n2 = a2;
23414
23415   if (n1->value < n2->value)
23416     return -1;
23417   if (n1->value > n2->value)
23418     return 1;
23419   return 0;
23420 }
23421
23422
23423 static int
23424 dump_msg_api_table (vat_main_t * vam)
23425 {
23426   api_main_t *am = &api_main;
23427   name_sort_t *nses = 0, *ns;
23428   hash_pair_t *hp;
23429   int i;
23430
23431   /* *INDENT-OFF* */
23432   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23433   ({
23434     vec_add2 (nses, ns, 1);
23435     ns->name = (u8 *)(hp->key);
23436     ns->value = (u32) hp->value[0];
23437   }));
23438   /* *INDENT-ON* */
23439
23440   vec_sort_with_function (nses, value_sort_cmp);
23441
23442   for (i = 0; i < vec_len (nses); i++)
23443     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23444   vec_free (nses);
23445   return 0;
23446 }
23447
23448 static int
23449 get_msg_id (vat_main_t * vam)
23450 {
23451   u8 *name_and_crc;
23452   u32 message_index;
23453
23454   if (unformat (vam->input, "%s", &name_and_crc))
23455     {
23456       message_index = vl_msg_api_get_msg_index (name_and_crc);
23457       if (message_index == ~0)
23458         {
23459           print (vam->ofp, " '%s' not found", name_and_crc);
23460           return 0;
23461         }
23462       print (vam->ofp, " '%s' has message index %d",
23463              name_and_crc, message_index);
23464       return 0;
23465     }
23466   errmsg ("name_and_crc required...");
23467   return 0;
23468 }
23469
23470 static int
23471 search_node_table (vat_main_t * vam)
23472 {
23473   unformat_input_t *line_input = vam->input;
23474   u8 *node_to_find;
23475   int j;
23476   vlib_node_t *node, *next_node;
23477   uword *p;
23478
23479   if (vam->graph_node_index_by_name == 0)
23480     {
23481       print (vam->ofp, "Node table empty, issue get_node_graph...");
23482       return 0;
23483     }
23484
23485   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23486     {
23487       if (unformat (line_input, "%s", &node_to_find))
23488         {
23489           vec_add1 (node_to_find, 0);
23490           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23491           if (p == 0)
23492             {
23493               print (vam->ofp, "%s not found...", node_to_find);
23494               goto out;
23495             }
23496           node = vam->graph_nodes[0][p[0]];
23497           print (vam->ofp, "[%d] %s", p[0], node->name);
23498           for (j = 0; j < vec_len (node->next_nodes); j++)
23499             {
23500               if (node->next_nodes[j] != ~0)
23501                 {
23502                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23503                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23504                 }
23505             }
23506         }
23507
23508       else
23509         {
23510           clib_warning ("parse error '%U'", format_unformat_error,
23511                         line_input);
23512           return -99;
23513         }
23514
23515     out:
23516       vec_free (node_to_find);
23517
23518     }
23519
23520   return 0;
23521 }
23522
23523
23524 static int
23525 script (vat_main_t * vam)
23526 {
23527 #if (VPP_API_TEST_BUILTIN==0)
23528   u8 *s = 0;
23529   char *save_current_file;
23530   unformat_input_t save_input;
23531   jmp_buf save_jump_buf;
23532   u32 save_line_number;
23533
23534   FILE *new_fp, *save_ifp;
23535
23536   if (unformat (vam->input, "%s", &s))
23537     {
23538       new_fp = fopen ((char *) s, "r");
23539       if (new_fp == 0)
23540         {
23541           errmsg ("Couldn't open script file %s", s);
23542           vec_free (s);
23543           return -99;
23544         }
23545     }
23546   else
23547     {
23548       errmsg ("Missing script name");
23549       return -99;
23550     }
23551
23552   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23553   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23554   save_ifp = vam->ifp;
23555   save_line_number = vam->input_line_number;
23556   save_current_file = (char *) vam->current_file;
23557
23558   vam->input_line_number = 0;
23559   vam->ifp = new_fp;
23560   vam->current_file = s;
23561   do_one_file (vam);
23562
23563   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23564   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23565   vam->ifp = save_ifp;
23566   vam->input_line_number = save_line_number;
23567   vam->current_file = (u8 *) save_current_file;
23568   vec_free (s);
23569
23570   return 0;
23571 #else
23572   clib_warning ("use the exec command...");
23573   return -99;
23574 #endif
23575 }
23576
23577 static int
23578 echo (vat_main_t * vam)
23579 {
23580   print (vam->ofp, "%v", vam->input->buffer);
23581   return 0;
23582 }
23583
23584 /* List of API message constructors, CLI names map to api_xxx */
23585 #define foreach_vpe_api_msg                                             \
23586 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23587 _(sw_interface_dump,"")                                                 \
23588 _(sw_interface_set_flags,                                               \
23589   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23590 _(sw_interface_add_del_address,                                         \
23591   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23592 _(sw_interface_set_rx_mode,                                             \
23593   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23594 _(sw_interface_set_table,                                               \
23595   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23596 _(sw_interface_set_mpls_enable,                                         \
23597   "<intfc> | sw_if_index [disable | dis]")                              \
23598 _(sw_interface_set_vpath,                                               \
23599   "<intfc> | sw_if_index <id> enable | disable")                        \
23600 _(sw_interface_set_vxlan_bypass,                                        \
23601   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23602 _(sw_interface_set_geneve_bypass,                                       \
23603   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23604 _(sw_interface_set_l2_xconnect,                                         \
23605   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23606   "enable | disable")                                                   \
23607 _(sw_interface_set_l2_bridge,                                           \
23608   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23609   "[shg <split-horizon-group>] [bvi]\n"                                 \
23610   "enable | disable")                                                   \
23611 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23612 _(bridge_domain_add_del,                                                \
23613   "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") \
23614 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23615 _(l2fib_add_del,                                                        \
23616   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23617 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23618 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23619 _(l2_flags,                                                             \
23620   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23621 _(bridge_flags,                                                         \
23622   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23623 _(tap_connect,                                                          \
23624   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23625 _(tap_modify,                                                           \
23626   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23627 _(tap_delete,                                                           \
23628   "<vpp-if-name> | sw_if_index <id>")                                   \
23629 _(sw_interface_tap_dump, "")                                            \
23630 _(tap_create_v2,                                                        \
23631   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23632 _(tap_delete_v2,                                                        \
23633   "<vpp-if-name> | sw_if_index <id>")                                   \
23634 _(sw_interface_tap_v2_dump, "")                                         \
23635 _(bond_create,                                                          \
23636   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23637   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23638 _(bond_delete,                                                          \
23639   "<vpp-if-name> | sw_if_index <id>")                                   \
23640 _(bond_enslave,                                                         \
23641   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23642 _(bond_detach_slave,                                                    \
23643   "sw_if_index <n>")                                                    \
23644 _(sw_interface_bond_dump, "")                                           \
23645 _(sw_interface_slave_dump,                                              \
23646   "<vpp-if-name> | sw_if_index <id>")                                   \
23647 _(ip_table_add_del,                                                     \
23648   "table-id <n> [ipv6]\n")                                              \
23649 _(ip_add_del_route,                                                     \
23650   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23651   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23652   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23653   "[multipath] [count <n>]")                                            \
23654 _(ip_mroute_add_del,                                                    \
23655   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23656   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23657 _(mpls_table_add_del,                                                   \
23658   "table-id <n>\n")                                                     \
23659 _(mpls_route_add_del,                                                   \
23660   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23661   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23662   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23663   "[multipath] [count <n>]")                                            \
23664 _(mpls_ip_bind_unbind,                                                  \
23665   "<label> <addr/len>")                                                 \
23666 _(mpls_tunnel_add_del,                                                  \
23667   " via <addr> [table-id <n>]\n"                                        \
23668   "sw_if_index <id>] [l2]  [del]")                                      \
23669 _(bier_table_add_del,                                                   \
23670   "<label> <sub-domain> <set> <bsl> [del]")                             \
23671 _(bier_route_add_del,                                                   \
23672   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23673   "[<intfc> | sw_if_index <id>]"                                        \
23674   "[weight <n>] [del] [multipath]")                                     \
23675 _(proxy_arp_add_del,                                                    \
23676   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23677 _(proxy_arp_intfc_enable_disable,                                       \
23678   "<intfc> | sw_if_index <id> enable | disable")                        \
23679 _(sw_interface_set_unnumbered,                                          \
23680   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23681 _(ip_neighbor_add_del,                                                  \
23682   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23683   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23684 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23685 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23686   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23687   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23688   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23689 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23690 _(reset_fib, "vrf <n> [ipv6]")                                          \
23691 _(dhcp_proxy_config,                                                    \
23692   "svr <v46-address> src <v46-address>\n"                               \
23693    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23694 _(dhcp_proxy_set_vss,                                                   \
23695   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23696 _(dhcp_proxy_dump, "ip6")                                               \
23697 _(dhcp_client_config,                                                   \
23698   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23699 _(set_ip_flow_hash,                                                     \
23700   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23701 _(sw_interface_ip6_enable_disable,                                      \
23702   "<intfc> | sw_if_index <id> enable | disable")                        \
23703 _(sw_interface_ip6_set_link_local_address,                              \
23704   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23705 _(ip6nd_proxy_add_del,                                                  \
23706   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23707 _(ip6nd_proxy_dump, "")                                                 \
23708 _(sw_interface_ip6nd_ra_prefix,                                         \
23709   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23710   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23711   "[nolink] [isno]")                                                    \
23712 _(sw_interface_ip6nd_ra_config,                                         \
23713   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23714   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23715   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23716 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23717 _(l2_patch_add_del,                                                     \
23718   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23719   "enable | disable")                                                   \
23720 _(sr_localsid_add_del,                                                  \
23721   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23722   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23723 _(classify_add_del_table,                                               \
23724   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23725   " [del] [del-chain] mask <mask-value>\n"                              \
23726   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23727   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23728 _(classify_add_del_session,                                             \
23729   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23730   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23731   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23732   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23733 _(classify_set_interface_ip_table,                                      \
23734   "<intfc> | sw_if_index <nn> table <nn>")                              \
23735 _(classify_set_interface_l2_tables,                                     \
23736   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23737   "  [other-table <nn>]")                                               \
23738 _(get_node_index, "node <node-name")                                    \
23739 _(add_node_next, "node <node-name> next <next-node-name>")              \
23740 _(l2tpv3_create_tunnel,                                                 \
23741   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23742   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23743   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23744 _(l2tpv3_set_tunnel_cookies,                                            \
23745   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23746   "[new_remote_cookie <nn>]\n")                                         \
23747 _(l2tpv3_interface_enable_disable,                                      \
23748   "<intfc> | sw_if_index <nn> enable | disable")                        \
23749 _(l2tpv3_set_lookup_key,                                                \
23750   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23751 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23752 _(vxlan_offload_rx,                                                     \
23753   "hw { <interface name> | hw_if_index <nn>} "                          \
23754   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23755 _(vxlan_add_del_tunnel,                                                 \
23756   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23757   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23758   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23759 _(geneve_add_del_tunnel,                                                \
23760   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23761   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23762   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23763 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23764 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23765 _(gre_add_del_tunnel,                                                   \
23766   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23767   "[teb | erspan <session-id>] [del]")                                  \
23768 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23769 _(l2_fib_clear_table, "")                                               \
23770 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23771 _(l2_interface_vlan_tag_rewrite,                                        \
23772   "<intfc> | sw_if_index <nn> \n"                                       \
23773   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23774   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23775 _(create_vhost_user_if,                                                 \
23776         "socket <filename> [server] [renumber <dev_instance>] "         \
23777         "[mac <mac_address>]")                                          \
23778 _(modify_vhost_user_if,                                                 \
23779         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23780         "[server] [renumber <dev_instance>]")                           \
23781 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23782 _(sw_interface_vhost_user_dump, "")                                     \
23783 _(show_version, "")                                                     \
23784 _(vxlan_gpe_add_del_tunnel,                                             \
23785   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23786   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23787   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23788   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23789 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23790 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23791 _(interface_name_renumber,                                              \
23792   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23793 _(input_acl_set_interface,                                              \
23794   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23795   "  [l2-table <nn>] [del]")                                            \
23796 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23797 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23798   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23799 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23800 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23801 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23802 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23803 _(ip_dump, "ipv4 | ipv6")                                               \
23804 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23805 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23806   "  spid_id <n> ")                                                     \
23807 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23808   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23809   "  integ_alg <alg> integ_key <hex>")                                  \
23810 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23811   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23812   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23813   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23814 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23815 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23816   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23817   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23818   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23819   "  [instance <n>]")     \
23820 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23821 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23822   "  <alg> <hex>\n")                                                    \
23823 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23824 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23825 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23826   "(auth_data 0x<data> | auth_data <data>)")                            \
23827 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23828   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23829 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23830   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23831   "(local|remote)")                                                     \
23832 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23833 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23834 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23835 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23836 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23837 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23838 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23839 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23840 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23841 _(delete_loopback,"sw_if_index <nn>")                                   \
23842 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23843 _(map_add_domain,                                                       \
23844   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23845   "ip6-src <ip6addr> "                                                  \
23846   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23847 _(map_del_domain, "index <n>")                                          \
23848 _(map_add_del_rule,                                                     \
23849   "index <n> psid <n> dst <ip6addr> [del]")                             \
23850 _(map_domain_dump, "")                                                  \
23851 _(map_rule_dump, "index <map-domain>")                                  \
23852 _(want_interface_events,  "enable|disable")                             \
23853 _(want_stats,"enable|disable")                                          \
23854 _(get_first_msg_id, "client <name>")                                    \
23855 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23856 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23857   "fib-id <nn> [ip4][ip6][default]")                                    \
23858 _(get_node_graph, " ")                                                  \
23859 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23860 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23861 _(ioam_disable, "")                                                     \
23862 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23863                             " sw_if_index <sw_if_index> p <priority> "  \
23864                             "w <weight>] [del]")                        \
23865 _(one_add_del_locator, "locator-set <locator_name> "                    \
23866                         "iface <intf> | sw_if_index <sw_if_index> "     \
23867                         "p <priority> w <weight> [del]")                \
23868 _(one_add_del_local_eid,"vni <vni> eid "                                \
23869                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23870                          "locator-set <locator_name> [del]"             \
23871                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23872 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23873 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23874 _(one_enable_disable, "enable|disable")                                 \
23875 _(one_map_register_enable_disable, "enable|disable")                    \
23876 _(one_map_register_fallback_threshold, "<value>")                       \
23877 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23878 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23879                                "[seid <seid>] "                         \
23880                                "rloc <locator> p <prio> "               \
23881                                "w <weight> [rloc <loc> ... ] "          \
23882                                "action <action> [del-all]")             \
23883 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23884                           "<local-eid>")                                \
23885 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23886 _(one_use_petr, "ip-address> | disable")                                \
23887 _(one_map_request_mode, "src-dst|dst-only")                             \
23888 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23889 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23890 _(one_locator_set_dump, "[local | remote]")                             \
23891 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23892 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23893                        "[local] | [remote]")                            \
23894 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23895 _(one_ndp_bd_get, "")                                                   \
23896 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23897 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23898 _(one_l2_arp_bd_get, "")                                                \
23899 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23900 _(one_stats_enable_disable, "enable|disalbe")                           \
23901 _(show_one_stats_enable_disable, "")                                    \
23902 _(one_eid_table_vni_dump, "")                                           \
23903 _(one_eid_table_map_dump, "l2|l3")                                      \
23904 _(one_map_resolver_dump, "")                                            \
23905 _(one_map_server_dump, "")                                              \
23906 _(one_adjacencies_get, "vni <vni>")                                     \
23907 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23908 _(show_one_rloc_probe_state, "")                                        \
23909 _(show_one_map_register_state, "")                                      \
23910 _(show_one_status, "")                                                  \
23911 _(one_stats_dump, "")                                                   \
23912 _(one_stats_flush, "")                                                  \
23913 _(one_get_map_request_itr_rlocs, "")                                    \
23914 _(one_map_register_set_ttl, "<ttl>")                                    \
23915 _(one_set_transport_protocol, "udp|api")                                \
23916 _(one_get_transport_protocol, "")                                       \
23917 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23918 _(one_show_xtr_mode, "")                                                \
23919 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23920 _(one_show_pitr_mode, "")                                               \
23921 _(one_enable_disable_petr_mode, "enable|disable")                       \
23922 _(one_show_petr_mode, "")                                               \
23923 _(show_one_nsh_mapping, "")                                             \
23924 _(show_one_pitr, "")                                                    \
23925 _(show_one_use_petr, "")                                                \
23926 _(show_one_map_request_mode, "")                                        \
23927 _(show_one_map_register_ttl, "")                                        \
23928 _(show_one_map_register_fallback_threshold, "")                         \
23929 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23930                             " sw_if_index <sw_if_index> p <priority> "  \
23931                             "w <weight>] [del]")                        \
23932 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23933                         "iface <intf> | sw_if_index <sw_if_index> "     \
23934                         "p <priority> w <weight> [del]")                \
23935 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23936                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23937                          "locator-set <locator_name> [del]"             \
23938                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23939 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23940 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23941 _(lisp_enable_disable, "enable|disable")                                \
23942 _(lisp_map_register_enable_disable, "enable|disable")                   \
23943 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23944 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23945                                "[seid <seid>] "                         \
23946                                "rloc <locator> p <prio> "               \
23947                                "w <weight> [rloc <loc> ... ] "          \
23948                                "action <action> [del-all]")             \
23949 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23950                           "<local-eid>")                                \
23951 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23952 _(lisp_use_petr, "<ip-address> | disable")                              \
23953 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23954 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23955 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23956 _(lisp_locator_set_dump, "[local | remote]")                            \
23957 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23958 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23959                        "[local] | [remote]")                            \
23960 _(lisp_eid_table_vni_dump, "")                                          \
23961 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23962 _(lisp_map_resolver_dump, "")                                           \
23963 _(lisp_map_server_dump, "")                                             \
23964 _(lisp_adjacencies_get, "vni <vni>")                                    \
23965 _(gpe_fwd_entry_vnis_get, "")                                           \
23966 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23967 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23968                                 "[table <table-id>]")                   \
23969 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23970 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23971 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23972 _(gpe_get_encap_mode, "")                                               \
23973 _(lisp_gpe_add_del_iface, "up|down")                                    \
23974 _(lisp_gpe_enable_disable, "enable|disable")                            \
23975 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23976   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23977 _(show_lisp_rloc_probe_state, "")                                       \
23978 _(show_lisp_map_register_state, "")                                     \
23979 _(show_lisp_status, "")                                                 \
23980 _(lisp_get_map_request_itr_rlocs, "")                                   \
23981 _(show_lisp_pitr, "")                                                   \
23982 _(show_lisp_use_petr, "")                                               \
23983 _(show_lisp_map_request_mode, "")                                       \
23984 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23985 _(af_packet_delete, "name <host interface name>")                       \
23986 _(af_packet_dump, "")                                                   \
23987 _(policer_add_del, "name <policer name> <params> [del]")                \
23988 _(policer_dump, "[name <policer name>]")                                \
23989 _(policer_classify_set_interface,                                       \
23990   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23991   "  [l2-table <nn>] [del]")                                            \
23992 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23993 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23994     "[master|slave]")                                                   \
23995 _(netmap_delete, "name <interface name>")                               \
23996 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23997 _(mpls_fib_dump, "")                                                    \
23998 _(classify_table_ids, "")                                               \
23999 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
24000 _(classify_table_info, "table_id <nn>")                                 \
24001 _(classify_session_dump, "table_id <nn>")                               \
24002 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24003     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24004     "[template_interval <nn>] [udp_checksum]")                          \
24005 _(ipfix_exporter_dump, "")                                              \
24006 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24007 _(ipfix_classify_stream_dump, "")                                       \
24008 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24009 _(ipfix_classify_table_dump, "")                                        \
24010 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24011 _(sw_interface_span_dump, "[l2]")                                           \
24012 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24013 _(pg_create_interface, "if_id <nn>")                                    \
24014 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24015 _(pg_enable_disable, "[stream <id>] disable")                           \
24016 _(ip_source_and_port_range_check_add_del,                               \
24017   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24018 _(ip_source_and_port_range_check_interface_add_del,                     \
24019   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24020   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24021 _(ipsec_gre_add_del_tunnel,                                             \
24022   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24023 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24024 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24025 _(l2_interface_pbb_tag_rewrite,                                         \
24026   "<intfc> | sw_if_index <nn> \n"                                       \
24027   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24028   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24029 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24030 _(flow_classify_set_interface,                                          \
24031   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24032 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24033 _(ip_fib_dump, "")                                                      \
24034 _(ip_mfib_dump, "")                                                     \
24035 _(ip6_fib_dump, "")                                                     \
24036 _(ip6_mfib_dump, "")                                                    \
24037 _(feature_enable_disable, "arc_name <arc_name> "                        \
24038   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24039 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24040 "[disable]")                                                            \
24041 _(l2_xconnect_dump, "")                                                 \
24042 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24043 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24044 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24045 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24046 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24047 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24048 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24049   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24050 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24051 _(sock_init_shm, "size <nnn>")                                          \
24052 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24053 _(dns_enable_disable, "[enable][disable]")                              \
24054 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24055 _(dns_resolve_name, "<hostname>")                                       \
24056 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24057 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24058 _(dns_resolve_name, "<hostname>")                                       \
24059 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24060   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24061 _(session_rules_dump, "")                                               \
24062 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24063 _(output_acl_set_interface,                                             \
24064   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24065   "  [l2-table <nn>] [del]")                                            \
24066 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]") \
24067 _(map_stats_segment, "<no-args>")
24068
24069 /* List of command functions, CLI names map directly to functions */
24070 #define foreach_cli_function                                    \
24071 _(comment, "usage: comment <ignore-rest-of-line>")              \
24072 _(dump_interface_table, "usage: dump_interface_table")          \
24073 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24074 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24075 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24076 _(dump_stats_table, "usage: dump_stats_table")                  \
24077 _(dump_macro_table, "usage: dump_macro_table ")                 \
24078 _(dump_node_table, "usage: dump_node_table")                    \
24079 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24080 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24081 _(echo, "usage: echo <message>")                                \
24082 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24083 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24084 _(help, "usage: help")                                          \
24085 _(q, "usage: quit")                                             \
24086 _(quit, "usage: quit")                                          \
24087 _(search_node_table, "usage: search_node_table <name>...")      \
24088 _(set, "usage: set <variable-name> <value>")                    \
24089 _(script, "usage: script <file-name>")                          \
24090 _(statseg, "usage: statseg");                                   \
24091 _(unset, "usage: unset <variable-name>")
24092
24093 #define _(N,n)                                  \
24094     static void vl_api_##n##_t_handler_uni      \
24095     (vl_api_##n##_t * mp)                       \
24096     {                                           \
24097         vat_main_t * vam = &vat_main;           \
24098         if (vam->json_output) {                 \
24099             vl_api_##n##_t_handler_json(mp);    \
24100         } else {                                \
24101             vl_api_##n##_t_handler(mp);         \
24102         }                                       \
24103     }
24104 foreach_vpe_api_reply_msg;
24105 #if VPP_API_TEST_BUILTIN == 0
24106 foreach_standalone_reply_msg;
24107 #endif
24108 #undef _
24109
24110 void
24111 vat_api_hookup (vat_main_t * vam)
24112 {
24113 #define _(N,n)                                                  \
24114     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24115                            vl_api_##n##_t_handler_uni,          \
24116                            vl_noop_handler,                     \
24117                            vl_api_##n##_t_endian,               \
24118                            vl_api_##n##_t_print,                \
24119                            sizeof(vl_api_##n##_t), 1);
24120   foreach_vpe_api_reply_msg;
24121 #if VPP_API_TEST_BUILTIN == 0
24122   foreach_standalone_reply_msg;
24123 #endif
24124 #undef _
24125
24126 #if (VPP_API_TEST_BUILTIN==0)
24127   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24128
24129   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24130
24131   vam->function_by_name = hash_create_string (0, sizeof (uword));
24132
24133   vam->help_by_name = hash_create_string (0, sizeof (uword));
24134 #endif
24135
24136   /* API messages we can send */
24137 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24138   foreach_vpe_api_msg;
24139 #undef _
24140
24141   /* Help strings */
24142 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24143   foreach_vpe_api_msg;
24144 #undef _
24145
24146   /* CLI functions */
24147 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24148   foreach_cli_function;
24149 #undef _
24150
24151   /* Help strings */
24152 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24153   foreach_cli_function;
24154 #undef _
24155 }
24156
24157 #if VPP_API_TEST_BUILTIN
24158 static clib_error_t *
24159 vat_api_hookup_shim (vlib_main_t * vm)
24160 {
24161   vat_api_hookup (&vat_main);
24162   return 0;
24163 }
24164
24165 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24166 #endif
24167
24168 /*
24169  * fd.io coding-style-patch-verification: ON
24170  *
24171  * Local Variables:
24172  * eval: (c-set-style "gnu")
24173  * End:
24174  */