Fixed bugs in SRv6 API
[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
5935 #define foreach_standalone_reply_msg                                    \
5936 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5937 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5938 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5939 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5940 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5941 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5942 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5943
5944 typedef struct
5945 {
5946   u8 *name;
5947   u32 value;
5948 } name_sort_t;
5949
5950 #define STR_VTR_OP_CASE(op)     \
5951     case L2_VTR_ ## op:         \
5952         return "" # op;
5953
5954 static const char *
5955 str_vtr_op (u32 vtr_op)
5956 {
5957   switch (vtr_op)
5958     {
5959       STR_VTR_OP_CASE (DISABLED);
5960       STR_VTR_OP_CASE (PUSH_1);
5961       STR_VTR_OP_CASE (PUSH_2);
5962       STR_VTR_OP_CASE (POP_1);
5963       STR_VTR_OP_CASE (POP_2);
5964       STR_VTR_OP_CASE (TRANSLATE_1_1);
5965       STR_VTR_OP_CASE (TRANSLATE_1_2);
5966       STR_VTR_OP_CASE (TRANSLATE_2_1);
5967       STR_VTR_OP_CASE (TRANSLATE_2_2);
5968     }
5969
5970   return "UNKNOWN";
5971 }
5972
5973 static int
5974 dump_sub_interface_table (vat_main_t * vam)
5975 {
5976   const sw_interface_subif_t *sub = NULL;
5977
5978   if (vam->json_output)
5979     {
5980       clib_warning
5981         ("JSON output supported only for VPE API calls and dump_stats_table");
5982       return -99;
5983     }
5984
5985   print (vam->ofp,
5986          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5987          "Interface", "sw_if_index",
5988          "sub id", "dot1ad", "tags", "outer id",
5989          "inner id", "exact", "default", "outer any", "inner any");
5990
5991   vec_foreach (sub, vam->sw_if_subif_table)
5992   {
5993     print (vam->ofp,
5994            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5995            sub->interface_name,
5996            sub->sw_if_index,
5997            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5998            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5999            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
6000            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
6001     if (sub->vtr_op != L2_VTR_DISABLED)
6002       {
6003         print (vam->ofp,
6004                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
6005                "tag1: %d tag2: %d ]",
6006                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
6007                sub->vtr_tag1, sub->vtr_tag2);
6008       }
6009   }
6010
6011   return 0;
6012 }
6013
6014 static int
6015 name_sort_cmp (void *a1, void *a2)
6016 {
6017   name_sort_t *n1 = a1;
6018   name_sort_t *n2 = a2;
6019
6020   return strcmp ((char *) n1->name, (char *) n2->name);
6021 }
6022
6023 static int
6024 dump_interface_table (vat_main_t * vam)
6025 {
6026   hash_pair_t *p;
6027   name_sort_t *nses = 0, *ns;
6028
6029   if (vam->json_output)
6030     {
6031       clib_warning
6032         ("JSON output supported only for VPE API calls and dump_stats_table");
6033       return -99;
6034     }
6035
6036   /* *INDENT-OFF* */
6037   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6038   ({
6039     vec_add2 (nses, ns, 1);
6040     ns->name = (u8 *)(p->key);
6041     ns->value = (u32) p->value[0];
6042   }));
6043   /* *INDENT-ON* */
6044
6045   vec_sort_with_function (nses, name_sort_cmp);
6046
6047   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6048   vec_foreach (ns, nses)
6049   {
6050     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6051   }
6052   vec_free (nses);
6053   return 0;
6054 }
6055
6056 static int
6057 dump_ip_table (vat_main_t * vam, int is_ipv6)
6058 {
6059   const ip_details_t *det = NULL;
6060   const ip_address_details_t *address = NULL;
6061   u32 i = ~0;
6062
6063   print (vam->ofp, "%-12s", "sw_if_index");
6064
6065   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6066   {
6067     i++;
6068     if (!det->present)
6069       {
6070         continue;
6071       }
6072     print (vam->ofp, "%-12d", i);
6073     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6074     if (!det->addr)
6075       {
6076         continue;
6077       }
6078     vec_foreach (address, det->addr)
6079     {
6080       print (vam->ofp,
6081              "            %-30U%-13d",
6082              is_ipv6 ? format_ip6_address : format_ip4_address,
6083              address->ip, address->prefix_length);
6084     }
6085   }
6086
6087   return 0;
6088 }
6089
6090 static int
6091 dump_ipv4_table (vat_main_t * vam)
6092 {
6093   if (vam->json_output)
6094     {
6095       clib_warning
6096         ("JSON output supported only for VPE API calls and dump_stats_table");
6097       return -99;
6098     }
6099
6100   return dump_ip_table (vam, 0);
6101 }
6102
6103 static int
6104 dump_ipv6_table (vat_main_t * vam)
6105 {
6106   if (vam->json_output)
6107     {
6108       clib_warning
6109         ("JSON output supported only for VPE API calls and dump_stats_table");
6110       return -99;
6111     }
6112
6113   return dump_ip_table (vam, 1);
6114 }
6115
6116 static char *
6117 counter_type_to_str (u8 counter_type, u8 is_combined)
6118 {
6119   if (!is_combined)
6120     {
6121       switch (counter_type)
6122         {
6123         case VNET_INTERFACE_COUNTER_DROP:
6124           return "drop";
6125         case VNET_INTERFACE_COUNTER_PUNT:
6126           return "punt";
6127         case VNET_INTERFACE_COUNTER_IP4:
6128           return "ip4";
6129         case VNET_INTERFACE_COUNTER_IP6:
6130           return "ip6";
6131         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6132           return "rx-no-buf";
6133         case VNET_INTERFACE_COUNTER_RX_MISS:
6134           return "rx-miss";
6135         case VNET_INTERFACE_COUNTER_RX_ERROR:
6136           return "rx-error";
6137         case VNET_INTERFACE_COUNTER_TX_ERROR:
6138           return "tx-error";
6139         default:
6140           return "INVALID-COUNTER-TYPE";
6141         }
6142     }
6143   else
6144     {
6145       switch (counter_type)
6146         {
6147         case VNET_INTERFACE_COUNTER_RX:
6148           return "rx";
6149         case VNET_INTERFACE_COUNTER_TX:
6150           return "tx";
6151         default:
6152           return "INVALID-COUNTER-TYPE";
6153         }
6154     }
6155 }
6156
6157 static int
6158 dump_stats_table (vat_main_t * vam)
6159 {
6160   vat_json_node_t node;
6161   vat_json_node_t *msg_array;
6162   vat_json_node_t *msg;
6163   vat_json_node_t *counter_array;
6164   vat_json_node_t *counter;
6165   interface_counter_t c;
6166   u64 packets;
6167   ip4_fib_counter_t *c4;
6168   ip6_fib_counter_t *c6;
6169   ip4_nbr_counter_t *n4;
6170   ip6_nbr_counter_t *n6;
6171   int i, j;
6172
6173   if (!vam->json_output)
6174     {
6175       clib_warning ("dump_stats_table supported only in JSON format");
6176       return -99;
6177     }
6178
6179   vat_json_init_object (&node);
6180
6181   /* interface counters */
6182   msg_array = vat_json_object_add (&node, "interface_counters");
6183   vat_json_init_array (msg_array);
6184   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6185     {
6186       msg = vat_json_array_add (msg_array);
6187       vat_json_init_object (msg);
6188       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6189                                        (u8 *) counter_type_to_str (i, 0));
6190       vat_json_object_add_int (msg, "is_combined", 0);
6191       counter_array = vat_json_object_add (msg, "data");
6192       vat_json_init_array (counter_array);
6193       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6194         {
6195           packets = vam->simple_interface_counters[i][j];
6196           vat_json_array_add_uint (counter_array, packets);
6197         }
6198     }
6199   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6200     {
6201       msg = vat_json_array_add (msg_array);
6202       vat_json_init_object (msg);
6203       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6204                                        (u8 *) counter_type_to_str (i, 1));
6205       vat_json_object_add_int (msg, "is_combined", 1);
6206       counter_array = vat_json_object_add (msg, "data");
6207       vat_json_init_array (counter_array);
6208       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6209         {
6210           c = vam->combined_interface_counters[i][j];
6211           counter = vat_json_array_add (counter_array);
6212           vat_json_init_object (counter);
6213           vat_json_object_add_uint (counter, "packets", c.packets);
6214           vat_json_object_add_uint (counter, "bytes", c.bytes);
6215         }
6216     }
6217
6218   /* ip4 fib counters */
6219   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6220   vat_json_init_array (msg_array);
6221   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6222     {
6223       msg = vat_json_array_add (msg_array);
6224       vat_json_init_object (msg);
6225       vat_json_object_add_uint (msg, "vrf_id",
6226                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6227       counter_array = vat_json_object_add (msg, "c");
6228       vat_json_init_array (counter_array);
6229       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6230         {
6231           counter = vat_json_array_add (counter_array);
6232           vat_json_init_object (counter);
6233           c4 = &vam->ip4_fib_counters[i][j];
6234           vat_json_object_add_ip4 (counter, "address", c4->address);
6235           vat_json_object_add_uint (counter, "address_length",
6236                                     c4->address_length);
6237           vat_json_object_add_uint (counter, "packets", c4->packets);
6238           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6239         }
6240     }
6241
6242   /* ip6 fib counters */
6243   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6244   vat_json_init_array (msg_array);
6245   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6246     {
6247       msg = vat_json_array_add (msg_array);
6248       vat_json_init_object (msg);
6249       vat_json_object_add_uint (msg, "vrf_id",
6250                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6251       counter_array = vat_json_object_add (msg, "c");
6252       vat_json_init_array (counter_array);
6253       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6254         {
6255           counter = vat_json_array_add (counter_array);
6256           vat_json_init_object (counter);
6257           c6 = &vam->ip6_fib_counters[i][j];
6258           vat_json_object_add_ip6 (counter, "address", c6->address);
6259           vat_json_object_add_uint (counter, "address_length",
6260                                     c6->address_length);
6261           vat_json_object_add_uint (counter, "packets", c6->packets);
6262           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6263         }
6264     }
6265
6266   /* ip4 nbr counters */
6267   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6268   vat_json_init_array (msg_array);
6269   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6270     {
6271       msg = vat_json_array_add (msg_array);
6272       vat_json_init_object (msg);
6273       vat_json_object_add_uint (msg, "sw_if_index", i);
6274       counter_array = vat_json_object_add (msg, "c");
6275       vat_json_init_array (counter_array);
6276       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6277         {
6278           counter = vat_json_array_add (counter_array);
6279           vat_json_init_object (counter);
6280           n4 = &vam->ip4_nbr_counters[i][j];
6281           vat_json_object_add_ip4 (counter, "address", n4->address);
6282           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6283           vat_json_object_add_uint (counter, "packets", n4->packets);
6284           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6285         }
6286     }
6287
6288   /* ip6 nbr counters */
6289   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6290   vat_json_init_array (msg_array);
6291   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6292     {
6293       msg = vat_json_array_add (msg_array);
6294       vat_json_init_object (msg);
6295       vat_json_object_add_uint (msg, "sw_if_index", i);
6296       counter_array = vat_json_object_add (msg, "c");
6297       vat_json_init_array (counter_array);
6298       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6299         {
6300           counter = vat_json_array_add (counter_array);
6301           vat_json_init_object (counter);
6302           n6 = &vam->ip6_nbr_counters[i][j];
6303           vat_json_object_add_ip6 (counter, "address", n6->address);
6304           vat_json_object_add_uint (counter, "packets", n6->packets);
6305           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6306         }
6307     }
6308
6309   vat_json_print (vam->ofp, &node);
6310   vat_json_free (&node);
6311
6312   return 0;
6313 }
6314
6315 /*
6316  * Pass CLI buffers directly in the CLI_INBAND API message,
6317  * instead of an additional shared memory area.
6318  */
6319 static int
6320 exec_inband (vat_main_t * vam)
6321 {
6322   vl_api_cli_inband_t *mp;
6323   unformat_input_t *i = vam->input;
6324   int ret;
6325
6326   if (vec_len (i->buffer) == 0)
6327     return -1;
6328
6329   if (vam->exec_mode == 0 && unformat (i, "mode"))
6330     {
6331       vam->exec_mode = 1;
6332       return 0;
6333     }
6334   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6335     {
6336       vam->exec_mode = 0;
6337       return 0;
6338     }
6339
6340   /*
6341    * In order for the CLI command to work, it
6342    * must be a vector ending in \n, not a C-string ending
6343    * in \n\0.
6344    */
6345   u32 len = vec_len (vam->input->buffer);
6346   M2 (CLI_INBAND, mp, len);
6347   clib_memcpy (mp->cmd, vam->input->buffer, len);
6348   mp->length = htonl (len);
6349
6350   S (mp);
6351   W (ret);
6352   /* json responses may or may not include a useful reply... */
6353   if (vec_len (vam->cmd_reply))
6354     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6355   return ret;
6356 }
6357
6358 int
6359 exec (vat_main_t * vam)
6360 {
6361   return exec_inband (vam);
6362 }
6363
6364 static int
6365 api_create_loopback (vat_main_t * vam)
6366 {
6367   unformat_input_t *i = vam->input;
6368   vl_api_create_loopback_t *mp;
6369   vl_api_create_loopback_instance_t *mp_lbi;
6370   u8 mac_address[6];
6371   u8 mac_set = 0;
6372   u8 is_specified = 0;
6373   u32 user_instance = 0;
6374   int ret;
6375
6376   memset (mac_address, 0, sizeof (mac_address));
6377
6378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6379     {
6380       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6381         mac_set = 1;
6382       if (unformat (i, "instance %d", &user_instance))
6383         is_specified = 1;
6384       else
6385         break;
6386     }
6387
6388   if (is_specified)
6389     {
6390       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6391       mp_lbi->is_specified = is_specified;
6392       if (is_specified)
6393         mp_lbi->user_instance = htonl (user_instance);
6394       if (mac_set)
6395         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6396       S (mp_lbi);
6397     }
6398   else
6399     {
6400       /* Construct the API message */
6401       M (CREATE_LOOPBACK, mp);
6402       if (mac_set)
6403         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6404       S (mp);
6405     }
6406
6407   W (ret);
6408   return ret;
6409 }
6410
6411 static int
6412 api_delete_loopback (vat_main_t * vam)
6413 {
6414   unformat_input_t *i = vam->input;
6415   vl_api_delete_loopback_t *mp;
6416   u32 sw_if_index = ~0;
6417   int ret;
6418
6419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6420     {
6421       if (unformat (i, "sw_if_index %d", &sw_if_index))
6422         ;
6423       else
6424         break;
6425     }
6426
6427   if (sw_if_index == ~0)
6428     {
6429       errmsg ("missing sw_if_index");
6430       return -99;
6431     }
6432
6433   /* Construct the API message */
6434   M (DELETE_LOOPBACK, mp);
6435   mp->sw_if_index = ntohl (sw_if_index);
6436
6437   S (mp);
6438   W (ret);
6439   return ret;
6440 }
6441
6442 static int
6443 api_want_stats (vat_main_t * vam)
6444 {
6445   unformat_input_t *i = vam->input;
6446   vl_api_want_stats_t *mp;
6447   int enable = -1;
6448   int ret;
6449
6450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6451     {
6452       if (unformat (i, "enable"))
6453         enable = 1;
6454       else if (unformat (i, "disable"))
6455         enable = 0;
6456       else
6457         break;
6458     }
6459
6460   if (enable == -1)
6461     {
6462       errmsg ("missing enable|disable");
6463       return -99;
6464     }
6465
6466   M (WANT_STATS, mp);
6467   mp->enable_disable = enable;
6468
6469   S (mp);
6470   W (ret);
6471   return ret;
6472 }
6473
6474 static int
6475 api_want_interface_events (vat_main_t * vam)
6476 {
6477   unformat_input_t *i = vam->input;
6478   vl_api_want_interface_events_t *mp;
6479   int enable = -1;
6480   int ret;
6481
6482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6483     {
6484       if (unformat (i, "enable"))
6485         enable = 1;
6486       else if (unformat (i, "disable"))
6487         enable = 0;
6488       else
6489         break;
6490     }
6491
6492   if (enable == -1)
6493     {
6494       errmsg ("missing enable|disable");
6495       return -99;
6496     }
6497
6498   M (WANT_INTERFACE_EVENTS, mp);
6499   mp->enable_disable = enable;
6500
6501   vam->interface_event_display = enable;
6502
6503   S (mp);
6504   W (ret);
6505   return ret;
6506 }
6507
6508
6509 /* Note: non-static, called once to set up the initial intfc table */
6510 int
6511 api_sw_interface_dump (vat_main_t * vam)
6512 {
6513   vl_api_sw_interface_dump_t *mp;
6514   vl_api_control_ping_t *mp_ping;
6515   hash_pair_t *p;
6516   name_sort_t *nses = 0, *ns;
6517   sw_interface_subif_t *sub = NULL;
6518   int ret;
6519
6520   /* Toss the old name table */
6521   /* *INDENT-OFF* */
6522   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6523   ({
6524     vec_add2 (nses, ns, 1);
6525     ns->name = (u8 *)(p->key);
6526     ns->value = (u32) p->value[0];
6527   }));
6528   /* *INDENT-ON* */
6529
6530   hash_free (vam->sw_if_index_by_interface_name);
6531
6532   vec_foreach (ns, nses) vec_free (ns->name);
6533
6534   vec_free (nses);
6535
6536   vec_foreach (sub, vam->sw_if_subif_table)
6537   {
6538     vec_free (sub->interface_name);
6539   }
6540   vec_free (vam->sw_if_subif_table);
6541
6542   /* recreate the interface name hash table */
6543   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6544
6545   /*
6546    * Ask for all interface names. Otherwise, the epic catalog of
6547    * name filters becomes ridiculously long, and vat ends up needing
6548    * to be taught about new interface types.
6549    */
6550   M (SW_INTERFACE_DUMP, mp);
6551   S (mp);
6552
6553   /* Use a control ping for synchronization */
6554   MPING (CONTROL_PING, mp_ping);
6555   S (mp_ping);
6556
6557   W (ret);
6558   return ret;
6559 }
6560
6561 static int
6562 api_sw_interface_set_flags (vat_main_t * vam)
6563 {
6564   unformat_input_t *i = vam->input;
6565   vl_api_sw_interface_set_flags_t *mp;
6566   u32 sw_if_index;
6567   u8 sw_if_index_set = 0;
6568   u8 admin_up = 0;
6569   int ret;
6570
6571   /* Parse args required to build the message */
6572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6573     {
6574       if (unformat (i, "admin-up"))
6575         admin_up = 1;
6576       else if (unformat (i, "admin-down"))
6577         admin_up = 0;
6578       else
6579         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6580         sw_if_index_set = 1;
6581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6582         sw_if_index_set = 1;
6583       else
6584         break;
6585     }
6586
6587   if (sw_if_index_set == 0)
6588     {
6589       errmsg ("missing interface name or sw_if_index");
6590       return -99;
6591     }
6592
6593   /* Construct the API message */
6594   M (SW_INTERFACE_SET_FLAGS, mp);
6595   mp->sw_if_index = ntohl (sw_if_index);
6596   mp->admin_up_down = admin_up;
6597
6598   /* send it... */
6599   S (mp);
6600
6601   /* Wait for a reply, return the good/bad news... */
6602   W (ret);
6603   return ret;
6604 }
6605
6606 static int
6607 api_sw_interface_set_rx_mode (vat_main_t * vam)
6608 {
6609   unformat_input_t *i = vam->input;
6610   vl_api_sw_interface_set_rx_mode_t *mp;
6611   u32 sw_if_index;
6612   u8 sw_if_index_set = 0;
6613   int ret;
6614   u8 queue_id_valid = 0;
6615   u32 queue_id;
6616   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6617
6618   /* Parse args required to build the message */
6619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6620     {
6621       if (unformat (i, "queue %d", &queue_id))
6622         queue_id_valid = 1;
6623       else if (unformat (i, "polling"))
6624         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6625       else if (unformat (i, "interrupt"))
6626         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6627       else if (unformat (i, "adaptive"))
6628         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6629       else
6630         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6631         sw_if_index_set = 1;
6632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6633         sw_if_index_set = 1;
6634       else
6635         break;
6636     }
6637
6638   if (sw_if_index_set == 0)
6639     {
6640       errmsg ("missing interface name or sw_if_index");
6641       return -99;
6642     }
6643   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6644     {
6645       errmsg ("missing rx-mode");
6646       return -99;
6647     }
6648
6649   /* Construct the API message */
6650   M (SW_INTERFACE_SET_RX_MODE, mp);
6651   mp->sw_if_index = ntohl (sw_if_index);
6652   mp->mode = mode;
6653   mp->queue_id_valid = queue_id_valid;
6654   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6655
6656   /* send it... */
6657   S (mp);
6658
6659   /* Wait for a reply, return the good/bad news... */
6660   W (ret);
6661   return ret;
6662 }
6663
6664 static int
6665 api_sw_interface_clear_stats (vat_main_t * vam)
6666 {
6667   unformat_input_t *i = vam->input;
6668   vl_api_sw_interface_clear_stats_t *mp;
6669   u32 sw_if_index;
6670   u8 sw_if_index_set = 0;
6671   int ret;
6672
6673   /* Parse args required to build the message */
6674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6675     {
6676       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6677         sw_if_index_set = 1;
6678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6679         sw_if_index_set = 1;
6680       else
6681         break;
6682     }
6683
6684   /* Construct the API message */
6685   M (SW_INTERFACE_CLEAR_STATS, mp);
6686
6687   if (sw_if_index_set == 1)
6688     mp->sw_if_index = ntohl (sw_if_index);
6689   else
6690     mp->sw_if_index = ~0;
6691
6692   /* send it... */
6693   S (mp);
6694
6695   /* Wait for a reply, return the good/bad news... */
6696   W (ret);
6697   return ret;
6698 }
6699
6700 static int
6701 api_sw_interface_add_del_address (vat_main_t * vam)
6702 {
6703   unformat_input_t *i = vam->input;
6704   vl_api_sw_interface_add_del_address_t *mp;
6705   u32 sw_if_index;
6706   u8 sw_if_index_set = 0;
6707   u8 is_add = 1, del_all = 0;
6708   u32 address_length = 0;
6709   u8 v4_address_set = 0;
6710   u8 v6_address_set = 0;
6711   ip4_address_t v4address;
6712   ip6_address_t v6address;
6713   int ret;
6714
6715   /* Parse args required to build the message */
6716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6717     {
6718       if (unformat (i, "del-all"))
6719         del_all = 1;
6720       else if (unformat (i, "del"))
6721         is_add = 0;
6722       else
6723         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6724         sw_if_index_set = 1;
6725       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6726         sw_if_index_set = 1;
6727       else if (unformat (i, "%U/%d",
6728                          unformat_ip4_address, &v4address, &address_length))
6729         v4_address_set = 1;
6730       else if (unformat (i, "%U/%d",
6731                          unformat_ip6_address, &v6address, &address_length))
6732         v6_address_set = 1;
6733       else
6734         break;
6735     }
6736
6737   if (sw_if_index_set == 0)
6738     {
6739       errmsg ("missing interface name or sw_if_index");
6740       return -99;
6741     }
6742   if (v4_address_set && v6_address_set)
6743     {
6744       errmsg ("both v4 and v6 addresses set");
6745       return -99;
6746     }
6747   if (!v4_address_set && !v6_address_set && !del_all)
6748     {
6749       errmsg ("no addresses set");
6750       return -99;
6751     }
6752
6753   /* Construct the API message */
6754   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6755
6756   mp->sw_if_index = ntohl (sw_if_index);
6757   mp->is_add = is_add;
6758   mp->del_all = del_all;
6759   if (v6_address_set)
6760     {
6761       mp->is_ipv6 = 1;
6762       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6763     }
6764   else
6765     {
6766       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6767     }
6768   mp->address_length = address_length;
6769
6770   /* send it... */
6771   S (mp);
6772
6773   /* Wait for a reply, return good/bad news  */
6774   W (ret);
6775   return ret;
6776 }
6777
6778 static int
6779 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6780 {
6781   unformat_input_t *i = vam->input;
6782   vl_api_sw_interface_set_mpls_enable_t *mp;
6783   u32 sw_if_index;
6784   u8 sw_if_index_set = 0;
6785   u8 enable = 1;
6786   int ret;
6787
6788   /* Parse args required to build the message */
6789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6790     {
6791       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6792         sw_if_index_set = 1;
6793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6794         sw_if_index_set = 1;
6795       else if (unformat (i, "disable"))
6796         enable = 0;
6797       else if (unformat (i, "dis"))
6798         enable = 0;
6799       else
6800         break;
6801     }
6802
6803   if (sw_if_index_set == 0)
6804     {
6805       errmsg ("missing interface name or sw_if_index");
6806       return -99;
6807     }
6808
6809   /* Construct the API message */
6810   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6811
6812   mp->sw_if_index = ntohl (sw_if_index);
6813   mp->enable = enable;
6814
6815   /* send it... */
6816   S (mp);
6817
6818   /* Wait for a reply... */
6819   W (ret);
6820   return ret;
6821 }
6822
6823 static int
6824 api_sw_interface_set_table (vat_main_t * vam)
6825 {
6826   unformat_input_t *i = vam->input;
6827   vl_api_sw_interface_set_table_t *mp;
6828   u32 sw_if_index, vrf_id = 0;
6829   u8 sw_if_index_set = 0;
6830   u8 is_ipv6 = 0;
6831   int ret;
6832
6833   /* Parse args required to build the message */
6834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6835     {
6836       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6837         sw_if_index_set = 1;
6838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6839         sw_if_index_set = 1;
6840       else if (unformat (i, "vrf %d", &vrf_id))
6841         ;
6842       else if (unformat (i, "ipv6"))
6843         is_ipv6 = 1;
6844       else
6845         break;
6846     }
6847
6848   if (sw_if_index_set == 0)
6849     {
6850       errmsg ("missing interface name or sw_if_index");
6851       return -99;
6852     }
6853
6854   /* Construct the API message */
6855   M (SW_INTERFACE_SET_TABLE, mp);
6856
6857   mp->sw_if_index = ntohl (sw_if_index);
6858   mp->is_ipv6 = is_ipv6;
6859   mp->vrf_id = ntohl (vrf_id);
6860
6861   /* send it... */
6862   S (mp);
6863
6864   /* Wait for a reply... */
6865   W (ret);
6866   return ret;
6867 }
6868
6869 static void vl_api_sw_interface_get_table_reply_t_handler
6870   (vl_api_sw_interface_get_table_reply_t * mp)
6871 {
6872   vat_main_t *vam = &vat_main;
6873
6874   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6875
6876   vam->retval = ntohl (mp->retval);
6877   vam->result_ready = 1;
6878
6879 }
6880
6881 static void vl_api_sw_interface_get_table_reply_t_handler_json
6882   (vl_api_sw_interface_get_table_reply_t * mp)
6883 {
6884   vat_main_t *vam = &vat_main;
6885   vat_json_node_t node;
6886
6887   vat_json_init_object (&node);
6888   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6889   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6890
6891   vat_json_print (vam->ofp, &node);
6892   vat_json_free (&node);
6893
6894   vam->retval = ntohl (mp->retval);
6895   vam->result_ready = 1;
6896 }
6897
6898 static int
6899 api_sw_interface_get_table (vat_main_t * vam)
6900 {
6901   unformat_input_t *i = vam->input;
6902   vl_api_sw_interface_get_table_t *mp;
6903   u32 sw_if_index;
6904   u8 sw_if_index_set = 0;
6905   u8 is_ipv6 = 0;
6906   int ret;
6907
6908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909     {
6910       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6911         sw_if_index_set = 1;
6912       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6913         sw_if_index_set = 1;
6914       else if (unformat (i, "ipv6"))
6915         is_ipv6 = 1;
6916       else
6917         break;
6918     }
6919
6920   if (sw_if_index_set == 0)
6921     {
6922       errmsg ("missing interface name or sw_if_index");
6923       return -99;
6924     }
6925
6926   M (SW_INTERFACE_GET_TABLE, mp);
6927   mp->sw_if_index = htonl (sw_if_index);
6928   mp->is_ipv6 = is_ipv6;
6929
6930   S (mp);
6931   W (ret);
6932   return ret;
6933 }
6934
6935 static int
6936 api_sw_interface_set_vpath (vat_main_t * vam)
6937 {
6938   unformat_input_t *i = vam->input;
6939   vl_api_sw_interface_set_vpath_t *mp;
6940   u32 sw_if_index = 0;
6941   u8 sw_if_index_set = 0;
6942   u8 is_enable = 0;
6943   int ret;
6944
6945   /* Parse args required to build the message */
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6949         sw_if_index_set = 1;
6950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6951         sw_if_index_set = 1;
6952       else if (unformat (i, "enable"))
6953         is_enable = 1;
6954       else if (unformat (i, "disable"))
6955         is_enable = 0;
6956       else
6957         break;
6958     }
6959
6960   if (sw_if_index_set == 0)
6961     {
6962       errmsg ("missing interface name or sw_if_index");
6963       return -99;
6964     }
6965
6966   /* Construct the API message */
6967   M (SW_INTERFACE_SET_VPATH, mp);
6968
6969   mp->sw_if_index = ntohl (sw_if_index);
6970   mp->enable = is_enable;
6971
6972   /* send it... */
6973   S (mp);
6974
6975   /* Wait for a reply... */
6976   W (ret);
6977   return ret;
6978 }
6979
6980 static int
6981 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6982 {
6983   unformat_input_t *i = vam->input;
6984   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6985   u32 sw_if_index = 0;
6986   u8 sw_if_index_set = 0;
6987   u8 is_enable = 1;
6988   u8 is_ipv6 = 0;
6989   int ret;
6990
6991   /* Parse args required to build the message */
6992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6993     {
6994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6995         sw_if_index_set = 1;
6996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6997         sw_if_index_set = 1;
6998       else if (unformat (i, "enable"))
6999         is_enable = 1;
7000       else if (unformat (i, "disable"))
7001         is_enable = 0;
7002       else if (unformat (i, "ip4"))
7003         is_ipv6 = 0;
7004       else if (unformat (i, "ip6"))
7005         is_ipv6 = 1;
7006       else
7007         break;
7008     }
7009
7010   if (sw_if_index_set == 0)
7011     {
7012       errmsg ("missing interface name or sw_if_index");
7013       return -99;
7014     }
7015
7016   /* Construct the API message */
7017   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7018
7019   mp->sw_if_index = ntohl (sw_if_index);
7020   mp->enable = is_enable;
7021   mp->is_ipv6 = is_ipv6;
7022
7023   /* send it... */
7024   S (mp);
7025
7026   /* Wait for a reply... */
7027   W (ret);
7028   return ret;
7029 }
7030
7031 static int
7032 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7033 {
7034   unformat_input_t *i = vam->input;
7035   vl_api_sw_interface_set_geneve_bypass_t *mp;
7036   u32 sw_if_index = 0;
7037   u8 sw_if_index_set = 0;
7038   u8 is_enable = 1;
7039   u8 is_ipv6 = 0;
7040   int ret;
7041
7042   /* Parse args required to build the message */
7043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7044     {
7045       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7046         sw_if_index_set = 1;
7047       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7048         sw_if_index_set = 1;
7049       else if (unformat (i, "enable"))
7050         is_enable = 1;
7051       else if (unformat (i, "disable"))
7052         is_enable = 0;
7053       else if (unformat (i, "ip4"))
7054         is_ipv6 = 0;
7055       else if (unformat (i, "ip6"))
7056         is_ipv6 = 1;
7057       else
7058         break;
7059     }
7060
7061   if (sw_if_index_set == 0)
7062     {
7063       errmsg ("missing interface name or sw_if_index");
7064       return -99;
7065     }
7066
7067   /* Construct the API message */
7068   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7069
7070   mp->sw_if_index = ntohl (sw_if_index);
7071   mp->enable = is_enable;
7072   mp->is_ipv6 = is_ipv6;
7073
7074   /* send it... */
7075   S (mp);
7076
7077   /* Wait for a reply... */
7078   W (ret);
7079   return ret;
7080 }
7081
7082 static int
7083 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7084 {
7085   unformat_input_t *i = vam->input;
7086   vl_api_sw_interface_set_l2_xconnect_t *mp;
7087   u32 rx_sw_if_index;
7088   u8 rx_sw_if_index_set = 0;
7089   u32 tx_sw_if_index;
7090   u8 tx_sw_if_index_set = 0;
7091   u8 enable = 1;
7092   int ret;
7093
7094   /* Parse args required to build the message */
7095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7096     {
7097       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7098         rx_sw_if_index_set = 1;
7099       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7100         tx_sw_if_index_set = 1;
7101       else if (unformat (i, "rx"))
7102         {
7103           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7104             {
7105               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7106                             &rx_sw_if_index))
7107                 rx_sw_if_index_set = 1;
7108             }
7109           else
7110             break;
7111         }
7112       else if (unformat (i, "tx"))
7113         {
7114           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7115             {
7116               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7117                             &tx_sw_if_index))
7118                 tx_sw_if_index_set = 1;
7119             }
7120           else
7121             break;
7122         }
7123       else if (unformat (i, "enable"))
7124         enable = 1;
7125       else if (unformat (i, "disable"))
7126         enable = 0;
7127       else
7128         break;
7129     }
7130
7131   if (rx_sw_if_index_set == 0)
7132     {
7133       errmsg ("missing rx interface name or rx_sw_if_index");
7134       return -99;
7135     }
7136
7137   if (enable && (tx_sw_if_index_set == 0))
7138     {
7139       errmsg ("missing tx interface name or tx_sw_if_index");
7140       return -99;
7141     }
7142
7143   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7144
7145   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7146   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7147   mp->enable = enable;
7148
7149   S (mp);
7150   W (ret);
7151   return ret;
7152 }
7153
7154 static int
7155 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7156 {
7157   unformat_input_t *i = vam->input;
7158   vl_api_sw_interface_set_l2_bridge_t *mp;
7159   u32 rx_sw_if_index;
7160   u8 rx_sw_if_index_set = 0;
7161   u32 bd_id;
7162   u8 bd_id_set = 0;
7163   u8 bvi = 0;
7164   u32 shg = 0;
7165   u8 enable = 1;
7166   int ret;
7167
7168   /* Parse args required to build the message */
7169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7170     {
7171       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7172         rx_sw_if_index_set = 1;
7173       else if (unformat (i, "bd_id %d", &bd_id))
7174         bd_id_set = 1;
7175       else
7176         if (unformat
7177             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7178         rx_sw_if_index_set = 1;
7179       else if (unformat (i, "shg %d", &shg))
7180         ;
7181       else if (unformat (i, "bvi"))
7182         bvi = 1;
7183       else if (unformat (i, "enable"))
7184         enable = 1;
7185       else if (unformat (i, "disable"))
7186         enable = 0;
7187       else
7188         break;
7189     }
7190
7191   if (rx_sw_if_index_set == 0)
7192     {
7193       errmsg ("missing rx interface name or sw_if_index");
7194       return -99;
7195     }
7196
7197   if (enable && (bd_id_set == 0))
7198     {
7199       errmsg ("missing bridge domain");
7200       return -99;
7201     }
7202
7203   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7204
7205   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7206   mp->bd_id = ntohl (bd_id);
7207   mp->shg = (u8) shg;
7208   mp->bvi = bvi;
7209   mp->enable = enable;
7210
7211   S (mp);
7212   W (ret);
7213   return ret;
7214 }
7215
7216 static int
7217 api_bridge_domain_dump (vat_main_t * vam)
7218 {
7219   unformat_input_t *i = vam->input;
7220   vl_api_bridge_domain_dump_t *mp;
7221   vl_api_control_ping_t *mp_ping;
7222   u32 bd_id = ~0;
7223   int ret;
7224
7225   /* Parse args required to build the message */
7226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7227     {
7228       if (unformat (i, "bd_id %d", &bd_id))
7229         ;
7230       else
7231         break;
7232     }
7233
7234   M (BRIDGE_DOMAIN_DUMP, mp);
7235   mp->bd_id = ntohl (bd_id);
7236   S (mp);
7237
7238   /* Use a control ping for synchronization */
7239   MPING (CONTROL_PING, mp_ping);
7240   S (mp_ping);
7241
7242   W (ret);
7243   return ret;
7244 }
7245
7246 static int
7247 api_bridge_domain_add_del (vat_main_t * vam)
7248 {
7249   unformat_input_t *i = vam->input;
7250   vl_api_bridge_domain_add_del_t *mp;
7251   u32 bd_id = ~0;
7252   u8 is_add = 1;
7253   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7254   u8 *bd_tag = NULL;
7255   u32 mac_age = 0;
7256   int ret;
7257
7258   /* Parse args required to build the message */
7259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7260     {
7261       if (unformat (i, "bd_id %d", &bd_id))
7262         ;
7263       else if (unformat (i, "flood %d", &flood))
7264         ;
7265       else if (unformat (i, "uu-flood %d", &uu_flood))
7266         ;
7267       else if (unformat (i, "forward %d", &forward))
7268         ;
7269       else if (unformat (i, "learn %d", &learn))
7270         ;
7271       else if (unformat (i, "arp-term %d", &arp_term))
7272         ;
7273       else if (unformat (i, "mac-age %d", &mac_age))
7274         ;
7275       else if (unformat (i, "bd-tag %s", &bd_tag))
7276         ;
7277       else if (unformat (i, "del"))
7278         {
7279           is_add = 0;
7280           flood = uu_flood = forward = learn = 0;
7281         }
7282       else
7283         break;
7284     }
7285
7286   if (bd_id == ~0)
7287     {
7288       errmsg ("missing bridge domain");
7289       ret = -99;
7290       goto done;
7291     }
7292
7293   if (mac_age > 255)
7294     {
7295       errmsg ("mac age must be less than 256 ");
7296       ret = -99;
7297       goto done;
7298     }
7299
7300   if ((bd_tag) && (vec_len (bd_tag) > 63))
7301     {
7302       errmsg ("bd-tag cannot be longer than 63");
7303       ret = -99;
7304       goto done;
7305     }
7306
7307   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7308
7309   mp->bd_id = ntohl (bd_id);
7310   mp->flood = flood;
7311   mp->uu_flood = uu_flood;
7312   mp->forward = forward;
7313   mp->learn = learn;
7314   mp->arp_term = arp_term;
7315   mp->is_add = is_add;
7316   mp->mac_age = (u8) mac_age;
7317   if (bd_tag)
7318     {
7319       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7320       mp->bd_tag[vec_len (bd_tag)] = 0;
7321     }
7322   S (mp);
7323   W (ret);
7324
7325 done:
7326   vec_free (bd_tag);
7327   return ret;
7328 }
7329
7330 static int
7331 api_l2fib_flush_bd (vat_main_t * vam)
7332 {
7333   unformat_input_t *i = vam->input;
7334   vl_api_l2fib_flush_bd_t *mp;
7335   u32 bd_id = ~0;
7336   int ret;
7337
7338   /* Parse args required to build the message */
7339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7340     {
7341       if (unformat (i, "bd_id %d", &bd_id));
7342       else
7343         break;
7344     }
7345
7346   if (bd_id == ~0)
7347     {
7348       errmsg ("missing bridge domain");
7349       return -99;
7350     }
7351
7352   M (L2FIB_FLUSH_BD, mp);
7353
7354   mp->bd_id = htonl (bd_id);
7355
7356   S (mp);
7357   W (ret);
7358   return ret;
7359 }
7360
7361 static int
7362 api_l2fib_flush_int (vat_main_t * vam)
7363 {
7364   unformat_input_t *i = vam->input;
7365   vl_api_l2fib_flush_int_t *mp;
7366   u32 sw_if_index = ~0;
7367   int ret;
7368
7369   /* Parse args required to build the message */
7370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7371     {
7372       if (unformat (i, "sw_if_index %d", &sw_if_index));
7373       else
7374         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7375       else
7376         break;
7377     }
7378
7379   if (sw_if_index == ~0)
7380     {
7381       errmsg ("missing interface name or sw_if_index");
7382       return -99;
7383     }
7384
7385   M (L2FIB_FLUSH_INT, mp);
7386
7387   mp->sw_if_index = ntohl (sw_if_index);
7388
7389   S (mp);
7390   W (ret);
7391   return ret;
7392 }
7393
7394 static int
7395 api_l2fib_add_del (vat_main_t * vam)
7396 {
7397   unformat_input_t *i = vam->input;
7398   vl_api_l2fib_add_del_t *mp;
7399   f64 timeout;
7400   u8 mac[6] = { 0 };
7401   u8 mac_set = 0;
7402   u32 bd_id;
7403   u8 bd_id_set = 0;
7404   u32 sw_if_index = 0;
7405   u8 sw_if_index_set = 0;
7406   u8 is_add = 1;
7407   u8 static_mac = 0;
7408   u8 filter_mac = 0;
7409   u8 bvi_mac = 0;
7410   int count = 1;
7411   f64 before = 0;
7412   int j;
7413
7414   /* Parse args required to build the message */
7415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7416     {
7417       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7418         mac_set = 1;
7419       else if (unformat (i, "bd_id %d", &bd_id))
7420         bd_id_set = 1;
7421       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7422         sw_if_index_set = 1;
7423       else if (unformat (i, "sw_if"))
7424         {
7425           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7426             {
7427               if (unformat
7428                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7429                 sw_if_index_set = 1;
7430             }
7431           else
7432             break;
7433         }
7434       else if (unformat (i, "static"))
7435         static_mac = 1;
7436       else if (unformat (i, "filter"))
7437         {
7438           filter_mac = 1;
7439           static_mac = 1;
7440         }
7441       else if (unformat (i, "bvi"))
7442         {
7443           bvi_mac = 1;
7444           static_mac = 1;
7445         }
7446       else if (unformat (i, "del"))
7447         is_add = 0;
7448       else if (unformat (i, "count %d", &count))
7449         ;
7450       else
7451         break;
7452     }
7453
7454   if (mac_set == 0)
7455     {
7456       errmsg ("missing mac address");
7457       return -99;
7458     }
7459
7460   if (bd_id_set == 0)
7461     {
7462       errmsg ("missing bridge domain");
7463       return -99;
7464     }
7465
7466   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7467     {
7468       errmsg ("missing interface name or sw_if_index");
7469       return -99;
7470     }
7471
7472   if (count > 1)
7473     {
7474       /* Turn on async mode */
7475       vam->async_mode = 1;
7476       vam->async_errors = 0;
7477       before = vat_time_now (vam);
7478     }
7479
7480   for (j = 0; j < count; j++)
7481     {
7482       M (L2FIB_ADD_DEL, mp);
7483
7484       clib_memcpy (mp->mac, mac, 6);
7485       mp->bd_id = ntohl (bd_id);
7486       mp->is_add = is_add;
7487       mp->sw_if_index = ntohl (sw_if_index);
7488
7489       if (is_add)
7490         {
7491           mp->static_mac = static_mac;
7492           mp->filter_mac = filter_mac;
7493           mp->bvi_mac = bvi_mac;
7494         }
7495       increment_mac_address (mac);
7496       /* send it... */
7497       S (mp);
7498     }
7499
7500   if (count > 1)
7501     {
7502       vl_api_control_ping_t *mp_ping;
7503       f64 after;
7504
7505       /* Shut off async mode */
7506       vam->async_mode = 0;
7507
7508       MPING (CONTROL_PING, mp_ping);
7509       S (mp_ping);
7510
7511       timeout = vat_time_now (vam) + 1.0;
7512       while (vat_time_now (vam) < timeout)
7513         if (vam->result_ready == 1)
7514           goto out;
7515       vam->retval = -99;
7516
7517     out:
7518       if (vam->retval == -99)
7519         errmsg ("timeout");
7520
7521       if (vam->async_errors > 0)
7522         {
7523           errmsg ("%d asynchronous errors", vam->async_errors);
7524           vam->retval = -98;
7525         }
7526       vam->async_errors = 0;
7527       after = vat_time_now (vam);
7528
7529       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7530              count, after - before, count / (after - before));
7531     }
7532   else
7533     {
7534       int ret;
7535
7536       /* Wait for a reply... */
7537       W (ret);
7538       return ret;
7539     }
7540   /* Return the good/bad news */
7541   return (vam->retval);
7542 }
7543
7544 static int
7545 api_bridge_domain_set_mac_age (vat_main_t * vam)
7546 {
7547   unformat_input_t *i = vam->input;
7548   vl_api_bridge_domain_set_mac_age_t *mp;
7549   u32 bd_id = ~0;
7550   u32 mac_age = 0;
7551   int ret;
7552
7553   /* Parse args required to build the message */
7554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7555     {
7556       if (unformat (i, "bd_id %d", &bd_id));
7557       else if (unformat (i, "mac-age %d", &mac_age));
7558       else
7559         break;
7560     }
7561
7562   if (bd_id == ~0)
7563     {
7564       errmsg ("missing bridge domain");
7565       return -99;
7566     }
7567
7568   if (mac_age > 255)
7569     {
7570       errmsg ("mac age must be less than 256 ");
7571       return -99;
7572     }
7573
7574   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7575
7576   mp->bd_id = htonl (bd_id);
7577   mp->mac_age = (u8) mac_age;
7578
7579   S (mp);
7580   W (ret);
7581   return ret;
7582 }
7583
7584 static int
7585 api_l2_flags (vat_main_t * vam)
7586 {
7587   unformat_input_t *i = vam->input;
7588   vl_api_l2_flags_t *mp;
7589   u32 sw_if_index;
7590   u32 flags = 0;
7591   u8 sw_if_index_set = 0;
7592   u8 is_set = 0;
7593   int ret;
7594
7595   /* Parse args required to build the message */
7596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7597     {
7598       if (unformat (i, "sw_if_index %d", &sw_if_index))
7599         sw_if_index_set = 1;
7600       else if (unformat (i, "sw_if"))
7601         {
7602           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7603             {
7604               if (unformat
7605                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7606                 sw_if_index_set = 1;
7607             }
7608           else
7609             break;
7610         }
7611       else if (unformat (i, "learn"))
7612         flags |= L2_LEARN;
7613       else if (unformat (i, "forward"))
7614         flags |= L2_FWD;
7615       else if (unformat (i, "flood"))
7616         flags |= L2_FLOOD;
7617       else if (unformat (i, "uu-flood"))
7618         flags |= L2_UU_FLOOD;
7619       else if (unformat (i, "arp-term"))
7620         flags |= L2_ARP_TERM;
7621       else if (unformat (i, "off"))
7622         is_set = 0;
7623       else if (unformat (i, "disable"))
7624         is_set = 0;
7625       else
7626         break;
7627     }
7628
7629   if (sw_if_index_set == 0)
7630     {
7631       errmsg ("missing interface name or sw_if_index");
7632       return -99;
7633     }
7634
7635   M (L2_FLAGS, mp);
7636
7637   mp->sw_if_index = ntohl (sw_if_index);
7638   mp->feature_bitmap = ntohl (flags);
7639   mp->is_set = is_set;
7640
7641   S (mp);
7642   W (ret);
7643   return ret;
7644 }
7645
7646 static int
7647 api_bridge_flags (vat_main_t * vam)
7648 {
7649   unformat_input_t *i = vam->input;
7650   vl_api_bridge_flags_t *mp;
7651   u32 bd_id;
7652   u8 bd_id_set = 0;
7653   u8 is_set = 1;
7654   u32 flags = 0;
7655   int ret;
7656
7657   /* Parse args required to build the message */
7658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7659     {
7660       if (unformat (i, "bd_id %d", &bd_id))
7661         bd_id_set = 1;
7662       else if (unformat (i, "learn"))
7663         flags |= L2_LEARN;
7664       else if (unformat (i, "forward"))
7665         flags |= L2_FWD;
7666       else if (unformat (i, "flood"))
7667         flags |= L2_FLOOD;
7668       else if (unformat (i, "uu-flood"))
7669         flags |= L2_UU_FLOOD;
7670       else if (unformat (i, "arp-term"))
7671         flags |= L2_ARP_TERM;
7672       else if (unformat (i, "off"))
7673         is_set = 0;
7674       else if (unformat (i, "disable"))
7675         is_set = 0;
7676       else
7677         break;
7678     }
7679
7680   if (bd_id_set == 0)
7681     {
7682       errmsg ("missing bridge domain");
7683       return -99;
7684     }
7685
7686   M (BRIDGE_FLAGS, mp);
7687
7688   mp->bd_id = ntohl (bd_id);
7689   mp->feature_bitmap = ntohl (flags);
7690   mp->is_set = is_set;
7691
7692   S (mp);
7693   W (ret);
7694   return ret;
7695 }
7696
7697 static int
7698 api_bd_ip_mac_add_del (vat_main_t * vam)
7699 {
7700   unformat_input_t *i = vam->input;
7701   vl_api_bd_ip_mac_add_del_t *mp;
7702   u32 bd_id;
7703   u8 is_ipv6 = 0;
7704   u8 is_add = 1;
7705   u8 bd_id_set = 0;
7706   u8 ip_set = 0;
7707   u8 mac_set = 0;
7708   ip4_address_t v4addr;
7709   ip6_address_t v6addr;
7710   u8 macaddr[6];
7711   int ret;
7712
7713
7714   /* Parse args required to build the message */
7715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7716     {
7717       if (unformat (i, "bd_id %d", &bd_id))
7718         {
7719           bd_id_set++;
7720         }
7721       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7722         {
7723           ip_set++;
7724         }
7725       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7726         {
7727           ip_set++;
7728           is_ipv6++;
7729         }
7730       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7731         {
7732           mac_set++;
7733         }
7734       else if (unformat (i, "del"))
7735         is_add = 0;
7736       else
7737         break;
7738     }
7739
7740   if (bd_id_set == 0)
7741     {
7742       errmsg ("missing bridge domain");
7743       return -99;
7744     }
7745   else if (ip_set == 0)
7746     {
7747       errmsg ("missing IP address");
7748       return -99;
7749     }
7750   else if (mac_set == 0)
7751     {
7752       errmsg ("missing MAC address");
7753       return -99;
7754     }
7755
7756   M (BD_IP_MAC_ADD_DEL, mp);
7757
7758   mp->bd_id = ntohl (bd_id);
7759   mp->is_ipv6 = is_ipv6;
7760   mp->is_add = is_add;
7761   if (is_ipv6)
7762     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7763   else
7764     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7765   clib_memcpy (mp->mac_address, macaddr, 6);
7766   S (mp);
7767   W (ret);
7768   return ret;
7769 }
7770
7771 static int
7772 api_tap_connect (vat_main_t * vam)
7773 {
7774   unformat_input_t *i = vam->input;
7775   vl_api_tap_connect_t *mp;
7776   u8 mac_address[6];
7777   u8 random_mac = 1;
7778   u8 name_set = 0;
7779   u8 *tap_name;
7780   u8 *tag = 0;
7781   ip4_address_t ip4_address;
7782   u32 ip4_mask_width;
7783   int ip4_address_set = 0;
7784   ip6_address_t ip6_address;
7785   u32 ip6_mask_width;
7786   int ip6_address_set = 0;
7787   int ret;
7788
7789   memset (mac_address, 0, sizeof (mac_address));
7790
7791   /* Parse args required to build the message */
7792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7793     {
7794       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7795         {
7796           random_mac = 0;
7797         }
7798       else if (unformat (i, "random-mac"))
7799         random_mac = 1;
7800       else if (unformat (i, "tapname %s", &tap_name))
7801         name_set = 1;
7802       else if (unformat (i, "tag %s", &tag))
7803         ;
7804       else if (unformat (i, "address %U/%d",
7805                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7806         ip4_address_set = 1;
7807       else if (unformat (i, "address %U/%d",
7808                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7809         ip6_address_set = 1;
7810       else
7811         break;
7812     }
7813
7814   if (name_set == 0)
7815     {
7816       errmsg ("missing tap name");
7817       return -99;
7818     }
7819   if (vec_len (tap_name) > 63)
7820     {
7821       errmsg ("tap name too long");
7822       return -99;
7823     }
7824   vec_add1 (tap_name, 0);
7825
7826   if (vec_len (tag) > 63)
7827     {
7828       errmsg ("tag too long");
7829       return -99;
7830     }
7831
7832   /* Construct the API message */
7833   M (TAP_CONNECT, mp);
7834
7835   mp->use_random_mac = random_mac;
7836   clib_memcpy (mp->mac_address, mac_address, 6);
7837   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7838   if (tag)
7839     clib_memcpy (mp->tag, tag, vec_len (tag));
7840
7841   if (ip4_address_set)
7842     {
7843       mp->ip4_address_set = 1;
7844       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7845       mp->ip4_mask_width = ip4_mask_width;
7846     }
7847   if (ip6_address_set)
7848     {
7849       mp->ip6_address_set = 1;
7850       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7851       mp->ip6_mask_width = ip6_mask_width;
7852     }
7853
7854   vec_free (tap_name);
7855   vec_free (tag);
7856
7857   /* send it... */
7858   S (mp);
7859
7860   /* Wait for a reply... */
7861   W (ret);
7862   return ret;
7863 }
7864
7865 static int
7866 api_tap_modify (vat_main_t * vam)
7867 {
7868   unformat_input_t *i = vam->input;
7869   vl_api_tap_modify_t *mp;
7870   u8 mac_address[6];
7871   u8 random_mac = 1;
7872   u8 name_set = 0;
7873   u8 *tap_name;
7874   u32 sw_if_index = ~0;
7875   u8 sw_if_index_set = 0;
7876   int ret;
7877
7878   memset (mac_address, 0, sizeof (mac_address));
7879
7880   /* Parse args required to build the message */
7881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7882     {
7883       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7884         sw_if_index_set = 1;
7885       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7886         sw_if_index_set = 1;
7887       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7888         {
7889           random_mac = 0;
7890         }
7891       else if (unformat (i, "random-mac"))
7892         random_mac = 1;
7893       else if (unformat (i, "tapname %s", &tap_name))
7894         name_set = 1;
7895       else
7896         break;
7897     }
7898
7899   if (sw_if_index_set == 0)
7900     {
7901       errmsg ("missing vpp interface name");
7902       return -99;
7903     }
7904   if (name_set == 0)
7905     {
7906       errmsg ("missing tap name");
7907       return -99;
7908     }
7909   if (vec_len (tap_name) > 63)
7910     {
7911       errmsg ("tap name too long");
7912     }
7913   vec_add1 (tap_name, 0);
7914
7915   /* Construct the API message */
7916   M (TAP_MODIFY, mp);
7917
7918   mp->use_random_mac = random_mac;
7919   mp->sw_if_index = ntohl (sw_if_index);
7920   clib_memcpy (mp->mac_address, mac_address, 6);
7921   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7922   vec_free (tap_name);
7923
7924   /* send it... */
7925   S (mp);
7926
7927   /* Wait for a reply... */
7928   W (ret);
7929   return ret;
7930 }
7931
7932 static int
7933 api_tap_delete (vat_main_t * vam)
7934 {
7935   unformat_input_t *i = vam->input;
7936   vl_api_tap_delete_t *mp;
7937   u32 sw_if_index = ~0;
7938   u8 sw_if_index_set = 0;
7939   int ret;
7940
7941   /* Parse args required to build the message */
7942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7943     {
7944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7945         sw_if_index_set = 1;
7946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7947         sw_if_index_set = 1;
7948       else
7949         break;
7950     }
7951
7952   if (sw_if_index_set == 0)
7953     {
7954       errmsg ("missing vpp interface name");
7955       return -99;
7956     }
7957
7958   /* Construct the API message */
7959   M (TAP_DELETE, mp);
7960
7961   mp->sw_if_index = ntohl (sw_if_index);
7962
7963   /* send it... */
7964   S (mp);
7965
7966   /* Wait for a reply... */
7967   W (ret);
7968   return ret;
7969 }
7970
7971 static int
7972 api_tap_create_v2 (vat_main_t * vam)
7973 {
7974   unformat_input_t *i = vam->input;
7975   vl_api_tap_create_v2_t *mp;
7976   u8 mac_address[6];
7977   u8 random_mac = 1;
7978   u32 id = ~0;
7979   u8 *host_if_name = 0;
7980   u8 *host_ns = 0;
7981   u8 host_mac_addr[6];
7982   u8 host_mac_addr_set = 0;
7983   u8 *host_bridge = 0;
7984   ip4_address_t host_ip4_addr;
7985   ip4_address_t host_ip4_gw;
7986   u8 host_ip4_gw_set = 0;
7987   u32 host_ip4_prefix_len = 0;
7988   ip6_address_t host_ip6_addr;
7989   ip6_address_t host_ip6_gw;
7990   u8 host_ip6_gw_set = 0;
7991   u32 host_ip6_prefix_len = 0;
7992   int ret;
7993   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7994
7995   memset (mac_address, 0, sizeof (mac_address));
7996
7997   /* Parse args required to build the message */
7998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7999     {
8000       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8001         {
8002           random_mac = 0;
8003         }
8004       else if (unformat (i, "id %u", &id))
8005         ;
8006       else if (unformat (i, "host-if-name %s", &host_if_name))
8007         ;
8008       else if (unformat (i, "host-ns %s", &host_ns))
8009         ;
8010       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8011                          host_mac_addr))
8012         host_mac_addr_set = 1;
8013       else if (unformat (i, "host-bridge %s", &host_bridge))
8014         ;
8015       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8016                          &host_ip4_addr, &host_ip4_prefix_len))
8017         ;
8018       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8019                          &host_ip6_addr, &host_ip6_prefix_len))
8020         ;
8021       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8022                          &host_ip4_gw))
8023         host_ip4_gw_set = 1;
8024       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8025                          &host_ip6_gw))
8026         host_ip6_gw_set = 1;
8027       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8028         ;
8029       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8030         ;
8031       else
8032         break;
8033     }
8034
8035   if (vec_len (host_if_name) > 63)
8036     {
8037       errmsg ("tap name too long. ");
8038       return -99;
8039     }
8040   if (vec_len (host_ns) > 63)
8041     {
8042       errmsg ("host name space too long. ");
8043       return -99;
8044     }
8045   if (vec_len (host_bridge) > 63)
8046     {
8047       errmsg ("host bridge name too long. ");
8048       return -99;
8049     }
8050   if (host_ip4_prefix_len > 32)
8051     {
8052       errmsg ("host ip4 prefix length not valid. ");
8053       return -99;
8054     }
8055   if (host_ip6_prefix_len > 128)
8056     {
8057       errmsg ("host ip6 prefix length not valid. ");
8058       return -99;
8059     }
8060   if (!is_pow2 (rx_ring_sz))
8061     {
8062       errmsg ("rx ring size must be power of 2. ");
8063       return -99;
8064     }
8065   if (rx_ring_sz > 32768)
8066     {
8067       errmsg ("rx ring size must be 32768 or lower. ");
8068       return -99;
8069     }
8070   if (!is_pow2 (tx_ring_sz))
8071     {
8072       errmsg ("tx ring size must be power of 2. ");
8073       return -99;
8074     }
8075   if (tx_ring_sz > 32768)
8076     {
8077       errmsg ("tx ring size must be 32768 or lower. ");
8078       return -99;
8079     }
8080
8081   /* Construct the API message */
8082   M (TAP_CREATE_V2, mp);
8083
8084   mp->use_random_mac = random_mac;
8085
8086   mp->id = ntohl (id);
8087   mp->host_namespace_set = host_ns != 0;
8088   mp->host_bridge_set = host_bridge != 0;
8089   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8090   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8091   mp->rx_ring_sz = ntohs (rx_ring_sz);
8092   mp->tx_ring_sz = ntohs (tx_ring_sz);
8093
8094   if (random_mac == 0)
8095     clib_memcpy (mp->mac_address, mac_address, 6);
8096   if (host_mac_addr_set)
8097     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8098   if (host_if_name)
8099     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8100   if (host_ns)
8101     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8102   if (host_bridge)
8103     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8104   if (host_ip4_prefix_len)
8105     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8106   if (host_ip4_prefix_len)
8107     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8108   if (host_ip4_gw_set)
8109     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8110   if (host_ip6_gw_set)
8111     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8112
8113   vec_free (host_ns);
8114   vec_free (host_if_name);
8115   vec_free (host_bridge);
8116
8117   /* send it... */
8118   S (mp);
8119
8120   /* Wait for a reply... */
8121   W (ret);
8122   return ret;
8123 }
8124
8125 static int
8126 api_tap_delete_v2 (vat_main_t * vam)
8127 {
8128   unformat_input_t *i = vam->input;
8129   vl_api_tap_delete_v2_t *mp;
8130   u32 sw_if_index = ~0;
8131   u8 sw_if_index_set = 0;
8132   int ret;
8133
8134   /* Parse args required to build the message */
8135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8136     {
8137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8138         sw_if_index_set = 1;
8139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8140         sw_if_index_set = 1;
8141       else
8142         break;
8143     }
8144
8145   if (sw_if_index_set == 0)
8146     {
8147       errmsg ("missing vpp interface name. ");
8148       return -99;
8149     }
8150
8151   /* Construct the API message */
8152   M (TAP_DELETE_V2, mp);
8153
8154   mp->sw_if_index = ntohl (sw_if_index);
8155
8156   /* send it... */
8157   S (mp);
8158
8159   /* Wait for a reply... */
8160   W (ret);
8161   return ret;
8162 }
8163
8164 static int
8165 api_bond_create (vat_main_t * vam)
8166 {
8167   unformat_input_t *i = vam->input;
8168   vl_api_bond_create_t *mp;
8169   u8 mac_address[6];
8170   u8 custom_mac = 0;
8171   int ret;
8172   u8 mode;
8173   u8 lb;
8174   u8 mode_is_set = 0;
8175
8176   memset (mac_address, 0, sizeof (mac_address));
8177   lb = BOND_LB_L2;
8178
8179   /* Parse args required to build the message */
8180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8181     {
8182       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8183         mode_is_set = 1;
8184       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8185                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8186         ;
8187       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8188                          mac_address))
8189         custom_mac = 1;
8190       else
8191         break;
8192     }
8193
8194   if (mode_is_set == 0)
8195     {
8196       errmsg ("Missing bond mode. ");
8197       return -99;
8198     }
8199
8200   /* Construct the API message */
8201   M (BOND_CREATE, mp);
8202
8203   mp->use_custom_mac = custom_mac;
8204
8205   mp->mode = mode;
8206   mp->lb = lb;
8207
8208   if (custom_mac)
8209     clib_memcpy (mp->mac_address, mac_address, 6);
8210
8211   /* send it... */
8212   S (mp);
8213
8214   /* Wait for a reply... */
8215   W (ret);
8216   return ret;
8217 }
8218
8219 static int
8220 api_bond_delete (vat_main_t * vam)
8221 {
8222   unformat_input_t *i = vam->input;
8223   vl_api_bond_delete_t *mp;
8224   u32 sw_if_index = ~0;
8225   u8 sw_if_index_set = 0;
8226   int ret;
8227
8228   /* Parse args required to build the message */
8229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8230     {
8231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8232         sw_if_index_set = 1;
8233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8234         sw_if_index_set = 1;
8235       else
8236         break;
8237     }
8238
8239   if (sw_if_index_set == 0)
8240     {
8241       errmsg ("missing vpp interface name. ");
8242       return -99;
8243     }
8244
8245   /* Construct the API message */
8246   M (BOND_DELETE, mp);
8247
8248   mp->sw_if_index = ntohl (sw_if_index);
8249
8250   /* send it... */
8251   S (mp);
8252
8253   /* Wait for a reply... */
8254   W (ret);
8255   return ret;
8256 }
8257
8258 static int
8259 api_bond_enslave (vat_main_t * vam)
8260 {
8261   unformat_input_t *i = vam->input;
8262   vl_api_bond_enslave_t *mp;
8263   u32 bond_sw_if_index;
8264   int ret;
8265   u8 is_passive;
8266   u8 is_long_timeout;
8267   u32 bond_sw_if_index_is_set = 0;
8268   u32 sw_if_index;
8269   u8 sw_if_index_is_set = 0;
8270
8271   /* Parse args required to build the message */
8272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8273     {
8274       if (unformat (i, "sw_if_index %d", &sw_if_index))
8275         sw_if_index_is_set = 1;
8276       else if (unformat (i, "bond %u", &bond_sw_if_index))
8277         bond_sw_if_index_is_set = 1;
8278       else if (unformat (i, "passive %d", &is_passive))
8279         ;
8280       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8281         ;
8282       else
8283         break;
8284     }
8285
8286   if (bond_sw_if_index_is_set == 0)
8287     {
8288       errmsg ("Missing bond sw_if_index. ");
8289       return -99;
8290     }
8291   if (sw_if_index_is_set == 0)
8292     {
8293       errmsg ("Missing slave sw_if_index. ");
8294       return -99;
8295     }
8296
8297   /* Construct the API message */
8298   M (BOND_ENSLAVE, mp);
8299
8300   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8301   mp->sw_if_index = ntohl (sw_if_index);
8302   mp->is_long_timeout = is_long_timeout;
8303   mp->is_passive = is_passive;
8304
8305   /* send it... */
8306   S (mp);
8307
8308   /* Wait for a reply... */
8309   W (ret);
8310   return ret;
8311 }
8312
8313 static int
8314 api_bond_detach_slave (vat_main_t * vam)
8315 {
8316   unformat_input_t *i = vam->input;
8317   vl_api_bond_detach_slave_t *mp;
8318   u32 sw_if_index = ~0;
8319   u8 sw_if_index_set = 0;
8320   int ret;
8321
8322   /* Parse args required to build the message */
8323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8324     {
8325       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8326         sw_if_index_set = 1;
8327       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8328         sw_if_index_set = 1;
8329       else
8330         break;
8331     }
8332
8333   if (sw_if_index_set == 0)
8334     {
8335       errmsg ("missing vpp interface name. ");
8336       return -99;
8337     }
8338
8339   /* Construct the API message */
8340   M (BOND_DETACH_SLAVE, mp);
8341
8342   mp->sw_if_index = ntohl (sw_if_index);
8343
8344   /* send it... */
8345   S (mp);
8346
8347   /* Wait for a reply... */
8348   W (ret);
8349   return ret;
8350 }
8351
8352 static int
8353 api_ip_table_add_del (vat_main_t * vam)
8354 {
8355   unformat_input_t *i = vam->input;
8356   vl_api_ip_table_add_del_t *mp;
8357   u32 table_id = ~0;
8358   u8 is_ipv6 = 0;
8359   u8 is_add = 1;
8360   int ret = 0;
8361
8362   /* Parse args required to build the message */
8363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8364     {
8365       if (unformat (i, "ipv6"))
8366         is_ipv6 = 1;
8367       else if (unformat (i, "del"))
8368         is_add = 0;
8369       else if (unformat (i, "add"))
8370         is_add = 1;
8371       else if (unformat (i, "table %d", &table_id))
8372         ;
8373       else
8374         {
8375           clib_warning ("parse error '%U'", format_unformat_error, i);
8376           return -99;
8377         }
8378     }
8379
8380   if (~0 == table_id)
8381     {
8382       errmsg ("missing table-ID");
8383       return -99;
8384     }
8385
8386   /* Construct the API message */
8387   M (IP_TABLE_ADD_DEL, mp);
8388
8389   mp->table_id = ntohl (table_id);
8390   mp->is_ipv6 = is_ipv6;
8391   mp->is_add = is_add;
8392
8393   /* send it... */
8394   S (mp);
8395
8396   /* Wait for a reply... */
8397   W (ret);
8398
8399   return ret;
8400 }
8401
8402 static int
8403 api_ip_add_del_route (vat_main_t * vam)
8404 {
8405   unformat_input_t *i = vam->input;
8406   vl_api_ip_add_del_route_t *mp;
8407   u32 sw_if_index = ~0, vrf_id = 0;
8408   u8 is_ipv6 = 0;
8409   u8 is_local = 0, is_drop = 0;
8410   u8 is_unreach = 0, is_prohibit = 0;
8411   u8 is_add = 1;
8412   u32 next_hop_weight = 1;
8413   u8 is_multipath = 0;
8414   u8 address_set = 0;
8415   u8 address_length_set = 0;
8416   u32 next_hop_table_id = 0;
8417   u32 resolve_attempts = 0;
8418   u32 dst_address_length = 0;
8419   u8 next_hop_set = 0;
8420   ip4_address_t v4_dst_address, v4_next_hop_address;
8421   ip6_address_t v6_dst_address, v6_next_hop_address;
8422   int count = 1;
8423   int j;
8424   f64 before = 0;
8425   u32 random_add_del = 0;
8426   u32 *random_vector = 0;
8427   uword *random_hash;
8428   u32 random_seed = 0xdeaddabe;
8429   u32 classify_table_index = ~0;
8430   u8 is_classify = 0;
8431   u8 resolve_host = 0, resolve_attached = 0;
8432   mpls_label_t *next_hop_out_label_stack = NULL;
8433   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8434   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8435
8436   /* Parse args required to build the message */
8437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8438     {
8439       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8440         ;
8441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8442         ;
8443       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8444         {
8445           address_set = 1;
8446           is_ipv6 = 0;
8447         }
8448       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8449         {
8450           address_set = 1;
8451           is_ipv6 = 1;
8452         }
8453       else if (unformat (i, "/%d", &dst_address_length))
8454         {
8455           address_length_set = 1;
8456         }
8457
8458       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8459                                          &v4_next_hop_address))
8460         {
8461           next_hop_set = 1;
8462         }
8463       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8464                                          &v6_next_hop_address))
8465         {
8466           next_hop_set = 1;
8467         }
8468       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8469         ;
8470       else if (unformat (i, "weight %d", &next_hop_weight))
8471         ;
8472       else if (unformat (i, "drop"))
8473         {
8474           is_drop = 1;
8475         }
8476       else if (unformat (i, "null-send-unreach"))
8477         {
8478           is_unreach = 1;
8479         }
8480       else if (unformat (i, "null-send-prohibit"))
8481         {
8482           is_prohibit = 1;
8483         }
8484       else if (unformat (i, "local"))
8485         {
8486           is_local = 1;
8487         }
8488       else if (unformat (i, "classify %d", &classify_table_index))
8489         {
8490           is_classify = 1;
8491         }
8492       else if (unformat (i, "del"))
8493         is_add = 0;
8494       else if (unformat (i, "add"))
8495         is_add = 1;
8496       else if (unformat (i, "resolve-via-host"))
8497         resolve_host = 1;
8498       else if (unformat (i, "resolve-via-attached"))
8499         resolve_attached = 1;
8500       else if (unformat (i, "multipath"))
8501         is_multipath = 1;
8502       else if (unformat (i, "vrf %d", &vrf_id))
8503         ;
8504       else if (unformat (i, "count %d", &count))
8505         ;
8506       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8507         ;
8508       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8509         ;
8510       else if (unformat (i, "out-label %d", &next_hop_out_label))
8511         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8512       else if (unformat (i, "via-label %d", &next_hop_via_label))
8513         ;
8514       else if (unformat (i, "random"))
8515         random_add_del = 1;
8516       else if (unformat (i, "seed %d", &random_seed))
8517         ;
8518       else
8519         {
8520           clib_warning ("parse error '%U'", format_unformat_error, i);
8521           return -99;
8522         }
8523     }
8524
8525   if (!next_hop_set && !is_drop && !is_local &&
8526       !is_classify && !is_unreach && !is_prohibit &&
8527       MPLS_LABEL_INVALID == next_hop_via_label)
8528     {
8529       errmsg
8530         ("next hop / local / drop / unreach / prohibit / classify not set");
8531       return -99;
8532     }
8533
8534   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8535     {
8536       errmsg ("next hop and next-hop via label set");
8537       return -99;
8538     }
8539   if (address_set == 0)
8540     {
8541       errmsg ("missing addresses");
8542       return -99;
8543     }
8544
8545   if (address_length_set == 0)
8546     {
8547       errmsg ("missing address length");
8548       return -99;
8549     }
8550
8551   /* Generate a pile of unique, random routes */
8552   if (random_add_del)
8553     {
8554       u32 this_random_address;
8555       random_hash = hash_create (count, sizeof (uword));
8556
8557       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8558       for (j = 0; j <= count; j++)
8559         {
8560           do
8561             {
8562               this_random_address = random_u32 (&random_seed);
8563               this_random_address =
8564                 clib_host_to_net_u32 (this_random_address);
8565             }
8566           while (hash_get (random_hash, this_random_address));
8567           vec_add1 (random_vector, this_random_address);
8568           hash_set (random_hash, this_random_address, 1);
8569         }
8570       hash_free (random_hash);
8571       v4_dst_address.as_u32 = random_vector[0];
8572     }
8573
8574   if (count > 1)
8575     {
8576       /* Turn on async mode */
8577       vam->async_mode = 1;
8578       vam->async_errors = 0;
8579       before = vat_time_now (vam);
8580     }
8581
8582   for (j = 0; j < count; j++)
8583     {
8584       /* Construct the API message */
8585       M2 (IP_ADD_DEL_ROUTE, mp,
8586           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8587
8588       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8589       mp->table_id = ntohl (vrf_id);
8590
8591       mp->is_add = is_add;
8592       mp->is_drop = is_drop;
8593       mp->is_unreach = is_unreach;
8594       mp->is_prohibit = is_prohibit;
8595       mp->is_ipv6 = is_ipv6;
8596       mp->is_local = is_local;
8597       mp->is_classify = is_classify;
8598       mp->is_multipath = is_multipath;
8599       mp->is_resolve_host = resolve_host;
8600       mp->is_resolve_attached = resolve_attached;
8601       mp->next_hop_weight = next_hop_weight;
8602       mp->dst_address_length = dst_address_length;
8603       mp->next_hop_table_id = ntohl (next_hop_table_id);
8604       mp->classify_table_index = ntohl (classify_table_index);
8605       mp->next_hop_via_label = ntohl (next_hop_via_label);
8606       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8607       if (0 != mp->next_hop_n_out_labels)
8608         {
8609           memcpy (mp->next_hop_out_label_stack,
8610                   next_hop_out_label_stack,
8611                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8612           vec_free (next_hop_out_label_stack);
8613         }
8614
8615       if (is_ipv6)
8616         {
8617           clib_memcpy (mp->dst_address, &v6_dst_address,
8618                        sizeof (v6_dst_address));
8619           if (next_hop_set)
8620             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8621                          sizeof (v6_next_hop_address));
8622           increment_v6_address (&v6_dst_address);
8623         }
8624       else
8625         {
8626           clib_memcpy (mp->dst_address, &v4_dst_address,
8627                        sizeof (v4_dst_address));
8628           if (next_hop_set)
8629             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8630                          sizeof (v4_next_hop_address));
8631           if (random_add_del)
8632             v4_dst_address.as_u32 = random_vector[j + 1];
8633           else
8634             increment_v4_address (&v4_dst_address);
8635         }
8636       /* send it... */
8637       S (mp);
8638       /* If we receive SIGTERM, stop now... */
8639       if (vam->do_exit)
8640         break;
8641     }
8642
8643   /* When testing multiple add/del ops, use a control-ping to sync */
8644   if (count > 1)
8645     {
8646       vl_api_control_ping_t *mp_ping;
8647       f64 after;
8648       f64 timeout;
8649
8650       /* Shut off async mode */
8651       vam->async_mode = 0;
8652
8653       MPING (CONTROL_PING, mp_ping);
8654       S (mp_ping);
8655
8656       timeout = vat_time_now (vam) + 1.0;
8657       while (vat_time_now (vam) < timeout)
8658         if (vam->result_ready == 1)
8659           goto out;
8660       vam->retval = -99;
8661
8662     out:
8663       if (vam->retval == -99)
8664         errmsg ("timeout");
8665
8666       if (vam->async_errors > 0)
8667         {
8668           errmsg ("%d asynchronous errors", vam->async_errors);
8669           vam->retval = -98;
8670         }
8671       vam->async_errors = 0;
8672       after = vat_time_now (vam);
8673
8674       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8675       if (j > 0)
8676         count = j;
8677
8678       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8679              count, after - before, count / (after - before));
8680     }
8681   else
8682     {
8683       int ret;
8684
8685       /* Wait for a reply... */
8686       W (ret);
8687       return ret;
8688     }
8689
8690   /* Return the good/bad news */
8691   return (vam->retval);
8692 }
8693
8694 static int
8695 api_ip_mroute_add_del (vat_main_t * vam)
8696 {
8697   unformat_input_t *i = vam->input;
8698   vl_api_ip_mroute_add_del_t *mp;
8699   u32 sw_if_index = ~0, vrf_id = 0;
8700   u8 is_ipv6 = 0;
8701   u8 is_local = 0;
8702   u8 is_add = 1;
8703   u8 address_set = 0;
8704   u32 grp_address_length = 0;
8705   ip4_address_t v4_grp_address, v4_src_address;
8706   ip6_address_t v6_grp_address, v6_src_address;
8707   mfib_itf_flags_t iflags = 0;
8708   mfib_entry_flags_t eflags = 0;
8709   int ret;
8710
8711   /* Parse args required to build the message */
8712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8713     {
8714       if (unformat (i, "sw_if_index %d", &sw_if_index))
8715         ;
8716       else if (unformat (i, "%U %U",
8717                          unformat_ip4_address, &v4_src_address,
8718                          unformat_ip4_address, &v4_grp_address))
8719         {
8720           grp_address_length = 64;
8721           address_set = 1;
8722           is_ipv6 = 0;
8723         }
8724       else if (unformat (i, "%U %U",
8725                          unformat_ip6_address, &v6_src_address,
8726                          unformat_ip6_address, &v6_grp_address))
8727         {
8728           grp_address_length = 256;
8729           address_set = 1;
8730           is_ipv6 = 1;
8731         }
8732       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8733         {
8734           memset (&v4_src_address, 0, sizeof (v4_src_address));
8735           grp_address_length = 32;
8736           address_set = 1;
8737           is_ipv6 = 0;
8738         }
8739       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8740         {
8741           memset (&v6_src_address, 0, sizeof (v6_src_address));
8742           grp_address_length = 128;
8743           address_set = 1;
8744           is_ipv6 = 1;
8745         }
8746       else if (unformat (i, "/%d", &grp_address_length))
8747         ;
8748       else if (unformat (i, "local"))
8749         {
8750           is_local = 1;
8751         }
8752       else if (unformat (i, "del"))
8753         is_add = 0;
8754       else if (unformat (i, "add"))
8755         is_add = 1;
8756       else if (unformat (i, "vrf %d", &vrf_id))
8757         ;
8758       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8759         ;
8760       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8761         ;
8762       else
8763         {
8764           clib_warning ("parse error '%U'", format_unformat_error, i);
8765           return -99;
8766         }
8767     }
8768
8769   if (address_set == 0)
8770     {
8771       errmsg ("missing addresses\n");
8772       return -99;
8773     }
8774
8775   /* Construct the API message */
8776   M (IP_MROUTE_ADD_DEL, mp);
8777
8778   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8779   mp->table_id = ntohl (vrf_id);
8780
8781   mp->is_add = is_add;
8782   mp->is_ipv6 = is_ipv6;
8783   mp->is_local = is_local;
8784   mp->itf_flags = ntohl (iflags);
8785   mp->entry_flags = ntohl (eflags);
8786   mp->grp_address_length = grp_address_length;
8787   mp->grp_address_length = ntohs (mp->grp_address_length);
8788
8789   if (is_ipv6)
8790     {
8791       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8792       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8793     }
8794   else
8795     {
8796       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8797       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8798
8799     }
8800
8801   /* send it... */
8802   S (mp);
8803   /* Wait for a reply... */
8804   W (ret);
8805   return ret;
8806 }
8807
8808 static int
8809 api_mpls_table_add_del (vat_main_t * vam)
8810 {
8811   unformat_input_t *i = vam->input;
8812   vl_api_mpls_table_add_del_t *mp;
8813   u32 table_id = ~0;
8814   u8 is_add = 1;
8815   int ret = 0;
8816
8817   /* Parse args required to build the message */
8818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8819     {
8820       if (unformat (i, "table %d", &table_id))
8821         ;
8822       else if (unformat (i, "del"))
8823         is_add = 0;
8824       else if (unformat (i, "add"))
8825         is_add = 1;
8826       else
8827         {
8828           clib_warning ("parse error '%U'", format_unformat_error, i);
8829           return -99;
8830         }
8831     }
8832
8833   if (~0 == table_id)
8834     {
8835       errmsg ("missing table-ID");
8836       return -99;
8837     }
8838
8839   /* Construct the API message */
8840   M (MPLS_TABLE_ADD_DEL, mp);
8841
8842   mp->mt_table_id = ntohl (table_id);
8843   mp->mt_is_add = is_add;
8844
8845   /* send it... */
8846   S (mp);
8847
8848   /* Wait for a reply... */
8849   W (ret);
8850
8851   return ret;
8852 }
8853
8854 static int
8855 api_mpls_route_add_del (vat_main_t * vam)
8856 {
8857   unformat_input_t *i = vam->input;
8858   vl_api_mpls_route_add_del_t *mp;
8859   u32 sw_if_index = ~0, table_id = 0;
8860   u8 is_add = 1;
8861   u32 next_hop_weight = 1;
8862   u8 is_multipath = 0;
8863   u32 next_hop_table_id = 0;
8864   u8 next_hop_set = 0;
8865   ip4_address_t v4_next_hop_address = {
8866     .as_u32 = 0,
8867   };
8868   ip6_address_t v6_next_hop_address = { {0} };
8869   int count = 1;
8870   int j;
8871   f64 before = 0;
8872   u32 classify_table_index = ~0;
8873   u8 is_classify = 0;
8874   u8 resolve_host = 0, resolve_attached = 0;
8875   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8876   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8877   mpls_label_t *next_hop_out_label_stack = NULL;
8878   mpls_label_t local_label = MPLS_LABEL_INVALID;
8879   u8 is_eos = 0;
8880   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8881
8882   /* Parse args required to build the message */
8883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8884     {
8885       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8886         ;
8887       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8888         ;
8889       else if (unformat (i, "%d", &local_label))
8890         ;
8891       else if (unformat (i, "eos"))
8892         is_eos = 1;
8893       else if (unformat (i, "non-eos"))
8894         is_eos = 0;
8895       else if (unformat (i, "via %U", unformat_ip4_address,
8896                          &v4_next_hop_address))
8897         {
8898           next_hop_set = 1;
8899           next_hop_proto = DPO_PROTO_IP4;
8900         }
8901       else if (unformat (i, "via %U", unformat_ip6_address,
8902                          &v6_next_hop_address))
8903         {
8904           next_hop_set = 1;
8905           next_hop_proto = DPO_PROTO_IP6;
8906         }
8907       else if (unformat (i, "weight %d", &next_hop_weight))
8908         ;
8909       else if (unformat (i, "classify %d", &classify_table_index))
8910         {
8911           is_classify = 1;
8912         }
8913       else if (unformat (i, "del"))
8914         is_add = 0;
8915       else if (unformat (i, "add"))
8916         is_add = 1;
8917       else if (unformat (i, "resolve-via-host"))
8918         resolve_host = 1;
8919       else if (unformat (i, "resolve-via-attached"))
8920         resolve_attached = 1;
8921       else if (unformat (i, "multipath"))
8922         is_multipath = 1;
8923       else if (unformat (i, "count %d", &count))
8924         ;
8925       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8926         {
8927           next_hop_set = 1;
8928           next_hop_proto = DPO_PROTO_IP4;
8929         }
8930       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8931         {
8932           next_hop_set = 1;
8933           next_hop_proto = DPO_PROTO_IP6;
8934         }
8935       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8936         ;
8937       else if (unformat (i, "via-label %d", &next_hop_via_label))
8938         ;
8939       else if (unformat (i, "out-label %d", &next_hop_out_label))
8940         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8941       else
8942         {
8943           clib_warning ("parse error '%U'", format_unformat_error, i);
8944           return -99;
8945         }
8946     }
8947
8948   if (!next_hop_set && !is_classify)
8949     {
8950       errmsg ("next hop / classify not set");
8951       return -99;
8952     }
8953
8954   if (MPLS_LABEL_INVALID == local_label)
8955     {
8956       errmsg ("missing label");
8957       return -99;
8958     }
8959
8960   if (count > 1)
8961     {
8962       /* Turn on async mode */
8963       vam->async_mode = 1;
8964       vam->async_errors = 0;
8965       before = vat_time_now (vam);
8966     }
8967
8968   for (j = 0; j < count; j++)
8969     {
8970       /* Construct the API message */
8971       M2 (MPLS_ROUTE_ADD_DEL, mp,
8972           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8973
8974       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8975       mp->mr_table_id = ntohl (table_id);
8976
8977       mp->mr_is_add = is_add;
8978       mp->mr_next_hop_proto = next_hop_proto;
8979       mp->mr_is_classify = is_classify;
8980       mp->mr_is_multipath = is_multipath;
8981       mp->mr_is_resolve_host = resolve_host;
8982       mp->mr_is_resolve_attached = resolve_attached;
8983       mp->mr_next_hop_weight = next_hop_weight;
8984       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8985       mp->mr_classify_table_index = ntohl (classify_table_index);
8986       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8987       mp->mr_label = ntohl (local_label);
8988       mp->mr_eos = is_eos;
8989
8990       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8991       if (0 != mp->mr_next_hop_n_out_labels)
8992         {
8993           memcpy (mp->mr_next_hop_out_label_stack,
8994                   next_hop_out_label_stack,
8995                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8996           vec_free (next_hop_out_label_stack);
8997         }
8998
8999       if (next_hop_set)
9000         {
9001           if (DPO_PROTO_IP4 == next_hop_proto)
9002             {
9003               clib_memcpy (mp->mr_next_hop,
9004                            &v4_next_hop_address,
9005                            sizeof (v4_next_hop_address));
9006             }
9007           else if (DPO_PROTO_IP6 == next_hop_proto)
9008
9009             {
9010               clib_memcpy (mp->mr_next_hop,
9011                            &v6_next_hop_address,
9012                            sizeof (v6_next_hop_address));
9013             }
9014         }
9015       local_label++;
9016
9017       /* send it... */
9018       S (mp);
9019       /* If we receive SIGTERM, stop now... */
9020       if (vam->do_exit)
9021         break;
9022     }
9023
9024   /* When testing multiple add/del ops, use a control-ping to sync */
9025   if (count > 1)
9026     {
9027       vl_api_control_ping_t *mp_ping;
9028       f64 after;
9029       f64 timeout;
9030
9031       /* Shut off async mode */
9032       vam->async_mode = 0;
9033
9034       MPING (CONTROL_PING, mp_ping);
9035       S (mp_ping);
9036
9037       timeout = vat_time_now (vam) + 1.0;
9038       while (vat_time_now (vam) < timeout)
9039         if (vam->result_ready == 1)
9040           goto out;
9041       vam->retval = -99;
9042
9043     out:
9044       if (vam->retval == -99)
9045         errmsg ("timeout");
9046
9047       if (vam->async_errors > 0)
9048         {
9049           errmsg ("%d asynchronous errors", vam->async_errors);
9050           vam->retval = -98;
9051         }
9052       vam->async_errors = 0;
9053       after = vat_time_now (vam);
9054
9055       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9056       if (j > 0)
9057         count = j;
9058
9059       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9060              count, after - before, count / (after - before));
9061     }
9062   else
9063     {
9064       int ret;
9065
9066       /* Wait for a reply... */
9067       W (ret);
9068       return ret;
9069     }
9070
9071   /* Return the good/bad news */
9072   return (vam->retval);
9073 }
9074
9075 static int
9076 api_mpls_ip_bind_unbind (vat_main_t * vam)
9077 {
9078   unformat_input_t *i = vam->input;
9079   vl_api_mpls_ip_bind_unbind_t *mp;
9080   u32 ip_table_id = 0;
9081   u8 is_bind = 1;
9082   u8 is_ip4 = 1;
9083   ip4_address_t v4_address;
9084   ip6_address_t v6_address;
9085   u32 address_length;
9086   u8 address_set = 0;
9087   mpls_label_t local_label = MPLS_LABEL_INVALID;
9088   int ret;
9089
9090   /* Parse args required to build the message */
9091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9092     {
9093       if (unformat (i, "%U/%d", unformat_ip4_address,
9094                     &v4_address, &address_length))
9095         {
9096           is_ip4 = 1;
9097           address_set = 1;
9098         }
9099       else if (unformat (i, "%U/%d", unformat_ip6_address,
9100                          &v6_address, &address_length))
9101         {
9102           is_ip4 = 0;
9103           address_set = 1;
9104         }
9105       else if (unformat (i, "%d", &local_label))
9106         ;
9107       else if (unformat (i, "table-id %d", &ip_table_id))
9108         ;
9109       else if (unformat (i, "unbind"))
9110         is_bind = 0;
9111       else if (unformat (i, "bind"))
9112         is_bind = 1;
9113       else
9114         {
9115           clib_warning ("parse error '%U'", format_unformat_error, i);
9116           return -99;
9117         }
9118     }
9119
9120   if (!address_set)
9121     {
9122       errmsg ("IP addres not set");
9123       return -99;
9124     }
9125
9126   if (MPLS_LABEL_INVALID == local_label)
9127     {
9128       errmsg ("missing label");
9129       return -99;
9130     }
9131
9132   /* Construct the API message */
9133   M (MPLS_IP_BIND_UNBIND, mp);
9134
9135   mp->mb_is_bind = is_bind;
9136   mp->mb_is_ip4 = is_ip4;
9137   mp->mb_ip_table_id = ntohl (ip_table_id);
9138   mp->mb_mpls_table_id = 0;
9139   mp->mb_label = ntohl (local_label);
9140   mp->mb_address_length = address_length;
9141
9142   if (is_ip4)
9143     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9144   else
9145     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9146
9147   /* send it... */
9148   S (mp);
9149
9150   /* Wait for a reply... */
9151   W (ret);
9152   return ret;
9153 }
9154
9155 static int
9156 api_bier_table_add_del (vat_main_t * vam)
9157 {
9158   unformat_input_t *i = vam->input;
9159   vl_api_bier_table_add_del_t *mp;
9160   u8 is_add = 1;
9161   u32 set = 0, sub_domain = 0, hdr_len = 3;
9162   mpls_label_t local_label = MPLS_LABEL_INVALID;
9163   int ret;
9164
9165   /* Parse args required to build the message */
9166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9167     {
9168       if (unformat (i, "sub-domain %d", &sub_domain))
9169         ;
9170       else if (unformat (i, "set %d", &set))
9171         ;
9172       else if (unformat (i, "label %d", &local_label))
9173         ;
9174       else if (unformat (i, "hdr-len %d", &hdr_len))
9175         ;
9176       else if (unformat (i, "add"))
9177         is_add = 1;
9178       else if (unformat (i, "del"))
9179         is_add = 0;
9180       else
9181         {
9182           clib_warning ("parse error '%U'", format_unformat_error, i);
9183           return -99;
9184         }
9185     }
9186
9187   if (MPLS_LABEL_INVALID == local_label)
9188     {
9189       errmsg ("missing label\n");
9190       return -99;
9191     }
9192
9193   /* Construct the API message */
9194   M (BIER_TABLE_ADD_DEL, mp);
9195
9196   mp->bt_is_add = is_add;
9197   mp->bt_label = ntohl (local_label);
9198   mp->bt_tbl_id.bt_set = set;
9199   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9200   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9201
9202   /* send it... */
9203   S (mp);
9204
9205   /* Wait for a reply... */
9206   W (ret);
9207
9208   return (ret);
9209 }
9210
9211 static int
9212 api_bier_route_add_del (vat_main_t * vam)
9213 {
9214   unformat_input_t *i = vam->input;
9215   vl_api_bier_route_add_del_t *mp;
9216   u8 is_add = 1;
9217   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9218   ip4_address_t v4_next_hop_address;
9219   ip6_address_t v6_next_hop_address;
9220   u8 next_hop_set = 0;
9221   u8 next_hop_proto_is_ip4 = 1;
9222   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9223   int ret;
9224
9225   /* Parse args required to build the message */
9226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9227     {
9228       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9229         {
9230           next_hop_proto_is_ip4 = 1;
9231           next_hop_set = 1;
9232         }
9233       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9234         {
9235           next_hop_proto_is_ip4 = 0;
9236           next_hop_set = 1;
9237         }
9238       if (unformat (i, "sub-domain %d", &sub_domain))
9239         ;
9240       else if (unformat (i, "set %d", &set))
9241         ;
9242       else if (unformat (i, "hdr-len %d", &hdr_len))
9243         ;
9244       else if (unformat (i, "bp %d", &bp))
9245         ;
9246       else if (unformat (i, "add"))
9247         is_add = 1;
9248       else if (unformat (i, "del"))
9249         is_add = 0;
9250       else if (unformat (i, "out-label %d", &next_hop_out_label))
9251         ;
9252       else
9253         {
9254           clib_warning ("parse error '%U'", format_unformat_error, i);
9255           return -99;
9256         }
9257     }
9258
9259   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9260     {
9261       errmsg ("next hop / label set\n");
9262       return -99;
9263     }
9264   if (0 == bp)
9265     {
9266       errmsg ("bit=position not set\n");
9267       return -99;
9268     }
9269
9270   /* Construct the API message */
9271   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9272
9273   mp->br_is_add = is_add;
9274   mp->br_tbl_id.bt_set = set;
9275   mp->br_tbl_id.bt_sub_domain = sub_domain;
9276   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9277   mp->br_bp = ntohs (bp);
9278   mp->br_n_paths = 1;
9279   mp->br_paths[0].n_labels = 1;
9280   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9281   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9282
9283   if (next_hop_proto_is_ip4)
9284     {
9285       clib_memcpy (mp->br_paths[0].next_hop,
9286                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9287     }
9288   else
9289     {
9290       clib_memcpy (mp->br_paths[0].next_hop,
9291                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9292     }
9293
9294   /* send it... */
9295   S (mp);
9296
9297   /* Wait for a reply... */
9298   W (ret);
9299
9300   return (ret);
9301 }
9302
9303 static int
9304 api_proxy_arp_add_del (vat_main_t * vam)
9305 {
9306   unformat_input_t *i = vam->input;
9307   vl_api_proxy_arp_add_del_t *mp;
9308   u32 vrf_id = 0;
9309   u8 is_add = 1;
9310   ip4_address_t lo, hi;
9311   u8 range_set = 0;
9312   int ret;
9313
9314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9315     {
9316       if (unformat (i, "vrf %d", &vrf_id))
9317         ;
9318       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9319                          unformat_ip4_address, &hi))
9320         range_set = 1;
9321       else if (unformat (i, "del"))
9322         is_add = 0;
9323       else
9324         {
9325           clib_warning ("parse error '%U'", format_unformat_error, i);
9326           return -99;
9327         }
9328     }
9329
9330   if (range_set == 0)
9331     {
9332       errmsg ("address range not set");
9333       return -99;
9334     }
9335
9336   M (PROXY_ARP_ADD_DEL, mp);
9337
9338   mp->proxy.vrf_id = ntohl (vrf_id);
9339   mp->is_add = is_add;
9340   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9341   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9342
9343   S (mp);
9344   W (ret);
9345   return ret;
9346 }
9347
9348 static int
9349 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9350 {
9351   unformat_input_t *i = vam->input;
9352   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9353   u32 sw_if_index;
9354   u8 enable = 1;
9355   u8 sw_if_index_set = 0;
9356   int ret;
9357
9358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9359     {
9360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9361         sw_if_index_set = 1;
9362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9363         sw_if_index_set = 1;
9364       else if (unformat (i, "enable"))
9365         enable = 1;
9366       else if (unformat (i, "disable"))
9367         enable = 0;
9368       else
9369         {
9370           clib_warning ("parse error '%U'", format_unformat_error, i);
9371           return -99;
9372         }
9373     }
9374
9375   if (sw_if_index_set == 0)
9376     {
9377       errmsg ("missing interface name or sw_if_index");
9378       return -99;
9379     }
9380
9381   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9382
9383   mp->sw_if_index = ntohl (sw_if_index);
9384   mp->enable_disable = enable;
9385
9386   S (mp);
9387   W (ret);
9388   return ret;
9389 }
9390
9391 static int
9392 api_mpls_tunnel_add_del (vat_main_t * vam)
9393 {
9394   unformat_input_t *i = vam->input;
9395   vl_api_mpls_tunnel_add_del_t *mp;
9396
9397   u8 is_add = 1;
9398   u8 l2_only = 0;
9399   u32 sw_if_index = ~0;
9400   u32 next_hop_sw_if_index = ~0;
9401   u32 next_hop_proto_is_ip4 = 1;
9402
9403   u32 next_hop_table_id = 0;
9404   ip4_address_t v4_next_hop_address = {
9405     .as_u32 = 0,
9406   };
9407   ip6_address_t v6_next_hop_address = { {0} };
9408   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9409   int ret;
9410
9411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9412     {
9413       if (unformat (i, "add"))
9414         is_add = 1;
9415       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9416         is_add = 0;
9417       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9418         ;
9419       else if (unformat (i, "via %U",
9420                          unformat_ip4_address, &v4_next_hop_address))
9421         {
9422           next_hop_proto_is_ip4 = 1;
9423         }
9424       else if (unformat (i, "via %U",
9425                          unformat_ip6_address, &v6_next_hop_address))
9426         {
9427           next_hop_proto_is_ip4 = 0;
9428         }
9429       else if (unformat (i, "l2-only"))
9430         l2_only = 1;
9431       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9432         ;
9433       else if (unformat (i, "out-label %d", &next_hop_out_label))
9434         vec_add1 (labels, ntohl (next_hop_out_label));
9435       else
9436         {
9437           clib_warning ("parse error '%U'", format_unformat_error, i);
9438           return -99;
9439         }
9440     }
9441
9442   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9443
9444   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9445   mp->mt_sw_if_index = ntohl (sw_if_index);
9446   mp->mt_is_add = is_add;
9447   mp->mt_l2_only = l2_only;
9448   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9449   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9450
9451   mp->mt_next_hop_n_out_labels = vec_len (labels);
9452
9453   if (0 != mp->mt_next_hop_n_out_labels)
9454     {
9455       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9456                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9457       vec_free (labels);
9458     }
9459
9460   if (next_hop_proto_is_ip4)
9461     {
9462       clib_memcpy (mp->mt_next_hop,
9463                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9464     }
9465   else
9466     {
9467       clib_memcpy (mp->mt_next_hop,
9468                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9469     }
9470
9471   S (mp);
9472   W (ret);
9473   return ret;
9474 }
9475
9476 static int
9477 api_sw_interface_set_unnumbered (vat_main_t * vam)
9478 {
9479   unformat_input_t *i = vam->input;
9480   vl_api_sw_interface_set_unnumbered_t *mp;
9481   u32 sw_if_index;
9482   u32 unnum_sw_index = ~0;
9483   u8 is_add = 1;
9484   u8 sw_if_index_set = 0;
9485   int ret;
9486
9487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9488     {
9489       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9490         sw_if_index_set = 1;
9491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9492         sw_if_index_set = 1;
9493       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9494         ;
9495       else if (unformat (i, "del"))
9496         is_add = 0;
9497       else
9498         {
9499           clib_warning ("parse error '%U'", format_unformat_error, i);
9500           return -99;
9501         }
9502     }
9503
9504   if (sw_if_index_set == 0)
9505     {
9506       errmsg ("missing interface name or sw_if_index");
9507       return -99;
9508     }
9509
9510   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9511
9512   mp->sw_if_index = ntohl (sw_if_index);
9513   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9514   mp->is_add = is_add;
9515
9516   S (mp);
9517   W (ret);
9518   return ret;
9519 }
9520
9521 static int
9522 api_ip_neighbor_add_del (vat_main_t * vam)
9523 {
9524   unformat_input_t *i = vam->input;
9525   vl_api_ip_neighbor_add_del_t *mp;
9526   u32 sw_if_index;
9527   u8 sw_if_index_set = 0;
9528   u8 is_add = 1;
9529   u8 is_static = 0;
9530   u8 is_no_fib_entry = 0;
9531   u8 mac_address[6];
9532   u8 mac_set = 0;
9533   u8 v4_address_set = 0;
9534   u8 v6_address_set = 0;
9535   ip4_address_t v4address;
9536   ip6_address_t v6address;
9537   int ret;
9538
9539   memset (mac_address, 0, sizeof (mac_address));
9540
9541   /* Parse args required to build the message */
9542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9543     {
9544       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9545         {
9546           mac_set = 1;
9547         }
9548       else if (unformat (i, "del"))
9549         is_add = 0;
9550       else
9551         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9552         sw_if_index_set = 1;
9553       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9554         sw_if_index_set = 1;
9555       else if (unformat (i, "is_static"))
9556         is_static = 1;
9557       else if (unformat (i, "no-fib-entry"))
9558         is_no_fib_entry = 1;
9559       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9560         v4_address_set = 1;
9561       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9562         v6_address_set = 1;
9563       else
9564         {
9565           clib_warning ("parse error '%U'", format_unformat_error, i);
9566           return -99;
9567         }
9568     }
9569
9570   if (sw_if_index_set == 0)
9571     {
9572       errmsg ("missing interface name or sw_if_index");
9573       return -99;
9574     }
9575   if (v4_address_set && v6_address_set)
9576     {
9577       errmsg ("both v4 and v6 addresses set");
9578       return -99;
9579     }
9580   if (!v4_address_set && !v6_address_set)
9581     {
9582       errmsg ("no address set");
9583       return -99;
9584     }
9585
9586   /* Construct the API message */
9587   M (IP_NEIGHBOR_ADD_DEL, mp);
9588
9589   mp->sw_if_index = ntohl (sw_if_index);
9590   mp->is_add = is_add;
9591   mp->is_static = is_static;
9592   mp->is_no_adj_fib = is_no_fib_entry;
9593   if (mac_set)
9594     clib_memcpy (mp->mac_address, mac_address, 6);
9595   if (v6_address_set)
9596     {
9597       mp->is_ipv6 = 1;
9598       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9599     }
9600   else
9601     {
9602       /* mp->is_ipv6 = 0; via memset in M macro above */
9603       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9604     }
9605
9606   /* send it... */
9607   S (mp);
9608
9609   /* Wait for a reply, return good/bad news  */
9610   W (ret);
9611   return ret;
9612 }
9613
9614 static int
9615 api_create_vlan_subif (vat_main_t * vam)
9616 {
9617   unformat_input_t *i = vam->input;
9618   vl_api_create_vlan_subif_t *mp;
9619   u32 sw_if_index;
9620   u8 sw_if_index_set = 0;
9621   u32 vlan_id;
9622   u8 vlan_id_set = 0;
9623   int ret;
9624
9625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9626     {
9627       if (unformat (i, "sw_if_index %d", &sw_if_index))
9628         sw_if_index_set = 1;
9629       else
9630         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9631         sw_if_index_set = 1;
9632       else if (unformat (i, "vlan %d", &vlan_id))
9633         vlan_id_set = 1;
9634       else
9635         {
9636           clib_warning ("parse error '%U'", format_unformat_error, i);
9637           return -99;
9638         }
9639     }
9640
9641   if (sw_if_index_set == 0)
9642     {
9643       errmsg ("missing interface name or sw_if_index");
9644       return -99;
9645     }
9646
9647   if (vlan_id_set == 0)
9648     {
9649       errmsg ("missing vlan_id");
9650       return -99;
9651     }
9652   M (CREATE_VLAN_SUBIF, mp);
9653
9654   mp->sw_if_index = ntohl (sw_if_index);
9655   mp->vlan_id = ntohl (vlan_id);
9656
9657   S (mp);
9658   W (ret);
9659   return ret;
9660 }
9661
9662 #define foreach_create_subif_bit                \
9663 _(no_tags)                                      \
9664 _(one_tag)                                      \
9665 _(two_tags)                                     \
9666 _(dot1ad)                                       \
9667 _(exact_match)                                  \
9668 _(default_sub)                                  \
9669 _(outer_vlan_id_any)                            \
9670 _(inner_vlan_id_any)
9671
9672 static int
9673 api_create_subif (vat_main_t * vam)
9674 {
9675   unformat_input_t *i = vam->input;
9676   vl_api_create_subif_t *mp;
9677   u32 sw_if_index;
9678   u8 sw_if_index_set = 0;
9679   u32 sub_id;
9680   u8 sub_id_set = 0;
9681   u32 no_tags = 0;
9682   u32 one_tag = 0;
9683   u32 two_tags = 0;
9684   u32 dot1ad = 0;
9685   u32 exact_match = 0;
9686   u32 default_sub = 0;
9687   u32 outer_vlan_id_any = 0;
9688   u32 inner_vlan_id_any = 0;
9689   u32 tmp;
9690   u16 outer_vlan_id = 0;
9691   u16 inner_vlan_id = 0;
9692   int ret;
9693
9694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9695     {
9696       if (unformat (i, "sw_if_index %d", &sw_if_index))
9697         sw_if_index_set = 1;
9698       else
9699         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9700         sw_if_index_set = 1;
9701       else if (unformat (i, "sub_id %d", &sub_id))
9702         sub_id_set = 1;
9703       else if (unformat (i, "outer_vlan_id %d", &tmp))
9704         outer_vlan_id = tmp;
9705       else if (unformat (i, "inner_vlan_id %d", &tmp))
9706         inner_vlan_id = tmp;
9707
9708 #define _(a) else if (unformat (i, #a)) a = 1 ;
9709       foreach_create_subif_bit
9710 #undef _
9711         else
9712         {
9713           clib_warning ("parse error '%U'", format_unformat_error, i);
9714           return -99;
9715         }
9716     }
9717
9718   if (sw_if_index_set == 0)
9719     {
9720       errmsg ("missing interface name or sw_if_index");
9721       return -99;
9722     }
9723
9724   if (sub_id_set == 0)
9725     {
9726       errmsg ("missing sub_id");
9727       return -99;
9728     }
9729   M (CREATE_SUBIF, mp);
9730
9731   mp->sw_if_index = ntohl (sw_if_index);
9732   mp->sub_id = ntohl (sub_id);
9733
9734 #define _(a) mp->a = a;
9735   foreach_create_subif_bit;
9736 #undef _
9737
9738   mp->outer_vlan_id = ntohs (outer_vlan_id);
9739   mp->inner_vlan_id = ntohs (inner_vlan_id);
9740
9741   S (mp);
9742   W (ret);
9743   return ret;
9744 }
9745
9746 static int
9747 api_oam_add_del (vat_main_t * vam)
9748 {
9749   unformat_input_t *i = vam->input;
9750   vl_api_oam_add_del_t *mp;
9751   u32 vrf_id = 0;
9752   u8 is_add = 1;
9753   ip4_address_t src, dst;
9754   u8 src_set = 0;
9755   u8 dst_set = 0;
9756   int ret;
9757
9758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9759     {
9760       if (unformat (i, "vrf %d", &vrf_id))
9761         ;
9762       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9763         src_set = 1;
9764       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9765         dst_set = 1;
9766       else if (unformat (i, "del"))
9767         is_add = 0;
9768       else
9769         {
9770           clib_warning ("parse error '%U'", format_unformat_error, i);
9771           return -99;
9772         }
9773     }
9774
9775   if (src_set == 0)
9776     {
9777       errmsg ("missing src addr");
9778       return -99;
9779     }
9780
9781   if (dst_set == 0)
9782     {
9783       errmsg ("missing dst addr");
9784       return -99;
9785     }
9786
9787   M (OAM_ADD_DEL, mp);
9788
9789   mp->vrf_id = ntohl (vrf_id);
9790   mp->is_add = is_add;
9791   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9792   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9793
9794   S (mp);
9795   W (ret);
9796   return ret;
9797 }
9798
9799 static int
9800 api_reset_fib (vat_main_t * vam)
9801 {
9802   unformat_input_t *i = vam->input;
9803   vl_api_reset_fib_t *mp;
9804   u32 vrf_id = 0;
9805   u8 is_ipv6 = 0;
9806   u8 vrf_id_set = 0;
9807
9808   int ret;
9809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9810     {
9811       if (unformat (i, "vrf %d", &vrf_id))
9812         vrf_id_set = 1;
9813       else if (unformat (i, "ipv6"))
9814         is_ipv6 = 1;
9815       else
9816         {
9817           clib_warning ("parse error '%U'", format_unformat_error, i);
9818           return -99;
9819         }
9820     }
9821
9822   if (vrf_id_set == 0)
9823     {
9824       errmsg ("missing vrf id");
9825       return -99;
9826     }
9827
9828   M (RESET_FIB, mp);
9829
9830   mp->vrf_id = ntohl (vrf_id);
9831   mp->is_ipv6 = is_ipv6;
9832
9833   S (mp);
9834   W (ret);
9835   return ret;
9836 }
9837
9838 static int
9839 api_dhcp_proxy_config (vat_main_t * vam)
9840 {
9841   unformat_input_t *i = vam->input;
9842   vl_api_dhcp_proxy_config_t *mp;
9843   u32 rx_vrf_id = 0;
9844   u32 server_vrf_id = 0;
9845   u8 is_add = 1;
9846   u8 v4_address_set = 0;
9847   u8 v6_address_set = 0;
9848   ip4_address_t v4address;
9849   ip6_address_t v6address;
9850   u8 v4_src_address_set = 0;
9851   u8 v6_src_address_set = 0;
9852   ip4_address_t v4srcaddress;
9853   ip6_address_t v6srcaddress;
9854   int ret;
9855
9856   /* Parse args required to build the message */
9857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9858     {
9859       if (unformat (i, "del"))
9860         is_add = 0;
9861       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9862         ;
9863       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9864         ;
9865       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9866         v4_address_set = 1;
9867       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9868         v6_address_set = 1;
9869       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9870         v4_src_address_set = 1;
9871       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9872         v6_src_address_set = 1;
9873       else
9874         break;
9875     }
9876
9877   if (v4_address_set && v6_address_set)
9878     {
9879       errmsg ("both v4 and v6 server addresses set");
9880       return -99;
9881     }
9882   if (!v4_address_set && !v6_address_set)
9883     {
9884       errmsg ("no server addresses set");
9885       return -99;
9886     }
9887
9888   if (v4_src_address_set && v6_src_address_set)
9889     {
9890       errmsg ("both v4 and v6  src addresses set");
9891       return -99;
9892     }
9893   if (!v4_src_address_set && !v6_src_address_set)
9894     {
9895       errmsg ("no src addresses set");
9896       return -99;
9897     }
9898
9899   if (!(v4_src_address_set && v4_address_set) &&
9900       !(v6_src_address_set && v6_address_set))
9901     {
9902       errmsg ("no matching server and src addresses set");
9903       return -99;
9904     }
9905
9906   /* Construct the API message */
9907   M (DHCP_PROXY_CONFIG, mp);
9908
9909   mp->is_add = is_add;
9910   mp->rx_vrf_id = ntohl (rx_vrf_id);
9911   mp->server_vrf_id = ntohl (server_vrf_id);
9912   if (v6_address_set)
9913     {
9914       mp->is_ipv6 = 1;
9915       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9916       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9917     }
9918   else
9919     {
9920       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9921       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9922     }
9923
9924   /* send it... */
9925   S (mp);
9926
9927   /* Wait for a reply, return good/bad news  */
9928   W (ret);
9929   return ret;
9930 }
9931
9932 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9933 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9934
9935 static void
9936 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9937 {
9938   vat_main_t *vam = &vat_main;
9939   u32 i, count = mp->count;
9940   vl_api_dhcp_server_t *s;
9941
9942   if (mp->is_ipv6)
9943     print (vam->ofp,
9944            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9945            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9946            ntohl (mp->rx_vrf_id),
9947            format_ip6_address, mp->dhcp_src_address,
9948            mp->vss_type, mp->vss_vpn_ascii_id,
9949            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9950   else
9951     print (vam->ofp,
9952            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9953            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9954            ntohl (mp->rx_vrf_id),
9955            format_ip4_address, mp->dhcp_src_address,
9956            mp->vss_type, mp->vss_vpn_ascii_id,
9957            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9958
9959   for (i = 0; i < count; i++)
9960     {
9961       s = &mp->servers[i];
9962
9963       if (mp->is_ipv6)
9964         print (vam->ofp,
9965                " Server Table-ID %d, Server Address %U",
9966                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9967       else
9968         print (vam->ofp,
9969                " Server Table-ID %d, Server Address %U",
9970                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9971     }
9972 }
9973
9974 static void vl_api_dhcp_proxy_details_t_handler_json
9975   (vl_api_dhcp_proxy_details_t * mp)
9976 {
9977   vat_main_t *vam = &vat_main;
9978   vat_json_node_t *node = NULL;
9979   u32 i, count = mp->count;
9980   struct in_addr ip4;
9981   struct in6_addr ip6;
9982   vl_api_dhcp_server_t *s;
9983
9984   if (VAT_JSON_ARRAY != vam->json_tree.type)
9985     {
9986       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9987       vat_json_init_array (&vam->json_tree);
9988     }
9989   node = vat_json_array_add (&vam->json_tree);
9990
9991   vat_json_init_object (node);
9992   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9993   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9994                              sizeof (mp->vss_type));
9995   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9996                                    mp->vss_vpn_ascii_id);
9997   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9998   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9999
10000   if (mp->is_ipv6)
10001     {
10002       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10003       vat_json_object_add_ip6 (node, "src_address", ip6);
10004     }
10005   else
10006     {
10007       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10008       vat_json_object_add_ip4 (node, "src_address", ip4);
10009     }
10010
10011   for (i = 0; i < count; i++)
10012     {
10013       s = &mp->servers[i];
10014
10015       vat_json_object_add_uint (node, "server-table-id",
10016                                 ntohl (s->server_vrf_id));
10017
10018       if (mp->is_ipv6)
10019         {
10020           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10021           vat_json_object_add_ip4 (node, "src_address", ip4);
10022         }
10023       else
10024         {
10025           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10026           vat_json_object_add_ip6 (node, "server_address", ip6);
10027         }
10028     }
10029 }
10030
10031 static int
10032 api_dhcp_proxy_dump (vat_main_t * vam)
10033 {
10034   unformat_input_t *i = vam->input;
10035   vl_api_control_ping_t *mp_ping;
10036   vl_api_dhcp_proxy_dump_t *mp;
10037   u8 is_ipv6 = 0;
10038   int ret;
10039
10040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10041     {
10042       if (unformat (i, "ipv6"))
10043         is_ipv6 = 1;
10044       else
10045         {
10046           clib_warning ("parse error '%U'", format_unformat_error, i);
10047           return -99;
10048         }
10049     }
10050
10051   M (DHCP_PROXY_DUMP, mp);
10052
10053   mp->is_ip6 = is_ipv6;
10054   S (mp);
10055
10056   /* Use a control ping for synchronization */
10057   MPING (CONTROL_PING, mp_ping);
10058   S (mp_ping);
10059
10060   W (ret);
10061   return ret;
10062 }
10063
10064 static int
10065 api_dhcp_proxy_set_vss (vat_main_t * vam)
10066 {
10067   unformat_input_t *i = vam->input;
10068   vl_api_dhcp_proxy_set_vss_t *mp;
10069   u8 is_ipv6 = 0;
10070   u8 is_add = 1;
10071   u32 tbl_id = ~0;
10072   u8 vss_type = VSS_TYPE_DEFAULT;
10073   u8 *vpn_ascii_id = 0;
10074   u32 oui = 0;
10075   u32 fib_id = 0;
10076   int ret;
10077
10078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10079     {
10080       if (unformat (i, "tbl_id %d", &tbl_id))
10081         ;
10082       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10083         vss_type = VSS_TYPE_ASCII;
10084       else if (unformat (i, "fib_id %d", &fib_id))
10085         vss_type = VSS_TYPE_VPN_ID;
10086       else if (unformat (i, "oui %d", &oui))
10087         vss_type = VSS_TYPE_VPN_ID;
10088       else if (unformat (i, "ipv6"))
10089         is_ipv6 = 1;
10090       else if (unformat (i, "del"))
10091         is_add = 0;
10092       else
10093         break;
10094     }
10095
10096   if (tbl_id == ~0)
10097     {
10098       errmsg ("missing tbl_id ");
10099       vec_free (vpn_ascii_id);
10100       return -99;
10101     }
10102
10103   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10104     {
10105       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10106       vec_free (vpn_ascii_id);
10107       return -99;
10108     }
10109
10110   M (DHCP_PROXY_SET_VSS, mp);
10111   mp->tbl_id = ntohl (tbl_id);
10112   mp->vss_type = vss_type;
10113   if (vpn_ascii_id)
10114     {
10115       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10116       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10117     }
10118   mp->vpn_index = ntohl (fib_id);
10119   mp->oui = ntohl (oui);
10120   mp->is_ipv6 = is_ipv6;
10121   mp->is_add = is_add;
10122
10123   S (mp);
10124   W (ret);
10125
10126   vec_free (vpn_ascii_id);
10127   return ret;
10128 }
10129
10130 static int
10131 api_dhcp_client_config (vat_main_t * vam)
10132 {
10133   unformat_input_t *i = vam->input;
10134   vl_api_dhcp_client_config_t *mp;
10135   u32 sw_if_index;
10136   u8 sw_if_index_set = 0;
10137   u8 is_add = 1;
10138   u8 *hostname = 0;
10139   u8 disable_event = 0;
10140   int ret;
10141
10142   /* Parse args required to build the message */
10143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (i, "del"))
10146         is_add = 0;
10147       else
10148         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10149         sw_if_index_set = 1;
10150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10151         sw_if_index_set = 1;
10152       else if (unformat (i, "hostname %s", &hostname))
10153         ;
10154       else if (unformat (i, "disable_event"))
10155         disable_event = 1;
10156       else
10157         break;
10158     }
10159
10160   if (sw_if_index_set == 0)
10161     {
10162       errmsg ("missing interface name or sw_if_index");
10163       return -99;
10164     }
10165
10166   if (vec_len (hostname) > 63)
10167     {
10168       errmsg ("hostname too long");
10169     }
10170   vec_add1 (hostname, 0);
10171
10172   /* Construct the API message */
10173   M (DHCP_CLIENT_CONFIG, mp);
10174
10175   mp->is_add = is_add;
10176   mp->client.sw_if_index = htonl (sw_if_index);
10177   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10178   vec_free (hostname);
10179   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10180   mp->client.pid = htonl (getpid ());
10181
10182   /* send it... */
10183   S (mp);
10184
10185   /* Wait for a reply, return good/bad news  */
10186   W (ret);
10187   return ret;
10188 }
10189
10190 static int
10191 api_set_ip_flow_hash (vat_main_t * vam)
10192 {
10193   unformat_input_t *i = vam->input;
10194   vl_api_set_ip_flow_hash_t *mp;
10195   u32 vrf_id = 0;
10196   u8 is_ipv6 = 0;
10197   u8 vrf_id_set = 0;
10198   u8 src = 0;
10199   u8 dst = 0;
10200   u8 sport = 0;
10201   u8 dport = 0;
10202   u8 proto = 0;
10203   u8 reverse = 0;
10204   int ret;
10205
10206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10207     {
10208       if (unformat (i, "vrf %d", &vrf_id))
10209         vrf_id_set = 1;
10210       else if (unformat (i, "ipv6"))
10211         is_ipv6 = 1;
10212       else if (unformat (i, "src"))
10213         src = 1;
10214       else if (unformat (i, "dst"))
10215         dst = 1;
10216       else if (unformat (i, "sport"))
10217         sport = 1;
10218       else if (unformat (i, "dport"))
10219         dport = 1;
10220       else if (unformat (i, "proto"))
10221         proto = 1;
10222       else if (unformat (i, "reverse"))
10223         reverse = 1;
10224
10225       else
10226         {
10227           clib_warning ("parse error '%U'", format_unformat_error, i);
10228           return -99;
10229         }
10230     }
10231
10232   if (vrf_id_set == 0)
10233     {
10234       errmsg ("missing vrf id");
10235       return -99;
10236     }
10237
10238   M (SET_IP_FLOW_HASH, mp);
10239   mp->src = src;
10240   mp->dst = dst;
10241   mp->sport = sport;
10242   mp->dport = dport;
10243   mp->proto = proto;
10244   mp->reverse = reverse;
10245   mp->vrf_id = ntohl (vrf_id);
10246   mp->is_ipv6 = is_ipv6;
10247
10248   S (mp);
10249   W (ret);
10250   return ret;
10251 }
10252
10253 static int
10254 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10255 {
10256   unformat_input_t *i = vam->input;
10257   vl_api_sw_interface_ip6_enable_disable_t *mp;
10258   u32 sw_if_index;
10259   u8 sw_if_index_set = 0;
10260   u8 enable = 0;
10261   int ret;
10262
10263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10264     {
10265       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10266         sw_if_index_set = 1;
10267       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10268         sw_if_index_set = 1;
10269       else if (unformat (i, "enable"))
10270         enable = 1;
10271       else if (unformat (i, "disable"))
10272         enable = 0;
10273       else
10274         {
10275           clib_warning ("parse error '%U'", format_unformat_error, i);
10276           return -99;
10277         }
10278     }
10279
10280   if (sw_if_index_set == 0)
10281     {
10282       errmsg ("missing interface name or sw_if_index");
10283       return -99;
10284     }
10285
10286   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10287
10288   mp->sw_if_index = ntohl (sw_if_index);
10289   mp->enable = enable;
10290
10291   S (mp);
10292   W (ret);
10293   return ret;
10294 }
10295
10296 static int
10297 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10298 {
10299   unformat_input_t *i = vam->input;
10300   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10301   u32 sw_if_index;
10302   u8 sw_if_index_set = 0;
10303   u8 v6_address_set = 0;
10304   ip6_address_t v6address;
10305   int ret;
10306
10307   /* Parse args required to build the message */
10308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10309     {
10310       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10311         sw_if_index_set = 1;
10312       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10313         sw_if_index_set = 1;
10314       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10315         v6_address_set = 1;
10316       else
10317         break;
10318     }
10319
10320   if (sw_if_index_set == 0)
10321     {
10322       errmsg ("missing interface name or sw_if_index");
10323       return -99;
10324     }
10325   if (!v6_address_set)
10326     {
10327       errmsg ("no address set");
10328       return -99;
10329     }
10330
10331   /* Construct the API message */
10332   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10333
10334   mp->sw_if_index = ntohl (sw_if_index);
10335   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10336
10337   /* send it... */
10338   S (mp);
10339
10340   /* Wait for a reply, return good/bad news  */
10341   W (ret);
10342   return ret;
10343 }
10344
10345 static int
10346 api_ip6nd_proxy_add_del (vat_main_t * vam)
10347 {
10348   unformat_input_t *i = vam->input;
10349   vl_api_ip6nd_proxy_add_del_t *mp;
10350   u32 sw_if_index = ~0;
10351   u8 v6_address_set = 0;
10352   ip6_address_t v6address;
10353   u8 is_del = 0;
10354   int ret;
10355
10356   /* Parse args required to build the message */
10357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10358     {
10359       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10360         ;
10361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10362         ;
10363       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10364         v6_address_set = 1;
10365       if (unformat (i, "del"))
10366         is_del = 1;
10367       else
10368         {
10369           clib_warning ("parse error '%U'", format_unformat_error, i);
10370           return -99;
10371         }
10372     }
10373
10374   if (sw_if_index == ~0)
10375     {
10376       errmsg ("missing interface name or sw_if_index");
10377       return -99;
10378     }
10379   if (!v6_address_set)
10380     {
10381       errmsg ("no address set");
10382       return -99;
10383     }
10384
10385   /* Construct the API message */
10386   M (IP6ND_PROXY_ADD_DEL, mp);
10387
10388   mp->is_del = is_del;
10389   mp->sw_if_index = ntohl (sw_if_index);
10390   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10391
10392   /* send it... */
10393   S (mp);
10394
10395   /* Wait for a reply, return good/bad news  */
10396   W (ret);
10397   return ret;
10398 }
10399
10400 static int
10401 api_ip6nd_proxy_dump (vat_main_t * vam)
10402 {
10403   vl_api_ip6nd_proxy_dump_t *mp;
10404   vl_api_control_ping_t *mp_ping;
10405   int ret;
10406
10407   M (IP6ND_PROXY_DUMP, mp);
10408
10409   S (mp);
10410
10411   /* Use a control ping for synchronization */
10412   MPING (CONTROL_PING, mp_ping);
10413   S (mp_ping);
10414
10415   W (ret);
10416   return ret;
10417 }
10418
10419 static void vl_api_ip6nd_proxy_details_t_handler
10420   (vl_api_ip6nd_proxy_details_t * mp)
10421 {
10422   vat_main_t *vam = &vat_main;
10423
10424   print (vam->ofp, "host %U sw_if_index %d",
10425          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10426 }
10427
10428 static void vl_api_ip6nd_proxy_details_t_handler_json
10429   (vl_api_ip6nd_proxy_details_t * mp)
10430 {
10431   vat_main_t *vam = &vat_main;
10432   struct in6_addr ip6;
10433   vat_json_node_t *node = NULL;
10434
10435   if (VAT_JSON_ARRAY != vam->json_tree.type)
10436     {
10437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10438       vat_json_init_array (&vam->json_tree);
10439     }
10440   node = vat_json_array_add (&vam->json_tree);
10441
10442   vat_json_init_object (node);
10443   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10444
10445   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10446   vat_json_object_add_ip6 (node, "host", ip6);
10447 }
10448
10449 static int
10450 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10451 {
10452   unformat_input_t *i = vam->input;
10453   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10454   u32 sw_if_index;
10455   u8 sw_if_index_set = 0;
10456   u32 address_length = 0;
10457   u8 v6_address_set = 0;
10458   ip6_address_t v6address;
10459   u8 use_default = 0;
10460   u8 no_advertise = 0;
10461   u8 off_link = 0;
10462   u8 no_autoconfig = 0;
10463   u8 no_onlink = 0;
10464   u8 is_no = 0;
10465   u32 val_lifetime = 0;
10466   u32 pref_lifetime = 0;
10467   int ret;
10468
10469   /* Parse args required to build the message */
10470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10471     {
10472       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10473         sw_if_index_set = 1;
10474       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10475         sw_if_index_set = 1;
10476       else if (unformat (i, "%U/%d",
10477                          unformat_ip6_address, &v6address, &address_length))
10478         v6_address_set = 1;
10479       else if (unformat (i, "val_life %d", &val_lifetime))
10480         ;
10481       else if (unformat (i, "pref_life %d", &pref_lifetime))
10482         ;
10483       else if (unformat (i, "def"))
10484         use_default = 1;
10485       else if (unformat (i, "noadv"))
10486         no_advertise = 1;
10487       else if (unformat (i, "offl"))
10488         off_link = 1;
10489       else if (unformat (i, "noauto"))
10490         no_autoconfig = 1;
10491       else if (unformat (i, "nolink"))
10492         no_onlink = 1;
10493       else if (unformat (i, "isno"))
10494         is_no = 1;
10495       else
10496         {
10497           clib_warning ("parse error '%U'", format_unformat_error, i);
10498           return -99;
10499         }
10500     }
10501
10502   if (sw_if_index_set == 0)
10503     {
10504       errmsg ("missing interface name or sw_if_index");
10505       return -99;
10506     }
10507   if (!v6_address_set)
10508     {
10509       errmsg ("no address set");
10510       return -99;
10511     }
10512
10513   /* Construct the API message */
10514   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10515
10516   mp->sw_if_index = ntohl (sw_if_index);
10517   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10518   mp->address_length = address_length;
10519   mp->use_default = use_default;
10520   mp->no_advertise = no_advertise;
10521   mp->off_link = off_link;
10522   mp->no_autoconfig = no_autoconfig;
10523   mp->no_onlink = no_onlink;
10524   mp->is_no = is_no;
10525   mp->val_lifetime = ntohl (val_lifetime);
10526   mp->pref_lifetime = ntohl (pref_lifetime);
10527
10528   /* send it... */
10529   S (mp);
10530
10531   /* Wait for a reply, return good/bad news  */
10532   W (ret);
10533   return ret;
10534 }
10535
10536 static int
10537 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10538 {
10539   unformat_input_t *i = vam->input;
10540   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10541   u32 sw_if_index;
10542   u8 sw_if_index_set = 0;
10543   u8 suppress = 0;
10544   u8 managed = 0;
10545   u8 other = 0;
10546   u8 ll_option = 0;
10547   u8 send_unicast = 0;
10548   u8 cease = 0;
10549   u8 is_no = 0;
10550   u8 default_router = 0;
10551   u32 max_interval = 0;
10552   u32 min_interval = 0;
10553   u32 lifetime = 0;
10554   u32 initial_count = 0;
10555   u32 initial_interval = 0;
10556   int ret;
10557
10558
10559   /* Parse args required to build the message */
10560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10561     {
10562       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10563         sw_if_index_set = 1;
10564       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10565         sw_if_index_set = 1;
10566       else if (unformat (i, "maxint %d", &max_interval))
10567         ;
10568       else if (unformat (i, "minint %d", &min_interval))
10569         ;
10570       else if (unformat (i, "life %d", &lifetime))
10571         ;
10572       else if (unformat (i, "count %d", &initial_count))
10573         ;
10574       else if (unformat (i, "interval %d", &initial_interval))
10575         ;
10576       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10577         suppress = 1;
10578       else if (unformat (i, "managed"))
10579         managed = 1;
10580       else if (unformat (i, "other"))
10581         other = 1;
10582       else if (unformat (i, "ll"))
10583         ll_option = 1;
10584       else if (unformat (i, "send"))
10585         send_unicast = 1;
10586       else if (unformat (i, "cease"))
10587         cease = 1;
10588       else if (unformat (i, "isno"))
10589         is_no = 1;
10590       else if (unformat (i, "def"))
10591         default_router = 1;
10592       else
10593         {
10594           clib_warning ("parse error '%U'", format_unformat_error, i);
10595           return -99;
10596         }
10597     }
10598
10599   if (sw_if_index_set == 0)
10600     {
10601       errmsg ("missing interface name or sw_if_index");
10602       return -99;
10603     }
10604
10605   /* Construct the API message */
10606   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10607
10608   mp->sw_if_index = ntohl (sw_if_index);
10609   mp->max_interval = ntohl (max_interval);
10610   mp->min_interval = ntohl (min_interval);
10611   mp->lifetime = ntohl (lifetime);
10612   mp->initial_count = ntohl (initial_count);
10613   mp->initial_interval = ntohl (initial_interval);
10614   mp->suppress = suppress;
10615   mp->managed = managed;
10616   mp->other = other;
10617   mp->ll_option = ll_option;
10618   mp->send_unicast = send_unicast;
10619   mp->cease = cease;
10620   mp->is_no = is_no;
10621   mp->default_router = default_router;
10622
10623   /* send it... */
10624   S (mp);
10625
10626   /* Wait for a reply, return good/bad news  */
10627   W (ret);
10628   return ret;
10629 }
10630
10631 static int
10632 api_set_arp_neighbor_limit (vat_main_t * vam)
10633 {
10634   unformat_input_t *i = vam->input;
10635   vl_api_set_arp_neighbor_limit_t *mp;
10636   u32 arp_nbr_limit;
10637   u8 limit_set = 0;
10638   u8 is_ipv6 = 0;
10639   int ret;
10640
10641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10642     {
10643       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10644         limit_set = 1;
10645       else if (unformat (i, "ipv6"))
10646         is_ipv6 = 1;
10647       else
10648         {
10649           clib_warning ("parse error '%U'", format_unformat_error, i);
10650           return -99;
10651         }
10652     }
10653
10654   if (limit_set == 0)
10655     {
10656       errmsg ("missing limit value");
10657       return -99;
10658     }
10659
10660   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10661
10662   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10663   mp->is_ipv6 = is_ipv6;
10664
10665   S (mp);
10666   W (ret);
10667   return ret;
10668 }
10669
10670 static int
10671 api_l2_patch_add_del (vat_main_t * vam)
10672 {
10673   unformat_input_t *i = vam->input;
10674   vl_api_l2_patch_add_del_t *mp;
10675   u32 rx_sw_if_index;
10676   u8 rx_sw_if_index_set = 0;
10677   u32 tx_sw_if_index;
10678   u8 tx_sw_if_index_set = 0;
10679   u8 is_add = 1;
10680   int ret;
10681
10682   /* Parse args required to build the message */
10683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10684     {
10685       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10686         rx_sw_if_index_set = 1;
10687       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10688         tx_sw_if_index_set = 1;
10689       else if (unformat (i, "rx"))
10690         {
10691           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10692             {
10693               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10694                             &rx_sw_if_index))
10695                 rx_sw_if_index_set = 1;
10696             }
10697           else
10698             break;
10699         }
10700       else if (unformat (i, "tx"))
10701         {
10702           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10703             {
10704               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10705                             &tx_sw_if_index))
10706                 tx_sw_if_index_set = 1;
10707             }
10708           else
10709             break;
10710         }
10711       else if (unformat (i, "del"))
10712         is_add = 0;
10713       else
10714         break;
10715     }
10716
10717   if (rx_sw_if_index_set == 0)
10718     {
10719       errmsg ("missing rx interface name or rx_sw_if_index");
10720       return -99;
10721     }
10722
10723   if (tx_sw_if_index_set == 0)
10724     {
10725       errmsg ("missing tx interface name or tx_sw_if_index");
10726       return -99;
10727     }
10728
10729   M (L2_PATCH_ADD_DEL, mp);
10730
10731   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10732   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10733   mp->is_add = is_add;
10734
10735   S (mp);
10736   W (ret);
10737   return ret;
10738 }
10739
10740 u8 is_del;
10741 u8 localsid_addr[16];
10742 u8 end_psp;
10743 u8 behavior;
10744 u32 sw_if_index;
10745 u32 vlan_index;
10746 u32 fib_table;
10747 u8 nh_addr[16];
10748
10749 static int
10750 api_sr_localsid_add_del (vat_main_t * vam)
10751 {
10752   unformat_input_t *i = vam->input;
10753   vl_api_sr_localsid_add_del_t *mp;
10754
10755   u8 is_del;
10756   ip6_address_t localsid;
10757   u8 end_psp = 0;
10758   u8 behavior = ~0;
10759   u32 sw_if_index;
10760   u32 fib_table = ~(u32) 0;
10761   ip6_address_t nh_addr6;
10762   ip4_address_t nh_addr4;
10763   memset (&nh_addr6, 0, sizeof (ip6_address_t));
10764   memset (&nh_addr4, 0, sizeof (ip4_address_t));
10765
10766   bool nexthop_set = 0;
10767
10768   int ret;
10769
10770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10771     {
10772       if (unformat (i, "del"))
10773         is_del = 1;
10774       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10775       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10776         nexthop_set = 1;
10777       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10778         nexthop_set = 1;
10779       else if (unformat (i, "behavior %u", &behavior));
10780       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10781       else if (unformat (i, "fib-table %u", &fib_table));
10782       else if (unformat (i, "end.psp %u", &behavior));
10783       else
10784         break;
10785     }
10786
10787   M (SR_LOCALSID_ADD_DEL, mp);
10788
10789   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10790   if (nexthop_set)
10791     {
10792       clib_memcpy (mp->nh_addr6, &nh_addr4, sizeof (mp->nh_addr6));
10793       clib_memcpy (mp->nh_addr4, &nh_addr6, sizeof (mp->nh_addr4));
10794     }
10795   mp->behavior = behavior;
10796   mp->sw_if_index = ntohl (sw_if_index);
10797   mp->fib_table = ntohl (fib_table);
10798   mp->end_psp = end_psp;
10799   mp->is_del = is_del;
10800
10801   S (mp);
10802   W (ret);
10803   return ret;
10804 }
10805
10806 static int
10807 api_ioam_enable (vat_main_t * vam)
10808 {
10809   unformat_input_t *input = vam->input;
10810   vl_api_ioam_enable_t *mp;
10811   u32 id = 0;
10812   int has_trace_option = 0;
10813   int has_pot_option = 0;
10814   int has_seqno_option = 0;
10815   int has_analyse_option = 0;
10816   int ret;
10817
10818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10819     {
10820       if (unformat (input, "trace"))
10821         has_trace_option = 1;
10822       else if (unformat (input, "pot"))
10823         has_pot_option = 1;
10824       else if (unformat (input, "seqno"))
10825         has_seqno_option = 1;
10826       else if (unformat (input, "analyse"))
10827         has_analyse_option = 1;
10828       else
10829         break;
10830     }
10831   M (IOAM_ENABLE, mp);
10832   mp->id = htons (id);
10833   mp->seqno = has_seqno_option;
10834   mp->analyse = has_analyse_option;
10835   mp->pot_enable = has_pot_option;
10836   mp->trace_enable = has_trace_option;
10837
10838   S (mp);
10839   W (ret);
10840   return ret;
10841 }
10842
10843
10844 static int
10845 api_ioam_disable (vat_main_t * vam)
10846 {
10847   vl_api_ioam_disable_t *mp;
10848   int ret;
10849
10850   M (IOAM_DISABLE, mp);
10851   S (mp);
10852   W (ret);
10853   return ret;
10854 }
10855
10856 #define foreach_tcp_proto_field                 \
10857 _(src_port)                                     \
10858 _(dst_port)
10859
10860 #define foreach_udp_proto_field                 \
10861 _(src_port)                                     \
10862 _(dst_port)
10863
10864 #define foreach_ip4_proto_field                 \
10865 _(src_address)                                  \
10866 _(dst_address)                                  \
10867 _(tos)                                          \
10868 _(length)                                       \
10869 _(fragment_id)                                  \
10870 _(ttl)                                          \
10871 _(protocol)                                     \
10872 _(checksum)
10873
10874 typedef struct
10875 {
10876   u16 src_port, dst_port;
10877 } tcpudp_header_t;
10878
10879 #if VPP_API_TEST_BUILTIN == 0
10880 uword
10881 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10882 {
10883   u8 **maskp = va_arg (*args, u8 **);
10884   u8 *mask = 0;
10885   u8 found_something = 0;
10886   tcp_header_t *tcp;
10887
10888 #define _(a) u8 a=0;
10889   foreach_tcp_proto_field;
10890 #undef _
10891
10892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10893     {
10894       if (0);
10895 #define _(a) else if (unformat (input, #a)) a=1;
10896       foreach_tcp_proto_field
10897 #undef _
10898         else
10899         break;
10900     }
10901
10902 #define _(a) found_something += a;
10903   foreach_tcp_proto_field;
10904 #undef _
10905
10906   if (found_something == 0)
10907     return 0;
10908
10909   vec_validate (mask, sizeof (*tcp) - 1);
10910
10911   tcp = (tcp_header_t *) mask;
10912
10913 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10914   foreach_tcp_proto_field;
10915 #undef _
10916
10917   *maskp = mask;
10918   return 1;
10919 }
10920
10921 uword
10922 unformat_udp_mask (unformat_input_t * input, va_list * args)
10923 {
10924   u8 **maskp = va_arg (*args, u8 **);
10925   u8 *mask = 0;
10926   u8 found_something = 0;
10927   udp_header_t *udp;
10928
10929 #define _(a) u8 a=0;
10930   foreach_udp_proto_field;
10931 #undef _
10932
10933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10934     {
10935       if (0);
10936 #define _(a) else if (unformat (input, #a)) a=1;
10937       foreach_udp_proto_field
10938 #undef _
10939         else
10940         break;
10941     }
10942
10943 #define _(a) found_something += a;
10944   foreach_udp_proto_field;
10945 #undef _
10946
10947   if (found_something == 0)
10948     return 0;
10949
10950   vec_validate (mask, sizeof (*udp) - 1);
10951
10952   udp = (udp_header_t *) mask;
10953
10954 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10955   foreach_udp_proto_field;
10956 #undef _
10957
10958   *maskp = mask;
10959   return 1;
10960 }
10961
10962 uword
10963 unformat_l4_mask (unformat_input_t * input, va_list * args)
10964 {
10965   u8 **maskp = va_arg (*args, u8 **);
10966   u16 src_port = 0, dst_port = 0;
10967   tcpudp_header_t *tcpudp;
10968
10969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10970     {
10971       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10972         return 1;
10973       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10974         return 1;
10975       else if (unformat (input, "src_port"))
10976         src_port = 0xFFFF;
10977       else if (unformat (input, "dst_port"))
10978         dst_port = 0xFFFF;
10979       else
10980         return 0;
10981     }
10982
10983   if (!src_port && !dst_port)
10984     return 0;
10985
10986   u8 *mask = 0;
10987   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10988
10989   tcpudp = (tcpudp_header_t *) mask;
10990   tcpudp->src_port = src_port;
10991   tcpudp->dst_port = dst_port;
10992
10993   *maskp = mask;
10994
10995   return 1;
10996 }
10997
10998 uword
10999 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11000 {
11001   u8 **maskp = va_arg (*args, u8 **);
11002   u8 *mask = 0;
11003   u8 found_something = 0;
11004   ip4_header_t *ip;
11005
11006 #define _(a) u8 a=0;
11007   foreach_ip4_proto_field;
11008 #undef _
11009   u8 version = 0;
11010   u8 hdr_length = 0;
11011
11012
11013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11014     {
11015       if (unformat (input, "version"))
11016         version = 1;
11017       else if (unformat (input, "hdr_length"))
11018         hdr_length = 1;
11019       else if (unformat (input, "src"))
11020         src_address = 1;
11021       else if (unformat (input, "dst"))
11022         dst_address = 1;
11023       else if (unformat (input, "proto"))
11024         protocol = 1;
11025
11026 #define _(a) else if (unformat (input, #a)) a=1;
11027       foreach_ip4_proto_field
11028 #undef _
11029         else
11030         break;
11031     }
11032
11033 #define _(a) found_something += a;
11034   foreach_ip4_proto_field;
11035 #undef _
11036
11037   if (found_something == 0)
11038     return 0;
11039
11040   vec_validate (mask, sizeof (*ip) - 1);
11041
11042   ip = (ip4_header_t *) mask;
11043
11044 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11045   foreach_ip4_proto_field;
11046 #undef _
11047
11048   ip->ip_version_and_header_length = 0;
11049
11050   if (version)
11051     ip->ip_version_and_header_length |= 0xF0;
11052
11053   if (hdr_length)
11054     ip->ip_version_and_header_length |= 0x0F;
11055
11056   *maskp = mask;
11057   return 1;
11058 }
11059
11060 #define foreach_ip6_proto_field                 \
11061 _(src_address)                                  \
11062 _(dst_address)                                  \
11063 _(payload_length)                               \
11064 _(hop_limit)                                    \
11065 _(protocol)
11066
11067 uword
11068 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11069 {
11070   u8 **maskp = va_arg (*args, u8 **);
11071   u8 *mask = 0;
11072   u8 found_something = 0;
11073   ip6_header_t *ip;
11074   u32 ip_version_traffic_class_and_flow_label;
11075
11076 #define _(a) u8 a=0;
11077   foreach_ip6_proto_field;
11078 #undef _
11079   u8 version = 0;
11080   u8 traffic_class = 0;
11081   u8 flow_label = 0;
11082
11083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11084     {
11085       if (unformat (input, "version"))
11086         version = 1;
11087       else if (unformat (input, "traffic-class"))
11088         traffic_class = 1;
11089       else if (unformat (input, "flow-label"))
11090         flow_label = 1;
11091       else if (unformat (input, "src"))
11092         src_address = 1;
11093       else if (unformat (input, "dst"))
11094         dst_address = 1;
11095       else if (unformat (input, "proto"))
11096         protocol = 1;
11097
11098 #define _(a) else if (unformat (input, #a)) a=1;
11099       foreach_ip6_proto_field
11100 #undef _
11101         else
11102         break;
11103     }
11104
11105 #define _(a) found_something += a;
11106   foreach_ip6_proto_field;
11107 #undef _
11108
11109   if (found_something == 0)
11110     return 0;
11111
11112   vec_validate (mask, sizeof (*ip) - 1);
11113
11114   ip = (ip6_header_t *) mask;
11115
11116 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11117   foreach_ip6_proto_field;
11118 #undef _
11119
11120   ip_version_traffic_class_and_flow_label = 0;
11121
11122   if (version)
11123     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11124
11125   if (traffic_class)
11126     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11127
11128   if (flow_label)
11129     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11130
11131   ip->ip_version_traffic_class_and_flow_label =
11132     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11133
11134   *maskp = mask;
11135   return 1;
11136 }
11137
11138 uword
11139 unformat_l3_mask (unformat_input_t * input, va_list * args)
11140 {
11141   u8 **maskp = va_arg (*args, u8 **);
11142
11143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11144     {
11145       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11146         return 1;
11147       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11148         return 1;
11149       else
11150         break;
11151     }
11152   return 0;
11153 }
11154
11155 uword
11156 unformat_l2_mask (unformat_input_t * input, va_list * args)
11157 {
11158   u8 **maskp = va_arg (*args, u8 **);
11159   u8 *mask = 0;
11160   u8 src = 0;
11161   u8 dst = 0;
11162   u8 proto = 0;
11163   u8 tag1 = 0;
11164   u8 tag2 = 0;
11165   u8 ignore_tag1 = 0;
11166   u8 ignore_tag2 = 0;
11167   u8 cos1 = 0;
11168   u8 cos2 = 0;
11169   u8 dot1q = 0;
11170   u8 dot1ad = 0;
11171   int len = 14;
11172
11173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11174     {
11175       if (unformat (input, "src"))
11176         src = 1;
11177       else if (unformat (input, "dst"))
11178         dst = 1;
11179       else if (unformat (input, "proto"))
11180         proto = 1;
11181       else if (unformat (input, "tag1"))
11182         tag1 = 1;
11183       else if (unformat (input, "tag2"))
11184         tag2 = 1;
11185       else if (unformat (input, "ignore-tag1"))
11186         ignore_tag1 = 1;
11187       else if (unformat (input, "ignore-tag2"))
11188         ignore_tag2 = 1;
11189       else if (unformat (input, "cos1"))
11190         cos1 = 1;
11191       else if (unformat (input, "cos2"))
11192         cos2 = 1;
11193       else if (unformat (input, "dot1q"))
11194         dot1q = 1;
11195       else if (unformat (input, "dot1ad"))
11196         dot1ad = 1;
11197       else
11198         break;
11199     }
11200   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11201        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11202     return 0;
11203
11204   if (tag1 || ignore_tag1 || cos1 || dot1q)
11205     len = 18;
11206   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11207     len = 22;
11208
11209   vec_validate (mask, len - 1);
11210
11211   if (dst)
11212     memset (mask, 0xff, 6);
11213
11214   if (src)
11215     memset (mask + 6, 0xff, 6);
11216
11217   if (tag2 || dot1ad)
11218     {
11219       /* inner vlan tag */
11220       if (tag2)
11221         {
11222           mask[19] = 0xff;
11223           mask[18] = 0x0f;
11224         }
11225       if (cos2)
11226         mask[18] |= 0xe0;
11227       if (proto)
11228         mask[21] = mask[20] = 0xff;
11229       if (tag1)
11230         {
11231           mask[15] = 0xff;
11232           mask[14] = 0x0f;
11233         }
11234       if (cos1)
11235         mask[14] |= 0xe0;
11236       *maskp = mask;
11237       return 1;
11238     }
11239   if (tag1 | dot1q)
11240     {
11241       if (tag1)
11242         {
11243           mask[15] = 0xff;
11244           mask[14] = 0x0f;
11245         }
11246       if (cos1)
11247         mask[14] |= 0xe0;
11248       if (proto)
11249         mask[16] = mask[17] = 0xff;
11250
11251       *maskp = mask;
11252       return 1;
11253     }
11254   if (cos2)
11255     mask[18] |= 0xe0;
11256   if (cos1)
11257     mask[14] |= 0xe0;
11258   if (proto)
11259     mask[12] = mask[13] = 0xff;
11260
11261   *maskp = mask;
11262   return 1;
11263 }
11264
11265 uword
11266 unformat_classify_mask (unformat_input_t * input, va_list * args)
11267 {
11268   u8 **maskp = va_arg (*args, u8 **);
11269   u32 *skipp = va_arg (*args, u32 *);
11270   u32 *matchp = va_arg (*args, u32 *);
11271   u32 match;
11272   u8 *mask = 0;
11273   u8 *l2 = 0;
11274   u8 *l3 = 0;
11275   u8 *l4 = 0;
11276   int i;
11277
11278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11279     {
11280       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11281         ;
11282       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11283         ;
11284       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11285         ;
11286       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11287         ;
11288       else
11289         break;
11290     }
11291
11292   if (l4 && !l3)
11293     {
11294       vec_free (mask);
11295       vec_free (l2);
11296       vec_free (l4);
11297       return 0;
11298     }
11299
11300   if (mask || l2 || l3 || l4)
11301     {
11302       if (l2 || l3 || l4)
11303         {
11304           /* "With a free Ethernet header in every package" */
11305           if (l2 == 0)
11306             vec_validate (l2, 13);
11307           mask = l2;
11308           if (vec_len (l3))
11309             {
11310               vec_append (mask, l3);
11311               vec_free (l3);
11312             }
11313           if (vec_len (l4))
11314             {
11315               vec_append (mask, l4);
11316               vec_free (l4);
11317             }
11318         }
11319
11320       /* Scan forward looking for the first significant mask octet */
11321       for (i = 0; i < vec_len (mask); i++)
11322         if (mask[i])
11323           break;
11324
11325       /* compute (skip, match) params */
11326       *skipp = i / sizeof (u32x4);
11327       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11328
11329       /* Pad mask to an even multiple of the vector size */
11330       while (vec_len (mask) % sizeof (u32x4))
11331         vec_add1 (mask, 0);
11332
11333       match = vec_len (mask) / sizeof (u32x4);
11334
11335       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11336         {
11337           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11338           if (*tmp || *(tmp + 1))
11339             break;
11340           match--;
11341         }
11342       if (match == 0)
11343         clib_warning ("BUG: match 0");
11344
11345       _vec_len (mask) = match * sizeof (u32x4);
11346
11347       *matchp = match;
11348       *maskp = mask;
11349
11350       return 1;
11351     }
11352
11353   return 0;
11354 }
11355 #endif /* VPP_API_TEST_BUILTIN */
11356
11357 #define foreach_l2_next                         \
11358 _(drop, DROP)                                   \
11359 _(ethernet, ETHERNET_INPUT)                     \
11360 _(ip4, IP4_INPUT)                               \
11361 _(ip6, IP6_INPUT)
11362
11363 uword
11364 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11365 {
11366   u32 *miss_next_indexp = va_arg (*args, u32 *);
11367   u32 next_index = 0;
11368   u32 tmp;
11369
11370 #define _(n,N) \
11371   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11372   foreach_l2_next;
11373 #undef _
11374
11375   if (unformat (input, "%d", &tmp))
11376     {
11377       next_index = tmp;
11378       goto out;
11379     }
11380
11381   return 0;
11382
11383 out:
11384   *miss_next_indexp = next_index;
11385   return 1;
11386 }
11387
11388 #define foreach_ip_next                         \
11389 _(drop, DROP)                                   \
11390 _(local, LOCAL)                                 \
11391 _(rewrite, REWRITE)
11392
11393 uword
11394 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11395 {
11396   u32 *miss_next_indexp = va_arg (*args, u32 *);
11397   u32 next_index = 0;
11398   u32 tmp;
11399
11400 #define _(n,N) \
11401   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11402   foreach_ip_next;
11403 #undef _
11404
11405   if (unformat (input, "%d", &tmp))
11406     {
11407       next_index = tmp;
11408       goto out;
11409     }
11410
11411   return 0;
11412
11413 out:
11414   *miss_next_indexp = next_index;
11415   return 1;
11416 }
11417
11418 #define foreach_acl_next                        \
11419 _(deny, DENY)
11420
11421 uword
11422 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11423 {
11424   u32 *miss_next_indexp = va_arg (*args, u32 *);
11425   u32 next_index = 0;
11426   u32 tmp;
11427
11428 #define _(n,N) \
11429   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11430   foreach_acl_next;
11431 #undef _
11432
11433   if (unformat (input, "permit"))
11434     {
11435       next_index = ~0;
11436       goto out;
11437     }
11438   else if (unformat (input, "%d", &tmp))
11439     {
11440       next_index = tmp;
11441       goto out;
11442     }
11443
11444   return 0;
11445
11446 out:
11447   *miss_next_indexp = next_index;
11448   return 1;
11449 }
11450
11451 uword
11452 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11453 {
11454   u32 *r = va_arg (*args, u32 *);
11455
11456   if (unformat (input, "conform-color"))
11457     *r = POLICE_CONFORM;
11458   else if (unformat (input, "exceed-color"))
11459     *r = POLICE_EXCEED;
11460   else
11461     return 0;
11462
11463   return 1;
11464 }
11465
11466 static int
11467 api_classify_add_del_table (vat_main_t * vam)
11468 {
11469   unformat_input_t *i = vam->input;
11470   vl_api_classify_add_del_table_t *mp;
11471
11472   u32 nbuckets = 2;
11473   u32 skip = ~0;
11474   u32 match = ~0;
11475   int is_add = 1;
11476   int del_chain = 0;
11477   u32 table_index = ~0;
11478   u32 next_table_index = ~0;
11479   u32 miss_next_index = ~0;
11480   u32 memory_size = 32 << 20;
11481   u8 *mask = 0;
11482   u32 current_data_flag = 0;
11483   int current_data_offset = 0;
11484   int ret;
11485
11486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11487     {
11488       if (unformat (i, "del"))
11489         is_add = 0;
11490       else if (unformat (i, "del-chain"))
11491         {
11492           is_add = 0;
11493           del_chain = 1;
11494         }
11495       else if (unformat (i, "buckets %d", &nbuckets))
11496         ;
11497       else if (unformat (i, "memory_size %d", &memory_size))
11498         ;
11499       else if (unformat (i, "skip %d", &skip))
11500         ;
11501       else if (unformat (i, "match %d", &match))
11502         ;
11503       else if (unformat (i, "table %d", &table_index))
11504         ;
11505       else if (unformat (i, "mask %U", unformat_classify_mask,
11506                          &mask, &skip, &match))
11507         ;
11508       else if (unformat (i, "next-table %d", &next_table_index))
11509         ;
11510       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11511                          &miss_next_index))
11512         ;
11513       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11514                          &miss_next_index))
11515         ;
11516       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11517                          &miss_next_index))
11518         ;
11519       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11520         ;
11521       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11522         ;
11523       else
11524         break;
11525     }
11526
11527   if (is_add && mask == 0)
11528     {
11529       errmsg ("Mask required");
11530       return -99;
11531     }
11532
11533   if (is_add && skip == ~0)
11534     {
11535       errmsg ("skip count required");
11536       return -99;
11537     }
11538
11539   if (is_add && match == ~0)
11540     {
11541       errmsg ("match count required");
11542       return -99;
11543     }
11544
11545   if (!is_add && table_index == ~0)
11546     {
11547       errmsg ("table index required for delete");
11548       return -99;
11549     }
11550
11551   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11552
11553   mp->is_add = is_add;
11554   mp->del_chain = del_chain;
11555   mp->table_index = ntohl (table_index);
11556   mp->nbuckets = ntohl (nbuckets);
11557   mp->memory_size = ntohl (memory_size);
11558   mp->skip_n_vectors = ntohl (skip);
11559   mp->match_n_vectors = ntohl (match);
11560   mp->next_table_index = ntohl (next_table_index);
11561   mp->miss_next_index = ntohl (miss_next_index);
11562   mp->current_data_flag = ntohl (current_data_flag);
11563   mp->current_data_offset = ntohl (current_data_offset);
11564   clib_memcpy (mp->mask, mask, vec_len (mask));
11565
11566   vec_free (mask);
11567
11568   S (mp);
11569   W (ret);
11570   return ret;
11571 }
11572
11573 #if VPP_API_TEST_BUILTIN == 0
11574 uword
11575 unformat_l4_match (unformat_input_t * input, va_list * args)
11576 {
11577   u8 **matchp = va_arg (*args, u8 **);
11578
11579   u8 *proto_header = 0;
11580   int src_port = 0;
11581   int dst_port = 0;
11582
11583   tcpudp_header_t h;
11584
11585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11586     {
11587       if (unformat (input, "src_port %d", &src_port))
11588         ;
11589       else if (unformat (input, "dst_port %d", &dst_port))
11590         ;
11591       else
11592         return 0;
11593     }
11594
11595   h.src_port = clib_host_to_net_u16 (src_port);
11596   h.dst_port = clib_host_to_net_u16 (dst_port);
11597   vec_validate (proto_header, sizeof (h) - 1);
11598   memcpy (proto_header, &h, sizeof (h));
11599
11600   *matchp = proto_header;
11601
11602   return 1;
11603 }
11604
11605 uword
11606 unformat_ip4_match (unformat_input_t * input, va_list * args)
11607 {
11608   u8 **matchp = va_arg (*args, u8 **);
11609   u8 *match = 0;
11610   ip4_header_t *ip;
11611   int version = 0;
11612   u32 version_val;
11613   int hdr_length = 0;
11614   u32 hdr_length_val;
11615   int src = 0, dst = 0;
11616   ip4_address_t src_val, dst_val;
11617   int proto = 0;
11618   u32 proto_val;
11619   int tos = 0;
11620   u32 tos_val;
11621   int length = 0;
11622   u32 length_val;
11623   int fragment_id = 0;
11624   u32 fragment_id_val;
11625   int ttl = 0;
11626   int ttl_val;
11627   int checksum = 0;
11628   u32 checksum_val;
11629
11630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11631     {
11632       if (unformat (input, "version %d", &version_val))
11633         version = 1;
11634       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11635         hdr_length = 1;
11636       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11637         src = 1;
11638       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11639         dst = 1;
11640       else if (unformat (input, "proto %d", &proto_val))
11641         proto = 1;
11642       else if (unformat (input, "tos %d", &tos_val))
11643         tos = 1;
11644       else if (unformat (input, "length %d", &length_val))
11645         length = 1;
11646       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11647         fragment_id = 1;
11648       else if (unformat (input, "ttl %d", &ttl_val))
11649         ttl = 1;
11650       else if (unformat (input, "checksum %d", &checksum_val))
11651         checksum = 1;
11652       else
11653         break;
11654     }
11655
11656   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11657       + ttl + checksum == 0)
11658     return 0;
11659
11660   /*
11661    * Aligned because we use the real comparison functions
11662    */
11663   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11664
11665   ip = (ip4_header_t *) match;
11666
11667   /* These are realistically matched in practice */
11668   if (src)
11669     ip->src_address.as_u32 = src_val.as_u32;
11670
11671   if (dst)
11672     ip->dst_address.as_u32 = dst_val.as_u32;
11673
11674   if (proto)
11675     ip->protocol = proto_val;
11676
11677
11678   /* These are not, but they're included for completeness */
11679   if (version)
11680     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11681
11682   if (hdr_length)
11683     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11684
11685   if (tos)
11686     ip->tos = tos_val;
11687
11688   if (length)
11689     ip->length = clib_host_to_net_u16 (length_val);
11690
11691   if (ttl)
11692     ip->ttl = ttl_val;
11693
11694   if (checksum)
11695     ip->checksum = clib_host_to_net_u16 (checksum_val);
11696
11697   *matchp = match;
11698   return 1;
11699 }
11700
11701 uword
11702 unformat_ip6_match (unformat_input_t * input, va_list * args)
11703 {
11704   u8 **matchp = va_arg (*args, u8 **);
11705   u8 *match = 0;
11706   ip6_header_t *ip;
11707   int version = 0;
11708   u32 version_val;
11709   u8 traffic_class = 0;
11710   u32 traffic_class_val = 0;
11711   u8 flow_label = 0;
11712   u8 flow_label_val;
11713   int src = 0, dst = 0;
11714   ip6_address_t src_val, dst_val;
11715   int proto = 0;
11716   u32 proto_val;
11717   int payload_length = 0;
11718   u32 payload_length_val;
11719   int hop_limit = 0;
11720   int hop_limit_val;
11721   u32 ip_version_traffic_class_and_flow_label;
11722
11723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11724     {
11725       if (unformat (input, "version %d", &version_val))
11726         version = 1;
11727       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11728         traffic_class = 1;
11729       else if (unformat (input, "flow_label %d", &flow_label_val))
11730         flow_label = 1;
11731       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11732         src = 1;
11733       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11734         dst = 1;
11735       else if (unformat (input, "proto %d", &proto_val))
11736         proto = 1;
11737       else if (unformat (input, "payload_length %d", &payload_length_val))
11738         payload_length = 1;
11739       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11740         hop_limit = 1;
11741       else
11742         break;
11743     }
11744
11745   if (version + traffic_class + flow_label + src + dst + proto +
11746       payload_length + hop_limit == 0)
11747     return 0;
11748
11749   /*
11750    * Aligned because we use the real comparison functions
11751    */
11752   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11753
11754   ip = (ip6_header_t *) match;
11755
11756   if (src)
11757     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11758
11759   if (dst)
11760     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11761
11762   if (proto)
11763     ip->protocol = proto_val;
11764
11765   ip_version_traffic_class_and_flow_label = 0;
11766
11767   if (version)
11768     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11769
11770   if (traffic_class)
11771     ip_version_traffic_class_and_flow_label |=
11772       (traffic_class_val & 0xFF) << 20;
11773
11774   if (flow_label)
11775     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11776
11777   ip->ip_version_traffic_class_and_flow_label =
11778     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11779
11780   if (payload_length)
11781     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11782
11783   if (hop_limit)
11784     ip->hop_limit = hop_limit_val;
11785
11786   *matchp = match;
11787   return 1;
11788 }
11789
11790 uword
11791 unformat_l3_match (unformat_input_t * input, va_list * args)
11792 {
11793   u8 **matchp = va_arg (*args, u8 **);
11794
11795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11796     {
11797       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11798         return 1;
11799       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11800         return 1;
11801       else
11802         break;
11803     }
11804   return 0;
11805 }
11806
11807 uword
11808 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11809 {
11810   u8 *tagp = va_arg (*args, u8 *);
11811   u32 tag;
11812
11813   if (unformat (input, "%d", &tag))
11814     {
11815       tagp[0] = (tag >> 8) & 0x0F;
11816       tagp[1] = tag & 0xFF;
11817       return 1;
11818     }
11819
11820   return 0;
11821 }
11822
11823 uword
11824 unformat_l2_match (unformat_input_t * input, va_list * args)
11825 {
11826   u8 **matchp = va_arg (*args, u8 **);
11827   u8 *match = 0;
11828   u8 src = 0;
11829   u8 src_val[6];
11830   u8 dst = 0;
11831   u8 dst_val[6];
11832   u8 proto = 0;
11833   u16 proto_val;
11834   u8 tag1 = 0;
11835   u8 tag1_val[2];
11836   u8 tag2 = 0;
11837   u8 tag2_val[2];
11838   int len = 14;
11839   u8 ignore_tag1 = 0;
11840   u8 ignore_tag2 = 0;
11841   u8 cos1 = 0;
11842   u8 cos2 = 0;
11843   u32 cos1_val = 0;
11844   u32 cos2_val = 0;
11845
11846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11847     {
11848       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11849         src = 1;
11850       else
11851         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11852         dst = 1;
11853       else if (unformat (input, "proto %U",
11854                          unformat_ethernet_type_host_byte_order, &proto_val))
11855         proto = 1;
11856       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11857         tag1 = 1;
11858       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11859         tag2 = 1;
11860       else if (unformat (input, "ignore-tag1"))
11861         ignore_tag1 = 1;
11862       else if (unformat (input, "ignore-tag2"))
11863         ignore_tag2 = 1;
11864       else if (unformat (input, "cos1 %d", &cos1_val))
11865         cos1 = 1;
11866       else if (unformat (input, "cos2 %d", &cos2_val))
11867         cos2 = 1;
11868       else
11869         break;
11870     }
11871   if ((src + dst + proto + tag1 + tag2 +
11872        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11873     return 0;
11874
11875   if (tag1 || ignore_tag1 || cos1)
11876     len = 18;
11877   if (tag2 || ignore_tag2 || cos2)
11878     len = 22;
11879
11880   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11881
11882   if (dst)
11883     clib_memcpy (match, dst_val, 6);
11884
11885   if (src)
11886     clib_memcpy (match + 6, src_val, 6);
11887
11888   if (tag2)
11889     {
11890       /* inner vlan tag */
11891       match[19] = tag2_val[1];
11892       match[18] = tag2_val[0];
11893       if (cos2)
11894         match[18] |= (cos2_val & 0x7) << 5;
11895       if (proto)
11896         {
11897           match[21] = proto_val & 0xff;
11898           match[20] = proto_val >> 8;
11899         }
11900       if (tag1)
11901         {
11902           match[15] = tag1_val[1];
11903           match[14] = tag1_val[0];
11904         }
11905       if (cos1)
11906         match[14] |= (cos1_val & 0x7) << 5;
11907       *matchp = match;
11908       return 1;
11909     }
11910   if (tag1)
11911     {
11912       match[15] = tag1_val[1];
11913       match[14] = tag1_val[0];
11914       if (proto)
11915         {
11916           match[17] = proto_val & 0xff;
11917           match[16] = proto_val >> 8;
11918         }
11919       if (cos1)
11920         match[14] |= (cos1_val & 0x7) << 5;
11921
11922       *matchp = match;
11923       return 1;
11924     }
11925   if (cos2)
11926     match[18] |= (cos2_val & 0x7) << 5;
11927   if (cos1)
11928     match[14] |= (cos1_val & 0x7) << 5;
11929   if (proto)
11930     {
11931       match[13] = proto_val & 0xff;
11932       match[12] = proto_val >> 8;
11933     }
11934
11935   *matchp = match;
11936   return 1;
11937 }
11938
11939 uword
11940 unformat_qos_source (unformat_input_t * input, va_list * args)
11941 {
11942   int *qs = va_arg (*args, int *);
11943
11944   if (unformat (input, "ip"))
11945     *qs = QOS_SOURCE_IP;
11946   else if (unformat (input, "mpls"))
11947     *qs = QOS_SOURCE_MPLS;
11948   else if (unformat (input, "ext"))
11949     *qs = QOS_SOURCE_EXT;
11950   else if (unformat (input, "vlan"))
11951     *qs = QOS_SOURCE_VLAN;
11952   else
11953     return 0;
11954
11955   return 1;
11956 }
11957 #endif
11958
11959 uword
11960 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11961 {
11962   u8 **matchp = va_arg (*args, u8 **);
11963   u32 skip_n_vectors = va_arg (*args, u32);
11964   u32 match_n_vectors = va_arg (*args, u32);
11965
11966   u8 *match = 0;
11967   u8 *l2 = 0;
11968   u8 *l3 = 0;
11969   u8 *l4 = 0;
11970
11971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11972     {
11973       if (unformat (input, "hex %U", unformat_hex_string, &match))
11974         ;
11975       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11976         ;
11977       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11978         ;
11979       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11980         ;
11981       else
11982         break;
11983     }
11984
11985   if (l4 && !l3)
11986     {
11987       vec_free (match);
11988       vec_free (l2);
11989       vec_free (l4);
11990       return 0;
11991     }
11992
11993   if (match || l2 || l3 || l4)
11994     {
11995       if (l2 || l3 || l4)
11996         {
11997           /* "Win a free Ethernet header in every packet" */
11998           if (l2 == 0)
11999             vec_validate_aligned (l2, 13, sizeof (u32x4));
12000           match = l2;
12001           if (vec_len (l3))
12002             {
12003               vec_append_aligned (match, l3, sizeof (u32x4));
12004               vec_free (l3);
12005             }
12006           if (vec_len (l4))
12007             {
12008               vec_append_aligned (match, l4, sizeof (u32x4));
12009               vec_free (l4);
12010             }
12011         }
12012
12013       /* Make sure the vector is big enough even if key is all 0's */
12014       vec_validate_aligned
12015         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12016          sizeof (u32x4));
12017
12018       /* Set size, include skipped vectors */
12019       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12020
12021       *matchp = match;
12022
12023       return 1;
12024     }
12025
12026   return 0;
12027 }
12028
12029 static int
12030 api_classify_add_del_session (vat_main_t * vam)
12031 {
12032   unformat_input_t *i = vam->input;
12033   vl_api_classify_add_del_session_t *mp;
12034   int is_add = 1;
12035   u32 table_index = ~0;
12036   u32 hit_next_index = ~0;
12037   u32 opaque_index = ~0;
12038   u8 *match = 0;
12039   i32 advance = 0;
12040   u32 skip_n_vectors = 0;
12041   u32 match_n_vectors = 0;
12042   u32 action = 0;
12043   u32 metadata = 0;
12044   int ret;
12045
12046   /*
12047    * Warning: you have to supply skip_n and match_n
12048    * because the API client cant simply look at the classify
12049    * table object.
12050    */
12051
12052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12053     {
12054       if (unformat (i, "del"))
12055         is_add = 0;
12056       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12057                          &hit_next_index))
12058         ;
12059       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12060                          &hit_next_index))
12061         ;
12062       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12063                          &hit_next_index))
12064         ;
12065       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12066         ;
12067       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12068         ;
12069       else if (unformat (i, "opaque-index %d", &opaque_index))
12070         ;
12071       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12072         ;
12073       else if (unformat (i, "match_n %d", &match_n_vectors))
12074         ;
12075       else if (unformat (i, "match %U", api_unformat_classify_match,
12076                          &match, skip_n_vectors, match_n_vectors))
12077         ;
12078       else if (unformat (i, "advance %d", &advance))
12079         ;
12080       else if (unformat (i, "table-index %d", &table_index))
12081         ;
12082       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12083         action = 1;
12084       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12085         action = 2;
12086       else if (unformat (i, "action %d", &action))
12087         ;
12088       else if (unformat (i, "metadata %d", &metadata))
12089         ;
12090       else
12091         break;
12092     }
12093
12094   if (table_index == ~0)
12095     {
12096       errmsg ("Table index required");
12097       return -99;
12098     }
12099
12100   if (is_add && match == 0)
12101     {
12102       errmsg ("Match value required");
12103       return -99;
12104     }
12105
12106   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12107
12108   mp->is_add = is_add;
12109   mp->table_index = ntohl (table_index);
12110   mp->hit_next_index = ntohl (hit_next_index);
12111   mp->opaque_index = ntohl (opaque_index);
12112   mp->advance = ntohl (advance);
12113   mp->action = action;
12114   mp->metadata = ntohl (metadata);
12115   clib_memcpy (mp->match, match, vec_len (match));
12116   vec_free (match);
12117
12118   S (mp);
12119   W (ret);
12120   return ret;
12121 }
12122
12123 static int
12124 api_classify_set_interface_ip_table (vat_main_t * vam)
12125 {
12126   unformat_input_t *i = vam->input;
12127   vl_api_classify_set_interface_ip_table_t *mp;
12128   u32 sw_if_index;
12129   int sw_if_index_set;
12130   u32 table_index = ~0;
12131   u8 is_ipv6 = 0;
12132   int ret;
12133
12134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12135     {
12136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12137         sw_if_index_set = 1;
12138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12139         sw_if_index_set = 1;
12140       else if (unformat (i, "table %d", &table_index))
12141         ;
12142       else
12143         {
12144           clib_warning ("parse error '%U'", format_unformat_error, i);
12145           return -99;
12146         }
12147     }
12148
12149   if (sw_if_index_set == 0)
12150     {
12151       errmsg ("missing interface name or sw_if_index");
12152       return -99;
12153     }
12154
12155
12156   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12157
12158   mp->sw_if_index = ntohl (sw_if_index);
12159   mp->table_index = ntohl (table_index);
12160   mp->is_ipv6 = is_ipv6;
12161
12162   S (mp);
12163   W (ret);
12164   return ret;
12165 }
12166
12167 static int
12168 api_classify_set_interface_l2_tables (vat_main_t * vam)
12169 {
12170   unformat_input_t *i = vam->input;
12171   vl_api_classify_set_interface_l2_tables_t *mp;
12172   u32 sw_if_index;
12173   int sw_if_index_set;
12174   u32 ip4_table_index = ~0;
12175   u32 ip6_table_index = ~0;
12176   u32 other_table_index = ~0;
12177   u32 is_input = 1;
12178   int ret;
12179
12180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12181     {
12182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12183         sw_if_index_set = 1;
12184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12185         sw_if_index_set = 1;
12186       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12187         ;
12188       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12189         ;
12190       else if (unformat (i, "other-table %d", &other_table_index))
12191         ;
12192       else if (unformat (i, "is-input %d", &is_input))
12193         ;
12194       else
12195         {
12196           clib_warning ("parse error '%U'", format_unformat_error, i);
12197           return -99;
12198         }
12199     }
12200
12201   if (sw_if_index_set == 0)
12202     {
12203       errmsg ("missing interface name or sw_if_index");
12204       return -99;
12205     }
12206
12207
12208   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12209
12210   mp->sw_if_index = ntohl (sw_if_index);
12211   mp->ip4_table_index = ntohl (ip4_table_index);
12212   mp->ip6_table_index = ntohl (ip6_table_index);
12213   mp->other_table_index = ntohl (other_table_index);
12214   mp->is_input = (u8) is_input;
12215
12216   S (mp);
12217   W (ret);
12218   return ret;
12219 }
12220
12221 static int
12222 api_set_ipfix_exporter (vat_main_t * vam)
12223 {
12224   unformat_input_t *i = vam->input;
12225   vl_api_set_ipfix_exporter_t *mp;
12226   ip4_address_t collector_address;
12227   u8 collector_address_set = 0;
12228   u32 collector_port = ~0;
12229   ip4_address_t src_address;
12230   u8 src_address_set = 0;
12231   u32 vrf_id = ~0;
12232   u32 path_mtu = ~0;
12233   u32 template_interval = ~0;
12234   u8 udp_checksum = 0;
12235   int ret;
12236
12237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12238     {
12239       if (unformat (i, "collector_address %U", unformat_ip4_address,
12240                     &collector_address))
12241         collector_address_set = 1;
12242       else if (unformat (i, "collector_port %d", &collector_port))
12243         ;
12244       else if (unformat (i, "src_address %U", unformat_ip4_address,
12245                          &src_address))
12246         src_address_set = 1;
12247       else if (unformat (i, "vrf_id %d", &vrf_id))
12248         ;
12249       else if (unformat (i, "path_mtu %d", &path_mtu))
12250         ;
12251       else if (unformat (i, "template_interval %d", &template_interval))
12252         ;
12253       else if (unformat (i, "udp_checksum"))
12254         udp_checksum = 1;
12255       else
12256         break;
12257     }
12258
12259   if (collector_address_set == 0)
12260     {
12261       errmsg ("collector_address required");
12262       return -99;
12263     }
12264
12265   if (src_address_set == 0)
12266     {
12267       errmsg ("src_address required");
12268       return -99;
12269     }
12270
12271   M (SET_IPFIX_EXPORTER, mp);
12272
12273   memcpy (mp->collector_address, collector_address.data,
12274           sizeof (collector_address.data));
12275   mp->collector_port = htons ((u16) collector_port);
12276   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12277   mp->vrf_id = htonl (vrf_id);
12278   mp->path_mtu = htonl (path_mtu);
12279   mp->template_interval = htonl (template_interval);
12280   mp->udp_checksum = udp_checksum;
12281
12282   S (mp);
12283   W (ret);
12284   return ret;
12285 }
12286
12287 static int
12288 api_set_ipfix_classify_stream (vat_main_t * vam)
12289 {
12290   unformat_input_t *i = vam->input;
12291   vl_api_set_ipfix_classify_stream_t *mp;
12292   u32 domain_id = 0;
12293   u32 src_port = UDP_DST_PORT_ipfix;
12294   int ret;
12295
12296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12297     {
12298       if (unformat (i, "domain %d", &domain_id))
12299         ;
12300       else if (unformat (i, "src_port %d", &src_port))
12301         ;
12302       else
12303         {
12304           errmsg ("unknown input `%U'", format_unformat_error, i);
12305           return -99;
12306         }
12307     }
12308
12309   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12310
12311   mp->domain_id = htonl (domain_id);
12312   mp->src_port = htons ((u16) src_port);
12313
12314   S (mp);
12315   W (ret);
12316   return ret;
12317 }
12318
12319 static int
12320 api_ipfix_classify_table_add_del (vat_main_t * vam)
12321 {
12322   unformat_input_t *i = vam->input;
12323   vl_api_ipfix_classify_table_add_del_t *mp;
12324   int is_add = -1;
12325   u32 classify_table_index = ~0;
12326   u8 ip_version = 0;
12327   u8 transport_protocol = 255;
12328   int ret;
12329
12330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (i, "add"))
12333         is_add = 1;
12334       else if (unformat (i, "del"))
12335         is_add = 0;
12336       else if (unformat (i, "table %d", &classify_table_index))
12337         ;
12338       else if (unformat (i, "ip4"))
12339         ip_version = 4;
12340       else if (unformat (i, "ip6"))
12341         ip_version = 6;
12342       else if (unformat (i, "tcp"))
12343         transport_protocol = 6;
12344       else if (unformat (i, "udp"))
12345         transport_protocol = 17;
12346       else
12347         {
12348           errmsg ("unknown input `%U'", format_unformat_error, i);
12349           return -99;
12350         }
12351     }
12352
12353   if (is_add == -1)
12354     {
12355       errmsg ("expecting: add|del");
12356       return -99;
12357     }
12358   if (classify_table_index == ~0)
12359     {
12360       errmsg ("classifier table not specified");
12361       return -99;
12362     }
12363   if (ip_version == 0)
12364     {
12365       errmsg ("IP version not specified");
12366       return -99;
12367     }
12368
12369   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12370
12371   mp->is_add = is_add;
12372   mp->table_id = htonl (classify_table_index);
12373   mp->ip_version = ip_version;
12374   mp->transport_protocol = transport_protocol;
12375
12376   S (mp);
12377   W (ret);
12378   return ret;
12379 }
12380
12381 static int
12382 api_get_node_index (vat_main_t * vam)
12383 {
12384   unformat_input_t *i = vam->input;
12385   vl_api_get_node_index_t *mp;
12386   u8 *name = 0;
12387   int ret;
12388
12389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12390     {
12391       if (unformat (i, "node %s", &name))
12392         ;
12393       else
12394         break;
12395     }
12396   if (name == 0)
12397     {
12398       errmsg ("node name required");
12399       return -99;
12400     }
12401   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12402     {
12403       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12404       return -99;
12405     }
12406
12407   M (GET_NODE_INDEX, mp);
12408   clib_memcpy (mp->node_name, name, vec_len (name));
12409   vec_free (name);
12410
12411   S (mp);
12412   W (ret);
12413   return ret;
12414 }
12415
12416 static int
12417 api_get_next_index (vat_main_t * vam)
12418 {
12419   unformat_input_t *i = vam->input;
12420   vl_api_get_next_index_t *mp;
12421   u8 *node_name = 0, *next_node_name = 0;
12422   int ret;
12423
12424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12425     {
12426       if (unformat (i, "node-name %s", &node_name))
12427         ;
12428       else if (unformat (i, "next-node-name %s", &next_node_name))
12429         break;
12430     }
12431
12432   if (node_name == 0)
12433     {
12434       errmsg ("node name required");
12435       return -99;
12436     }
12437   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12438     {
12439       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12440       return -99;
12441     }
12442
12443   if (next_node_name == 0)
12444     {
12445       errmsg ("next node name required");
12446       return -99;
12447     }
12448   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12449     {
12450       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12451       return -99;
12452     }
12453
12454   M (GET_NEXT_INDEX, mp);
12455   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12456   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12457   vec_free (node_name);
12458   vec_free (next_node_name);
12459
12460   S (mp);
12461   W (ret);
12462   return ret;
12463 }
12464
12465 static int
12466 api_add_node_next (vat_main_t * vam)
12467 {
12468   unformat_input_t *i = vam->input;
12469   vl_api_add_node_next_t *mp;
12470   u8 *name = 0;
12471   u8 *next = 0;
12472   int ret;
12473
12474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12475     {
12476       if (unformat (i, "node %s", &name))
12477         ;
12478       else if (unformat (i, "next %s", &next))
12479         ;
12480       else
12481         break;
12482     }
12483   if (name == 0)
12484     {
12485       errmsg ("node name required");
12486       return -99;
12487     }
12488   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12489     {
12490       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12491       return -99;
12492     }
12493   if (next == 0)
12494     {
12495       errmsg ("next node required");
12496       return -99;
12497     }
12498   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12499     {
12500       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12501       return -99;
12502     }
12503
12504   M (ADD_NODE_NEXT, mp);
12505   clib_memcpy (mp->node_name, name, vec_len (name));
12506   clib_memcpy (mp->next_name, next, vec_len (next));
12507   vec_free (name);
12508   vec_free (next);
12509
12510   S (mp);
12511   W (ret);
12512   return ret;
12513 }
12514
12515 static int
12516 api_l2tpv3_create_tunnel (vat_main_t * vam)
12517 {
12518   unformat_input_t *i = vam->input;
12519   ip6_address_t client_address, our_address;
12520   int client_address_set = 0;
12521   int our_address_set = 0;
12522   u32 local_session_id = 0;
12523   u32 remote_session_id = 0;
12524   u64 local_cookie = 0;
12525   u64 remote_cookie = 0;
12526   u8 l2_sublayer_present = 0;
12527   vl_api_l2tpv3_create_tunnel_t *mp;
12528   int ret;
12529
12530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12531     {
12532       if (unformat (i, "client_address %U", unformat_ip6_address,
12533                     &client_address))
12534         client_address_set = 1;
12535       else if (unformat (i, "our_address %U", unformat_ip6_address,
12536                          &our_address))
12537         our_address_set = 1;
12538       else if (unformat (i, "local_session_id %d", &local_session_id))
12539         ;
12540       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12541         ;
12542       else if (unformat (i, "local_cookie %lld", &local_cookie))
12543         ;
12544       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12545         ;
12546       else if (unformat (i, "l2-sublayer-present"))
12547         l2_sublayer_present = 1;
12548       else
12549         break;
12550     }
12551
12552   if (client_address_set == 0)
12553     {
12554       errmsg ("client_address required");
12555       return -99;
12556     }
12557
12558   if (our_address_set == 0)
12559     {
12560       errmsg ("our_address required");
12561       return -99;
12562     }
12563
12564   M (L2TPV3_CREATE_TUNNEL, mp);
12565
12566   clib_memcpy (mp->client_address, client_address.as_u8,
12567                sizeof (mp->client_address));
12568
12569   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12570
12571   mp->local_session_id = ntohl (local_session_id);
12572   mp->remote_session_id = ntohl (remote_session_id);
12573   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12574   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12575   mp->l2_sublayer_present = l2_sublayer_present;
12576   mp->is_ipv6 = 1;
12577
12578   S (mp);
12579   W (ret);
12580   return ret;
12581 }
12582
12583 static int
12584 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12585 {
12586   unformat_input_t *i = vam->input;
12587   u32 sw_if_index;
12588   u8 sw_if_index_set = 0;
12589   u64 new_local_cookie = 0;
12590   u64 new_remote_cookie = 0;
12591   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12592   int ret;
12593
12594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12595     {
12596       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12597         sw_if_index_set = 1;
12598       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12599         sw_if_index_set = 1;
12600       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12601         ;
12602       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12603         ;
12604       else
12605         break;
12606     }
12607
12608   if (sw_if_index_set == 0)
12609     {
12610       errmsg ("missing interface name or sw_if_index");
12611       return -99;
12612     }
12613
12614   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12615
12616   mp->sw_if_index = ntohl (sw_if_index);
12617   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12618   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12619
12620   S (mp);
12621   W (ret);
12622   return ret;
12623 }
12624
12625 static int
12626 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12627 {
12628   unformat_input_t *i = vam->input;
12629   vl_api_l2tpv3_interface_enable_disable_t *mp;
12630   u32 sw_if_index;
12631   u8 sw_if_index_set = 0;
12632   u8 enable_disable = 1;
12633   int ret;
12634
12635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12636     {
12637       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12638         sw_if_index_set = 1;
12639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12640         sw_if_index_set = 1;
12641       else if (unformat (i, "enable"))
12642         enable_disable = 1;
12643       else if (unformat (i, "disable"))
12644         enable_disable = 0;
12645       else
12646         break;
12647     }
12648
12649   if (sw_if_index_set == 0)
12650     {
12651       errmsg ("missing interface name or sw_if_index");
12652       return -99;
12653     }
12654
12655   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12656
12657   mp->sw_if_index = ntohl (sw_if_index);
12658   mp->enable_disable = enable_disable;
12659
12660   S (mp);
12661   W (ret);
12662   return ret;
12663 }
12664
12665 static int
12666 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12667 {
12668   unformat_input_t *i = vam->input;
12669   vl_api_l2tpv3_set_lookup_key_t *mp;
12670   u8 key = ~0;
12671   int ret;
12672
12673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12674     {
12675       if (unformat (i, "lookup_v6_src"))
12676         key = L2T_LOOKUP_SRC_ADDRESS;
12677       else if (unformat (i, "lookup_v6_dst"))
12678         key = L2T_LOOKUP_DST_ADDRESS;
12679       else if (unformat (i, "lookup_session_id"))
12680         key = L2T_LOOKUP_SESSION_ID;
12681       else
12682         break;
12683     }
12684
12685   if (key == (u8) ~ 0)
12686     {
12687       errmsg ("l2tp session lookup key unset");
12688       return -99;
12689     }
12690
12691   M (L2TPV3_SET_LOOKUP_KEY, mp);
12692
12693   mp->key = key;
12694
12695   S (mp);
12696   W (ret);
12697   return ret;
12698 }
12699
12700 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12701   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12702 {
12703   vat_main_t *vam = &vat_main;
12704
12705   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12706          format_ip6_address, mp->our_address,
12707          format_ip6_address, mp->client_address,
12708          clib_net_to_host_u32 (mp->sw_if_index));
12709
12710   print (vam->ofp,
12711          "   local cookies %016llx %016llx remote cookie %016llx",
12712          clib_net_to_host_u64 (mp->local_cookie[0]),
12713          clib_net_to_host_u64 (mp->local_cookie[1]),
12714          clib_net_to_host_u64 (mp->remote_cookie));
12715
12716   print (vam->ofp, "   local session-id %d remote session-id %d",
12717          clib_net_to_host_u32 (mp->local_session_id),
12718          clib_net_to_host_u32 (mp->remote_session_id));
12719
12720   print (vam->ofp, "   l2 specific sublayer %s\n",
12721          mp->l2_sublayer_present ? "preset" : "absent");
12722
12723 }
12724
12725 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12726   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12727 {
12728   vat_main_t *vam = &vat_main;
12729   vat_json_node_t *node = NULL;
12730   struct in6_addr addr;
12731
12732   if (VAT_JSON_ARRAY != vam->json_tree.type)
12733     {
12734       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12735       vat_json_init_array (&vam->json_tree);
12736     }
12737   node = vat_json_array_add (&vam->json_tree);
12738
12739   vat_json_init_object (node);
12740
12741   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12742   vat_json_object_add_ip6 (node, "our_address", addr);
12743   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12744   vat_json_object_add_ip6 (node, "client_address", addr);
12745
12746   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12747   vat_json_init_array (lc);
12748   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12749   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12750   vat_json_object_add_uint (node, "remote_cookie",
12751                             clib_net_to_host_u64 (mp->remote_cookie));
12752
12753   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12754   vat_json_object_add_uint (node, "local_session_id",
12755                             clib_net_to_host_u32 (mp->local_session_id));
12756   vat_json_object_add_uint (node, "remote_session_id",
12757                             clib_net_to_host_u32 (mp->remote_session_id));
12758   vat_json_object_add_string_copy (node, "l2_sublayer",
12759                                    mp->l2_sublayer_present ? (u8 *) "present"
12760                                    : (u8 *) "absent");
12761 }
12762
12763 static int
12764 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12765 {
12766   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12767   vl_api_control_ping_t *mp_ping;
12768   int ret;
12769
12770   /* Get list of l2tpv3-tunnel interfaces */
12771   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12772   S (mp);
12773
12774   /* Use a control ping for synchronization */
12775   MPING (CONTROL_PING, mp_ping);
12776   S (mp_ping);
12777
12778   W (ret);
12779   return ret;
12780 }
12781
12782
12783 static void vl_api_sw_interface_tap_details_t_handler
12784   (vl_api_sw_interface_tap_details_t * mp)
12785 {
12786   vat_main_t *vam = &vat_main;
12787
12788   print (vam->ofp, "%-16s %d",
12789          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12790 }
12791
12792 static void vl_api_sw_interface_tap_details_t_handler_json
12793   (vl_api_sw_interface_tap_details_t * mp)
12794 {
12795   vat_main_t *vam = &vat_main;
12796   vat_json_node_t *node = NULL;
12797
12798   if (VAT_JSON_ARRAY != vam->json_tree.type)
12799     {
12800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12801       vat_json_init_array (&vam->json_tree);
12802     }
12803   node = vat_json_array_add (&vam->json_tree);
12804
12805   vat_json_init_object (node);
12806   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12807   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12808 }
12809
12810 static int
12811 api_sw_interface_tap_dump (vat_main_t * vam)
12812 {
12813   vl_api_sw_interface_tap_dump_t *mp;
12814   vl_api_control_ping_t *mp_ping;
12815   int ret;
12816
12817   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12818   /* Get list of tap interfaces */
12819   M (SW_INTERFACE_TAP_DUMP, mp);
12820   S (mp);
12821
12822   /* Use a control ping for synchronization */
12823   MPING (CONTROL_PING, mp_ping);
12824   S (mp_ping);
12825
12826   W (ret);
12827   return ret;
12828 }
12829
12830 static void vl_api_sw_interface_tap_v2_details_t_handler
12831   (vl_api_sw_interface_tap_v2_details_t * mp)
12832 {
12833   vat_main_t *vam = &vat_main;
12834
12835   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12836                     mp->host_ip4_prefix_len);
12837   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12838                     mp->host_ip6_prefix_len);
12839
12840   print (vam->ofp,
12841          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12842          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12843          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12844          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12845          mp->host_bridge, ip4, ip6);
12846
12847   vec_free (ip4);
12848   vec_free (ip6);
12849 }
12850
12851 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12852   (vl_api_sw_interface_tap_v2_details_t * mp)
12853 {
12854   vat_main_t *vam = &vat_main;
12855   vat_json_node_t *node = NULL;
12856
12857   if (VAT_JSON_ARRAY != vam->json_tree.type)
12858     {
12859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12860       vat_json_init_array (&vam->json_tree);
12861     }
12862   node = vat_json_array_add (&vam->json_tree);
12863
12864   vat_json_init_object (node);
12865   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12866   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12867   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12868   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12869   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12870   vat_json_object_add_string_copy (node, "host_mac_addr",
12871                                    format (0, "%U", format_ethernet_address,
12872                                            &mp->host_mac_addr));
12873   vat_json_object_add_string_copy (node, "host_namespace",
12874                                    mp->host_namespace);
12875   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12876   vat_json_object_add_string_copy (node, "host_ip4_addr",
12877                                    format (0, "%U/%d", format_ip4_address,
12878                                            mp->host_ip4_addr,
12879                                            mp->host_ip4_prefix_len));
12880   vat_json_object_add_string_copy (node, "host_ip6_addr",
12881                                    format (0, "%U/%d", format_ip6_address,
12882                                            mp->host_ip6_addr,
12883                                            mp->host_ip6_prefix_len));
12884
12885 }
12886
12887 static int
12888 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12889 {
12890   vl_api_sw_interface_tap_v2_dump_t *mp;
12891   vl_api_control_ping_t *mp_ping;
12892   int ret;
12893
12894   print (vam->ofp,
12895          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12896          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12897          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12898          "host_ip6_addr");
12899
12900   /* Get list of tap interfaces */
12901   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12902   S (mp);
12903
12904   /* Use a control ping for synchronization */
12905   MPING (CONTROL_PING, mp_ping);
12906   S (mp_ping);
12907
12908   W (ret);
12909   return ret;
12910 }
12911
12912 static int
12913 api_vxlan_offload_rx (vat_main_t * vam)
12914 {
12915   unformat_input_t *line_input = vam->input;
12916   vl_api_vxlan_offload_rx_t *mp;
12917   u32 hw_if_index = ~0, rx_if_index = ~0;
12918   u8 is_add = 1;
12919   int ret;
12920
12921   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12922     {
12923       if (unformat (line_input, "del"))
12924         is_add = 0;
12925       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12926                          &hw_if_index))
12927         ;
12928       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12929         ;
12930       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12931                          &rx_if_index))
12932         ;
12933       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12934         ;
12935       else
12936         {
12937           errmsg ("parse error '%U'", format_unformat_error, line_input);
12938           return -99;
12939         }
12940     }
12941
12942   if (hw_if_index == ~0)
12943     {
12944       errmsg ("no hw interface");
12945       return -99;
12946     }
12947
12948   if (rx_if_index == ~0)
12949     {
12950       errmsg ("no rx tunnel");
12951       return -99;
12952     }
12953
12954   M (VXLAN_OFFLOAD_RX, mp);
12955
12956   mp->hw_if_index = ntohl (hw_if_index);
12957   mp->sw_if_index = ntohl (rx_if_index);
12958   mp->enable = is_add;
12959
12960   S (mp);
12961   W (ret);
12962   return ret;
12963 }
12964
12965 static uword unformat_vxlan_decap_next
12966   (unformat_input_t * input, va_list * args)
12967 {
12968   u32 *result = va_arg (*args, u32 *);
12969   u32 tmp;
12970
12971   if (unformat (input, "l2"))
12972     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12973   else if (unformat (input, "%d", &tmp))
12974     *result = tmp;
12975   else
12976     return 0;
12977   return 1;
12978 }
12979
12980 static int
12981 api_vxlan_add_del_tunnel (vat_main_t * vam)
12982 {
12983   unformat_input_t *line_input = vam->input;
12984   vl_api_vxlan_add_del_tunnel_t *mp;
12985   ip46_address_t src, dst;
12986   u8 is_add = 1;
12987   u8 ipv4_set = 0, ipv6_set = 0;
12988   u8 src_set = 0;
12989   u8 dst_set = 0;
12990   u8 grp_set = 0;
12991   u32 instance = ~0;
12992   u32 mcast_sw_if_index = ~0;
12993   u32 encap_vrf_id = 0;
12994   u32 decap_next_index = ~0;
12995   u32 vni = 0;
12996   int ret;
12997
12998   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12999   memset (&src, 0, sizeof src);
13000   memset (&dst, 0, sizeof dst);
13001
13002   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13003     {
13004       if (unformat (line_input, "del"))
13005         is_add = 0;
13006       else if (unformat (line_input, "instance %d", &instance))
13007         ;
13008       else
13009         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13010         {
13011           ipv4_set = 1;
13012           src_set = 1;
13013         }
13014       else
13015         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13016         {
13017           ipv4_set = 1;
13018           dst_set = 1;
13019         }
13020       else
13021         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13022         {
13023           ipv6_set = 1;
13024           src_set = 1;
13025         }
13026       else
13027         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13028         {
13029           ipv6_set = 1;
13030           dst_set = 1;
13031         }
13032       else if (unformat (line_input, "group %U %U",
13033                          unformat_ip4_address, &dst.ip4,
13034                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13035         {
13036           grp_set = dst_set = 1;
13037           ipv4_set = 1;
13038         }
13039       else if (unformat (line_input, "group %U",
13040                          unformat_ip4_address, &dst.ip4))
13041         {
13042           grp_set = dst_set = 1;
13043           ipv4_set = 1;
13044         }
13045       else if (unformat (line_input, "group %U %U",
13046                          unformat_ip6_address, &dst.ip6,
13047                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13048         {
13049           grp_set = dst_set = 1;
13050           ipv6_set = 1;
13051         }
13052       else if (unformat (line_input, "group %U",
13053                          unformat_ip6_address, &dst.ip6))
13054         {
13055           grp_set = dst_set = 1;
13056           ipv6_set = 1;
13057         }
13058       else
13059         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13060         ;
13061       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13062         ;
13063       else if (unformat (line_input, "decap-next %U",
13064                          unformat_vxlan_decap_next, &decap_next_index))
13065         ;
13066       else if (unformat (line_input, "vni %d", &vni))
13067         ;
13068       else
13069         {
13070           errmsg ("parse error '%U'", format_unformat_error, line_input);
13071           return -99;
13072         }
13073     }
13074
13075   if (src_set == 0)
13076     {
13077       errmsg ("tunnel src address not specified");
13078       return -99;
13079     }
13080   if (dst_set == 0)
13081     {
13082       errmsg ("tunnel dst address not specified");
13083       return -99;
13084     }
13085
13086   if (grp_set && !ip46_address_is_multicast (&dst))
13087     {
13088       errmsg ("tunnel group address not multicast");
13089       return -99;
13090     }
13091   if (grp_set && mcast_sw_if_index == ~0)
13092     {
13093       errmsg ("tunnel nonexistent multicast device");
13094       return -99;
13095     }
13096   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13097     {
13098       errmsg ("tunnel dst address must be unicast");
13099       return -99;
13100     }
13101
13102
13103   if (ipv4_set && ipv6_set)
13104     {
13105       errmsg ("both IPv4 and IPv6 addresses specified");
13106       return -99;
13107     }
13108
13109   if ((vni == 0) || (vni >> 24))
13110     {
13111       errmsg ("vni not specified or out of range");
13112       return -99;
13113     }
13114
13115   M (VXLAN_ADD_DEL_TUNNEL, mp);
13116
13117   if (ipv6_set)
13118     {
13119       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13120       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13121     }
13122   else
13123     {
13124       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13125       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13126     }
13127
13128   mp->instance = htonl (instance);
13129   mp->encap_vrf_id = ntohl (encap_vrf_id);
13130   mp->decap_next_index = ntohl (decap_next_index);
13131   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13132   mp->vni = ntohl (vni);
13133   mp->is_add = is_add;
13134   mp->is_ipv6 = ipv6_set;
13135
13136   S (mp);
13137   W (ret);
13138   return ret;
13139 }
13140
13141 static void vl_api_vxlan_tunnel_details_t_handler
13142   (vl_api_vxlan_tunnel_details_t * mp)
13143 {
13144   vat_main_t *vam = &vat_main;
13145   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13146   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13147
13148   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13149          ntohl (mp->sw_if_index),
13150          ntohl (mp->instance),
13151          format_ip46_address, &src, IP46_TYPE_ANY,
13152          format_ip46_address, &dst, IP46_TYPE_ANY,
13153          ntohl (mp->encap_vrf_id),
13154          ntohl (mp->decap_next_index), ntohl (mp->vni),
13155          ntohl (mp->mcast_sw_if_index));
13156 }
13157
13158 static void vl_api_vxlan_tunnel_details_t_handler_json
13159   (vl_api_vxlan_tunnel_details_t * mp)
13160 {
13161   vat_main_t *vam = &vat_main;
13162   vat_json_node_t *node = NULL;
13163
13164   if (VAT_JSON_ARRAY != vam->json_tree.type)
13165     {
13166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13167       vat_json_init_array (&vam->json_tree);
13168     }
13169   node = vat_json_array_add (&vam->json_tree);
13170
13171   vat_json_init_object (node);
13172   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13173
13174   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13175
13176   if (mp->is_ipv6)
13177     {
13178       struct in6_addr ip6;
13179
13180       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13181       vat_json_object_add_ip6 (node, "src_address", ip6);
13182       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13183       vat_json_object_add_ip6 (node, "dst_address", ip6);
13184     }
13185   else
13186     {
13187       struct in_addr ip4;
13188
13189       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13190       vat_json_object_add_ip4 (node, "src_address", ip4);
13191       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13192       vat_json_object_add_ip4 (node, "dst_address", ip4);
13193     }
13194   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13195   vat_json_object_add_uint (node, "decap_next_index",
13196                             ntohl (mp->decap_next_index));
13197   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13198   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13199   vat_json_object_add_uint (node, "mcast_sw_if_index",
13200                             ntohl (mp->mcast_sw_if_index));
13201 }
13202
13203 static int
13204 api_vxlan_tunnel_dump (vat_main_t * vam)
13205 {
13206   unformat_input_t *i = vam->input;
13207   vl_api_vxlan_tunnel_dump_t *mp;
13208   vl_api_control_ping_t *mp_ping;
13209   u32 sw_if_index;
13210   u8 sw_if_index_set = 0;
13211   int ret;
13212
13213   /* Parse args required to build the message */
13214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13215     {
13216       if (unformat (i, "sw_if_index %d", &sw_if_index))
13217         sw_if_index_set = 1;
13218       else
13219         break;
13220     }
13221
13222   if (sw_if_index_set == 0)
13223     {
13224       sw_if_index = ~0;
13225     }
13226
13227   if (!vam->json_output)
13228     {
13229       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13230              "sw_if_index", "instance", "src_address", "dst_address",
13231              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13232     }
13233
13234   /* Get list of vxlan-tunnel interfaces */
13235   M (VXLAN_TUNNEL_DUMP, mp);
13236
13237   mp->sw_if_index = htonl (sw_if_index);
13238
13239   S (mp);
13240
13241   /* Use a control ping for synchronization */
13242   MPING (CONTROL_PING, mp_ping);
13243   S (mp_ping);
13244
13245   W (ret);
13246   return ret;
13247 }
13248
13249 static uword unformat_geneve_decap_next
13250   (unformat_input_t * input, va_list * args)
13251 {
13252   u32 *result = va_arg (*args, u32 *);
13253   u32 tmp;
13254
13255   if (unformat (input, "l2"))
13256     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13257   else if (unformat (input, "%d", &tmp))
13258     *result = tmp;
13259   else
13260     return 0;
13261   return 1;
13262 }
13263
13264 static int
13265 api_geneve_add_del_tunnel (vat_main_t * vam)
13266 {
13267   unformat_input_t *line_input = vam->input;
13268   vl_api_geneve_add_del_tunnel_t *mp;
13269   ip46_address_t src, dst;
13270   u8 is_add = 1;
13271   u8 ipv4_set = 0, ipv6_set = 0;
13272   u8 src_set = 0;
13273   u8 dst_set = 0;
13274   u8 grp_set = 0;
13275   u32 mcast_sw_if_index = ~0;
13276   u32 encap_vrf_id = 0;
13277   u32 decap_next_index = ~0;
13278   u32 vni = 0;
13279   int ret;
13280
13281   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13282   memset (&src, 0, sizeof src);
13283   memset (&dst, 0, sizeof dst);
13284
13285   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13286     {
13287       if (unformat (line_input, "del"))
13288         is_add = 0;
13289       else
13290         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13291         {
13292           ipv4_set = 1;
13293           src_set = 1;
13294         }
13295       else
13296         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13297         {
13298           ipv4_set = 1;
13299           dst_set = 1;
13300         }
13301       else
13302         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13303         {
13304           ipv6_set = 1;
13305           src_set = 1;
13306         }
13307       else
13308         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13309         {
13310           ipv6_set = 1;
13311           dst_set = 1;
13312         }
13313       else if (unformat (line_input, "group %U %U",
13314                          unformat_ip4_address, &dst.ip4,
13315                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13316         {
13317           grp_set = dst_set = 1;
13318           ipv4_set = 1;
13319         }
13320       else if (unformat (line_input, "group %U",
13321                          unformat_ip4_address, &dst.ip4))
13322         {
13323           grp_set = dst_set = 1;
13324           ipv4_set = 1;
13325         }
13326       else if (unformat (line_input, "group %U %U",
13327                          unformat_ip6_address, &dst.ip6,
13328                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13329         {
13330           grp_set = dst_set = 1;
13331           ipv6_set = 1;
13332         }
13333       else if (unformat (line_input, "group %U",
13334                          unformat_ip6_address, &dst.ip6))
13335         {
13336           grp_set = dst_set = 1;
13337           ipv6_set = 1;
13338         }
13339       else
13340         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13341         ;
13342       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13343         ;
13344       else if (unformat (line_input, "decap-next %U",
13345                          unformat_geneve_decap_next, &decap_next_index))
13346         ;
13347       else if (unformat (line_input, "vni %d", &vni))
13348         ;
13349       else
13350         {
13351           errmsg ("parse error '%U'", format_unformat_error, line_input);
13352           return -99;
13353         }
13354     }
13355
13356   if (src_set == 0)
13357     {
13358       errmsg ("tunnel src address not specified");
13359       return -99;
13360     }
13361   if (dst_set == 0)
13362     {
13363       errmsg ("tunnel dst address not specified");
13364       return -99;
13365     }
13366
13367   if (grp_set && !ip46_address_is_multicast (&dst))
13368     {
13369       errmsg ("tunnel group address not multicast");
13370       return -99;
13371     }
13372   if (grp_set && mcast_sw_if_index == ~0)
13373     {
13374       errmsg ("tunnel nonexistent multicast device");
13375       return -99;
13376     }
13377   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13378     {
13379       errmsg ("tunnel dst address must be unicast");
13380       return -99;
13381     }
13382
13383
13384   if (ipv4_set && ipv6_set)
13385     {
13386       errmsg ("both IPv4 and IPv6 addresses specified");
13387       return -99;
13388     }
13389
13390   if ((vni == 0) || (vni >> 24))
13391     {
13392       errmsg ("vni not specified or out of range");
13393       return -99;
13394     }
13395
13396   M (GENEVE_ADD_DEL_TUNNEL, mp);
13397
13398   if (ipv6_set)
13399     {
13400       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13401       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13402     }
13403   else
13404     {
13405       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13406       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13407     }
13408   mp->encap_vrf_id = ntohl (encap_vrf_id);
13409   mp->decap_next_index = ntohl (decap_next_index);
13410   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13411   mp->vni = ntohl (vni);
13412   mp->is_add = is_add;
13413   mp->is_ipv6 = ipv6_set;
13414
13415   S (mp);
13416   W (ret);
13417   return ret;
13418 }
13419
13420 static void vl_api_geneve_tunnel_details_t_handler
13421   (vl_api_geneve_tunnel_details_t * mp)
13422 {
13423   vat_main_t *vam = &vat_main;
13424   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13425   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13426
13427   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13428          ntohl (mp->sw_if_index),
13429          format_ip46_address, &src, IP46_TYPE_ANY,
13430          format_ip46_address, &dst, IP46_TYPE_ANY,
13431          ntohl (mp->encap_vrf_id),
13432          ntohl (mp->decap_next_index), ntohl (mp->vni),
13433          ntohl (mp->mcast_sw_if_index));
13434 }
13435
13436 static void vl_api_geneve_tunnel_details_t_handler_json
13437   (vl_api_geneve_tunnel_details_t * mp)
13438 {
13439   vat_main_t *vam = &vat_main;
13440   vat_json_node_t *node = NULL;
13441
13442   if (VAT_JSON_ARRAY != vam->json_tree.type)
13443     {
13444       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13445       vat_json_init_array (&vam->json_tree);
13446     }
13447   node = vat_json_array_add (&vam->json_tree);
13448
13449   vat_json_init_object (node);
13450   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13451   if (mp->is_ipv6)
13452     {
13453       struct in6_addr ip6;
13454
13455       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13456       vat_json_object_add_ip6 (node, "src_address", ip6);
13457       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13458       vat_json_object_add_ip6 (node, "dst_address", ip6);
13459     }
13460   else
13461     {
13462       struct in_addr ip4;
13463
13464       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13465       vat_json_object_add_ip4 (node, "src_address", ip4);
13466       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13467       vat_json_object_add_ip4 (node, "dst_address", ip4);
13468     }
13469   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13470   vat_json_object_add_uint (node, "decap_next_index",
13471                             ntohl (mp->decap_next_index));
13472   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13473   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13474   vat_json_object_add_uint (node, "mcast_sw_if_index",
13475                             ntohl (mp->mcast_sw_if_index));
13476 }
13477
13478 static int
13479 api_geneve_tunnel_dump (vat_main_t * vam)
13480 {
13481   unformat_input_t *i = vam->input;
13482   vl_api_geneve_tunnel_dump_t *mp;
13483   vl_api_control_ping_t *mp_ping;
13484   u32 sw_if_index;
13485   u8 sw_if_index_set = 0;
13486   int ret;
13487
13488   /* Parse args required to build the message */
13489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13490     {
13491       if (unformat (i, "sw_if_index %d", &sw_if_index))
13492         sw_if_index_set = 1;
13493       else
13494         break;
13495     }
13496
13497   if (sw_if_index_set == 0)
13498     {
13499       sw_if_index = ~0;
13500     }
13501
13502   if (!vam->json_output)
13503     {
13504       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13505              "sw_if_index", "local_address", "remote_address",
13506              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13507     }
13508
13509   /* Get list of geneve-tunnel interfaces */
13510   M (GENEVE_TUNNEL_DUMP, mp);
13511
13512   mp->sw_if_index = htonl (sw_if_index);
13513
13514   S (mp);
13515
13516   /* Use a control ping for synchronization */
13517   M (CONTROL_PING, mp_ping);
13518   S (mp_ping);
13519
13520   W (ret);
13521   return ret;
13522 }
13523
13524 static int
13525 api_gre_add_del_tunnel (vat_main_t * vam)
13526 {
13527   unformat_input_t *line_input = vam->input;
13528   vl_api_gre_add_del_tunnel_t *mp;
13529   ip4_address_t src4, dst4;
13530   ip6_address_t src6, dst6;
13531   u8 is_add = 1;
13532   u8 ipv4_set = 0;
13533   u8 ipv6_set = 0;
13534   u8 t_type = GRE_TUNNEL_TYPE_L3;
13535   u8 src_set = 0;
13536   u8 dst_set = 0;
13537   u32 outer_fib_id = 0;
13538   u32 session_id = 0;
13539   u32 instance = ~0;
13540   int ret;
13541
13542   memset (&src4, 0, sizeof src4);
13543   memset (&dst4, 0, sizeof dst4);
13544   memset (&src6, 0, sizeof src6);
13545   memset (&dst6, 0, sizeof dst6);
13546
13547   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13548     {
13549       if (unformat (line_input, "del"))
13550         is_add = 0;
13551       else if (unformat (line_input, "instance %d", &instance))
13552         ;
13553       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13554         {
13555           src_set = 1;
13556           ipv4_set = 1;
13557         }
13558       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13559         {
13560           dst_set = 1;
13561           ipv4_set = 1;
13562         }
13563       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13564         {
13565           src_set = 1;
13566           ipv6_set = 1;
13567         }
13568       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13569         {
13570           dst_set = 1;
13571           ipv6_set = 1;
13572         }
13573       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13574         ;
13575       else if (unformat (line_input, "teb"))
13576         t_type = GRE_TUNNEL_TYPE_TEB;
13577       else if (unformat (line_input, "erspan %d", &session_id))
13578         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13579       else
13580         {
13581           errmsg ("parse error '%U'", format_unformat_error, line_input);
13582           return -99;
13583         }
13584     }
13585
13586   if (src_set == 0)
13587     {
13588       errmsg ("tunnel src address not specified");
13589       return -99;
13590     }
13591   if (dst_set == 0)
13592     {
13593       errmsg ("tunnel dst address not specified");
13594       return -99;
13595     }
13596   if (ipv4_set && ipv6_set)
13597     {
13598       errmsg ("both IPv4 and IPv6 addresses specified");
13599       return -99;
13600     }
13601
13602
13603   M (GRE_ADD_DEL_TUNNEL, mp);
13604
13605   if (ipv4_set)
13606     {
13607       clib_memcpy (&mp->src_address, &src4, 4);
13608       clib_memcpy (&mp->dst_address, &dst4, 4);
13609     }
13610   else
13611     {
13612       clib_memcpy (&mp->src_address, &src6, 16);
13613       clib_memcpy (&mp->dst_address, &dst6, 16);
13614     }
13615   mp->instance = htonl (instance);
13616   mp->outer_fib_id = htonl (outer_fib_id);
13617   mp->is_add = is_add;
13618   mp->session_id = htons ((u16) session_id);
13619   mp->tunnel_type = t_type;
13620   mp->is_ipv6 = ipv6_set;
13621
13622   S (mp);
13623   W (ret);
13624   return ret;
13625 }
13626
13627 static void vl_api_gre_tunnel_details_t_handler
13628   (vl_api_gre_tunnel_details_t * mp)
13629 {
13630   vat_main_t *vam = &vat_main;
13631   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13632   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13633
13634   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13635          ntohl (mp->sw_if_index),
13636          ntohl (mp->instance),
13637          format_ip46_address, &src, IP46_TYPE_ANY,
13638          format_ip46_address, &dst, IP46_TYPE_ANY,
13639          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13640 }
13641
13642 static void vl_api_gre_tunnel_details_t_handler_json
13643   (vl_api_gre_tunnel_details_t * mp)
13644 {
13645   vat_main_t *vam = &vat_main;
13646   vat_json_node_t *node = NULL;
13647   struct in_addr ip4;
13648   struct in6_addr ip6;
13649
13650   if (VAT_JSON_ARRAY != vam->json_tree.type)
13651     {
13652       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13653       vat_json_init_array (&vam->json_tree);
13654     }
13655   node = vat_json_array_add (&vam->json_tree);
13656
13657   vat_json_init_object (node);
13658   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13659   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13660   if (!mp->is_ipv6)
13661     {
13662       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13663       vat_json_object_add_ip4 (node, "src_address", ip4);
13664       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13665       vat_json_object_add_ip4 (node, "dst_address", ip4);
13666     }
13667   else
13668     {
13669       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13670       vat_json_object_add_ip6 (node, "src_address", ip6);
13671       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13672       vat_json_object_add_ip6 (node, "dst_address", ip6);
13673     }
13674   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13675   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13676   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13677   vat_json_object_add_uint (node, "session_id", mp->session_id);
13678 }
13679
13680 static int
13681 api_gre_tunnel_dump (vat_main_t * vam)
13682 {
13683   unformat_input_t *i = vam->input;
13684   vl_api_gre_tunnel_dump_t *mp;
13685   vl_api_control_ping_t *mp_ping;
13686   u32 sw_if_index;
13687   u8 sw_if_index_set = 0;
13688   int ret;
13689
13690   /* Parse args required to build the message */
13691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13692     {
13693       if (unformat (i, "sw_if_index %d", &sw_if_index))
13694         sw_if_index_set = 1;
13695       else
13696         break;
13697     }
13698
13699   if (sw_if_index_set == 0)
13700     {
13701       sw_if_index = ~0;
13702     }
13703
13704   if (!vam->json_output)
13705     {
13706       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13707              "sw_if_index", "instance", "src_address", "dst_address",
13708              "tunnel_type", "outer_fib_id", "session_id");
13709     }
13710
13711   /* Get list of gre-tunnel interfaces */
13712   M (GRE_TUNNEL_DUMP, mp);
13713
13714   mp->sw_if_index = htonl (sw_if_index);
13715
13716   S (mp);
13717
13718   /* Use a control ping for synchronization */
13719   MPING (CONTROL_PING, mp_ping);
13720   S (mp_ping);
13721
13722   W (ret);
13723   return ret;
13724 }
13725
13726 static int
13727 api_l2_fib_clear_table (vat_main_t * vam)
13728 {
13729 //  unformat_input_t * i = vam->input;
13730   vl_api_l2_fib_clear_table_t *mp;
13731   int ret;
13732
13733   M (L2_FIB_CLEAR_TABLE, mp);
13734
13735   S (mp);
13736   W (ret);
13737   return ret;
13738 }
13739
13740 static int
13741 api_l2_interface_efp_filter (vat_main_t * vam)
13742 {
13743   unformat_input_t *i = vam->input;
13744   vl_api_l2_interface_efp_filter_t *mp;
13745   u32 sw_if_index;
13746   u8 enable = 1;
13747   u8 sw_if_index_set = 0;
13748   int ret;
13749
13750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13751     {
13752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13753         sw_if_index_set = 1;
13754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13755         sw_if_index_set = 1;
13756       else if (unformat (i, "enable"))
13757         enable = 1;
13758       else if (unformat (i, "disable"))
13759         enable = 0;
13760       else
13761         {
13762           clib_warning ("parse error '%U'", format_unformat_error, i);
13763           return -99;
13764         }
13765     }
13766
13767   if (sw_if_index_set == 0)
13768     {
13769       errmsg ("missing sw_if_index");
13770       return -99;
13771     }
13772
13773   M (L2_INTERFACE_EFP_FILTER, mp);
13774
13775   mp->sw_if_index = ntohl (sw_if_index);
13776   mp->enable_disable = enable;
13777
13778   S (mp);
13779   W (ret);
13780   return ret;
13781 }
13782
13783 #define foreach_vtr_op                          \
13784 _("disable",  L2_VTR_DISABLED)                  \
13785 _("push-1",  L2_VTR_PUSH_1)                     \
13786 _("push-2",  L2_VTR_PUSH_2)                     \
13787 _("pop-1",  L2_VTR_POP_1)                       \
13788 _("pop-2",  L2_VTR_POP_2)                       \
13789 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13790 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13791 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13792 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13793
13794 static int
13795 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13796 {
13797   unformat_input_t *i = vam->input;
13798   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13799   u32 sw_if_index;
13800   u8 sw_if_index_set = 0;
13801   u8 vtr_op_set = 0;
13802   u32 vtr_op = 0;
13803   u32 push_dot1q = 1;
13804   u32 tag1 = ~0;
13805   u32 tag2 = ~0;
13806   int ret;
13807
13808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13809     {
13810       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13811         sw_if_index_set = 1;
13812       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13813         sw_if_index_set = 1;
13814       else if (unformat (i, "vtr_op %d", &vtr_op))
13815         vtr_op_set = 1;
13816 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13817       foreach_vtr_op
13818 #undef _
13819         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13820         ;
13821       else if (unformat (i, "tag1 %d", &tag1))
13822         ;
13823       else if (unformat (i, "tag2 %d", &tag2))
13824         ;
13825       else
13826         {
13827           clib_warning ("parse error '%U'", format_unformat_error, i);
13828           return -99;
13829         }
13830     }
13831
13832   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13833     {
13834       errmsg ("missing vtr operation or sw_if_index");
13835       return -99;
13836     }
13837
13838   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13839   mp->sw_if_index = ntohl (sw_if_index);
13840   mp->vtr_op = ntohl (vtr_op);
13841   mp->push_dot1q = ntohl (push_dot1q);
13842   mp->tag1 = ntohl (tag1);
13843   mp->tag2 = ntohl (tag2);
13844
13845   S (mp);
13846   W (ret);
13847   return ret;
13848 }
13849
13850 static int
13851 api_create_vhost_user_if (vat_main_t * vam)
13852 {
13853   unformat_input_t *i = vam->input;
13854   vl_api_create_vhost_user_if_t *mp;
13855   u8 *file_name;
13856   u8 is_server = 0;
13857   u8 file_name_set = 0;
13858   u32 custom_dev_instance = ~0;
13859   u8 hwaddr[6];
13860   u8 use_custom_mac = 0;
13861   u8 *tag = 0;
13862   int ret;
13863
13864   /* Shut up coverity */
13865   memset (hwaddr, 0, sizeof (hwaddr));
13866
13867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13868     {
13869       if (unformat (i, "socket %s", &file_name))
13870         {
13871           file_name_set = 1;
13872         }
13873       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13874         ;
13875       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13876         use_custom_mac = 1;
13877       else if (unformat (i, "server"))
13878         is_server = 1;
13879       else if (unformat (i, "tag %s", &tag))
13880         ;
13881       else
13882         break;
13883     }
13884
13885   if (file_name_set == 0)
13886     {
13887       errmsg ("missing socket file name");
13888       return -99;
13889     }
13890
13891   if (vec_len (file_name) > 255)
13892     {
13893       errmsg ("socket file name too long");
13894       return -99;
13895     }
13896   vec_add1 (file_name, 0);
13897
13898   M (CREATE_VHOST_USER_IF, mp);
13899
13900   mp->is_server = is_server;
13901   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13902   vec_free (file_name);
13903   if (custom_dev_instance != ~0)
13904     {
13905       mp->renumber = 1;
13906       mp->custom_dev_instance = ntohl (custom_dev_instance);
13907     }
13908   mp->use_custom_mac = use_custom_mac;
13909   clib_memcpy (mp->mac_address, hwaddr, 6);
13910   if (tag)
13911     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13912   vec_free (tag);
13913
13914   S (mp);
13915   W (ret);
13916   return ret;
13917 }
13918
13919 static int
13920 api_modify_vhost_user_if (vat_main_t * vam)
13921 {
13922   unformat_input_t *i = vam->input;
13923   vl_api_modify_vhost_user_if_t *mp;
13924   u8 *file_name;
13925   u8 is_server = 0;
13926   u8 file_name_set = 0;
13927   u32 custom_dev_instance = ~0;
13928   u8 sw_if_index_set = 0;
13929   u32 sw_if_index = (u32) ~ 0;
13930   int ret;
13931
13932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13933     {
13934       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13935         sw_if_index_set = 1;
13936       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13937         sw_if_index_set = 1;
13938       else if (unformat (i, "socket %s", &file_name))
13939         {
13940           file_name_set = 1;
13941         }
13942       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13943         ;
13944       else if (unformat (i, "server"))
13945         is_server = 1;
13946       else
13947         break;
13948     }
13949
13950   if (sw_if_index_set == 0)
13951     {
13952       errmsg ("missing sw_if_index or interface name");
13953       return -99;
13954     }
13955
13956   if (file_name_set == 0)
13957     {
13958       errmsg ("missing socket file name");
13959       return -99;
13960     }
13961
13962   if (vec_len (file_name) > 255)
13963     {
13964       errmsg ("socket file name too long");
13965       return -99;
13966     }
13967   vec_add1 (file_name, 0);
13968
13969   M (MODIFY_VHOST_USER_IF, mp);
13970
13971   mp->sw_if_index = ntohl (sw_if_index);
13972   mp->is_server = is_server;
13973   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13974   vec_free (file_name);
13975   if (custom_dev_instance != ~0)
13976     {
13977       mp->renumber = 1;
13978       mp->custom_dev_instance = ntohl (custom_dev_instance);
13979     }
13980
13981   S (mp);
13982   W (ret);
13983   return ret;
13984 }
13985
13986 static int
13987 api_delete_vhost_user_if (vat_main_t * vam)
13988 {
13989   unformat_input_t *i = vam->input;
13990   vl_api_delete_vhost_user_if_t *mp;
13991   u32 sw_if_index = ~0;
13992   u8 sw_if_index_set = 0;
13993   int ret;
13994
13995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13996     {
13997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13998         sw_if_index_set = 1;
13999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14000         sw_if_index_set = 1;
14001       else
14002         break;
14003     }
14004
14005   if (sw_if_index_set == 0)
14006     {
14007       errmsg ("missing sw_if_index or interface name");
14008       return -99;
14009     }
14010
14011
14012   M (DELETE_VHOST_USER_IF, mp);
14013
14014   mp->sw_if_index = ntohl (sw_if_index);
14015
14016   S (mp);
14017   W (ret);
14018   return ret;
14019 }
14020
14021 static void vl_api_sw_interface_vhost_user_details_t_handler
14022   (vl_api_sw_interface_vhost_user_details_t * mp)
14023 {
14024   vat_main_t *vam = &vat_main;
14025
14026   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14027          (char *) mp->interface_name,
14028          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14029          clib_net_to_host_u64 (mp->features), mp->is_server,
14030          ntohl (mp->num_regions), (char *) mp->sock_filename);
14031   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14032 }
14033
14034 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14035   (vl_api_sw_interface_vhost_user_details_t * mp)
14036 {
14037   vat_main_t *vam = &vat_main;
14038   vat_json_node_t *node = NULL;
14039
14040   if (VAT_JSON_ARRAY != vam->json_tree.type)
14041     {
14042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14043       vat_json_init_array (&vam->json_tree);
14044     }
14045   node = vat_json_array_add (&vam->json_tree);
14046
14047   vat_json_init_object (node);
14048   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14049   vat_json_object_add_string_copy (node, "interface_name",
14050                                    mp->interface_name);
14051   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14052                             ntohl (mp->virtio_net_hdr_sz));
14053   vat_json_object_add_uint (node, "features",
14054                             clib_net_to_host_u64 (mp->features));
14055   vat_json_object_add_uint (node, "is_server", mp->is_server);
14056   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14057   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14058   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14059 }
14060
14061 static int
14062 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14063 {
14064   vl_api_sw_interface_vhost_user_dump_t *mp;
14065   vl_api_control_ping_t *mp_ping;
14066   int ret;
14067   print (vam->ofp,
14068          "Interface name            idx hdr_sz features server regions filename");
14069
14070   /* Get list of vhost-user interfaces */
14071   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14072   S (mp);
14073
14074   /* Use a control ping for synchronization */
14075   MPING (CONTROL_PING, mp_ping);
14076   S (mp_ping);
14077
14078   W (ret);
14079   return ret;
14080 }
14081
14082 static int
14083 api_show_version (vat_main_t * vam)
14084 {
14085   vl_api_show_version_t *mp;
14086   int ret;
14087
14088   M (SHOW_VERSION, mp);
14089
14090   S (mp);
14091   W (ret);
14092   return ret;
14093 }
14094
14095
14096 static int
14097 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14098 {
14099   unformat_input_t *line_input = vam->input;
14100   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14101   ip4_address_t local4, remote4;
14102   ip6_address_t local6, remote6;
14103   u8 is_add = 1;
14104   u8 ipv4_set = 0, ipv6_set = 0;
14105   u8 local_set = 0;
14106   u8 remote_set = 0;
14107   u8 grp_set = 0;
14108   u32 mcast_sw_if_index = ~0;
14109   u32 encap_vrf_id = 0;
14110   u32 decap_vrf_id = 0;
14111   u8 protocol = ~0;
14112   u32 vni;
14113   u8 vni_set = 0;
14114   int ret;
14115
14116   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14117   memset (&local4, 0, sizeof local4);
14118   memset (&remote4, 0, sizeof remote4);
14119   memset (&local6, 0, sizeof local6);
14120   memset (&remote6, 0, sizeof remote6);
14121
14122   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14123     {
14124       if (unformat (line_input, "del"))
14125         is_add = 0;
14126       else if (unformat (line_input, "local %U",
14127                          unformat_ip4_address, &local4))
14128         {
14129           local_set = 1;
14130           ipv4_set = 1;
14131         }
14132       else if (unformat (line_input, "remote %U",
14133                          unformat_ip4_address, &remote4))
14134         {
14135           remote_set = 1;
14136           ipv4_set = 1;
14137         }
14138       else if (unformat (line_input, "local %U",
14139                          unformat_ip6_address, &local6))
14140         {
14141           local_set = 1;
14142           ipv6_set = 1;
14143         }
14144       else if (unformat (line_input, "remote %U",
14145                          unformat_ip6_address, &remote6))
14146         {
14147           remote_set = 1;
14148           ipv6_set = 1;
14149         }
14150       else if (unformat (line_input, "group %U %U",
14151                          unformat_ip4_address, &remote4,
14152                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14153         {
14154           grp_set = remote_set = 1;
14155           ipv4_set = 1;
14156         }
14157       else if (unformat (line_input, "group %U",
14158                          unformat_ip4_address, &remote4))
14159         {
14160           grp_set = remote_set = 1;
14161           ipv4_set = 1;
14162         }
14163       else if (unformat (line_input, "group %U %U",
14164                          unformat_ip6_address, &remote6,
14165                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14166         {
14167           grp_set = remote_set = 1;
14168           ipv6_set = 1;
14169         }
14170       else if (unformat (line_input, "group %U",
14171                          unformat_ip6_address, &remote6))
14172         {
14173           grp_set = remote_set = 1;
14174           ipv6_set = 1;
14175         }
14176       else
14177         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14178         ;
14179       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14180         ;
14181       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14182         ;
14183       else if (unformat (line_input, "vni %d", &vni))
14184         vni_set = 1;
14185       else if (unformat (line_input, "next-ip4"))
14186         protocol = 1;
14187       else if (unformat (line_input, "next-ip6"))
14188         protocol = 2;
14189       else if (unformat (line_input, "next-ethernet"))
14190         protocol = 3;
14191       else if (unformat (line_input, "next-nsh"))
14192         protocol = 4;
14193       else
14194         {
14195           errmsg ("parse error '%U'", format_unformat_error, line_input);
14196           return -99;
14197         }
14198     }
14199
14200   if (local_set == 0)
14201     {
14202       errmsg ("tunnel local address not specified");
14203       return -99;
14204     }
14205   if (remote_set == 0)
14206     {
14207       errmsg ("tunnel remote address not specified");
14208       return -99;
14209     }
14210   if (grp_set && mcast_sw_if_index == ~0)
14211     {
14212       errmsg ("tunnel nonexistent multicast device");
14213       return -99;
14214     }
14215   if (ipv4_set && ipv6_set)
14216     {
14217       errmsg ("both IPv4 and IPv6 addresses specified");
14218       return -99;
14219     }
14220
14221   if (vni_set == 0)
14222     {
14223       errmsg ("vni not specified");
14224       return -99;
14225     }
14226
14227   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14228
14229
14230   if (ipv6_set)
14231     {
14232       clib_memcpy (&mp->local, &local6, sizeof (local6));
14233       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14234     }
14235   else
14236     {
14237       clib_memcpy (&mp->local, &local4, sizeof (local4));
14238       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14239     }
14240
14241   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14242   mp->encap_vrf_id = ntohl (encap_vrf_id);
14243   mp->decap_vrf_id = ntohl (decap_vrf_id);
14244   mp->protocol = protocol;
14245   mp->vni = ntohl (vni);
14246   mp->is_add = is_add;
14247   mp->is_ipv6 = ipv6_set;
14248
14249   S (mp);
14250   W (ret);
14251   return ret;
14252 }
14253
14254 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14255   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14256 {
14257   vat_main_t *vam = &vat_main;
14258   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14259   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14260
14261   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14262          ntohl (mp->sw_if_index),
14263          format_ip46_address, &local, IP46_TYPE_ANY,
14264          format_ip46_address, &remote, IP46_TYPE_ANY,
14265          ntohl (mp->vni), mp->protocol,
14266          ntohl (mp->mcast_sw_if_index),
14267          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14268 }
14269
14270
14271 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14272   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14273 {
14274   vat_main_t *vam = &vat_main;
14275   vat_json_node_t *node = NULL;
14276   struct in_addr ip4;
14277   struct in6_addr ip6;
14278
14279   if (VAT_JSON_ARRAY != vam->json_tree.type)
14280     {
14281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14282       vat_json_init_array (&vam->json_tree);
14283     }
14284   node = vat_json_array_add (&vam->json_tree);
14285
14286   vat_json_init_object (node);
14287   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14288   if (mp->is_ipv6)
14289     {
14290       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14291       vat_json_object_add_ip6 (node, "local", ip6);
14292       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14293       vat_json_object_add_ip6 (node, "remote", ip6);
14294     }
14295   else
14296     {
14297       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14298       vat_json_object_add_ip4 (node, "local", ip4);
14299       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14300       vat_json_object_add_ip4 (node, "remote", ip4);
14301     }
14302   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14303   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14304   vat_json_object_add_uint (node, "mcast_sw_if_index",
14305                             ntohl (mp->mcast_sw_if_index));
14306   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14307   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14308   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14309 }
14310
14311 static int
14312 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14313 {
14314   unformat_input_t *i = vam->input;
14315   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14316   vl_api_control_ping_t *mp_ping;
14317   u32 sw_if_index;
14318   u8 sw_if_index_set = 0;
14319   int ret;
14320
14321   /* Parse args required to build the message */
14322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14323     {
14324       if (unformat (i, "sw_if_index %d", &sw_if_index))
14325         sw_if_index_set = 1;
14326       else
14327         break;
14328     }
14329
14330   if (sw_if_index_set == 0)
14331     {
14332       sw_if_index = ~0;
14333     }
14334
14335   if (!vam->json_output)
14336     {
14337       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14338              "sw_if_index", "local", "remote", "vni",
14339              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14340     }
14341
14342   /* Get list of vxlan-tunnel interfaces */
14343   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14344
14345   mp->sw_if_index = htonl (sw_if_index);
14346
14347   S (mp);
14348
14349   /* Use a control ping for synchronization */
14350   MPING (CONTROL_PING, mp_ping);
14351   S (mp_ping);
14352
14353   W (ret);
14354   return ret;
14355 }
14356
14357 static void vl_api_l2_fib_table_details_t_handler
14358   (vl_api_l2_fib_table_details_t * mp)
14359 {
14360   vat_main_t *vam = &vat_main;
14361
14362   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14363          "       %d       %d     %d",
14364          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14365          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14366          mp->bvi_mac);
14367 }
14368
14369 static void vl_api_l2_fib_table_details_t_handler_json
14370   (vl_api_l2_fib_table_details_t * mp)
14371 {
14372   vat_main_t *vam = &vat_main;
14373   vat_json_node_t *node = NULL;
14374
14375   if (VAT_JSON_ARRAY != vam->json_tree.type)
14376     {
14377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14378       vat_json_init_array (&vam->json_tree);
14379     }
14380   node = vat_json_array_add (&vam->json_tree);
14381
14382   vat_json_init_object (node);
14383   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14384   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14385   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14386   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14387   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14388   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14389 }
14390
14391 static int
14392 api_l2_fib_table_dump (vat_main_t * vam)
14393 {
14394   unformat_input_t *i = vam->input;
14395   vl_api_l2_fib_table_dump_t *mp;
14396   vl_api_control_ping_t *mp_ping;
14397   u32 bd_id;
14398   u8 bd_id_set = 0;
14399   int ret;
14400
14401   /* Parse args required to build the message */
14402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14403     {
14404       if (unformat (i, "bd_id %d", &bd_id))
14405         bd_id_set = 1;
14406       else
14407         break;
14408     }
14409
14410   if (bd_id_set == 0)
14411     {
14412       errmsg ("missing bridge domain");
14413       return -99;
14414     }
14415
14416   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14417
14418   /* Get list of l2 fib entries */
14419   M (L2_FIB_TABLE_DUMP, mp);
14420
14421   mp->bd_id = ntohl (bd_id);
14422   S (mp);
14423
14424   /* Use a control ping for synchronization */
14425   MPING (CONTROL_PING, mp_ping);
14426   S (mp_ping);
14427
14428   W (ret);
14429   return ret;
14430 }
14431
14432
14433 static int
14434 api_interface_name_renumber (vat_main_t * vam)
14435 {
14436   unformat_input_t *line_input = vam->input;
14437   vl_api_interface_name_renumber_t *mp;
14438   u32 sw_if_index = ~0;
14439   u32 new_show_dev_instance = ~0;
14440   int ret;
14441
14442   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14443     {
14444       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14445                     &sw_if_index))
14446         ;
14447       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14448         ;
14449       else if (unformat (line_input, "new_show_dev_instance %d",
14450                          &new_show_dev_instance))
14451         ;
14452       else
14453         break;
14454     }
14455
14456   if (sw_if_index == ~0)
14457     {
14458       errmsg ("missing interface name or sw_if_index");
14459       return -99;
14460     }
14461
14462   if (new_show_dev_instance == ~0)
14463     {
14464       errmsg ("missing new_show_dev_instance");
14465       return -99;
14466     }
14467
14468   M (INTERFACE_NAME_RENUMBER, mp);
14469
14470   mp->sw_if_index = ntohl (sw_if_index);
14471   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14472
14473   S (mp);
14474   W (ret);
14475   return ret;
14476 }
14477
14478 static int
14479 api_ip_probe_neighbor (vat_main_t * vam)
14480 {
14481   unformat_input_t *i = vam->input;
14482   vl_api_ip_probe_neighbor_t *mp;
14483   u8 int_set = 0;
14484   u8 adr_set = 0;
14485   u8 is_ipv6 = 0;
14486   u8 dst_adr[16];
14487   u32 sw_if_index;
14488   int ret;
14489
14490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14491     {
14492       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14493         int_set = 1;
14494       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14495         int_set = 1;
14496       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14497         adr_set = 1;
14498       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14499         {
14500           adr_set = 1;
14501           is_ipv6 = 1;
14502         }
14503       else
14504         break;
14505     }
14506
14507   if (int_set == 0)
14508     {
14509       errmsg ("missing interface");
14510       return -99;
14511     }
14512
14513   if (adr_set == 0)
14514     {
14515       errmsg ("missing addresses");
14516       return -99;
14517     }
14518
14519   M (IP_PROBE_NEIGHBOR, mp);
14520
14521   mp->sw_if_index = ntohl (sw_if_index);
14522   mp->is_ipv6 = is_ipv6;
14523   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14524
14525   S (mp);
14526   W (ret);
14527   return ret;
14528 }
14529
14530 static int
14531 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14532 {
14533   unformat_input_t *i = vam->input;
14534   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14535   u8 mode = IP_SCAN_V46_NEIGHBORS;
14536   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14537   int ret;
14538
14539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14540     {
14541       if (unformat (i, "ip4"))
14542         mode = IP_SCAN_V4_NEIGHBORS;
14543       else if (unformat (i, "ip6"))
14544         mode = IP_SCAN_V6_NEIGHBORS;
14545       if (unformat (i, "both"))
14546         mode = IP_SCAN_V46_NEIGHBORS;
14547       else if (unformat (i, "disable"))
14548         mode = IP_SCAN_DISABLED;
14549       else if (unformat (i, "interval %d", &interval))
14550         ;
14551       else if (unformat (i, "max-time %d", &time))
14552         ;
14553       else if (unformat (i, "max-update %d", &update))
14554         ;
14555       else if (unformat (i, "delay %d", &delay))
14556         ;
14557       else if (unformat (i, "stale %d", &stale))
14558         ;
14559       else
14560         break;
14561     }
14562
14563   if (interval > 255)
14564     {
14565       errmsg ("interval cannot exceed 255 minutes.");
14566       return -99;
14567     }
14568   if (time > 255)
14569     {
14570       errmsg ("max-time cannot exceed 255 usec.");
14571       return -99;
14572     }
14573   if (update > 255)
14574     {
14575       errmsg ("max-update cannot exceed 255.");
14576       return -99;
14577     }
14578   if (delay > 255)
14579     {
14580       errmsg ("delay cannot exceed 255 msec.");
14581       return -99;
14582     }
14583   if (stale > 255)
14584     {
14585       errmsg ("stale cannot exceed 255 minutes.");
14586       return -99;
14587     }
14588
14589   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14590   mp->mode = mode;
14591   mp->scan_interval = interval;
14592   mp->max_proc_time = time;
14593   mp->max_update = update;
14594   mp->scan_int_delay = delay;
14595   mp->stale_threshold = stale;
14596
14597   S (mp);
14598   W (ret);
14599   return ret;
14600 }
14601
14602 static int
14603 api_want_ip4_arp_events (vat_main_t * vam)
14604 {
14605   unformat_input_t *line_input = vam->input;
14606   vl_api_want_ip4_arp_events_t *mp;
14607   ip4_address_t address;
14608   int address_set = 0;
14609   u32 enable_disable = 1;
14610   int ret;
14611
14612   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14613     {
14614       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14615         address_set = 1;
14616       else if (unformat (line_input, "del"))
14617         enable_disable = 0;
14618       else
14619         break;
14620     }
14621
14622   if (address_set == 0)
14623     {
14624       errmsg ("missing addresses");
14625       return -99;
14626     }
14627
14628   M (WANT_IP4_ARP_EVENTS, mp);
14629   mp->enable_disable = enable_disable;
14630   mp->pid = htonl (getpid ());
14631   mp->address = address.as_u32;
14632
14633   S (mp);
14634   W (ret);
14635   return ret;
14636 }
14637
14638 static int
14639 api_want_ip6_nd_events (vat_main_t * vam)
14640 {
14641   unformat_input_t *line_input = vam->input;
14642   vl_api_want_ip6_nd_events_t *mp;
14643   ip6_address_t address;
14644   int address_set = 0;
14645   u32 enable_disable = 1;
14646   int ret;
14647
14648   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14649     {
14650       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14651         address_set = 1;
14652       else if (unformat (line_input, "del"))
14653         enable_disable = 0;
14654       else
14655         break;
14656     }
14657
14658   if (address_set == 0)
14659     {
14660       errmsg ("missing addresses");
14661       return -99;
14662     }
14663
14664   M (WANT_IP6_ND_EVENTS, mp);
14665   mp->enable_disable = enable_disable;
14666   mp->pid = htonl (getpid ());
14667   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14668
14669   S (mp);
14670   W (ret);
14671   return ret;
14672 }
14673
14674 static int
14675 api_want_l2_macs_events (vat_main_t * vam)
14676 {
14677   unformat_input_t *line_input = vam->input;
14678   vl_api_want_l2_macs_events_t *mp;
14679   u8 enable_disable = 1;
14680   u32 scan_delay = 0;
14681   u32 max_macs_in_event = 0;
14682   u32 learn_limit = 0;
14683   int ret;
14684
14685   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14686     {
14687       if (unformat (line_input, "learn-limit %d", &learn_limit))
14688         ;
14689       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14690         ;
14691       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14692         ;
14693       else if (unformat (line_input, "disable"))
14694         enable_disable = 0;
14695       else
14696         break;
14697     }
14698
14699   M (WANT_L2_MACS_EVENTS, mp);
14700   mp->enable_disable = enable_disable;
14701   mp->pid = htonl (getpid ());
14702   mp->learn_limit = htonl (learn_limit);
14703   mp->scan_delay = (u8) scan_delay;
14704   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14705   S (mp);
14706   W (ret);
14707   return ret;
14708 }
14709
14710 static int
14711 api_input_acl_set_interface (vat_main_t * vam)
14712 {
14713   unformat_input_t *i = vam->input;
14714   vl_api_input_acl_set_interface_t *mp;
14715   u32 sw_if_index;
14716   int sw_if_index_set;
14717   u32 ip4_table_index = ~0;
14718   u32 ip6_table_index = ~0;
14719   u32 l2_table_index = ~0;
14720   u8 is_add = 1;
14721   int ret;
14722
14723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14726         sw_if_index_set = 1;
14727       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14728         sw_if_index_set = 1;
14729       else if (unformat (i, "del"))
14730         is_add = 0;
14731       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14732         ;
14733       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14734         ;
14735       else if (unformat (i, "l2-table %d", &l2_table_index))
14736         ;
14737       else
14738         {
14739           clib_warning ("parse error '%U'", format_unformat_error, i);
14740           return -99;
14741         }
14742     }
14743
14744   if (sw_if_index_set == 0)
14745     {
14746       errmsg ("missing interface name or sw_if_index");
14747       return -99;
14748     }
14749
14750   M (INPUT_ACL_SET_INTERFACE, mp);
14751
14752   mp->sw_if_index = ntohl (sw_if_index);
14753   mp->ip4_table_index = ntohl (ip4_table_index);
14754   mp->ip6_table_index = ntohl (ip6_table_index);
14755   mp->l2_table_index = ntohl (l2_table_index);
14756   mp->is_add = is_add;
14757
14758   S (mp);
14759   W (ret);
14760   return ret;
14761 }
14762
14763 static int
14764 api_output_acl_set_interface (vat_main_t * vam)
14765 {
14766   unformat_input_t *i = vam->input;
14767   vl_api_output_acl_set_interface_t *mp;
14768   u32 sw_if_index;
14769   int sw_if_index_set;
14770   u32 ip4_table_index = ~0;
14771   u32 ip6_table_index = ~0;
14772   u32 l2_table_index = ~0;
14773   u8 is_add = 1;
14774   int ret;
14775
14776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14777     {
14778       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14779         sw_if_index_set = 1;
14780       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14781         sw_if_index_set = 1;
14782       else if (unformat (i, "del"))
14783         is_add = 0;
14784       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14785         ;
14786       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14787         ;
14788       else if (unformat (i, "l2-table %d", &l2_table_index))
14789         ;
14790       else
14791         {
14792           clib_warning ("parse error '%U'", format_unformat_error, i);
14793           return -99;
14794         }
14795     }
14796
14797   if (sw_if_index_set == 0)
14798     {
14799       errmsg ("missing interface name or sw_if_index");
14800       return -99;
14801     }
14802
14803   M (OUTPUT_ACL_SET_INTERFACE, mp);
14804
14805   mp->sw_if_index = ntohl (sw_if_index);
14806   mp->ip4_table_index = ntohl (ip4_table_index);
14807   mp->ip6_table_index = ntohl (ip6_table_index);
14808   mp->l2_table_index = ntohl (l2_table_index);
14809   mp->is_add = is_add;
14810
14811   S (mp);
14812   W (ret);
14813   return ret;
14814 }
14815
14816 static int
14817 api_ip_address_dump (vat_main_t * vam)
14818 {
14819   unformat_input_t *i = vam->input;
14820   vl_api_ip_address_dump_t *mp;
14821   vl_api_control_ping_t *mp_ping;
14822   u32 sw_if_index = ~0;
14823   u8 sw_if_index_set = 0;
14824   u8 ipv4_set = 0;
14825   u8 ipv6_set = 0;
14826   int ret;
14827
14828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14829     {
14830       if (unformat (i, "sw_if_index %d", &sw_if_index))
14831         sw_if_index_set = 1;
14832       else
14833         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14834         sw_if_index_set = 1;
14835       else if (unformat (i, "ipv4"))
14836         ipv4_set = 1;
14837       else if (unformat (i, "ipv6"))
14838         ipv6_set = 1;
14839       else
14840         break;
14841     }
14842
14843   if (ipv4_set && ipv6_set)
14844     {
14845       errmsg ("ipv4 and ipv6 flags cannot be both set");
14846       return -99;
14847     }
14848
14849   if ((!ipv4_set) && (!ipv6_set))
14850     {
14851       errmsg ("no ipv4 nor ipv6 flag set");
14852       return -99;
14853     }
14854
14855   if (sw_if_index_set == 0)
14856     {
14857       errmsg ("missing interface name or sw_if_index");
14858       return -99;
14859     }
14860
14861   vam->current_sw_if_index = sw_if_index;
14862   vam->is_ipv6 = ipv6_set;
14863
14864   M (IP_ADDRESS_DUMP, mp);
14865   mp->sw_if_index = ntohl (sw_if_index);
14866   mp->is_ipv6 = ipv6_set;
14867   S (mp);
14868
14869   /* Use a control ping for synchronization */
14870   MPING (CONTROL_PING, mp_ping);
14871   S (mp_ping);
14872
14873   W (ret);
14874   return ret;
14875 }
14876
14877 static int
14878 api_ip_dump (vat_main_t * vam)
14879 {
14880   vl_api_ip_dump_t *mp;
14881   vl_api_control_ping_t *mp_ping;
14882   unformat_input_t *in = vam->input;
14883   int ipv4_set = 0;
14884   int ipv6_set = 0;
14885   int is_ipv6;
14886   int i;
14887   int ret;
14888
14889   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14890     {
14891       if (unformat (in, "ipv4"))
14892         ipv4_set = 1;
14893       else if (unformat (in, "ipv6"))
14894         ipv6_set = 1;
14895       else
14896         break;
14897     }
14898
14899   if (ipv4_set && ipv6_set)
14900     {
14901       errmsg ("ipv4 and ipv6 flags cannot be both set");
14902       return -99;
14903     }
14904
14905   if ((!ipv4_set) && (!ipv6_set))
14906     {
14907       errmsg ("no ipv4 nor ipv6 flag set");
14908       return -99;
14909     }
14910
14911   is_ipv6 = ipv6_set;
14912   vam->is_ipv6 = is_ipv6;
14913
14914   /* free old data */
14915   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14916     {
14917       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14918     }
14919   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14920
14921   M (IP_DUMP, mp);
14922   mp->is_ipv6 = ipv6_set;
14923   S (mp);
14924
14925   /* Use a control ping for synchronization */
14926   MPING (CONTROL_PING, mp_ping);
14927   S (mp_ping);
14928
14929   W (ret);
14930   return ret;
14931 }
14932
14933 static int
14934 api_ipsec_spd_add_del (vat_main_t * vam)
14935 {
14936   unformat_input_t *i = vam->input;
14937   vl_api_ipsec_spd_add_del_t *mp;
14938   u32 spd_id = ~0;
14939   u8 is_add = 1;
14940   int ret;
14941
14942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14943     {
14944       if (unformat (i, "spd_id %d", &spd_id))
14945         ;
14946       else if (unformat (i, "del"))
14947         is_add = 0;
14948       else
14949         {
14950           clib_warning ("parse error '%U'", format_unformat_error, i);
14951           return -99;
14952         }
14953     }
14954   if (spd_id == ~0)
14955     {
14956       errmsg ("spd_id must be set");
14957       return -99;
14958     }
14959
14960   M (IPSEC_SPD_ADD_DEL, mp);
14961
14962   mp->spd_id = ntohl (spd_id);
14963   mp->is_add = is_add;
14964
14965   S (mp);
14966   W (ret);
14967   return ret;
14968 }
14969
14970 static int
14971 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14972 {
14973   unformat_input_t *i = vam->input;
14974   vl_api_ipsec_interface_add_del_spd_t *mp;
14975   u32 sw_if_index;
14976   u8 sw_if_index_set = 0;
14977   u32 spd_id = (u32) ~ 0;
14978   u8 is_add = 1;
14979   int ret;
14980
14981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14982     {
14983       if (unformat (i, "del"))
14984         is_add = 0;
14985       else if (unformat (i, "spd_id %d", &spd_id))
14986         ;
14987       else
14988         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14989         sw_if_index_set = 1;
14990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14991         sw_if_index_set = 1;
14992       else
14993         {
14994           clib_warning ("parse error '%U'", format_unformat_error, i);
14995           return -99;
14996         }
14997
14998     }
14999
15000   if (spd_id == (u32) ~ 0)
15001     {
15002       errmsg ("spd_id must be set");
15003       return -99;
15004     }
15005
15006   if (sw_if_index_set == 0)
15007     {
15008       errmsg ("missing interface name or sw_if_index");
15009       return -99;
15010     }
15011
15012   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15013
15014   mp->spd_id = ntohl (spd_id);
15015   mp->sw_if_index = ntohl (sw_if_index);
15016   mp->is_add = is_add;
15017
15018   S (mp);
15019   W (ret);
15020   return ret;
15021 }
15022
15023 static int
15024 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15025 {
15026   unformat_input_t *i = vam->input;
15027   vl_api_ipsec_spd_add_del_entry_t *mp;
15028   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15029   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15030   i32 priority = 0;
15031   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15032   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15033   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15034   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15035   int ret;
15036
15037   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15038   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15039   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15040   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15041   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15042   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15043
15044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15045     {
15046       if (unformat (i, "del"))
15047         is_add = 0;
15048       if (unformat (i, "outbound"))
15049         is_outbound = 1;
15050       if (unformat (i, "inbound"))
15051         is_outbound = 0;
15052       else if (unformat (i, "spd_id %d", &spd_id))
15053         ;
15054       else if (unformat (i, "sa_id %d", &sa_id))
15055         ;
15056       else if (unformat (i, "priority %d", &priority))
15057         ;
15058       else if (unformat (i, "protocol %d", &protocol))
15059         ;
15060       else if (unformat (i, "lport_start %d", &lport_start))
15061         ;
15062       else if (unformat (i, "lport_stop %d", &lport_stop))
15063         ;
15064       else if (unformat (i, "rport_start %d", &rport_start))
15065         ;
15066       else if (unformat (i, "rport_stop %d", &rport_stop))
15067         ;
15068       else
15069         if (unformat
15070             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15071         {
15072           is_ipv6 = 0;
15073           is_ip_any = 0;
15074         }
15075       else
15076         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15077         {
15078           is_ipv6 = 0;
15079           is_ip_any = 0;
15080         }
15081       else
15082         if (unformat
15083             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15084         {
15085           is_ipv6 = 0;
15086           is_ip_any = 0;
15087         }
15088       else
15089         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15090         {
15091           is_ipv6 = 0;
15092           is_ip_any = 0;
15093         }
15094       else
15095         if (unformat
15096             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15097         {
15098           is_ipv6 = 1;
15099           is_ip_any = 0;
15100         }
15101       else
15102         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15103         {
15104           is_ipv6 = 1;
15105           is_ip_any = 0;
15106         }
15107       else
15108         if (unformat
15109             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15110         {
15111           is_ipv6 = 1;
15112           is_ip_any = 0;
15113         }
15114       else
15115         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15116         {
15117           is_ipv6 = 1;
15118           is_ip_any = 0;
15119         }
15120       else
15121         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15122         {
15123           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15124             {
15125               clib_warning ("unsupported action: 'resolve'");
15126               return -99;
15127             }
15128         }
15129       else
15130         {
15131           clib_warning ("parse error '%U'", format_unformat_error, i);
15132           return -99;
15133         }
15134
15135     }
15136
15137   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15138
15139   mp->spd_id = ntohl (spd_id);
15140   mp->priority = ntohl (priority);
15141   mp->is_outbound = is_outbound;
15142
15143   mp->is_ipv6 = is_ipv6;
15144   if (is_ipv6 || is_ip_any)
15145     {
15146       clib_memcpy (mp->remote_address_start, &raddr6_start,
15147                    sizeof (ip6_address_t));
15148       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15149                    sizeof (ip6_address_t));
15150       clib_memcpy (mp->local_address_start, &laddr6_start,
15151                    sizeof (ip6_address_t));
15152       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15153                    sizeof (ip6_address_t));
15154     }
15155   else
15156     {
15157       clib_memcpy (mp->remote_address_start, &raddr4_start,
15158                    sizeof (ip4_address_t));
15159       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15160                    sizeof (ip4_address_t));
15161       clib_memcpy (mp->local_address_start, &laddr4_start,
15162                    sizeof (ip4_address_t));
15163       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15164                    sizeof (ip4_address_t));
15165     }
15166   mp->protocol = (u8) protocol;
15167   mp->local_port_start = ntohs ((u16) lport_start);
15168   mp->local_port_stop = ntohs ((u16) lport_stop);
15169   mp->remote_port_start = ntohs ((u16) rport_start);
15170   mp->remote_port_stop = ntohs ((u16) rport_stop);
15171   mp->policy = (u8) policy;
15172   mp->sa_id = ntohl (sa_id);
15173   mp->is_add = is_add;
15174   mp->is_ip_any = is_ip_any;
15175   S (mp);
15176   W (ret);
15177   return ret;
15178 }
15179
15180 static int
15181 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15182 {
15183   unformat_input_t *i = vam->input;
15184   vl_api_ipsec_sad_add_del_entry_t *mp;
15185   u32 sad_id = 0, spi = 0;
15186   u8 *ck = 0, *ik = 0;
15187   u8 is_add = 1;
15188
15189   u8 protocol = IPSEC_PROTOCOL_AH;
15190   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15191   u32 crypto_alg = 0, integ_alg = 0;
15192   ip4_address_t tun_src4;
15193   ip4_address_t tun_dst4;
15194   ip6_address_t tun_src6;
15195   ip6_address_t tun_dst6;
15196   int ret;
15197
15198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15199     {
15200       if (unformat (i, "del"))
15201         is_add = 0;
15202       else if (unformat (i, "sad_id %d", &sad_id))
15203         ;
15204       else if (unformat (i, "spi %d", &spi))
15205         ;
15206       else if (unformat (i, "esp"))
15207         protocol = IPSEC_PROTOCOL_ESP;
15208       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15209         {
15210           is_tunnel = 1;
15211           is_tunnel_ipv6 = 0;
15212         }
15213       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15214         {
15215           is_tunnel = 1;
15216           is_tunnel_ipv6 = 0;
15217         }
15218       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15219         {
15220           is_tunnel = 1;
15221           is_tunnel_ipv6 = 1;
15222         }
15223       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15224         {
15225           is_tunnel = 1;
15226           is_tunnel_ipv6 = 1;
15227         }
15228       else
15229         if (unformat
15230             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15231         {
15232           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15233               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15234             {
15235               clib_warning ("unsupported crypto-alg: '%U'",
15236                             format_ipsec_crypto_alg, crypto_alg);
15237               return -99;
15238             }
15239         }
15240       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15241         ;
15242       else
15243         if (unformat
15244             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15245         {
15246           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15247               integ_alg >= IPSEC_INTEG_N_ALG)
15248             {
15249               clib_warning ("unsupported integ-alg: '%U'",
15250                             format_ipsec_integ_alg, integ_alg);
15251               return -99;
15252             }
15253         }
15254       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15255         ;
15256       else
15257         {
15258           clib_warning ("parse error '%U'", format_unformat_error, i);
15259           return -99;
15260         }
15261
15262     }
15263
15264   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15265
15266   mp->sad_id = ntohl (sad_id);
15267   mp->is_add = is_add;
15268   mp->protocol = protocol;
15269   mp->spi = ntohl (spi);
15270   mp->is_tunnel = is_tunnel;
15271   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15272   mp->crypto_algorithm = crypto_alg;
15273   mp->integrity_algorithm = integ_alg;
15274   mp->crypto_key_length = vec_len (ck);
15275   mp->integrity_key_length = vec_len (ik);
15276
15277   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15278     mp->crypto_key_length = sizeof (mp->crypto_key);
15279
15280   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15281     mp->integrity_key_length = sizeof (mp->integrity_key);
15282
15283   if (ck)
15284     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15285   if (ik)
15286     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15287
15288   if (is_tunnel)
15289     {
15290       if (is_tunnel_ipv6)
15291         {
15292           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15293                        sizeof (ip6_address_t));
15294           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15295                        sizeof (ip6_address_t));
15296         }
15297       else
15298         {
15299           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15300                        sizeof (ip4_address_t));
15301           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15302                        sizeof (ip4_address_t));
15303         }
15304     }
15305
15306   S (mp);
15307   W (ret);
15308   return ret;
15309 }
15310
15311 static int
15312 api_ipsec_sa_set_key (vat_main_t * vam)
15313 {
15314   unformat_input_t *i = vam->input;
15315   vl_api_ipsec_sa_set_key_t *mp;
15316   u32 sa_id;
15317   u8 *ck = 0, *ik = 0;
15318   int ret;
15319
15320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15321     {
15322       if (unformat (i, "sa_id %d", &sa_id))
15323         ;
15324       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15325         ;
15326       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15327         ;
15328       else
15329         {
15330           clib_warning ("parse error '%U'", format_unformat_error, i);
15331           return -99;
15332         }
15333     }
15334
15335   M (IPSEC_SA_SET_KEY, mp);
15336
15337   mp->sa_id = ntohl (sa_id);
15338   mp->crypto_key_length = vec_len (ck);
15339   mp->integrity_key_length = vec_len (ik);
15340
15341   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15342     mp->crypto_key_length = sizeof (mp->crypto_key);
15343
15344   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15345     mp->integrity_key_length = sizeof (mp->integrity_key);
15346
15347   if (ck)
15348     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15349   if (ik)
15350     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15351
15352   S (mp);
15353   W (ret);
15354   return ret;
15355 }
15356
15357 static int
15358 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15359 {
15360   unformat_input_t *i = vam->input;
15361   vl_api_ipsec_tunnel_if_add_del_t *mp;
15362   u32 local_spi = 0, remote_spi = 0;
15363   u32 crypto_alg = 0, integ_alg = 0;
15364   u8 *lck = NULL, *rck = NULL;
15365   u8 *lik = NULL, *rik = NULL;
15366   ip4_address_t local_ip = { {0} };
15367   ip4_address_t remote_ip = { {0} };
15368   u8 is_add = 1;
15369   u8 esn = 0;
15370   u8 anti_replay = 0;
15371   u8 renumber = 0;
15372   u32 instance = ~0;
15373   int ret;
15374
15375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15376     {
15377       if (unformat (i, "del"))
15378         is_add = 0;
15379       else if (unformat (i, "esn"))
15380         esn = 1;
15381       else if (unformat (i, "anti_replay"))
15382         anti_replay = 1;
15383       else if (unformat (i, "local_spi %d", &local_spi))
15384         ;
15385       else if (unformat (i, "remote_spi %d", &remote_spi))
15386         ;
15387       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15388         ;
15389       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15390         ;
15391       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15392         ;
15393       else
15394         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15395         ;
15396       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15397         ;
15398       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15399         ;
15400       else
15401         if (unformat
15402             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15403         {
15404           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15405               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15406             {
15407               errmsg ("unsupported crypto-alg: '%U'\n",
15408                       format_ipsec_crypto_alg, crypto_alg);
15409               return -99;
15410             }
15411         }
15412       else
15413         if (unformat
15414             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15415         {
15416           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15417               integ_alg >= IPSEC_INTEG_N_ALG)
15418             {
15419               errmsg ("unsupported integ-alg: '%U'\n",
15420                       format_ipsec_integ_alg, integ_alg);
15421               return -99;
15422             }
15423         }
15424       else if (unformat (i, "instance %u", &instance))
15425         renumber = 1;
15426       else
15427         {
15428           errmsg ("parse error '%U'\n", format_unformat_error, i);
15429           return -99;
15430         }
15431     }
15432
15433   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15434
15435   mp->is_add = is_add;
15436   mp->esn = esn;
15437   mp->anti_replay = anti_replay;
15438
15439   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15440   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15441
15442   mp->local_spi = htonl (local_spi);
15443   mp->remote_spi = htonl (remote_spi);
15444   mp->crypto_alg = (u8) crypto_alg;
15445
15446   mp->local_crypto_key_len = 0;
15447   if (lck)
15448     {
15449       mp->local_crypto_key_len = vec_len (lck);
15450       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15451         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15452       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15453     }
15454
15455   mp->remote_crypto_key_len = 0;
15456   if (rck)
15457     {
15458       mp->remote_crypto_key_len = vec_len (rck);
15459       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15460         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15461       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15462     }
15463
15464   mp->integ_alg = (u8) integ_alg;
15465
15466   mp->local_integ_key_len = 0;
15467   if (lik)
15468     {
15469       mp->local_integ_key_len = vec_len (lik);
15470       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15471         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15472       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15473     }
15474
15475   mp->remote_integ_key_len = 0;
15476   if (rik)
15477     {
15478       mp->remote_integ_key_len = vec_len (rik);
15479       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15480         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15481       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15482     }
15483
15484   if (renumber)
15485     {
15486       mp->renumber = renumber;
15487       mp->show_instance = ntohl (instance);
15488     }
15489
15490   S (mp);
15491   W (ret);
15492   return ret;
15493 }
15494
15495 static void
15496 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15497 {
15498   vat_main_t *vam = &vat_main;
15499
15500   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15501          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15502          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15503          "tunnel_src_addr %U tunnel_dst_addr %U "
15504          "salt %u seq_outbound %lu last_seq_inbound %lu "
15505          "replay_window %lu total_data_size %lu\n",
15506          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15507          mp->protocol,
15508          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15509          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15510          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15511          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15512          mp->tunnel_src_addr,
15513          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15514          mp->tunnel_dst_addr,
15515          ntohl (mp->salt),
15516          clib_net_to_host_u64 (mp->seq_outbound),
15517          clib_net_to_host_u64 (mp->last_seq_inbound),
15518          clib_net_to_host_u64 (mp->replay_window),
15519          clib_net_to_host_u64 (mp->total_data_size));
15520 }
15521
15522 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15523 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15524
15525 static void vl_api_ipsec_sa_details_t_handler_json
15526   (vl_api_ipsec_sa_details_t * mp)
15527 {
15528   vat_main_t *vam = &vat_main;
15529   vat_json_node_t *node = NULL;
15530   struct in_addr src_ip4, dst_ip4;
15531   struct in6_addr src_ip6, dst_ip6;
15532
15533   if (VAT_JSON_ARRAY != vam->json_tree.type)
15534     {
15535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15536       vat_json_init_array (&vam->json_tree);
15537     }
15538   node = vat_json_array_add (&vam->json_tree);
15539
15540   vat_json_init_object (node);
15541   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15542   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15543   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15544   vat_json_object_add_uint (node, "proto", mp->protocol);
15545   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15546   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15547   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15548   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15549   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15550   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15551   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15552                              mp->crypto_key_len);
15553   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15554                              mp->integ_key_len);
15555   if (mp->is_tunnel_ip6)
15556     {
15557       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15558       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15559       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15560       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15561     }
15562   else
15563     {
15564       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15565       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15566       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15567       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15568     }
15569   vat_json_object_add_uint (node, "replay_window",
15570                             clib_net_to_host_u64 (mp->replay_window));
15571   vat_json_object_add_uint (node, "total_data_size",
15572                             clib_net_to_host_u64 (mp->total_data_size));
15573
15574 }
15575
15576 static int
15577 api_ipsec_sa_dump (vat_main_t * vam)
15578 {
15579   unformat_input_t *i = vam->input;
15580   vl_api_ipsec_sa_dump_t *mp;
15581   vl_api_control_ping_t *mp_ping;
15582   u32 sa_id = ~0;
15583   int ret;
15584
15585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15586     {
15587       if (unformat (i, "sa_id %d", &sa_id))
15588         ;
15589       else
15590         {
15591           clib_warning ("parse error '%U'", format_unformat_error, i);
15592           return -99;
15593         }
15594     }
15595
15596   M (IPSEC_SA_DUMP, mp);
15597
15598   mp->sa_id = ntohl (sa_id);
15599
15600   S (mp);
15601
15602   /* Use a control ping for synchronization */
15603   M (CONTROL_PING, mp_ping);
15604   S (mp_ping);
15605
15606   W (ret);
15607   return ret;
15608 }
15609
15610 static int
15611 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15612 {
15613   unformat_input_t *i = vam->input;
15614   vl_api_ipsec_tunnel_if_set_key_t *mp;
15615   u32 sw_if_index = ~0;
15616   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15617   u8 *key = 0;
15618   u32 alg = ~0;
15619   int ret;
15620
15621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15622     {
15623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15624         ;
15625       else
15626         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15627         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15628       else
15629         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15630         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15631       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15632         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15633       else
15634         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15635         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15636       else if (unformat (i, "%U", unformat_hex_string, &key))
15637         ;
15638       else
15639         {
15640           clib_warning ("parse error '%U'", format_unformat_error, i);
15641           return -99;
15642         }
15643     }
15644
15645   if (sw_if_index == ~0)
15646     {
15647       errmsg ("interface must be specified");
15648       return -99;
15649     }
15650
15651   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15652     {
15653       errmsg ("key type must be specified");
15654       return -99;
15655     }
15656
15657   if (alg == ~0)
15658     {
15659       errmsg ("algorithm must be specified");
15660       return -99;
15661     }
15662
15663   if (vec_len (key) == 0)
15664     {
15665       errmsg ("key must be specified");
15666       return -99;
15667     }
15668
15669   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15670
15671   mp->sw_if_index = htonl (sw_if_index);
15672   mp->alg = alg;
15673   mp->key_type = key_type;
15674   mp->key_len = vec_len (key);
15675   clib_memcpy (mp->key, key, vec_len (key));
15676
15677   S (mp);
15678   W (ret);
15679
15680   return ret;
15681 }
15682
15683 static int
15684 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15685 {
15686   unformat_input_t *i = vam->input;
15687   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15688   u32 sw_if_index = ~0;
15689   u32 sa_id = ~0;
15690   u8 is_outbound = (u8) ~ 0;
15691   int ret;
15692
15693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15694     {
15695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15696         ;
15697       else if (unformat (i, "sa_id %d", &sa_id))
15698         ;
15699       else if (unformat (i, "outbound"))
15700         is_outbound = 1;
15701       else if (unformat (i, "inbound"))
15702         is_outbound = 0;
15703       else
15704         {
15705           clib_warning ("parse error '%U'", format_unformat_error, i);
15706           return -99;
15707         }
15708     }
15709
15710   if (sw_if_index == ~0)
15711     {
15712       errmsg ("interface must be specified");
15713       return -99;
15714     }
15715
15716   if (sa_id == ~0)
15717     {
15718       errmsg ("SA ID must be specified");
15719       return -99;
15720     }
15721
15722   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15723
15724   mp->sw_if_index = htonl (sw_if_index);
15725   mp->sa_id = htonl (sa_id);
15726   mp->is_outbound = is_outbound;
15727
15728   S (mp);
15729   W (ret);
15730
15731   return ret;
15732 }
15733
15734 static int
15735 api_ikev2_profile_add_del (vat_main_t * vam)
15736 {
15737   unformat_input_t *i = vam->input;
15738   vl_api_ikev2_profile_add_del_t *mp;
15739   u8 is_add = 1;
15740   u8 *name = 0;
15741   int ret;
15742
15743   const char *valid_chars = "a-zA-Z0-9_";
15744
15745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15746     {
15747       if (unformat (i, "del"))
15748         is_add = 0;
15749       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15750         vec_add1 (name, 0);
15751       else
15752         {
15753           errmsg ("parse error '%U'", format_unformat_error, i);
15754           return -99;
15755         }
15756     }
15757
15758   if (!vec_len (name))
15759     {
15760       errmsg ("profile name must be specified");
15761       return -99;
15762     }
15763
15764   if (vec_len (name) > 64)
15765     {
15766       errmsg ("profile name too long");
15767       return -99;
15768     }
15769
15770   M (IKEV2_PROFILE_ADD_DEL, mp);
15771
15772   clib_memcpy (mp->name, name, vec_len (name));
15773   mp->is_add = is_add;
15774   vec_free (name);
15775
15776   S (mp);
15777   W (ret);
15778   return ret;
15779 }
15780
15781 static int
15782 api_ikev2_profile_set_auth (vat_main_t * vam)
15783 {
15784   unformat_input_t *i = vam->input;
15785   vl_api_ikev2_profile_set_auth_t *mp;
15786   u8 *name = 0;
15787   u8 *data = 0;
15788   u32 auth_method = 0;
15789   u8 is_hex = 0;
15790   int ret;
15791
15792   const char *valid_chars = "a-zA-Z0-9_";
15793
15794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15795     {
15796       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15797         vec_add1 (name, 0);
15798       else if (unformat (i, "auth_method %U",
15799                          unformat_ikev2_auth_method, &auth_method))
15800         ;
15801       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15802         is_hex = 1;
15803       else if (unformat (i, "auth_data %v", &data))
15804         ;
15805       else
15806         {
15807           errmsg ("parse error '%U'", format_unformat_error, i);
15808           return -99;
15809         }
15810     }
15811
15812   if (!vec_len (name))
15813     {
15814       errmsg ("profile name must be specified");
15815       return -99;
15816     }
15817
15818   if (vec_len (name) > 64)
15819     {
15820       errmsg ("profile name too long");
15821       return -99;
15822     }
15823
15824   if (!vec_len (data))
15825     {
15826       errmsg ("auth_data must be specified");
15827       return -99;
15828     }
15829
15830   if (!auth_method)
15831     {
15832       errmsg ("auth_method must be specified");
15833       return -99;
15834     }
15835
15836   M (IKEV2_PROFILE_SET_AUTH, mp);
15837
15838   mp->is_hex = is_hex;
15839   mp->auth_method = (u8) auth_method;
15840   mp->data_len = vec_len (data);
15841   clib_memcpy (mp->name, name, vec_len (name));
15842   clib_memcpy (mp->data, data, vec_len (data));
15843   vec_free (name);
15844   vec_free (data);
15845
15846   S (mp);
15847   W (ret);
15848   return ret;
15849 }
15850
15851 static int
15852 api_ikev2_profile_set_id (vat_main_t * vam)
15853 {
15854   unformat_input_t *i = vam->input;
15855   vl_api_ikev2_profile_set_id_t *mp;
15856   u8 *name = 0;
15857   u8 *data = 0;
15858   u8 is_local = 0;
15859   u32 id_type = 0;
15860   ip4_address_t ip4;
15861   int ret;
15862
15863   const char *valid_chars = "a-zA-Z0-9_";
15864
15865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15866     {
15867       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15868         vec_add1 (name, 0);
15869       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15870         ;
15871       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15872         {
15873           data = vec_new (u8, 4);
15874           clib_memcpy (data, ip4.as_u8, 4);
15875         }
15876       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15877         ;
15878       else if (unformat (i, "id_data %v", &data))
15879         ;
15880       else if (unformat (i, "local"))
15881         is_local = 1;
15882       else if (unformat (i, "remote"))
15883         is_local = 0;
15884       else
15885         {
15886           errmsg ("parse error '%U'", format_unformat_error, i);
15887           return -99;
15888         }
15889     }
15890
15891   if (!vec_len (name))
15892     {
15893       errmsg ("profile name must be specified");
15894       return -99;
15895     }
15896
15897   if (vec_len (name) > 64)
15898     {
15899       errmsg ("profile name too long");
15900       return -99;
15901     }
15902
15903   if (!vec_len (data))
15904     {
15905       errmsg ("id_data must be specified");
15906       return -99;
15907     }
15908
15909   if (!id_type)
15910     {
15911       errmsg ("id_type must be specified");
15912       return -99;
15913     }
15914
15915   M (IKEV2_PROFILE_SET_ID, mp);
15916
15917   mp->is_local = is_local;
15918   mp->id_type = (u8) id_type;
15919   mp->data_len = vec_len (data);
15920   clib_memcpy (mp->name, name, vec_len (name));
15921   clib_memcpy (mp->data, data, vec_len (data));
15922   vec_free (name);
15923   vec_free (data);
15924
15925   S (mp);
15926   W (ret);
15927   return ret;
15928 }
15929
15930 static int
15931 api_ikev2_profile_set_ts (vat_main_t * vam)
15932 {
15933   unformat_input_t *i = vam->input;
15934   vl_api_ikev2_profile_set_ts_t *mp;
15935   u8 *name = 0;
15936   u8 is_local = 0;
15937   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15938   ip4_address_t start_addr, end_addr;
15939
15940   const char *valid_chars = "a-zA-Z0-9_";
15941   int ret;
15942
15943   start_addr.as_u32 = 0;
15944   end_addr.as_u32 = (u32) ~ 0;
15945
15946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15947     {
15948       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15949         vec_add1 (name, 0);
15950       else if (unformat (i, "protocol %d", &proto))
15951         ;
15952       else if (unformat (i, "start_port %d", &start_port))
15953         ;
15954       else if (unformat (i, "end_port %d", &end_port))
15955         ;
15956       else
15957         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15958         ;
15959       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15960         ;
15961       else if (unformat (i, "local"))
15962         is_local = 1;
15963       else if (unformat (i, "remote"))
15964         is_local = 0;
15965       else
15966         {
15967           errmsg ("parse error '%U'", format_unformat_error, i);
15968           return -99;
15969         }
15970     }
15971
15972   if (!vec_len (name))
15973     {
15974       errmsg ("profile name must be specified");
15975       return -99;
15976     }
15977
15978   if (vec_len (name) > 64)
15979     {
15980       errmsg ("profile name too long");
15981       return -99;
15982     }
15983
15984   M (IKEV2_PROFILE_SET_TS, mp);
15985
15986   mp->is_local = is_local;
15987   mp->proto = (u8) proto;
15988   mp->start_port = (u16) start_port;
15989   mp->end_port = (u16) end_port;
15990   mp->start_addr = start_addr.as_u32;
15991   mp->end_addr = end_addr.as_u32;
15992   clib_memcpy (mp->name, name, vec_len (name));
15993   vec_free (name);
15994
15995   S (mp);
15996   W (ret);
15997   return ret;
15998 }
15999
16000 static int
16001 api_ikev2_set_local_key (vat_main_t * vam)
16002 {
16003   unformat_input_t *i = vam->input;
16004   vl_api_ikev2_set_local_key_t *mp;
16005   u8 *file = 0;
16006   int ret;
16007
16008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16009     {
16010       if (unformat (i, "file %v", &file))
16011         vec_add1 (file, 0);
16012       else
16013         {
16014           errmsg ("parse error '%U'", format_unformat_error, i);
16015           return -99;
16016         }
16017     }
16018
16019   if (!vec_len (file))
16020     {
16021       errmsg ("RSA key file must be specified");
16022       return -99;
16023     }
16024
16025   if (vec_len (file) > 256)
16026     {
16027       errmsg ("file name too long");
16028       return -99;
16029     }
16030
16031   M (IKEV2_SET_LOCAL_KEY, mp);
16032
16033   clib_memcpy (mp->key_file, file, vec_len (file));
16034   vec_free (file);
16035
16036   S (mp);
16037   W (ret);
16038   return ret;
16039 }
16040
16041 static int
16042 api_ikev2_set_responder (vat_main_t * vam)
16043 {
16044   unformat_input_t *i = vam->input;
16045   vl_api_ikev2_set_responder_t *mp;
16046   int ret;
16047   u8 *name = 0;
16048   u32 sw_if_index = ~0;
16049   ip4_address_t address;
16050
16051   const char *valid_chars = "a-zA-Z0-9_";
16052
16053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16054     {
16055       if (unformat
16056           (i, "%U interface %d address %U", unformat_token, valid_chars,
16057            &name, &sw_if_index, unformat_ip4_address, &address))
16058         vec_add1 (name, 0);
16059       else
16060         {
16061           errmsg ("parse error '%U'", format_unformat_error, i);
16062           return -99;
16063         }
16064     }
16065
16066   if (!vec_len (name))
16067     {
16068       errmsg ("profile name must be specified");
16069       return -99;
16070     }
16071
16072   if (vec_len (name) > 64)
16073     {
16074       errmsg ("profile name too long");
16075       return -99;
16076     }
16077
16078   M (IKEV2_SET_RESPONDER, mp);
16079
16080   clib_memcpy (mp->name, name, vec_len (name));
16081   vec_free (name);
16082
16083   mp->sw_if_index = sw_if_index;
16084   clib_memcpy (mp->address, &address, sizeof (address));
16085
16086   S (mp);
16087   W (ret);
16088   return ret;
16089 }
16090
16091 static int
16092 api_ikev2_set_ike_transforms (vat_main_t * vam)
16093 {
16094   unformat_input_t *i = vam->input;
16095   vl_api_ikev2_set_ike_transforms_t *mp;
16096   int ret;
16097   u8 *name = 0;
16098   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16099
16100   const char *valid_chars = "a-zA-Z0-9_";
16101
16102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16103     {
16104       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16105                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16106         vec_add1 (name, 0);
16107       else
16108         {
16109           errmsg ("parse error '%U'", format_unformat_error, i);
16110           return -99;
16111         }
16112     }
16113
16114   if (!vec_len (name))
16115     {
16116       errmsg ("profile name must be specified");
16117       return -99;
16118     }
16119
16120   if (vec_len (name) > 64)
16121     {
16122       errmsg ("profile name too long");
16123       return -99;
16124     }
16125
16126   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16127
16128   clib_memcpy (mp->name, name, vec_len (name));
16129   vec_free (name);
16130   mp->crypto_alg = crypto_alg;
16131   mp->crypto_key_size = crypto_key_size;
16132   mp->integ_alg = integ_alg;
16133   mp->dh_group = dh_group;
16134
16135   S (mp);
16136   W (ret);
16137   return ret;
16138 }
16139
16140
16141 static int
16142 api_ikev2_set_esp_transforms (vat_main_t * vam)
16143 {
16144   unformat_input_t *i = vam->input;
16145   vl_api_ikev2_set_esp_transforms_t *mp;
16146   int ret;
16147   u8 *name = 0;
16148   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16149
16150   const char *valid_chars = "a-zA-Z0-9_";
16151
16152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16153     {
16154       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16155                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16156         vec_add1 (name, 0);
16157       else
16158         {
16159           errmsg ("parse error '%U'", format_unformat_error, i);
16160           return -99;
16161         }
16162     }
16163
16164   if (!vec_len (name))
16165     {
16166       errmsg ("profile name must be specified");
16167       return -99;
16168     }
16169
16170   if (vec_len (name) > 64)
16171     {
16172       errmsg ("profile name too long");
16173       return -99;
16174     }
16175
16176   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16177
16178   clib_memcpy (mp->name, name, vec_len (name));
16179   vec_free (name);
16180   mp->crypto_alg = crypto_alg;
16181   mp->crypto_key_size = crypto_key_size;
16182   mp->integ_alg = integ_alg;
16183   mp->dh_group = dh_group;
16184
16185   S (mp);
16186   W (ret);
16187   return ret;
16188 }
16189
16190 static int
16191 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16192 {
16193   unformat_input_t *i = vam->input;
16194   vl_api_ikev2_set_sa_lifetime_t *mp;
16195   int ret;
16196   u8 *name = 0;
16197   u64 lifetime, lifetime_maxdata;
16198   u32 lifetime_jitter, handover;
16199
16200   const char *valid_chars = "a-zA-Z0-9_";
16201
16202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16203     {
16204       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16205                     &lifetime, &lifetime_jitter, &handover,
16206                     &lifetime_maxdata))
16207         vec_add1 (name, 0);
16208       else
16209         {
16210           errmsg ("parse error '%U'", format_unformat_error, i);
16211           return -99;
16212         }
16213     }
16214
16215   if (!vec_len (name))
16216     {
16217       errmsg ("profile name must be specified");
16218       return -99;
16219     }
16220
16221   if (vec_len (name) > 64)
16222     {
16223       errmsg ("profile name too long");
16224       return -99;
16225     }
16226
16227   M (IKEV2_SET_SA_LIFETIME, mp);
16228
16229   clib_memcpy (mp->name, name, vec_len (name));
16230   vec_free (name);
16231   mp->lifetime = lifetime;
16232   mp->lifetime_jitter = lifetime_jitter;
16233   mp->handover = handover;
16234   mp->lifetime_maxdata = lifetime_maxdata;
16235
16236   S (mp);
16237   W (ret);
16238   return ret;
16239 }
16240
16241 static int
16242 api_ikev2_initiate_sa_init (vat_main_t * vam)
16243 {
16244   unformat_input_t *i = vam->input;
16245   vl_api_ikev2_initiate_sa_init_t *mp;
16246   int ret;
16247   u8 *name = 0;
16248
16249   const char *valid_chars = "a-zA-Z0-9_";
16250
16251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16252     {
16253       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16254         vec_add1 (name, 0);
16255       else
16256         {
16257           errmsg ("parse error '%U'", format_unformat_error, i);
16258           return -99;
16259         }
16260     }
16261
16262   if (!vec_len (name))
16263     {
16264       errmsg ("profile name must be specified");
16265       return -99;
16266     }
16267
16268   if (vec_len (name) > 64)
16269     {
16270       errmsg ("profile name too long");
16271       return -99;
16272     }
16273
16274   M (IKEV2_INITIATE_SA_INIT, mp);
16275
16276   clib_memcpy (mp->name, name, vec_len (name));
16277   vec_free (name);
16278
16279   S (mp);
16280   W (ret);
16281   return ret;
16282 }
16283
16284 static int
16285 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16286 {
16287   unformat_input_t *i = vam->input;
16288   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16289   int ret;
16290   u64 ispi;
16291
16292
16293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16294     {
16295       if (unformat (i, "%lx", &ispi))
16296         ;
16297       else
16298         {
16299           errmsg ("parse error '%U'", format_unformat_error, i);
16300           return -99;
16301         }
16302     }
16303
16304   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16305
16306   mp->ispi = ispi;
16307
16308   S (mp);
16309   W (ret);
16310   return ret;
16311 }
16312
16313 static int
16314 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16315 {
16316   unformat_input_t *i = vam->input;
16317   vl_api_ikev2_initiate_del_child_sa_t *mp;
16318   int ret;
16319   u32 ispi;
16320
16321
16322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16323     {
16324       if (unformat (i, "%x", &ispi))
16325         ;
16326       else
16327         {
16328           errmsg ("parse error '%U'", format_unformat_error, i);
16329           return -99;
16330         }
16331     }
16332
16333   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16334
16335   mp->ispi = ispi;
16336
16337   S (mp);
16338   W (ret);
16339   return ret;
16340 }
16341
16342 static int
16343 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16344 {
16345   unformat_input_t *i = vam->input;
16346   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16347   int ret;
16348   u32 ispi;
16349
16350
16351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16352     {
16353       if (unformat (i, "%x", &ispi))
16354         ;
16355       else
16356         {
16357           errmsg ("parse error '%U'", format_unformat_error, i);
16358           return -99;
16359         }
16360     }
16361
16362   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16363
16364   mp->ispi = ispi;
16365
16366   S (mp);
16367   W (ret);
16368   return ret;
16369 }
16370
16371 /*
16372  * MAP
16373  */
16374 static int
16375 api_map_add_domain (vat_main_t * vam)
16376 {
16377   unformat_input_t *i = vam->input;
16378   vl_api_map_add_domain_t *mp;
16379
16380   ip4_address_t ip4_prefix;
16381   ip6_address_t ip6_prefix;
16382   ip6_address_t ip6_src;
16383   u32 num_m_args = 0;
16384   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16385     0, psid_length = 0;
16386   u8 is_translation = 0;
16387   u32 mtu = 0;
16388   u32 ip6_src_len = 128;
16389   int ret;
16390
16391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16392     {
16393       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16394                     &ip4_prefix, &ip4_prefix_len))
16395         num_m_args++;
16396       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16397                          &ip6_prefix, &ip6_prefix_len))
16398         num_m_args++;
16399       else
16400         if (unformat
16401             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16402              &ip6_src_len))
16403         num_m_args++;
16404       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16405         num_m_args++;
16406       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16407         num_m_args++;
16408       else if (unformat (i, "psid-offset %d", &psid_offset))
16409         num_m_args++;
16410       else if (unformat (i, "psid-len %d", &psid_length))
16411         num_m_args++;
16412       else if (unformat (i, "mtu %d", &mtu))
16413         num_m_args++;
16414       else if (unformat (i, "map-t"))
16415         is_translation = 1;
16416       else
16417         {
16418           clib_warning ("parse error '%U'", format_unformat_error, i);
16419           return -99;
16420         }
16421     }
16422
16423   if (num_m_args < 3)
16424     {
16425       errmsg ("mandatory argument(s) missing");
16426       return -99;
16427     }
16428
16429   /* Construct the API message */
16430   M (MAP_ADD_DOMAIN, mp);
16431
16432   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16433   mp->ip4_prefix_len = ip4_prefix_len;
16434
16435   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16436   mp->ip6_prefix_len = ip6_prefix_len;
16437
16438   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16439   mp->ip6_src_prefix_len = ip6_src_len;
16440
16441   mp->ea_bits_len = ea_bits_len;
16442   mp->psid_offset = psid_offset;
16443   mp->psid_length = psid_length;
16444   mp->is_translation = is_translation;
16445   mp->mtu = htons (mtu);
16446
16447   /* send it... */
16448   S (mp);
16449
16450   /* Wait for a reply, return good/bad news  */
16451   W (ret);
16452   return ret;
16453 }
16454
16455 static int
16456 api_map_del_domain (vat_main_t * vam)
16457 {
16458   unformat_input_t *i = vam->input;
16459   vl_api_map_del_domain_t *mp;
16460
16461   u32 num_m_args = 0;
16462   u32 index;
16463   int ret;
16464
16465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16466     {
16467       if (unformat (i, "index %d", &index))
16468         num_m_args++;
16469       else
16470         {
16471           clib_warning ("parse error '%U'", format_unformat_error, i);
16472           return -99;
16473         }
16474     }
16475
16476   if (num_m_args != 1)
16477     {
16478       errmsg ("mandatory argument(s) missing");
16479       return -99;
16480     }
16481
16482   /* Construct the API message */
16483   M (MAP_DEL_DOMAIN, mp);
16484
16485   mp->index = ntohl (index);
16486
16487   /* send it... */
16488   S (mp);
16489
16490   /* Wait for a reply, return good/bad news  */
16491   W (ret);
16492   return ret;
16493 }
16494
16495 static int
16496 api_map_add_del_rule (vat_main_t * vam)
16497 {
16498   unformat_input_t *i = vam->input;
16499   vl_api_map_add_del_rule_t *mp;
16500   u8 is_add = 1;
16501   ip6_address_t ip6_dst;
16502   u32 num_m_args = 0, index, psid = 0;
16503   int ret;
16504
16505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16506     {
16507       if (unformat (i, "index %d", &index))
16508         num_m_args++;
16509       else if (unformat (i, "psid %d", &psid))
16510         num_m_args++;
16511       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16512         num_m_args++;
16513       else if (unformat (i, "del"))
16514         {
16515           is_add = 0;
16516         }
16517       else
16518         {
16519           clib_warning ("parse error '%U'", format_unformat_error, i);
16520           return -99;
16521         }
16522     }
16523
16524   /* Construct the API message */
16525   M (MAP_ADD_DEL_RULE, mp);
16526
16527   mp->index = ntohl (index);
16528   mp->is_add = is_add;
16529   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16530   mp->psid = ntohs (psid);
16531
16532   /* send it... */
16533   S (mp);
16534
16535   /* Wait for a reply, return good/bad news  */
16536   W (ret);
16537   return ret;
16538 }
16539
16540 static int
16541 api_map_domain_dump (vat_main_t * vam)
16542 {
16543   vl_api_map_domain_dump_t *mp;
16544   vl_api_control_ping_t *mp_ping;
16545   int ret;
16546
16547   /* Construct the API message */
16548   M (MAP_DOMAIN_DUMP, mp);
16549
16550   /* send it... */
16551   S (mp);
16552
16553   /* Use a control ping for synchronization */
16554   MPING (CONTROL_PING, mp_ping);
16555   S (mp_ping);
16556
16557   W (ret);
16558   return ret;
16559 }
16560
16561 static int
16562 api_map_rule_dump (vat_main_t * vam)
16563 {
16564   unformat_input_t *i = vam->input;
16565   vl_api_map_rule_dump_t *mp;
16566   vl_api_control_ping_t *mp_ping;
16567   u32 domain_index = ~0;
16568   int ret;
16569
16570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16571     {
16572       if (unformat (i, "index %u", &domain_index))
16573         ;
16574       else
16575         break;
16576     }
16577
16578   if (domain_index == ~0)
16579     {
16580       clib_warning ("parse error: domain index expected");
16581       return -99;
16582     }
16583
16584   /* Construct the API message */
16585   M (MAP_RULE_DUMP, mp);
16586
16587   mp->domain_index = htonl (domain_index);
16588
16589   /* send it... */
16590   S (mp);
16591
16592   /* Use a control ping for synchronization */
16593   MPING (CONTROL_PING, mp_ping);
16594   S (mp_ping);
16595
16596   W (ret);
16597   return ret;
16598 }
16599
16600 static void vl_api_map_add_domain_reply_t_handler
16601   (vl_api_map_add_domain_reply_t * mp)
16602 {
16603   vat_main_t *vam = &vat_main;
16604   i32 retval = ntohl (mp->retval);
16605
16606   if (vam->async_mode)
16607     {
16608       vam->async_errors += (retval < 0);
16609     }
16610   else
16611     {
16612       vam->retval = retval;
16613       vam->result_ready = 1;
16614     }
16615 }
16616
16617 static void vl_api_map_add_domain_reply_t_handler_json
16618   (vl_api_map_add_domain_reply_t * mp)
16619 {
16620   vat_main_t *vam = &vat_main;
16621   vat_json_node_t node;
16622
16623   vat_json_init_object (&node);
16624   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16625   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16626
16627   vat_json_print (vam->ofp, &node);
16628   vat_json_free (&node);
16629
16630   vam->retval = ntohl (mp->retval);
16631   vam->result_ready = 1;
16632 }
16633
16634 static int
16635 api_get_first_msg_id (vat_main_t * vam)
16636 {
16637   vl_api_get_first_msg_id_t *mp;
16638   unformat_input_t *i = vam->input;
16639   u8 *name;
16640   u8 name_set = 0;
16641   int ret;
16642
16643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16644     {
16645       if (unformat (i, "client %s", &name))
16646         name_set = 1;
16647       else
16648         break;
16649     }
16650
16651   if (name_set == 0)
16652     {
16653       errmsg ("missing client name");
16654       return -99;
16655     }
16656   vec_add1 (name, 0);
16657
16658   if (vec_len (name) > 63)
16659     {
16660       errmsg ("client name too long");
16661       return -99;
16662     }
16663
16664   M (GET_FIRST_MSG_ID, mp);
16665   clib_memcpy (mp->name, name, vec_len (name));
16666   S (mp);
16667   W (ret);
16668   return ret;
16669 }
16670
16671 static int
16672 api_cop_interface_enable_disable (vat_main_t * vam)
16673 {
16674   unformat_input_t *line_input = vam->input;
16675   vl_api_cop_interface_enable_disable_t *mp;
16676   u32 sw_if_index = ~0;
16677   u8 enable_disable = 1;
16678   int ret;
16679
16680   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16681     {
16682       if (unformat (line_input, "disable"))
16683         enable_disable = 0;
16684       if (unformat (line_input, "enable"))
16685         enable_disable = 1;
16686       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16687                          vam, &sw_if_index))
16688         ;
16689       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16690         ;
16691       else
16692         break;
16693     }
16694
16695   if (sw_if_index == ~0)
16696     {
16697       errmsg ("missing interface name or sw_if_index");
16698       return -99;
16699     }
16700
16701   /* Construct the API message */
16702   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16703   mp->sw_if_index = ntohl (sw_if_index);
16704   mp->enable_disable = enable_disable;
16705
16706   /* send it... */
16707   S (mp);
16708   /* Wait for the reply */
16709   W (ret);
16710   return ret;
16711 }
16712
16713 static int
16714 api_cop_whitelist_enable_disable (vat_main_t * vam)
16715 {
16716   unformat_input_t *line_input = vam->input;
16717   vl_api_cop_whitelist_enable_disable_t *mp;
16718   u32 sw_if_index = ~0;
16719   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16720   u32 fib_id = 0;
16721   int ret;
16722
16723   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16724     {
16725       if (unformat (line_input, "ip4"))
16726         ip4 = 1;
16727       else if (unformat (line_input, "ip6"))
16728         ip6 = 1;
16729       else if (unformat (line_input, "default"))
16730         default_cop = 1;
16731       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16732                          vam, &sw_if_index))
16733         ;
16734       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16735         ;
16736       else if (unformat (line_input, "fib-id %d", &fib_id))
16737         ;
16738       else
16739         break;
16740     }
16741
16742   if (sw_if_index == ~0)
16743     {
16744       errmsg ("missing interface name or sw_if_index");
16745       return -99;
16746     }
16747
16748   /* Construct the API message */
16749   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16750   mp->sw_if_index = ntohl (sw_if_index);
16751   mp->fib_id = ntohl (fib_id);
16752   mp->ip4 = ip4;
16753   mp->ip6 = ip6;
16754   mp->default_cop = default_cop;
16755
16756   /* send it... */
16757   S (mp);
16758   /* Wait for the reply */
16759   W (ret);
16760   return ret;
16761 }
16762
16763 static int
16764 api_get_node_graph (vat_main_t * vam)
16765 {
16766   vl_api_get_node_graph_t *mp;
16767   int ret;
16768
16769   M (GET_NODE_GRAPH, mp);
16770
16771   /* send it... */
16772   S (mp);
16773   /* Wait for the reply */
16774   W (ret);
16775   return ret;
16776 }
16777
16778 /* *INDENT-OFF* */
16779 /** Used for parsing LISP eids */
16780 typedef CLIB_PACKED(struct{
16781   u8 addr[16];   /**< eid address */
16782   u32 len;       /**< prefix length if IP */
16783   u8 type;      /**< type of eid */
16784 }) lisp_eid_vat_t;
16785 /* *INDENT-ON* */
16786
16787 static uword
16788 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16789 {
16790   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16791
16792   memset (a, 0, sizeof (a[0]));
16793
16794   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16795     {
16796       a->type = 0;              /* ipv4 type */
16797     }
16798   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16799     {
16800       a->type = 1;              /* ipv6 type */
16801     }
16802   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16803     {
16804       a->type = 2;              /* mac type */
16805     }
16806   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16807     {
16808       a->type = 3;              /* NSH type */
16809       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16810       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16811     }
16812   else
16813     {
16814       return 0;
16815     }
16816
16817   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16818     {
16819       return 0;
16820     }
16821
16822   return 1;
16823 }
16824
16825 static int
16826 lisp_eid_size_vat (u8 type)
16827 {
16828   switch (type)
16829     {
16830     case 0:
16831       return 4;
16832     case 1:
16833       return 16;
16834     case 2:
16835       return 6;
16836     case 3:
16837       return 5;
16838     }
16839   return 0;
16840 }
16841
16842 static void
16843 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16844 {
16845   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16846 }
16847
16848 static int
16849 api_one_add_del_locator_set (vat_main_t * vam)
16850 {
16851   unformat_input_t *input = vam->input;
16852   vl_api_one_add_del_locator_set_t *mp;
16853   u8 is_add = 1;
16854   u8 *locator_set_name = NULL;
16855   u8 locator_set_name_set = 0;
16856   vl_api_local_locator_t locator, *locators = 0;
16857   u32 sw_if_index, priority, weight;
16858   u32 data_len = 0;
16859
16860   int ret;
16861   /* Parse args required to build the message */
16862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16863     {
16864       if (unformat (input, "del"))
16865         {
16866           is_add = 0;
16867         }
16868       else if (unformat (input, "locator-set %s", &locator_set_name))
16869         {
16870           locator_set_name_set = 1;
16871         }
16872       else if (unformat (input, "sw_if_index %u p %u w %u",
16873                          &sw_if_index, &priority, &weight))
16874         {
16875           locator.sw_if_index = htonl (sw_if_index);
16876           locator.priority = priority;
16877           locator.weight = weight;
16878           vec_add1 (locators, locator);
16879         }
16880       else
16881         if (unformat
16882             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16883              &sw_if_index, &priority, &weight))
16884         {
16885           locator.sw_if_index = htonl (sw_if_index);
16886           locator.priority = priority;
16887           locator.weight = weight;
16888           vec_add1 (locators, locator);
16889         }
16890       else
16891         break;
16892     }
16893
16894   if (locator_set_name_set == 0)
16895     {
16896       errmsg ("missing locator-set name");
16897       vec_free (locators);
16898       return -99;
16899     }
16900
16901   if (vec_len (locator_set_name) > 64)
16902     {
16903       errmsg ("locator-set name too long");
16904       vec_free (locator_set_name);
16905       vec_free (locators);
16906       return -99;
16907     }
16908   vec_add1 (locator_set_name, 0);
16909
16910   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16911
16912   /* Construct the API message */
16913   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16914
16915   mp->is_add = is_add;
16916   clib_memcpy (mp->locator_set_name, locator_set_name,
16917                vec_len (locator_set_name));
16918   vec_free (locator_set_name);
16919
16920   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16921   if (locators)
16922     clib_memcpy (mp->locators, locators, data_len);
16923   vec_free (locators);
16924
16925   /* send it... */
16926   S (mp);
16927
16928   /* Wait for a reply... */
16929   W (ret);
16930   return ret;
16931 }
16932
16933 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16934
16935 static int
16936 api_one_add_del_locator (vat_main_t * vam)
16937 {
16938   unformat_input_t *input = vam->input;
16939   vl_api_one_add_del_locator_t *mp;
16940   u32 tmp_if_index = ~0;
16941   u32 sw_if_index = ~0;
16942   u8 sw_if_index_set = 0;
16943   u8 sw_if_index_if_name_set = 0;
16944   u32 priority = ~0;
16945   u8 priority_set = 0;
16946   u32 weight = ~0;
16947   u8 weight_set = 0;
16948   u8 is_add = 1;
16949   u8 *locator_set_name = NULL;
16950   u8 locator_set_name_set = 0;
16951   int ret;
16952
16953   /* Parse args required to build the message */
16954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16955     {
16956       if (unformat (input, "del"))
16957         {
16958           is_add = 0;
16959         }
16960       else if (unformat (input, "locator-set %s", &locator_set_name))
16961         {
16962           locator_set_name_set = 1;
16963         }
16964       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16965                          &tmp_if_index))
16966         {
16967           sw_if_index_if_name_set = 1;
16968           sw_if_index = tmp_if_index;
16969         }
16970       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16971         {
16972           sw_if_index_set = 1;
16973           sw_if_index = tmp_if_index;
16974         }
16975       else if (unformat (input, "p %d", &priority))
16976         {
16977           priority_set = 1;
16978         }
16979       else if (unformat (input, "w %d", &weight))
16980         {
16981           weight_set = 1;
16982         }
16983       else
16984         break;
16985     }
16986
16987   if (locator_set_name_set == 0)
16988     {
16989       errmsg ("missing 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 ("missing sw_if_index");
16996       vec_free (locator_set_name);
16997       return -99;
16998     }
16999
17000   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17001     {
17002       errmsg ("cannot use both params interface name and sw_if_index");
17003       vec_free (locator_set_name);
17004       return -99;
17005     }
17006
17007   if (priority_set == 0)
17008     {
17009       errmsg ("missing locator-set priority");
17010       vec_free (locator_set_name);
17011       return -99;
17012     }
17013
17014   if (weight_set == 0)
17015     {
17016       errmsg ("missing locator-set weight");
17017       vec_free (locator_set_name);
17018       return -99;
17019     }
17020
17021   if (vec_len (locator_set_name) > 64)
17022     {
17023       errmsg ("locator-set name too long");
17024       vec_free (locator_set_name);
17025       return -99;
17026     }
17027   vec_add1 (locator_set_name, 0);
17028
17029   /* Construct the API message */
17030   M (ONE_ADD_DEL_LOCATOR, mp);
17031
17032   mp->is_add = is_add;
17033   mp->sw_if_index = ntohl (sw_if_index);
17034   mp->priority = priority;
17035   mp->weight = weight;
17036   clib_memcpy (mp->locator_set_name, locator_set_name,
17037                vec_len (locator_set_name));
17038   vec_free (locator_set_name);
17039
17040   /* send it... */
17041   S (mp);
17042
17043   /* Wait for a reply... */
17044   W (ret);
17045   return ret;
17046 }
17047
17048 #define api_lisp_add_del_locator api_one_add_del_locator
17049
17050 uword
17051 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17052 {
17053   u32 *key_id = va_arg (*args, u32 *);
17054   u8 *s = 0;
17055
17056   if (unformat (input, "%s", &s))
17057     {
17058       if (!strcmp ((char *) s, "sha1"))
17059         key_id[0] = HMAC_SHA_1_96;
17060       else if (!strcmp ((char *) s, "sha256"))
17061         key_id[0] = HMAC_SHA_256_128;
17062       else
17063         {
17064           clib_warning ("invalid key_id: '%s'", s);
17065           key_id[0] = HMAC_NO_KEY;
17066         }
17067     }
17068   else
17069     return 0;
17070
17071   vec_free (s);
17072   return 1;
17073 }
17074
17075 static int
17076 api_one_add_del_local_eid (vat_main_t * vam)
17077 {
17078   unformat_input_t *input = vam->input;
17079   vl_api_one_add_del_local_eid_t *mp;
17080   u8 is_add = 1;
17081   u8 eid_set = 0;
17082   lisp_eid_vat_t _eid, *eid = &_eid;
17083   u8 *locator_set_name = 0;
17084   u8 locator_set_name_set = 0;
17085   u32 vni = 0;
17086   u16 key_id = 0;
17087   u8 *key = 0;
17088   int ret;
17089
17090   /* Parse args required to build the message */
17091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17092     {
17093       if (unformat (input, "del"))
17094         {
17095           is_add = 0;
17096         }
17097       else if (unformat (input, "vni %d", &vni))
17098         {
17099           ;
17100         }
17101       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17102         {
17103           eid_set = 1;
17104         }
17105       else if (unformat (input, "locator-set %s", &locator_set_name))
17106         {
17107           locator_set_name_set = 1;
17108         }
17109       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17110         ;
17111       else if (unformat (input, "secret-key %_%v%_", &key))
17112         ;
17113       else
17114         break;
17115     }
17116
17117   if (locator_set_name_set == 0)
17118     {
17119       errmsg ("missing locator-set name");
17120       return -99;
17121     }
17122
17123   if (0 == eid_set)
17124     {
17125       errmsg ("EID address not set!");
17126       vec_free (locator_set_name);
17127       return -99;
17128     }
17129
17130   if (key && (0 == key_id))
17131     {
17132       errmsg ("invalid key_id!");
17133       return -99;
17134     }
17135
17136   if (vec_len (key) > 64)
17137     {
17138       errmsg ("key too long");
17139       vec_free (key);
17140       return -99;
17141     }
17142
17143   if (vec_len (locator_set_name) > 64)
17144     {
17145       errmsg ("locator-set name too long");
17146       vec_free (locator_set_name);
17147       return -99;
17148     }
17149   vec_add1 (locator_set_name, 0);
17150
17151   /* Construct the API message */
17152   M (ONE_ADD_DEL_LOCAL_EID, mp);
17153
17154   mp->is_add = is_add;
17155   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17156   mp->eid_type = eid->type;
17157   mp->prefix_len = eid->len;
17158   mp->vni = clib_host_to_net_u32 (vni);
17159   mp->key_id = clib_host_to_net_u16 (key_id);
17160   clib_memcpy (mp->locator_set_name, locator_set_name,
17161                vec_len (locator_set_name));
17162   clib_memcpy (mp->key, key, vec_len (key));
17163
17164   vec_free (locator_set_name);
17165   vec_free (key);
17166
17167   /* send it... */
17168   S (mp);
17169
17170   /* Wait for a reply... */
17171   W (ret);
17172   return ret;
17173 }
17174
17175 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17176
17177 static int
17178 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17179 {
17180   u32 dp_table = 0, vni = 0;;
17181   unformat_input_t *input = vam->input;
17182   vl_api_gpe_add_del_fwd_entry_t *mp;
17183   u8 is_add = 1;
17184   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17185   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17186   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17187   u32 action = ~0, w;
17188   ip4_address_t rmt_rloc4, lcl_rloc4;
17189   ip6_address_t rmt_rloc6, lcl_rloc6;
17190   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17191   int ret;
17192
17193   memset (&rloc, 0, sizeof (rloc));
17194
17195   /* Parse args required to build the message */
17196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17197     {
17198       if (unformat (input, "del"))
17199         is_add = 0;
17200       else if (unformat (input, "add"))
17201         is_add = 1;
17202       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17203         {
17204           rmt_eid_set = 1;
17205         }
17206       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17207         {
17208           lcl_eid_set = 1;
17209         }
17210       else if (unformat (input, "vrf %d", &dp_table))
17211         ;
17212       else if (unformat (input, "bd %d", &dp_table))
17213         ;
17214       else if (unformat (input, "vni %d", &vni))
17215         ;
17216       else if (unformat (input, "w %d", &w))
17217         {
17218           if (!curr_rloc)
17219             {
17220               errmsg ("No RLOC configured for setting priority/weight!");
17221               return -99;
17222             }
17223           curr_rloc->weight = w;
17224         }
17225       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17226                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17227         {
17228           rloc.is_ip4 = 1;
17229
17230           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17231           rloc.weight = 0;
17232           vec_add1 (lcl_locs, rloc);
17233
17234           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17235           vec_add1 (rmt_locs, rloc);
17236           /* weight saved in rmt loc */
17237           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17238         }
17239       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17240                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17241         {
17242           rloc.is_ip4 = 0;
17243           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17244           rloc.weight = 0;
17245           vec_add1 (lcl_locs, rloc);
17246
17247           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17248           vec_add1 (rmt_locs, rloc);
17249           /* weight saved in rmt loc */
17250           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17251         }
17252       else if (unformat (input, "action %d", &action))
17253         {
17254           ;
17255         }
17256       else
17257         {
17258           clib_warning ("parse error '%U'", format_unformat_error, input);
17259           return -99;
17260         }
17261     }
17262
17263   if (!rmt_eid_set)
17264     {
17265       errmsg ("remote eid addresses not set");
17266       return -99;
17267     }
17268
17269   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17270     {
17271       errmsg ("eid types don't match");
17272       return -99;
17273     }
17274
17275   if (0 == rmt_locs && (u32) ~ 0 == action)
17276     {
17277       errmsg ("action not set for negative mapping");
17278       return -99;
17279     }
17280
17281   /* Construct the API message */
17282   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17283       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17284
17285   mp->is_add = is_add;
17286   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17287   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17288   mp->eid_type = rmt_eid->type;
17289   mp->dp_table = clib_host_to_net_u32 (dp_table);
17290   mp->vni = clib_host_to_net_u32 (vni);
17291   mp->rmt_len = rmt_eid->len;
17292   mp->lcl_len = lcl_eid->len;
17293   mp->action = action;
17294
17295   if (0 != rmt_locs && 0 != lcl_locs)
17296     {
17297       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17298       clib_memcpy (mp->locs, lcl_locs,
17299                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17300
17301       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17302       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17303                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17304     }
17305   vec_free (lcl_locs);
17306   vec_free (rmt_locs);
17307
17308   /* send it... */
17309   S (mp);
17310
17311   /* Wait for a reply... */
17312   W (ret);
17313   return ret;
17314 }
17315
17316 static int
17317 api_one_add_del_map_server (vat_main_t * vam)
17318 {
17319   unformat_input_t *input = vam->input;
17320   vl_api_one_add_del_map_server_t *mp;
17321   u8 is_add = 1;
17322   u8 ipv4_set = 0;
17323   u8 ipv6_set = 0;
17324   ip4_address_t ipv4;
17325   ip6_address_t ipv6;
17326   int ret;
17327
17328   /* Parse args required to build the message */
17329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17330     {
17331       if (unformat (input, "del"))
17332         {
17333           is_add = 0;
17334         }
17335       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17336         {
17337           ipv4_set = 1;
17338         }
17339       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17340         {
17341           ipv6_set = 1;
17342         }
17343       else
17344         break;
17345     }
17346
17347   if (ipv4_set && ipv6_set)
17348     {
17349       errmsg ("both eid v4 and v6 addresses set");
17350       return -99;
17351     }
17352
17353   if (!ipv4_set && !ipv6_set)
17354     {
17355       errmsg ("eid addresses not set");
17356       return -99;
17357     }
17358
17359   /* Construct the API message */
17360   M (ONE_ADD_DEL_MAP_SERVER, mp);
17361
17362   mp->is_add = is_add;
17363   if (ipv6_set)
17364     {
17365       mp->is_ipv6 = 1;
17366       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17367     }
17368   else
17369     {
17370       mp->is_ipv6 = 0;
17371       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17372     }
17373
17374   /* send it... */
17375   S (mp);
17376
17377   /* Wait for a reply... */
17378   W (ret);
17379   return ret;
17380 }
17381
17382 #define api_lisp_add_del_map_server api_one_add_del_map_server
17383
17384 static int
17385 api_one_add_del_map_resolver (vat_main_t * vam)
17386 {
17387   unformat_input_t *input = vam->input;
17388   vl_api_one_add_del_map_resolver_t *mp;
17389   u8 is_add = 1;
17390   u8 ipv4_set = 0;
17391   u8 ipv6_set = 0;
17392   ip4_address_t ipv4;
17393   ip6_address_t ipv6;
17394   int ret;
17395
17396   /* Parse args required to build the message */
17397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17398     {
17399       if (unformat (input, "del"))
17400         {
17401           is_add = 0;
17402         }
17403       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17404         {
17405           ipv4_set = 1;
17406         }
17407       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17408         {
17409           ipv6_set = 1;
17410         }
17411       else
17412         break;
17413     }
17414
17415   if (ipv4_set && ipv6_set)
17416     {
17417       errmsg ("both eid v4 and v6 addresses set");
17418       return -99;
17419     }
17420
17421   if (!ipv4_set && !ipv6_set)
17422     {
17423       errmsg ("eid addresses not set");
17424       return -99;
17425     }
17426
17427   /* Construct the API message */
17428   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17429
17430   mp->is_add = is_add;
17431   if (ipv6_set)
17432     {
17433       mp->is_ipv6 = 1;
17434       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17435     }
17436   else
17437     {
17438       mp->is_ipv6 = 0;
17439       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17440     }
17441
17442   /* send it... */
17443   S (mp);
17444
17445   /* Wait for a reply... */
17446   W (ret);
17447   return ret;
17448 }
17449
17450 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17451
17452 static int
17453 api_lisp_gpe_enable_disable (vat_main_t * vam)
17454 {
17455   unformat_input_t *input = vam->input;
17456   vl_api_gpe_enable_disable_t *mp;
17457   u8 is_set = 0;
17458   u8 is_en = 1;
17459   int ret;
17460
17461   /* Parse args required to build the message */
17462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17463     {
17464       if (unformat (input, "enable"))
17465         {
17466           is_set = 1;
17467           is_en = 1;
17468         }
17469       else if (unformat (input, "disable"))
17470         {
17471           is_set = 1;
17472           is_en = 0;
17473         }
17474       else
17475         break;
17476     }
17477
17478   if (is_set == 0)
17479     {
17480       errmsg ("Value not set");
17481       return -99;
17482     }
17483
17484   /* Construct the API message */
17485   M (GPE_ENABLE_DISABLE, mp);
17486
17487   mp->is_en = is_en;
17488
17489   /* send it... */
17490   S (mp);
17491
17492   /* Wait for a reply... */
17493   W (ret);
17494   return ret;
17495 }
17496
17497 static int
17498 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17499 {
17500   unformat_input_t *input = vam->input;
17501   vl_api_one_rloc_probe_enable_disable_t *mp;
17502   u8 is_set = 0;
17503   u8 is_en = 0;
17504   int ret;
17505
17506   /* Parse args required to build the message */
17507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17508     {
17509       if (unformat (input, "enable"))
17510         {
17511           is_set = 1;
17512           is_en = 1;
17513         }
17514       else if (unformat (input, "disable"))
17515         is_set = 1;
17516       else
17517         break;
17518     }
17519
17520   if (!is_set)
17521     {
17522       errmsg ("Value not set");
17523       return -99;
17524     }
17525
17526   /* Construct the API message */
17527   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17528
17529   mp->is_enabled = is_en;
17530
17531   /* send it... */
17532   S (mp);
17533
17534   /* Wait for a reply... */
17535   W (ret);
17536   return ret;
17537 }
17538
17539 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17540
17541 static int
17542 api_one_map_register_enable_disable (vat_main_t * vam)
17543 {
17544   unformat_input_t *input = vam->input;
17545   vl_api_one_map_register_enable_disable_t *mp;
17546   u8 is_set = 0;
17547   u8 is_en = 0;
17548   int ret;
17549
17550   /* Parse args required to build the message */
17551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17552     {
17553       if (unformat (input, "enable"))
17554         {
17555           is_set = 1;
17556           is_en = 1;
17557         }
17558       else if (unformat (input, "disable"))
17559         is_set = 1;
17560       else
17561         break;
17562     }
17563
17564   if (!is_set)
17565     {
17566       errmsg ("Value not set");
17567       return -99;
17568     }
17569
17570   /* Construct the API message */
17571   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17572
17573   mp->is_enabled = is_en;
17574
17575   /* send it... */
17576   S (mp);
17577
17578   /* Wait for a reply... */
17579   W (ret);
17580   return ret;
17581 }
17582
17583 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17584
17585 static int
17586 api_one_enable_disable (vat_main_t * vam)
17587 {
17588   unformat_input_t *input = vam->input;
17589   vl_api_one_enable_disable_t *mp;
17590   u8 is_set = 0;
17591   u8 is_en = 0;
17592   int ret;
17593
17594   /* Parse args required to build the message */
17595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17596     {
17597       if (unformat (input, "enable"))
17598         {
17599           is_set = 1;
17600           is_en = 1;
17601         }
17602       else if (unformat (input, "disable"))
17603         {
17604           is_set = 1;
17605         }
17606       else
17607         break;
17608     }
17609
17610   if (!is_set)
17611     {
17612       errmsg ("Value not set");
17613       return -99;
17614     }
17615
17616   /* Construct the API message */
17617   M (ONE_ENABLE_DISABLE, mp);
17618
17619   mp->is_en = is_en;
17620
17621   /* send it... */
17622   S (mp);
17623
17624   /* Wait for a reply... */
17625   W (ret);
17626   return ret;
17627 }
17628
17629 #define api_lisp_enable_disable api_one_enable_disable
17630
17631 static int
17632 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17633 {
17634   unformat_input_t *input = vam->input;
17635   vl_api_one_enable_disable_xtr_mode_t *mp;
17636   u8 is_set = 0;
17637   u8 is_en = 0;
17638   int ret;
17639
17640   /* Parse args required to build the message */
17641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17642     {
17643       if (unformat (input, "enable"))
17644         {
17645           is_set = 1;
17646           is_en = 1;
17647         }
17648       else if (unformat (input, "disable"))
17649         {
17650           is_set = 1;
17651         }
17652       else
17653         break;
17654     }
17655
17656   if (!is_set)
17657     {
17658       errmsg ("Value not set");
17659       return -99;
17660     }
17661
17662   /* Construct the API message */
17663   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17664
17665   mp->is_en = is_en;
17666
17667   /* send it... */
17668   S (mp);
17669
17670   /* Wait for a reply... */
17671   W (ret);
17672   return ret;
17673 }
17674
17675 static int
17676 api_one_show_xtr_mode (vat_main_t * vam)
17677 {
17678   vl_api_one_show_xtr_mode_t *mp;
17679   int ret;
17680
17681   /* Construct the API message */
17682   M (ONE_SHOW_XTR_MODE, mp);
17683
17684   /* send it... */
17685   S (mp);
17686
17687   /* Wait for a reply... */
17688   W (ret);
17689   return ret;
17690 }
17691
17692 static int
17693 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17694 {
17695   unformat_input_t *input = vam->input;
17696   vl_api_one_enable_disable_pitr_mode_t *mp;
17697   u8 is_set = 0;
17698   u8 is_en = 0;
17699   int ret;
17700
17701   /* Parse args required to build the message */
17702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17703     {
17704       if (unformat (input, "enable"))
17705         {
17706           is_set = 1;
17707           is_en = 1;
17708         }
17709       else if (unformat (input, "disable"))
17710         {
17711           is_set = 1;
17712         }
17713       else
17714         break;
17715     }
17716
17717   if (!is_set)
17718     {
17719       errmsg ("Value not set");
17720       return -99;
17721     }
17722
17723   /* Construct the API message */
17724   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17725
17726   mp->is_en = is_en;
17727
17728   /* send it... */
17729   S (mp);
17730
17731   /* Wait for a reply... */
17732   W (ret);
17733   return ret;
17734 }
17735
17736 static int
17737 api_one_show_pitr_mode (vat_main_t * vam)
17738 {
17739   vl_api_one_show_pitr_mode_t *mp;
17740   int ret;
17741
17742   /* Construct the API message */
17743   M (ONE_SHOW_PITR_MODE, mp);
17744
17745   /* send it... */
17746   S (mp);
17747
17748   /* Wait for a reply... */
17749   W (ret);
17750   return ret;
17751 }
17752
17753 static int
17754 api_one_enable_disable_petr_mode (vat_main_t * vam)
17755 {
17756   unformat_input_t *input = vam->input;
17757   vl_api_one_enable_disable_petr_mode_t *mp;
17758   u8 is_set = 0;
17759   u8 is_en = 0;
17760   int ret;
17761
17762   /* Parse args required to build the message */
17763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17764     {
17765       if (unformat (input, "enable"))
17766         {
17767           is_set = 1;
17768           is_en = 1;
17769         }
17770       else if (unformat (input, "disable"))
17771         {
17772           is_set = 1;
17773         }
17774       else
17775         break;
17776     }
17777
17778   if (!is_set)
17779     {
17780       errmsg ("Value not set");
17781       return -99;
17782     }
17783
17784   /* Construct the API message */
17785   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17786
17787   mp->is_en = is_en;
17788
17789   /* send it... */
17790   S (mp);
17791
17792   /* Wait for a reply... */
17793   W (ret);
17794   return ret;
17795 }
17796
17797 static int
17798 api_one_show_petr_mode (vat_main_t * vam)
17799 {
17800   vl_api_one_show_petr_mode_t *mp;
17801   int ret;
17802
17803   /* Construct the API message */
17804   M (ONE_SHOW_PETR_MODE, mp);
17805
17806   /* send it... */
17807   S (mp);
17808
17809   /* Wait for a reply... */
17810   W (ret);
17811   return ret;
17812 }
17813
17814 static int
17815 api_show_one_map_register_state (vat_main_t * vam)
17816 {
17817   vl_api_show_one_map_register_state_t *mp;
17818   int ret;
17819
17820   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17821
17822   /* send */
17823   S (mp);
17824
17825   /* wait for reply */
17826   W (ret);
17827   return ret;
17828 }
17829
17830 #define api_show_lisp_map_register_state api_show_one_map_register_state
17831
17832 static int
17833 api_show_one_rloc_probe_state (vat_main_t * vam)
17834 {
17835   vl_api_show_one_rloc_probe_state_t *mp;
17836   int ret;
17837
17838   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17839
17840   /* send */
17841   S (mp);
17842
17843   /* wait for reply */
17844   W (ret);
17845   return ret;
17846 }
17847
17848 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17849
17850 static int
17851 api_one_add_del_ndp_entry (vat_main_t * vam)
17852 {
17853   vl_api_one_add_del_ndp_entry_t *mp;
17854   unformat_input_t *input = vam->input;
17855   u8 is_add = 1;
17856   u8 mac_set = 0;
17857   u8 bd_set = 0;
17858   u8 ip_set = 0;
17859   u8 mac[6] = { 0, };
17860   u8 ip6[16] = { 0, };
17861   u32 bd = ~0;
17862   int ret;
17863
17864   /* Parse args required to build the message */
17865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17866     {
17867       if (unformat (input, "del"))
17868         is_add = 0;
17869       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17870         mac_set = 1;
17871       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17872         ip_set = 1;
17873       else if (unformat (input, "bd %d", &bd))
17874         bd_set = 1;
17875       else
17876         {
17877           errmsg ("parse error '%U'", format_unformat_error, input);
17878           return -99;
17879         }
17880     }
17881
17882   if (!bd_set || !ip_set || (!mac_set && is_add))
17883     {
17884       errmsg ("Missing BD, IP or MAC!");
17885       return -99;
17886     }
17887
17888   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17889   mp->is_add = is_add;
17890   clib_memcpy (mp->mac, mac, 6);
17891   mp->bd = clib_host_to_net_u32 (bd);
17892   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17893
17894   /* send */
17895   S (mp);
17896
17897   /* wait for reply */
17898   W (ret);
17899   return ret;
17900 }
17901
17902 static int
17903 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17904 {
17905   vl_api_one_add_del_l2_arp_entry_t *mp;
17906   unformat_input_t *input = vam->input;
17907   u8 is_add = 1;
17908   u8 mac_set = 0;
17909   u8 bd_set = 0;
17910   u8 ip_set = 0;
17911   u8 mac[6] = { 0, };
17912   u32 ip4 = 0, bd = ~0;
17913   int ret;
17914
17915   /* Parse args required to build the message */
17916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17917     {
17918       if (unformat (input, "del"))
17919         is_add = 0;
17920       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17921         mac_set = 1;
17922       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17923         ip_set = 1;
17924       else if (unformat (input, "bd %d", &bd))
17925         bd_set = 1;
17926       else
17927         {
17928           errmsg ("parse error '%U'", format_unformat_error, input);
17929           return -99;
17930         }
17931     }
17932
17933   if (!bd_set || !ip_set || (!mac_set && is_add))
17934     {
17935       errmsg ("Missing BD, IP or MAC!");
17936       return -99;
17937     }
17938
17939   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17940   mp->is_add = is_add;
17941   clib_memcpy (mp->mac, mac, 6);
17942   mp->bd = clib_host_to_net_u32 (bd);
17943   mp->ip4 = ip4;
17944
17945   /* send */
17946   S (mp);
17947
17948   /* wait for reply */
17949   W (ret);
17950   return ret;
17951 }
17952
17953 static int
17954 api_one_ndp_bd_get (vat_main_t * vam)
17955 {
17956   vl_api_one_ndp_bd_get_t *mp;
17957   int ret;
17958
17959   M (ONE_NDP_BD_GET, mp);
17960
17961   /* send */
17962   S (mp);
17963
17964   /* wait for reply */
17965   W (ret);
17966   return ret;
17967 }
17968
17969 static int
17970 api_one_ndp_entries_get (vat_main_t * vam)
17971 {
17972   vl_api_one_ndp_entries_get_t *mp;
17973   unformat_input_t *input = vam->input;
17974   u8 bd_set = 0;
17975   u32 bd = ~0;
17976   int ret;
17977
17978   /* Parse args required to build the message */
17979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17980     {
17981       if (unformat (input, "bd %d", &bd))
17982         bd_set = 1;
17983       else
17984         {
17985           errmsg ("parse error '%U'", format_unformat_error, input);
17986           return -99;
17987         }
17988     }
17989
17990   if (!bd_set)
17991     {
17992       errmsg ("Expected bridge domain!");
17993       return -99;
17994     }
17995
17996   M (ONE_NDP_ENTRIES_GET, mp);
17997   mp->bd = clib_host_to_net_u32 (bd);
17998
17999   /* send */
18000   S (mp);
18001
18002   /* wait for reply */
18003   W (ret);
18004   return ret;
18005 }
18006
18007 static int
18008 api_one_l2_arp_bd_get (vat_main_t * vam)
18009 {
18010   vl_api_one_l2_arp_bd_get_t *mp;
18011   int ret;
18012
18013   M (ONE_L2_ARP_BD_GET, mp);
18014
18015   /* send */
18016   S (mp);
18017
18018   /* wait for reply */
18019   W (ret);
18020   return ret;
18021 }
18022
18023 static int
18024 api_one_l2_arp_entries_get (vat_main_t * vam)
18025 {
18026   vl_api_one_l2_arp_entries_get_t *mp;
18027   unformat_input_t *input = vam->input;
18028   u8 bd_set = 0;
18029   u32 bd = ~0;
18030   int ret;
18031
18032   /* Parse args required to build the message */
18033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18034     {
18035       if (unformat (input, "bd %d", &bd))
18036         bd_set = 1;
18037       else
18038         {
18039           errmsg ("parse error '%U'", format_unformat_error, input);
18040           return -99;
18041         }
18042     }
18043
18044   if (!bd_set)
18045     {
18046       errmsg ("Expected bridge domain!");
18047       return -99;
18048     }
18049
18050   M (ONE_L2_ARP_ENTRIES_GET, mp);
18051   mp->bd = clib_host_to_net_u32 (bd);
18052
18053   /* send */
18054   S (mp);
18055
18056   /* wait for reply */
18057   W (ret);
18058   return ret;
18059 }
18060
18061 static int
18062 api_one_stats_enable_disable (vat_main_t * vam)
18063 {
18064   vl_api_one_stats_enable_disable_t *mp;
18065   unformat_input_t *input = vam->input;
18066   u8 is_set = 0;
18067   u8 is_en = 0;
18068   int ret;
18069
18070   /* Parse args required to build the message */
18071   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18072     {
18073       if (unformat (input, "enable"))
18074         {
18075           is_set = 1;
18076           is_en = 1;
18077         }
18078       else if (unformat (input, "disable"))
18079         {
18080           is_set = 1;
18081         }
18082       else
18083         break;
18084     }
18085
18086   if (!is_set)
18087     {
18088       errmsg ("Value not set");
18089       return -99;
18090     }
18091
18092   M (ONE_STATS_ENABLE_DISABLE, mp);
18093   mp->is_en = is_en;
18094
18095   /* send */
18096   S (mp);
18097
18098   /* wait for reply */
18099   W (ret);
18100   return ret;
18101 }
18102
18103 static int
18104 api_show_one_stats_enable_disable (vat_main_t * vam)
18105 {
18106   vl_api_show_one_stats_enable_disable_t *mp;
18107   int ret;
18108
18109   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18110
18111   /* send */
18112   S (mp);
18113
18114   /* wait for reply */
18115   W (ret);
18116   return ret;
18117 }
18118
18119 static int
18120 api_show_one_map_request_mode (vat_main_t * vam)
18121 {
18122   vl_api_show_one_map_request_mode_t *mp;
18123   int ret;
18124
18125   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18126
18127   /* send */
18128   S (mp);
18129
18130   /* wait for reply */
18131   W (ret);
18132   return ret;
18133 }
18134
18135 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18136
18137 static int
18138 api_one_map_request_mode (vat_main_t * vam)
18139 {
18140   unformat_input_t *input = vam->input;
18141   vl_api_one_map_request_mode_t *mp;
18142   u8 mode = 0;
18143   int ret;
18144
18145   /* Parse args required to build the message */
18146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18147     {
18148       if (unformat (input, "dst-only"))
18149         mode = 0;
18150       else if (unformat (input, "src-dst"))
18151         mode = 1;
18152       else
18153         {
18154           errmsg ("parse error '%U'", format_unformat_error, input);
18155           return -99;
18156         }
18157     }
18158
18159   M (ONE_MAP_REQUEST_MODE, mp);
18160
18161   mp->mode = mode;
18162
18163   /* send */
18164   S (mp);
18165
18166   /* wait for reply */
18167   W (ret);
18168   return ret;
18169 }
18170
18171 #define api_lisp_map_request_mode api_one_map_request_mode
18172
18173 /**
18174  * Enable/disable ONE proxy ITR.
18175  *
18176  * @param vam vpp API test context
18177  * @return return code
18178  */
18179 static int
18180 api_one_pitr_set_locator_set (vat_main_t * vam)
18181 {
18182   u8 ls_name_set = 0;
18183   unformat_input_t *input = vam->input;
18184   vl_api_one_pitr_set_locator_set_t *mp;
18185   u8 is_add = 1;
18186   u8 *ls_name = 0;
18187   int ret;
18188
18189   /* Parse args required to build the message */
18190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18191     {
18192       if (unformat (input, "del"))
18193         is_add = 0;
18194       else if (unformat (input, "locator-set %s", &ls_name))
18195         ls_name_set = 1;
18196       else
18197         {
18198           errmsg ("parse error '%U'", format_unformat_error, input);
18199           return -99;
18200         }
18201     }
18202
18203   if (!ls_name_set)
18204     {
18205       errmsg ("locator-set name not set!");
18206       return -99;
18207     }
18208
18209   M (ONE_PITR_SET_LOCATOR_SET, mp);
18210
18211   mp->is_add = is_add;
18212   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18213   vec_free (ls_name);
18214
18215   /* send */
18216   S (mp);
18217
18218   /* wait for reply */
18219   W (ret);
18220   return ret;
18221 }
18222
18223 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18224
18225 static int
18226 api_one_nsh_set_locator_set (vat_main_t * vam)
18227 {
18228   u8 ls_name_set = 0;
18229   unformat_input_t *input = vam->input;
18230   vl_api_one_nsh_set_locator_set_t *mp;
18231   u8 is_add = 1;
18232   u8 *ls_name = 0;
18233   int ret;
18234
18235   /* Parse args required to build the message */
18236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18237     {
18238       if (unformat (input, "del"))
18239         is_add = 0;
18240       else if (unformat (input, "ls %s", &ls_name))
18241         ls_name_set = 1;
18242       else
18243         {
18244           errmsg ("parse error '%U'", format_unformat_error, input);
18245           return -99;
18246         }
18247     }
18248
18249   if (!ls_name_set && is_add)
18250     {
18251       errmsg ("locator-set name not set!");
18252       return -99;
18253     }
18254
18255   M (ONE_NSH_SET_LOCATOR_SET, mp);
18256
18257   mp->is_add = is_add;
18258   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18259   vec_free (ls_name);
18260
18261   /* send */
18262   S (mp);
18263
18264   /* wait for reply */
18265   W (ret);
18266   return ret;
18267 }
18268
18269 static int
18270 api_show_one_pitr (vat_main_t * vam)
18271 {
18272   vl_api_show_one_pitr_t *mp;
18273   int ret;
18274
18275   if (!vam->json_output)
18276     {
18277       print (vam->ofp, "%=20s", "lisp status:");
18278     }
18279
18280   M (SHOW_ONE_PITR, mp);
18281   /* send it... */
18282   S (mp);
18283
18284   /* Wait for a reply... */
18285   W (ret);
18286   return ret;
18287 }
18288
18289 #define api_show_lisp_pitr api_show_one_pitr
18290
18291 static int
18292 api_one_use_petr (vat_main_t * vam)
18293 {
18294   unformat_input_t *input = vam->input;
18295   vl_api_one_use_petr_t *mp;
18296   u8 is_add = 0;
18297   ip_address_t ip;
18298   int ret;
18299
18300   memset (&ip, 0, sizeof (ip));
18301
18302   /* Parse args required to build the message */
18303   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18304     {
18305       if (unformat (input, "disable"))
18306         is_add = 0;
18307       else
18308         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18309         {
18310           is_add = 1;
18311           ip_addr_version (&ip) = IP4;
18312         }
18313       else
18314         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18315         {
18316           is_add = 1;
18317           ip_addr_version (&ip) = IP6;
18318         }
18319       else
18320         {
18321           errmsg ("parse error '%U'", format_unformat_error, input);
18322           return -99;
18323         }
18324     }
18325
18326   M (ONE_USE_PETR, mp);
18327
18328   mp->is_add = is_add;
18329   if (is_add)
18330     {
18331       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18332       if (mp->is_ip4)
18333         clib_memcpy (mp->address, &ip, 4);
18334       else
18335         clib_memcpy (mp->address, &ip, 16);
18336     }
18337
18338   /* send */
18339   S (mp);
18340
18341   /* wait for reply */
18342   W (ret);
18343   return ret;
18344 }
18345
18346 #define api_lisp_use_petr api_one_use_petr
18347
18348 static int
18349 api_show_one_nsh_mapping (vat_main_t * vam)
18350 {
18351   vl_api_show_one_use_petr_t *mp;
18352   int ret;
18353
18354   if (!vam->json_output)
18355     {
18356       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18357     }
18358
18359   M (SHOW_ONE_NSH_MAPPING, mp);
18360   /* send it... */
18361   S (mp);
18362
18363   /* Wait for a reply... */
18364   W (ret);
18365   return ret;
18366 }
18367
18368 static int
18369 api_show_one_use_petr (vat_main_t * vam)
18370 {
18371   vl_api_show_one_use_petr_t *mp;
18372   int ret;
18373
18374   if (!vam->json_output)
18375     {
18376       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18377     }
18378
18379   M (SHOW_ONE_USE_PETR, mp);
18380   /* send it... */
18381   S (mp);
18382
18383   /* Wait for a reply... */
18384   W (ret);
18385   return ret;
18386 }
18387
18388 #define api_show_lisp_use_petr api_show_one_use_petr
18389
18390 /**
18391  * Add/delete mapping between vni and vrf
18392  */
18393 static int
18394 api_one_eid_table_add_del_map (vat_main_t * vam)
18395 {
18396   unformat_input_t *input = vam->input;
18397   vl_api_one_eid_table_add_del_map_t *mp;
18398   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18399   u32 vni, vrf, bd_index;
18400   int ret;
18401
18402   /* Parse args required to build the message */
18403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18404     {
18405       if (unformat (input, "del"))
18406         is_add = 0;
18407       else if (unformat (input, "vrf %d", &vrf))
18408         vrf_set = 1;
18409       else if (unformat (input, "bd_index %d", &bd_index))
18410         bd_index_set = 1;
18411       else if (unformat (input, "vni %d", &vni))
18412         vni_set = 1;
18413       else
18414         break;
18415     }
18416
18417   if (!vni_set || (!vrf_set && !bd_index_set))
18418     {
18419       errmsg ("missing arguments!");
18420       return -99;
18421     }
18422
18423   if (vrf_set && bd_index_set)
18424     {
18425       errmsg ("error: both vrf and bd entered!");
18426       return -99;
18427     }
18428
18429   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18430
18431   mp->is_add = is_add;
18432   mp->vni = htonl (vni);
18433   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18434   mp->is_l2 = bd_index_set;
18435
18436   /* send */
18437   S (mp);
18438
18439   /* wait for reply */
18440   W (ret);
18441   return ret;
18442 }
18443
18444 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18445
18446 uword
18447 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18448 {
18449   u32 *action = va_arg (*args, u32 *);
18450   u8 *s = 0;
18451
18452   if (unformat (input, "%s", &s))
18453     {
18454       if (!strcmp ((char *) s, "no-action"))
18455         action[0] = 0;
18456       else if (!strcmp ((char *) s, "natively-forward"))
18457         action[0] = 1;
18458       else if (!strcmp ((char *) s, "send-map-request"))
18459         action[0] = 2;
18460       else if (!strcmp ((char *) s, "drop"))
18461         action[0] = 3;
18462       else
18463         {
18464           clib_warning ("invalid action: '%s'", s);
18465           action[0] = 3;
18466         }
18467     }
18468   else
18469     return 0;
18470
18471   vec_free (s);
18472   return 1;
18473 }
18474
18475 /**
18476  * Add/del remote mapping to/from ONE control plane
18477  *
18478  * @param vam vpp API test context
18479  * @return return code
18480  */
18481 static int
18482 api_one_add_del_remote_mapping (vat_main_t * vam)
18483 {
18484   unformat_input_t *input = vam->input;
18485   vl_api_one_add_del_remote_mapping_t *mp;
18486   u32 vni = 0;
18487   lisp_eid_vat_t _eid, *eid = &_eid;
18488   lisp_eid_vat_t _seid, *seid = &_seid;
18489   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18490   u32 action = ~0, p, w, data_len;
18491   ip4_address_t rloc4;
18492   ip6_address_t rloc6;
18493   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18494   int ret;
18495
18496   memset (&rloc, 0, sizeof (rloc));
18497
18498   /* Parse args required to build the message */
18499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18500     {
18501       if (unformat (input, "del-all"))
18502         {
18503           del_all = 1;
18504         }
18505       else if (unformat (input, "del"))
18506         {
18507           is_add = 0;
18508         }
18509       else if (unformat (input, "add"))
18510         {
18511           is_add = 1;
18512         }
18513       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18514         {
18515           eid_set = 1;
18516         }
18517       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18518         {
18519           seid_set = 1;
18520         }
18521       else if (unformat (input, "vni %d", &vni))
18522         {
18523           ;
18524         }
18525       else if (unformat (input, "p %d w %d", &p, &w))
18526         {
18527           if (!curr_rloc)
18528             {
18529               errmsg ("No RLOC configured for setting priority/weight!");
18530               return -99;
18531             }
18532           curr_rloc->priority = p;
18533           curr_rloc->weight = w;
18534         }
18535       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18536         {
18537           rloc.is_ip4 = 1;
18538           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18539           vec_add1 (rlocs, rloc);
18540           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18541         }
18542       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18543         {
18544           rloc.is_ip4 = 0;
18545           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18546           vec_add1 (rlocs, rloc);
18547           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18548         }
18549       else if (unformat (input, "action %U",
18550                          unformat_negative_mapping_action, &action))
18551         {
18552           ;
18553         }
18554       else
18555         {
18556           clib_warning ("parse error '%U'", format_unformat_error, input);
18557           return -99;
18558         }
18559     }
18560
18561   if (0 == eid_set)
18562     {
18563       errmsg ("missing params!");
18564       return -99;
18565     }
18566
18567   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18568     {
18569       errmsg ("no action set for negative map-reply!");
18570       return -99;
18571     }
18572
18573   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18574
18575   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18576   mp->is_add = is_add;
18577   mp->vni = htonl (vni);
18578   mp->action = (u8) action;
18579   mp->is_src_dst = seid_set;
18580   mp->eid_len = eid->len;
18581   mp->seid_len = seid->len;
18582   mp->del_all = del_all;
18583   mp->eid_type = eid->type;
18584   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18585   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18586
18587   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18588   clib_memcpy (mp->rlocs, rlocs, data_len);
18589   vec_free (rlocs);
18590
18591   /* send it... */
18592   S (mp);
18593
18594   /* Wait for a reply... */
18595   W (ret);
18596   return ret;
18597 }
18598
18599 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18600
18601 /**
18602  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18603  * forwarding entries in data-plane accordingly.
18604  *
18605  * @param vam vpp API test context
18606  * @return return code
18607  */
18608 static int
18609 api_one_add_del_adjacency (vat_main_t * vam)
18610 {
18611   unformat_input_t *input = vam->input;
18612   vl_api_one_add_del_adjacency_t *mp;
18613   u32 vni = 0;
18614   ip4_address_t leid4, reid4;
18615   ip6_address_t leid6, reid6;
18616   u8 reid_mac[6] = { 0 };
18617   u8 leid_mac[6] = { 0 };
18618   u8 reid_type, leid_type;
18619   u32 leid_len = 0, reid_len = 0, len;
18620   u8 is_add = 1;
18621   int ret;
18622
18623   leid_type = reid_type = (u8) ~ 0;
18624
18625   /* Parse args required to build the message */
18626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18627     {
18628       if (unformat (input, "del"))
18629         {
18630           is_add = 0;
18631         }
18632       else if (unformat (input, "add"))
18633         {
18634           is_add = 1;
18635         }
18636       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18637                          &reid4, &len))
18638         {
18639           reid_type = 0;        /* ipv4 */
18640           reid_len = len;
18641         }
18642       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18643                          &reid6, &len))
18644         {
18645           reid_type = 1;        /* ipv6 */
18646           reid_len = len;
18647         }
18648       else if (unformat (input, "reid %U", unformat_ethernet_address,
18649                          reid_mac))
18650         {
18651           reid_type = 2;        /* mac */
18652         }
18653       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18654                          &leid4, &len))
18655         {
18656           leid_type = 0;        /* ipv4 */
18657           leid_len = len;
18658         }
18659       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18660                          &leid6, &len))
18661         {
18662           leid_type = 1;        /* ipv6 */
18663           leid_len = len;
18664         }
18665       else if (unformat (input, "leid %U", unformat_ethernet_address,
18666                          leid_mac))
18667         {
18668           leid_type = 2;        /* mac */
18669         }
18670       else if (unformat (input, "vni %d", &vni))
18671         {
18672           ;
18673         }
18674       else
18675         {
18676           errmsg ("parse error '%U'", format_unformat_error, input);
18677           return -99;
18678         }
18679     }
18680
18681   if ((u8) ~ 0 == reid_type)
18682     {
18683       errmsg ("missing params!");
18684       return -99;
18685     }
18686
18687   if (leid_type != reid_type)
18688     {
18689       errmsg ("remote and local EIDs are of different types!");
18690       return -99;
18691     }
18692
18693   M (ONE_ADD_DEL_ADJACENCY, mp);
18694   mp->is_add = is_add;
18695   mp->vni = htonl (vni);
18696   mp->leid_len = leid_len;
18697   mp->reid_len = reid_len;
18698   mp->eid_type = reid_type;
18699
18700   switch (mp->eid_type)
18701     {
18702     case 0:
18703       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18704       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18705       break;
18706     case 1:
18707       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18708       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18709       break;
18710     case 2:
18711       clib_memcpy (mp->leid, leid_mac, 6);
18712       clib_memcpy (mp->reid, reid_mac, 6);
18713       break;
18714     default:
18715       errmsg ("unknown EID type %d!", mp->eid_type);
18716       return 0;
18717     }
18718
18719   /* send it... */
18720   S (mp);
18721
18722   /* Wait for a reply... */
18723   W (ret);
18724   return ret;
18725 }
18726
18727 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18728
18729 uword
18730 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18731 {
18732   u32 *mode = va_arg (*args, u32 *);
18733
18734   if (unformat (input, "lisp"))
18735     *mode = 0;
18736   else if (unformat (input, "vxlan"))
18737     *mode = 1;
18738   else
18739     return 0;
18740
18741   return 1;
18742 }
18743
18744 static int
18745 api_gpe_get_encap_mode (vat_main_t * vam)
18746 {
18747   vl_api_gpe_get_encap_mode_t *mp;
18748   int ret;
18749
18750   /* Construct the API message */
18751   M (GPE_GET_ENCAP_MODE, mp);
18752
18753   /* send it... */
18754   S (mp);
18755
18756   /* Wait for a reply... */
18757   W (ret);
18758   return ret;
18759 }
18760
18761 static int
18762 api_gpe_set_encap_mode (vat_main_t * vam)
18763 {
18764   unformat_input_t *input = vam->input;
18765   vl_api_gpe_set_encap_mode_t *mp;
18766   int ret;
18767   u32 mode = 0;
18768
18769   /* Parse args required to build the message */
18770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18771     {
18772       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18773         ;
18774       else
18775         break;
18776     }
18777
18778   /* Construct the API message */
18779   M (GPE_SET_ENCAP_MODE, mp);
18780
18781   mp->mode = mode;
18782
18783   /* send it... */
18784   S (mp);
18785
18786   /* Wait for a reply... */
18787   W (ret);
18788   return ret;
18789 }
18790
18791 static int
18792 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18793 {
18794   unformat_input_t *input = vam->input;
18795   vl_api_gpe_add_del_iface_t *mp;
18796   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18797   u32 dp_table = 0, vni = 0;
18798   int ret;
18799
18800   /* Parse args required to build the message */
18801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18802     {
18803       if (unformat (input, "up"))
18804         {
18805           action_set = 1;
18806           is_add = 1;
18807         }
18808       else if (unformat (input, "down"))
18809         {
18810           action_set = 1;
18811           is_add = 0;
18812         }
18813       else if (unformat (input, "table_id %d", &dp_table))
18814         {
18815           dp_table_set = 1;
18816         }
18817       else if (unformat (input, "bd_id %d", &dp_table))
18818         {
18819           dp_table_set = 1;
18820           is_l2 = 1;
18821         }
18822       else if (unformat (input, "vni %d", &vni))
18823         {
18824           vni_set = 1;
18825         }
18826       else
18827         break;
18828     }
18829
18830   if (action_set == 0)
18831     {
18832       errmsg ("Action not set");
18833       return -99;
18834     }
18835   if (dp_table_set == 0 || vni_set == 0)
18836     {
18837       errmsg ("vni and dp_table must be set");
18838       return -99;
18839     }
18840
18841   /* Construct the API message */
18842   M (GPE_ADD_DEL_IFACE, mp);
18843
18844   mp->is_add = is_add;
18845   mp->dp_table = clib_host_to_net_u32 (dp_table);
18846   mp->is_l2 = is_l2;
18847   mp->vni = clib_host_to_net_u32 (vni);
18848
18849   /* send it... */
18850   S (mp);
18851
18852   /* Wait for a reply... */
18853   W (ret);
18854   return ret;
18855 }
18856
18857 static int
18858 api_one_map_register_fallback_threshold (vat_main_t * vam)
18859 {
18860   unformat_input_t *input = vam->input;
18861   vl_api_one_map_register_fallback_threshold_t *mp;
18862   u32 value = 0;
18863   u8 is_set = 0;
18864   int ret;
18865
18866   /* Parse args required to build the message */
18867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18868     {
18869       if (unformat (input, "%u", &value))
18870         is_set = 1;
18871       else
18872         {
18873           clib_warning ("parse error '%U'", format_unformat_error, input);
18874           return -99;
18875         }
18876     }
18877
18878   if (!is_set)
18879     {
18880       errmsg ("fallback threshold value is missing!");
18881       return -99;
18882     }
18883
18884   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18885   mp->value = clib_host_to_net_u32 (value);
18886
18887   /* send it... */
18888   S (mp);
18889
18890   /* Wait for a reply... */
18891   W (ret);
18892   return ret;
18893 }
18894
18895 static int
18896 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18897 {
18898   vl_api_show_one_map_register_fallback_threshold_t *mp;
18899   int ret;
18900
18901   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18902
18903   /* send it... */
18904   S (mp);
18905
18906   /* Wait for a reply... */
18907   W (ret);
18908   return ret;
18909 }
18910
18911 uword
18912 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18913 {
18914   u32 *proto = va_arg (*args, u32 *);
18915
18916   if (unformat (input, "udp"))
18917     *proto = 1;
18918   else if (unformat (input, "api"))
18919     *proto = 2;
18920   else
18921     return 0;
18922
18923   return 1;
18924 }
18925
18926 static int
18927 api_one_set_transport_protocol (vat_main_t * vam)
18928 {
18929   unformat_input_t *input = vam->input;
18930   vl_api_one_set_transport_protocol_t *mp;
18931   u8 is_set = 0;
18932   u32 protocol = 0;
18933   int ret;
18934
18935   /* Parse args required to build the message */
18936   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18937     {
18938       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18939         is_set = 1;
18940       else
18941         {
18942           clib_warning ("parse error '%U'", format_unformat_error, input);
18943           return -99;
18944         }
18945     }
18946
18947   if (!is_set)
18948     {
18949       errmsg ("Transport protocol missing!");
18950       return -99;
18951     }
18952
18953   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18954   mp->protocol = (u8) protocol;
18955
18956   /* send it... */
18957   S (mp);
18958
18959   /* Wait for a reply... */
18960   W (ret);
18961   return ret;
18962 }
18963
18964 static int
18965 api_one_get_transport_protocol (vat_main_t * vam)
18966 {
18967   vl_api_one_get_transport_protocol_t *mp;
18968   int ret;
18969
18970   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18971
18972   /* send it... */
18973   S (mp);
18974
18975   /* Wait for a reply... */
18976   W (ret);
18977   return ret;
18978 }
18979
18980 static int
18981 api_one_map_register_set_ttl (vat_main_t * vam)
18982 {
18983   unformat_input_t *input = vam->input;
18984   vl_api_one_map_register_set_ttl_t *mp;
18985   u32 ttl = 0;
18986   u8 is_set = 0;
18987   int ret;
18988
18989   /* Parse args required to build the message */
18990   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18991     {
18992       if (unformat (input, "%u", &ttl))
18993         is_set = 1;
18994       else
18995         {
18996           clib_warning ("parse error '%U'", format_unformat_error, input);
18997           return -99;
18998         }
18999     }
19000
19001   if (!is_set)
19002     {
19003       errmsg ("TTL value missing!");
19004       return -99;
19005     }
19006
19007   M (ONE_MAP_REGISTER_SET_TTL, mp);
19008   mp->ttl = clib_host_to_net_u32 (ttl);
19009
19010   /* send it... */
19011   S (mp);
19012
19013   /* Wait for a reply... */
19014   W (ret);
19015   return ret;
19016 }
19017
19018 static int
19019 api_show_one_map_register_ttl (vat_main_t * vam)
19020 {
19021   vl_api_show_one_map_register_ttl_t *mp;
19022   int ret;
19023
19024   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19025
19026   /* send it... */
19027   S (mp);
19028
19029   /* Wait for a reply... */
19030   W (ret);
19031   return ret;
19032 }
19033
19034 /**
19035  * Add/del map request itr rlocs from ONE control plane and updates
19036  *
19037  * @param vam vpp API test context
19038  * @return return code
19039  */
19040 static int
19041 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19042 {
19043   unformat_input_t *input = vam->input;
19044   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19045   u8 *locator_set_name = 0;
19046   u8 locator_set_name_set = 0;
19047   u8 is_add = 1;
19048   int ret;
19049
19050   /* Parse args required to build the message */
19051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19052     {
19053       if (unformat (input, "del"))
19054         {
19055           is_add = 0;
19056         }
19057       else if (unformat (input, "%_%v%_", &locator_set_name))
19058         {
19059           locator_set_name_set = 1;
19060         }
19061       else
19062         {
19063           clib_warning ("parse error '%U'", format_unformat_error, input);
19064           return -99;
19065         }
19066     }
19067
19068   if (is_add && !locator_set_name_set)
19069     {
19070       errmsg ("itr-rloc is not set!");
19071       return -99;
19072     }
19073
19074   if (is_add && vec_len (locator_set_name) > 64)
19075     {
19076       errmsg ("itr-rloc locator-set name too long");
19077       vec_free (locator_set_name);
19078       return -99;
19079     }
19080
19081   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19082   mp->is_add = is_add;
19083   if (is_add)
19084     {
19085       clib_memcpy (mp->locator_set_name, locator_set_name,
19086                    vec_len (locator_set_name));
19087     }
19088   else
19089     {
19090       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19091     }
19092   vec_free (locator_set_name);
19093
19094   /* send it... */
19095   S (mp);
19096
19097   /* Wait for a reply... */
19098   W (ret);
19099   return ret;
19100 }
19101
19102 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19103
19104 static int
19105 api_one_locator_dump (vat_main_t * vam)
19106 {
19107   unformat_input_t *input = vam->input;
19108   vl_api_one_locator_dump_t *mp;
19109   vl_api_control_ping_t *mp_ping;
19110   u8 is_index_set = 0, is_name_set = 0;
19111   u8 *ls_name = 0;
19112   u32 ls_index = ~0;
19113   int ret;
19114
19115   /* Parse args required to build the message */
19116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19117     {
19118       if (unformat (input, "ls_name %_%v%_", &ls_name))
19119         {
19120           is_name_set = 1;
19121         }
19122       else if (unformat (input, "ls_index %d", &ls_index))
19123         {
19124           is_index_set = 1;
19125         }
19126       else
19127         {
19128           errmsg ("parse error '%U'", format_unformat_error, input);
19129           return -99;
19130         }
19131     }
19132
19133   if (!is_index_set && !is_name_set)
19134     {
19135       errmsg ("error: expected one of index or name!");
19136       return -99;
19137     }
19138
19139   if (is_index_set && is_name_set)
19140     {
19141       errmsg ("error: only one param expected!");
19142       return -99;
19143     }
19144
19145   if (vec_len (ls_name) > 62)
19146     {
19147       errmsg ("error: locator set name too long!");
19148       return -99;
19149     }
19150
19151   if (!vam->json_output)
19152     {
19153       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19154     }
19155
19156   M (ONE_LOCATOR_DUMP, mp);
19157   mp->is_index_set = is_index_set;
19158
19159   if (is_index_set)
19160     mp->ls_index = clib_host_to_net_u32 (ls_index);
19161   else
19162     {
19163       vec_add1 (ls_name, 0);
19164       strncpy ((char *) mp->ls_name, (char *) ls_name,
19165                sizeof (mp->ls_name) - 1);
19166     }
19167
19168   /* send it... */
19169   S (mp);
19170
19171   /* Use a control ping for synchronization */
19172   MPING (CONTROL_PING, mp_ping);
19173   S (mp_ping);
19174
19175   /* Wait for a reply... */
19176   W (ret);
19177   return ret;
19178 }
19179
19180 #define api_lisp_locator_dump api_one_locator_dump
19181
19182 static int
19183 api_one_locator_set_dump (vat_main_t * vam)
19184 {
19185   vl_api_one_locator_set_dump_t *mp;
19186   vl_api_control_ping_t *mp_ping;
19187   unformat_input_t *input = vam->input;
19188   u8 filter = 0;
19189   int ret;
19190
19191   /* Parse args required to build the message */
19192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19193     {
19194       if (unformat (input, "local"))
19195         {
19196           filter = 1;
19197         }
19198       else if (unformat (input, "remote"))
19199         {
19200           filter = 2;
19201         }
19202       else
19203         {
19204           errmsg ("parse error '%U'", format_unformat_error, input);
19205           return -99;
19206         }
19207     }
19208
19209   if (!vam->json_output)
19210     {
19211       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19212     }
19213
19214   M (ONE_LOCATOR_SET_DUMP, mp);
19215
19216   mp->filter = filter;
19217
19218   /* send it... */
19219   S (mp);
19220
19221   /* Use a control ping for synchronization */
19222   MPING (CONTROL_PING, mp_ping);
19223   S (mp_ping);
19224
19225   /* Wait for a reply... */
19226   W (ret);
19227   return ret;
19228 }
19229
19230 #define api_lisp_locator_set_dump api_one_locator_set_dump
19231
19232 static int
19233 api_one_eid_table_map_dump (vat_main_t * vam)
19234 {
19235   u8 is_l2 = 0;
19236   u8 mode_set = 0;
19237   unformat_input_t *input = vam->input;
19238   vl_api_one_eid_table_map_dump_t *mp;
19239   vl_api_control_ping_t *mp_ping;
19240   int ret;
19241
19242   /* Parse args required to build the message */
19243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19244     {
19245       if (unformat (input, "l2"))
19246         {
19247           is_l2 = 1;
19248           mode_set = 1;
19249         }
19250       else if (unformat (input, "l3"))
19251         {
19252           is_l2 = 0;
19253           mode_set = 1;
19254         }
19255       else
19256         {
19257           errmsg ("parse error '%U'", format_unformat_error, input);
19258           return -99;
19259         }
19260     }
19261
19262   if (!mode_set)
19263     {
19264       errmsg ("expected one of 'l2' or 'l3' parameter!");
19265       return -99;
19266     }
19267
19268   if (!vam->json_output)
19269     {
19270       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19271     }
19272
19273   M (ONE_EID_TABLE_MAP_DUMP, mp);
19274   mp->is_l2 = is_l2;
19275
19276   /* send it... */
19277   S (mp);
19278
19279   /* Use a control ping for synchronization */
19280   MPING (CONTROL_PING, mp_ping);
19281   S (mp_ping);
19282
19283   /* Wait for a reply... */
19284   W (ret);
19285   return ret;
19286 }
19287
19288 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19289
19290 static int
19291 api_one_eid_table_vni_dump (vat_main_t * vam)
19292 {
19293   vl_api_one_eid_table_vni_dump_t *mp;
19294   vl_api_control_ping_t *mp_ping;
19295   int ret;
19296
19297   if (!vam->json_output)
19298     {
19299       print (vam->ofp, "VNI");
19300     }
19301
19302   M (ONE_EID_TABLE_VNI_DUMP, mp);
19303
19304   /* send it... */
19305   S (mp);
19306
19307   /* Use a control ping for synchronization */
19308   MPING (CONTROL_PING, mp_ping);
19309   S (mp_ping);
19310
19311   /* Wait for a reply... */
19312   W (ret);
19313   return ret;
19314 }
19315
19316 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19317
19318 static int
19319 api_one_eid_table_dump (vat_main_t * vam)
19320 {
19321   unformat_input_t *i = vam->input;
19322   vl_api_one_eid_table_dump_t *mp;
19323   vl_api_control_ping_t *mp_ping;
19324   struct in_addr ip4;
19325   struct in6_addr ip6;
19326   u8 mac[6];
19327   u8 eid_type = ~0, eid_set = 0;
19328   u32 prefix_length = ~0, t, vni = 0;
19329   u8 filter = 0;
19330   int ret;
19331   lisp_nsh_api_t nsh;
19332
19333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19334     {
19335       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19336         {
19337           eid_set = 1;
19338           eid_type = 0;
19339           prefix_length = t;
19340         }
19341       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19342         {
19343           eid_set = 1;
19344           eid_type = 1;
19345           prefix_length = t;
19346         }
19347       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19348         {
19349           eid_set = 1;
19350           eid_type = 2;
19351         }
19352       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19353         {
19354           eid_set = 1;
19355           eid_type = 3;
19356         }
19357       else if (unformat (i, "vni %d", &t))
19358         {
19359           vni = t;
19360         }
19361       else if (unformat (i, "local"))
19362         {
19363           filter = 1;
19364         }
19365       else if (unformat (i, "remote"))
19366         {
19367           filter = 2;
19368         }
19369       else
19370         {
19371           errmsg ("parse error '%U'", format_unformat_error, i);
19372           return -99;
19373         }
19374     }
19375
19376   if (!vam->json_output)
19377     {
19378       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19379              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19380     }
19381
19382   M (ONE_EID_TABLE_DUMP, mp);
19383
19384   mp->filter = filter;
19385   if (eid_set)
19386     {
19387       mp->eid_set = 1;
19388       mp->vni = htonl (vni);
19389       mp->eid_type = eid_type;
19390       switch (eid_type)
19391         {
19392         case 0:
19393           mp->prefix_length = prefix_length;
19394           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19395           break;
19396         case 1:
19397           mp->prefix_length = prefix_length;
19398           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19399           break;
19400         case 2:
19401           clib_memcpy (mp->eid, mac, sizeof (mac));
19402           break;
19403         case 3:
19404           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19405           break;
19406         default:
19407           errmsg ("unknown EID type %d!", eid_type);
19408           return -99;
19409         }
19410     }
19411
19412   /* send it... */
19413   S (mp);
19414
19415   /* Use a control ping for synchronization */
19416   MPING (CONTROL_PING, mp_ping);
19417   S (mp_ping);
19418
19419   /* Wait for a reply... */
19420   W (ret);
19421   return ret;
19422 }
19423
19424 #define api_lisp_eid_table_dump api_one_eid_table_dump
19425
19426 static int
19427 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19428 {
19429   unformat_input_t *i = vam->input;
19430   vl_api_gpe_fwd_entries_get_t *mp;
19431   u8 vni_set = 0;
19432   u32 vni = ~0;
19433   int ret;
19434
19435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19436     {
19437       if (unformat (i, "vni %d", &vni))
19438         {
19439           vni_set = 1;
19440         }
19441       else
19442         {
19443           errmsg ("parse error '%U'", format_unformat_error, i);
19444           return -99;
19445         }
19446     }
19447
19448   if (!vni_set)
19449     {
19450       errmsg ("vni not set!");
19451       return -99;
19452     }
19453
19454   if (!vam->json_output)
19455     {
19456       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19457              "leid", "reid");
19458     }
19459
19460   M (GPE_FWD_ENTRIES_GET, mp);
19461   mp->vni = clib_host_to_net_u32 (vni);
19462
19463   /* send it... */
19464   S (mp);
19465
19466   /* Wait for a reply... */
19467   W (ret);
19468   return ret;
19469 }
19470
19471 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19472 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19473 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19474 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19475 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19476 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19477 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19478 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19479
19480 static int
19481 api_one_adjacencies_get (vat_main_t * vam)
19482 {
19483   unformat_input_t *i = vam->input;
19484   vl_api_one_adjacencies_get_t *mp;
19485   u8 vni_set = 0;
19486   u32 vni = ~0;
19487   int ret;
19488
19489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19490     {
19491       if (unformat (i, "vni %d", &vni))
19492         {
19493           vni_set = 1;
19494         }
19495       else
19496         {
19497           errmsg ("parse error '%U'", format_unformat_error, i);
19498           return -99;
19499         }
19500     }
19501
19502   if (!vni_set)
19503     {
19504       errmsg ("vni not set!");
19505       return -99;
19506     }
19507
19508   if (!vam->json_output)
19509     {
19510       print (vam->ofp, "%s %40s", "leid", "reid");
19511     }
19512
19513   M (ONE_ADJACENCIES_GET, mp);
19514   mp->vni = clib_host_to_net_u32 (vni);
19515
19516   /* send it... */
19517   S (mp);
19518
19519   /* Wait for a reply... */
19520   W (ret);
19521   return ret;
19522 }
19523
19524 #define api_lisp_adjacencies_get api_one_adjacencies_get
19525
19526 static int
19527 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19528 {
19529   unformat_input_t *i = vam->input;
19530   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19531   int ret;
19532   u8 ip_family_set = 0, is_ip4 = 1;
19533
19534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19535     {
19536       if (unformat (i, "ip4"))
19537         {
19538           ip_family_set = 1;
19539           is_ip4 = 1;
19540         }
19541       else if (unformat (i, "ip6"))
19542         {
19543           ip_family_set = 1;
19544           is_ip4 = 0;
19545         }
19546       else
19547         {
19548           errmsg ("parse error '%U'", format_unformat_error, i);
19549           return -99;
19550         }
19551     }
19552
19553   if (!ip_family_set)
19554     {
19555       errmsg ("ip family not set!");
19556       return -99;
19557     }
19558
19559   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19560   mp->is_ip4 = is_ip4;
19561
19562   /* send it... */
19563   S (mp);
19564
19565   /* Wait for a reply... */
19566   W (ret);
19567   return ret;
19568 }
19569
19570 static int
19571 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19572 {
19573   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19574   int ret;
19575
19576   if (!vam->json_output)
19577     {
19578       print (vam->ofp, "VNIs");
19579     }
19580
19581   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19582
19583   /* send it... */
19584   S (mp);
19585
19586   /* Wait for a reply... */
19587   W (ret);
19588   return ret;
19589 }
19590
19591 static int
19592 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19593 {
19594   unformat_input_t *i = vam->input;
19595   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19596   int ret = 0;
19597   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19598   struct in_addr ip4;
19599   struct in6_addr ip6;
19600   u32 table_id = 0, nh_sw_if_index = ~0;
19601
19602   memset (&ip4, 0, sizeof (ip4));
19603   memset (&ip6, 0, sizeof (ip6));
19604
19605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19606     {
19607       if (unformat (i, "del"))
19608         is_add = 0;
19609       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19610                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19611         {
19612           ip_set = 1;
19613           is_ip4 = 1;
19614         }
19615       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19616                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19617         {
19618           ip_set = 1;
19619           is_ip4 = 0;
19620         }
19621       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19622         {
19623           ip_set = 1;
19624           is_ip4 = 1;
19625           nh_sw_if_index = ~0;
19626         }
19627       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19628         {
19629           ip_set = 1;
19630           is_ip4 = 0;
19631           nh_sw_if_index = ~0;
19632         }
19633       else if (unformat (i, "table %d", &table_id))
19634         ;
19635       else
19636         {
19637           errmsg ("parse error '%U'", format_unformat_error, i);
19638           return -99;
19639         }
19640     }
19641
19642   if (!ip_set)
19643     {
19644       errmsg ("nh addr not set!");
19645       return -99;
19646     }
19647
19648   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19649   mp->is_add = is_add;
19650   mp->table_id = clib_host_to_net_u32 (table_id);
19651   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19652   mp->is_ip4 = is_ip4;
19653   if (is_ip4)
19654     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19655   else
19656     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19657
19658   /* send it... */
19659   S (mp);
19660
19661   /* Wait for a reply... */
19662   W (ret);
19663   return ret;
19664 }
19665
19666 static int
19667 api_one_map_server_dump (vat_main_t * vam)
19668 {
19669   vl_api_one_map_server_dump_t *mp;
19670   vl_api_control_ping_t *mp_ping;
19671   int ret;
19672
19673   if (!vam->json_output)
19674     {
19675       print (vam->ofp, "%=20s", "Map server");
19676     }
19677
19678   M (ONE_MAP_SERVER_DUMP, mp);
19679   /* send it... */
19680   S (mp);
19681
19682   /* Use a control ping for synchronization */
19683   MPING (CONTROL_PING, mp_ping);
19684   S (mp_ping);
19685
19686   /* Wait for a reply... */
19687   W (ret);
19688   return ret;
19689 }
19690
19691 #define api_lisp_map_server_dump api_one_map_server_dump
19692
19693 static int
19694 api_one_map_resolver_dump (vat_main_t * vam)
19695 {
19696   vl_api_one_map_resolver_dump_t *mp;
19697   vl_api_control_ping_t *mp_ping;
19698   int ret;
19699
19700   if (!vam->json_output)
19701     {
19702       print (vam->ofp, "%=20s", "Map resolver");
19703     }
19704
19705   M (ONE_MAP_RESOLVER_DUMP, mp);
19706   /* send it... */
19707   S (mp);
19708
19709   /* Use a control ping for synchronization */
19710   MPING (CONTROL_PING, mp_ping);
19711   S (mp_ping);
19712
19713   /* Wait for a reply... */
19714   W (ret);
19715   return ret;
19716 }
19717
19718 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19719
19720 static int
19721 api_one_stats_flush (vat_main_t * vam)
19722 {
19723   vl_api_one_stats_flush_t *mp;
19724   int ret = 0;
19725
19726   M (ONE_STATS_FLUSH, mp);
19727   S (mp);
19728   W (ret);
19729   return ret;
19730 }
19731
19732 static int
19733 api_one_stats_dump (vat_main_t * vam)
19734 {
19735   vl_api_one_stats_dump_t *mp;
19736   vl_api_control_ping_t *mp_ping;
19737   int ret;
19738
19739   M (ONE_STATS_DUMP, mp);
19740   /* send it... */
19741   S (mp);
19742
19743   /* Use a control ping for synchronization */
19744   MPING (CONTROL_PING, mp_ping);
19745   S (mp_ping);
19746
19747   /* Wait for a reply... */
19748   W (ret);
19749   return ret;
19750 }
19751
19752 static int
19753 api_show_one_status (vat_main_t * vam)
19754 {
19755   vl_api_show_one_status_t *mp;
19756   int ret;
19757
19758   if (!vam->json_output)
19759     {
19760       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19761     }
19762
19763   M (SHOW_ONE_STATUS, mp);
19764   /* send it... */
19765   S (mp);
19766   /* Wait for a reply... */
19767   W (ret);
19768   return ret;
19769 }
19770
19771 #define api_show_lisp_status api_show_one_status
19772
19773 static int
19774 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19775 {
19776   vl_api_gpe_fwd_entry_path_dump_t *mp;
19777   vl_api_control_ping_t *mp_ping;
19778   unformat_input_t *i = vam->input;
19779   u32 fwd_entry_index = ~0;
19780   int ret;
19781
19782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19783     {
19784       if (unformat (i, "index %d", &fwd_entry_index))
19785         ;
19786       else
19787         break;
19788     }
19789
19790   if (~0 == fwd_entry_index)
19791     {
19792       errmsg ("no index specified!");
19793       return -99;
19794     }
19795
19796   if (!vam->json_output)
19797     {
19798       print (vam->ofp, "first line");
19799     }
19800
19801   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19802
19803   /* send it... */
19804   S (mp);
19805   /* Use a control ping for synchronization */
19806   MPING (CONTROL_PING, mp_ping);
19807   S (mp_ping);
19808
19809   /* Wait for a reply... */
19810   W (ret);
19811   return ret;
19812 }
19813
19814 static int
19815 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19816 {
19817   vl_api_one_get_map_request_itr_rlocs_t *mp;
19818   int ret;
19819
19820   if (!vam->json_output)
19821     {
19822       print (vam->ofp, "%=20s", "itr-rlocs:");
19823     }
19824
19825   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19826   /* send it... */
19827   S (mp);
19828   /* Wait for a reply... */
19829   W (ret);
19830   return ret;
19831 }
19832
19833 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19834
19835 static int
19836 api_af_packet_create (vat_main_t * vam)
19837 {
19838   unformat_input_t *i = vam->input;
19839   vl_api_af_packet_create_t *mp;
19840   u8 *host_if_name = 0;
19841   u8 hw_addr[6];
19842   u8 random_hw_addr = 1;
19843   int ret;
19844
19845   memset (hw_addr, 0, sizeof (hw_addr));
19846
19847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19848     {
19849       if (unformat (i, "name %s", &host_if_name))
19850         vec_add1 (host_if_name, 0);
19851       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19852         random_hw_addr = 0;
19853       else
19854         break;
19855     }
19856
19857   if (!vec_len (host_if_name))
19858     {
19859       errmsg ("host-interface name must be specified");
19860       return -99;
19861     }
19862
19863   if (vec_len (host_if_name) > 64)
19864     {
19865       errmsg ("host-interface name too long");
19866       return -99;
19867     }
19868
19869   M (AF_PACKET_CREATE, mp);
19870
19871   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19872   clib_memcpy (mp->hw_addr, hw_addr, 6);
19873   mp->use_random_hw_addr = random_hw_addr;
19874   vec_free (host_if_name);
19875
19876   S (mp);
19877
19878   /* *INDENT-OFF* */
19879   W2 (ret,
19880       ({
19881         if (ret == 0)
19882           fprintf (vam->ofp ? vam->ofp : stderr,
19883                    " new sw_if_index = %d\n", vam->sw_if_index);
19884       }));
19885   /* *INDENT-ON* */
19886   return ret;
19887 }
19888
19889 static int
19890 api_af_packet_delete (vat_main_t * vam)
19891 {
19892   unformat_input_t *i = vam->input;
19893   vl_api_af_packet_delete_t *mp;
19894   u8 *host_if_name = 0;
19895   int ret;
19896
19897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19898     {
19899       if (unformat (i, "name %s", &host_if_name))
19900         vec_add1 (host_if_name, 0);
19901       else
19902         break;
19903     }
19904
19905   if (!vec_len (host_if_name))
19906     {
19907       errmsg ("host-interface name must be specified");
19908       return -99;
19909     }
19910
19911   if (vec_len (host_if_name) > 64)
19912     {
19913       errmsg ("host-interface name too long");
19914       return -99;
19915     }
19916
19917   M (AF_PACKET_DELETE, mp);
19918
19919   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19920   vec_free (host_if_name);
19921
19922   S (mp);
19923   W (ret);
19924   return ret;
19925 }
19926
19927 static void vl_api_af_packet_details_t_handler
19928   (vl_api_af_packet_details_t * mp)
19929 {
19930   vat_main_t *vam = &vat_main;
19931
19932   print (vam->ofp, "%-16s %d",
19933          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19934 }
19935
19936 static void vl_api_af_packet_details_t_handler_json
19937   (vl_api_af_packet_details_t * mp)
19938 {
19939   vat_main_t *vam = &vat_main;
19940   vat_json_node_t *node = NULL;
19941
19942   if (VAT_JSON_ARRAY != vam->json_tree.type)
19943     {
19944       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19945       vat_json_init_array (&vam->json_tree);
19946     }
19947   node = vat_json_array_add (&vam->json_tree);
19948
19949   vat_json_init_object (node);
19950   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19951   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19952 }
19953
19954 static int
19955 api_af_packet_dump (vat_main_t * vam)
19956 {
19957   vl_api_af_packet_dump_t *mp;
19958   vl_api_control_ping_t *mp_ping;
19959   int ret;
19960
19961   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19962   /* Get list of tap interfaces */
19963   M (AF_PACKET_DUMP, mp);
19964   S (mp);
19965
19966   /* Use a control ping for synchronization */
19967   MPING (CONTROL_PING, mp_ping);
19968   S (mp_ping);
19969
19970   W (ret);
19971   return ret;
19972 }
19973
19974 static int
19975 api_policer_add_del (vat_main_t * vam)
19976 {
19977   unformat_input_t *i = vam->input;
19978   vl_api_policer_add_del_t *mp;
19979   u8 is_add = 1;
19980   u8 *name = 0;
19981   u32 cir = 0;
19982   u32 eir = 0;
19983   u64 cb = 0;
19984   u64 eb = 0;
19985   u8 rate_type = 0;
19986   u8 round_type = 0;
19987   u8 type = 0;
19988   u8 color_aware = 0;
19989   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19990   int ret;
19991
19992   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19993   conform_action.dscp = 0;
19994   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19995   exceed_action.dscp = 0;
19996   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19997   violate_action.dscp = 0;
19998
19999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20000     {
20001       if (unformat (i, "del"))
20002         is_add = 0;
20003       else if (unformat (i, "name %s", &name))
20004         vec_add1 (name, 0);
20005       else if (unformat (i, "cir %u", &cir))
20006         ;
20007       else if (unformat (i, "eir %u", &eir))
20008         ;
20009       else if (unformat (i, "cb %u", &cb))
20010         ;
20011       else if (unformat (i, "eb %u", &eb))
20012         ;
20013       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20014                          &rate_type))
20015         ;
20016       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20017                          &round_type))
20018         ;
20019       else if (unformat (i, "type %U", unformat_policer_type, &type))
20020         ;
20021       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20022                          &conform_action))
20023         ;
20024       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20025                          &exceed_action))
20026         ;
20027       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20028                          &violate_action))
20029         ;
20030       else if (unformat (i, "color-aware"))
20031         color_aware = 1;
20032       else
20033         break;
20034     }
20035
20036   if (!vec_len (name))
20037     {
20038       errmsg ("policer name must be specified");
20039       return -99;
20040     }
20041
20042   if (vec_len (name) > 64)
20043     {
20044       errmsg ("policer name too long");
20045       return -99;
20046     }
20047
20048   M (POLICER_ADD_DEL, mp);
20049
20050   clib_memcpy (mp->name, name, vec_len (name));
20051   vec_free (name);
20052   mp->is_add = is_add;
20053   mp->cir = ntohl (cir);
20054   mp->eir = ntohl (eir);
20055   mp->cb = clib_net_to_host_u64 (cb);
20056   mp->eb = clib_net_to_host_u64 (eb);
20057   mp->rate_type = rate_type;
20058   mp->round_type = round_type;
20059   mp->type = type;
20060   mp->conform_action_type = conform_action.action_type;
20061   mp->conform_dscp = conform_action.dscp;
20062   mp->exceed_action_type = exceed_action.action_type;
20063   mp->exceed_dscp = exceed_action.dscp;
20064   mp->violate_action_type = violate_action.action_type;
20065   mp->violate_dscp = violate_action.dscp;
20066   mp->color_aware = color_aware;
20067
20068   S (mp);
20069   W (ret);
20070   return ret;
20071 }
20072
20073 static int
20074 api_policer_dump (vat_main_t * vam)
20075 {
20076   unformat_input_t *i = vam->input;
20077   vl_api_policer_dump_t *mp;
20078   vl_api_control_ping_t *mp_ping;
20079   u8 *match_name = 0;
20080   u8 match_name_valid = 0;
20081   int ret;
20082
20083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20084     {
20085       if (unformat (i, "name %s", &match_name))
20086         {
20087           vec_add1 (match_name, 0);
20088           match_name_valid = 1;
20089         }
20090       else
20091         break;
20092     }
20093
20094   M (POLICER_DUMP, mp);
20095   mp->match_name_valid = match_name_valid;
20096   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20097   vec_free (match_name);
20098   /* send it... */
20099   S (mp);
20100
20101   /* Use a control ping for synchronization */
20102   MPING (CONTROL_PING, mp_ping);
20103   S (mp_ping);
20104
20105   /* Wait for a reply... */
20106   W (ret);
20107   return ret;
20108 }
20109
20110 static int
20111 api_policer_classify_set_interface (vat_main_t * vam)
20112 {
20113   unformat_input_t *i = vam->input;
20114   vl_api_policer_classify_set_interface_t *mp;
20115   u32 sw_if_index;
20116   int sw_if_index_set;
20117   u32 ip4_table_index = ~0;
20118   u32 ip6_table_index = ~0;
20119   u32 l2_table_index = ~0;
20120   u8 is_add = 1;
20121   int ret;
20122
20123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20124     {
20125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20126         sw_if_index_set = 1;
20127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20128         sw_if_index_set = 1;
20129       else if (unformat (i, "del"))
20130         is_add = 0;
20131       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20132         ;
20133       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20134         ;
20135       else if (unformat (i, "l2-table %d", &l2_table_index))
20136         ;
20137       else
20138         {
20139           clib_warning ("parse error '%U'", format_unformat_error, i);
20140           return -99;
20141         }
20142     }
20143
20144   if (sw_if_index_set == 0)
20145     {
20146       errmsg ("missing interface name or sw_if_index");
20147       return -99;
20148     }
20149
20150   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20151
20152   mp->sw_if_index = ntohl (sw_if_index);
20153   mp->ip4_table_index = ntohl (ip4_table_index);
20154   mp->ip6_table_index = ntohl (ip6_table_index);
20155   mp->l2_table_index = ntohl (l2_table_index);
20156   mp->is_add = is_add;
20157
20158   S (mp);
20159   W (ret);
20160   return ret;
20161 }
20162
20163 static int
20164 api_policer_classify_dump (vat_main_t * vam)
20165 {
20166   unformat_input_t *i = vam->input;
20167   vl_api_policer_classify_dump_t *mp;
20168   vl_api_control_ping_t *mp_ping;
20169   u8 type = POLICER_CLASSIFY_N_TABLES;
20170   int ret;
20171
20172   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20173     ;
20174   else
20175     {
20176       errmsg ("classify table type must be specified");
20177       return -99;
20178     }
20179
20180   if (!vam->json_output)
20181     {
20182       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20183     }
20184
20185   M (POLICER_CLASSIFY_DUMP, mp);
20186   mp->type = type;
20187   /* send it... */
20188   S (mp);
20189
20190   /* Use a control ping for synchronization */
20191   MPING (CONTROL_PING, mp_ping);
20192   S (mp_ping);
20193
20194   /* Wait for a reply... */
20195   W (ret);
20196   return ret;
20197 }
20198
20199 static int
20200 api_netmap_create (vat_main_t * vam)
20201 {
20202   unformat_input_t *i = vam->input;
20203   vl_api_netmap_create_t *mp;
20204   u8 *if_name = 0;
20205   u8 hw_addr[6];
20206   u8 random_hw_addr = 1;
20207   u8 is_pipe = 0;
20208   u8 is_master = 0;
20209   int ret;
20210
20211   memset (hw_addr, 0, sizeof (hw_addr));
20212
20213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20214     {
20215       if (unformat (i, "name %s", &if_name))
20216         vec_add1 (if_name, 0);
20217       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20218         random_hw_addr = 0;
20219       else if (unformat (i, "pipe"))
20220         is_pipe = 1;
20221       else if (unformat (i, "master"))
20222         is_master = 1;
20223       else if (unformat (i, "slave"))
20224         is_master = 0;
20225       else
20226         break;
20227     }
20228
20229   if (!vec_len (if_name))
20230     {
20231       errmsg ("interface name must be specified");
20232       return -99;
20233     }
20234
20235   if (vec_len (if_name) > 64)
20236     {
20237       errmsg ("interface name too long");
20238       return -99;
20239     }
20240
20241   M (NETMAP_CREATE, mp);
20242
20243   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20244   clib_memcpy (mp->hw_addr, hw_addr, 6);
20245   mp->use_random_hw_addr = random_hw_addr;
20246   mp->is_pipe = is_pipe;
20247   mp->is_master = is_master;
20248   vec_free (if_name);
20249
20250   S (mp);
20251   W (ret);
20252   return ret;
20253 }
20254
20255 static int
20256 api_netmap_delete (vat_main_t * vam)
20257 {
20258   unformat_input_t *i = vam->input;
20259   vl_api_netmap_delete_t *mp;
20260   u8 *if_name = 0;
20261   int ret;
20262
20263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20264     {
20265       if (unformat (i, "name %s", &if_name))
20266         vec_add1 (if_name, 0);
20267       else
20268         break;
20269     }
20270
20271   if (!vec_len (if_name))
20272     {
20273       errmsg ("interface name must be specified");
20274       return -99;
20275     }
20276
20277   if (vec_len (if_name) > 64)
20278     {
20279       errmsg ("interface name too long");
20280       return -99;
20281     }
20282
20283   M (NETMAP_DELETE, mp);
20284
20285   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20286   vec_free (if_name);
20287
20288   S (mp);
20289   W (ret);
20290   return ret;
20291 }
20292
20293 static void
20294 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20295 {
20296   if (fp->afi == IP46_TYPE_IP6)
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_ip6_address, fp->next_hop);
20303   else if (fp->afi == IP46_TYPE_IP4)
20304     print (vam->ofp,
20305            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20306            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20307            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20308            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20309            format_ip4_address, fp->next_hop);
20310 }
20311
20312 static void
20313 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20314                                  vl_api_fib_path_t * fp)
20315 {
20316   struct in_addr ip4;
20317   struct in6_addr ip6;
20318
20319   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20320   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20321   vat_json_object_add_uint (node, "is_local", fp->is_local);
20322   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20323   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20324   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20325   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20326   if (fp->afi == IP46_TYPE_IP4)
20327     {
20328       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20329       vat_json_object_add_ip4 (node, "next_hop", ip4);
20330     }
20331   else if (fp->afi == IP46_TYPE_IP6)
20332     {
20333       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20334       vat_json_object_add_ip6 (node, "next_hop", ip6);
20335     }
20336 }
20337
20338 static void
20339 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20340 {
20341   vat_main_t *vam = &vat_main;
20342   int count = ntohl (mp->mt_count);
20343   vl_api_fib_path_t *fp;
20344   i32 i;
20345
20346   print (vam->ofp, "[%d]: sw_if_index %d via:",
20347          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20348   fp = mp->mt_paths;
20349   for (i = 0; i < count; i++)
20350     {
20351       vl_api_mpls_fib_path_print (vam, fp);
20352       fp++;
20353     }
20354
20355   print (vam->ofp, "");
20356 }
20357
20358 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20359 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20360
20361 static void
20362 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20363 {
20364   vat_main_t *vam = &vat_main;
20365   vat_json_node_t *node = NULL;
20366   int count = ntohl (mp->mt_count);
20367   vl_api_fib_path_t *fp;
20368   i32 i;
20369
20370   if (VAT_JSON_ARRAY != vam->json_tree.type)
20371     {
20372       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20373       vat_json_init_array (&vam->json_tree);
20374     }
20375   node = vat_json_array_add (&vam->json_tree);
20376
20377   vat_json_init_object (node);
20378   vat_json_object_add_uint (node, "tunnel_index",
20379                             ntohl (mp->mt_tunnel_index));
20380   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20381
20382   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20383
20384   fp = mp->mt_paths;
20385   for (i = 0; i < count; i++)
20386     {
20387       vl_api_mpls_fib_path_json_print (node, fp);
20388       fp++;
20389     }
20390 }
20391
20392 static int
20393 api_mpls_tunnel_dump (vat_main_t * vam)
20394 {
20395   vl_api_mpls_tunnel_dump_t *mp;
20396   vl_api_control_ping_t *mp_ping;
20397   i32 index = -1;
20398   int ret;
20399
20400   /* Parse args required to build the message */
20401   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20402     {
20403       if (!unformat (vam->input, "tunnel_index %d", &index))
20404         {
20405           index = -1;
20406           break;
20407         }
20408     }
20409
20410   print (vam->ofp, "  tunnel_index %d", index);
20411
20412   M (MPLS_TUNNEL_DUMP, mp);
20413   mp->tunnel_index = htonl (index);
20414   S (mp);
20415
20416   /* Use a control ping for synchronization */
20417   MPING (CONTROL_PING, mp_ping);
20418   S (mp_ping);
20419
20420   W (ret);
20421   return ret;
20422 }
20423
20424 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20425 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20426
20427
20428 static void
20429 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20430 {
20431   vat_main_t *vam = &vat_main;
20432   int count = ntohl (mp->count);
20433   vl_api_fib_path_t *fp;
20434   int i;
20435
20436   print (vam->ofp,
20437          "table-id %d, label %u, ess_bit %u",
20438          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20439   fp = mp->path;
20440   for (i = 0; i < count; i++)
20441     {
20442       vl_api_mpls_fib_path_print (vam, fp);
20443       fp++;
20444     }
20445 }
20446
20447 static void vl_api_mpls_fib_details_t_handler_json
20448   (vl_api_mpls_fib_details_t * mp)
20449 {
20450   vat_main_t *vam = &vat_main;
20451   int count = ntohl (mp->count);
20452   vat_json_node_t *node = NULL;
20453   vl_api_fib_path_t *fp;
20454   int i;
20455
20456   if (VAT_JSON_ARRAY != vam->json_tree.type)
20457     {
20458       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20459       vat_json_init_array (&vam->json_tree);
20460     }
20461   node = vat_json_array_add (&vam->json_tree);
20462
20463   vat_json_init_object (node);
20464   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20465   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20466   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20467   vat_json_object_add_uint (node, "path_count", count);
20468   fp = mp->path;
20469   for (i = 0; i < count; i++)
20470     {
20471       vl_api_mpls_fib_path_json_print (node, fp);
20472       fp++;
20473     }
20474 }
20475
20476 static int
20477 api_mpls_fib_dump (vat_main_t * vam)
20478 {
20479   vl_api_mpls_fib_dump_t *mp;
20480   vl_api_control_ping_t *mp_ping;
20481   int ret;
20482
20483   M (MPLS_FIB_DUMP, mp);
20484   S (mp);
20485
20486   /* Use a control ping for synchronization */
20487   MPING (CONTROL_PING, mp_ping);
20488   S (mp_ping);
20489
20490   W (ret);
20491   return ret;
20492 }
20493
20494 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20495 #define vl_api_ip_fib_details_t_print vl_noop_handler
20496
20497 static void
20498 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20499 {
20500   vat_main_t *vam = &vat_main;
20501   int count = ntohl (mp->count);
20502   vl_api_fib_path_t *fp;
20503   int i;
20504
20505   print (vam->ofp,
20506          "table-id %d, prefix %U/%d",
20507          ntohl (mp->table_id), format_ip4_address, mp->address,
20508          mp->address_length);
20509   fp = mp->path;
20510   for (i = 0; i < count; i++)
20511     {
20512       if (fp->afi == IP46_TYPE_IP6)
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_ip6_address, fp->next_hop);
20519       else if (fp->afi == IP46_TYPE_IP4)
20520         print (vam->ofp,
20521                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20522                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20523                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20524                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20525                format_ip4_address, fp->next_hop);
20526       fp++;
20527     }
20528 }
20529
20530 static void vl_api_ip_fib_details_t_handler_json
20531   (vl_api_ip_fib_details_t * mp)
20532 {
20533   vat_main_t *vam = &vat_main;
20534   int count = ntohl (mp->count);
20535   vat_json_node_t *node = NULL;
20536   struct in_addr ip4;
20537   struct in6_addr ip6;
20538   vl_api_fib_path_t *fp;
20539   int i;
20540
20541   if (VAT_JSON_ARRAY != vam->json_tree.type)
20542     {
20543       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20544       vat_json_init_array (&vam->json_tree);
20545     }
20546   node = vat_json_array_add (&vam->json_tree);
20547
20548   vat_json_init_object (node);
20549   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20550   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20551   vat_json_object_add_ip4 (node, "prefix", ip4);
20552   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20553   vat_json_object_add_uint (node, "path_count", count);
20554   fp = mp->path;
20555   for (i = 0; i < count; i++)
20556     {
20557       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20558       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20559       vat_json_object_add_uint (node, "is_local", fp->is_local);
20560       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20561       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20562       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20563       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20564       if (fp->afi == IP46_TYPE_IP4)
20565         {
20566           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20567           vat_json_object_add_ip4 (node, "next_hop", ip4);
20568         }
20569       else if (fp->afi == IP46_TYPE_IP6)
20570         {
20571           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20572           vat_json_object_add_ip6 (node, "next_hop", ip6);
20573         }
20574     }
20575 }
20576
20577 static int
20578 api_ip_fib_dump (vat_main_t * vam)
20579 {
20580   vl_api_ip_fib_dump_t *mp;
20581   vl_api_control_ping_t *mp_ping;
20582   int ret;
20583
20584   M (IP_FIB_DUMP, mp);
20585   S (mp);
20586
20587   /* Use a control ping for synchronization */
20588   MPING (CONTROL_PING, mp_ping);
20589   S (mp_ping);
20590
20591   W (ret);
20592   return ret;
20593 }
20594
20595 static int
20596 api_ip_mfib_dump (vat_main_t * vam)
20597 {
20598   vl_api_ip_mfib_dump_t *mp;
20599   vl_api_control_ping_t *mp_ping;
20600   int ret;
20601
20602   M (IP_MFIB_DUMP, mp);
20603   S (mp);
20604
20605   /* Use a control ping for synchronization */
20606   MPING (CONTROL_PING, mp_ping);
20607   S (mp_ping);
20608
20609   W (ret);
20610   return ret;
20611 }
20612
20613 static void vl_api_ip_neighbor_details_t_handler
20614   (vl_api_ip_neighbor_details_t * mp)
20615 {
20616   vat_main_t *vam = &vat_main;
20617
20618   print (vam->ofp, "%c %U %U",
20619          (mp->is_static) ? 'S' : 'D',
20620          format_ethernet_address, &mp->mac_address,
20621          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20622          &mp->ip_address);
20623 }
20624
20625 static void vl_api_ip_neighbor_details_t_handler_json
20626   (vl_api_ip_neighbor_details_t * mp)
20627 {
20628
20629   vat_main_t *vam = &vat_main;
20630   vat_json_node_t *node;
20631   struct in_addr ip4;
20632   struct in6_addr ip6;
20633
20634   if (VAT_JSON_ARRAY != vam->json_tree.type)
20635     {
20636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20637       vat_json_init_array (&vam->json_tree);
20638     }
20639   node = vat_json_array_add (&vam->json_tree);
20640
20641   vat_json_init_object (node);
20642   vat_json_object_add_string_copy (node, "flag",
20643                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20644                                    "dynamic");
20645
20646   vat_json_object_add_string_copy (node, "link_layer",
20647                                    format (0, "%U", format_ethernet_address,
20648                                            &mp->mac_address));
20649
20650   if (mp->is_ipv6)
20651     {
20652       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20653       vat_json_object_add_ip6 (node, "ip_address", ip6);
20654     }
20655   else
20656     {
20657       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20658       vat_json_object_add_ip4 (node, "ip_address", ip4);
20659     }
20660 }
20661
20662 static int
20663 api_ip_neighbor_dump (vat_main_t * vam)
20664 {
20665   unformat_input_t *i = vam->input;
20666   vl_api_ip_neighbor_dump_t *mp;
20667   vl_api_control_ping_t *mp_ping;
20668   u8 is_ipv6 = 0;
20669   u32 sw_if_index = ~0;
20670   int ret;
20671
20672   /* Parse args required to build the message */
20673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20674     {
20675       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20676         ;
20677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20678         ;
20679       else if (unformat (i, "ip6"))
20680         is_ipv6 = 1;
20681       else
20682         break;
20683     }
20684
20685   if (sw_if_index == ~0)
20686     {
20687       errmsg ("missing interface name or sw_if_index");
20688       return -99;
20689     }
20690
20691   M (IP_NEIGHBOR_DUMP, mp);
20692   mp->is_ipv6 = (u8) is_ipv6;
20693   mp->sw_if_index = ntohl (sw_if_index);
20694   S (mp);
20695
20696   /* Use a control ping for synchronization */
20697   MPING (CONTROL_PING, mp_ping);
20698   S (mp_ping);
20699
20700   W (ret);
20701   return ret;
20702 }
20703
20704 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20705 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20706
20707 static void
20708 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20709 {
20710   vat_main_t *vam = &vat_main;
20711   int count = ntohl (mp->count);
20712   vl_api_fib_path_t *fp;
20713   int i;
20714
20715   print (vam->ofp,
20716          "table-id %d, prefix %U/%d",
20717          ntohl (mp->table_id), format_ip6_address, mp->address,
20718          mp->address_length);
20719   fp = mp->path;
20720   for (i = 0; i < count; i++)
20721     {
20722       if (fp->afi == IP46_TYPE_IP6)
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_ip6_address, fp->next_hop);
20729       else if (fp->afi == IP46_TYPE_IP4)
20730         print (vam->ofp,
20731                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20732                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20733                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20734                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20735                format_ip4_address, fp->next_hop);
20736       fp++;
20737     }
20738 }
20739
20740 static void vl_api_ip6_fib_details_t_handler_json
20741   (vl_api_ip6_fib_details_t * mp)
20742 {
20743   vat_main_t *vam = &vat_main;
20744   int count = ntohl (mp->count);
20745   vat_json_node_t *node = NULL;
20746   struct in_addr ip4;
20747   struct in6_addr ip6;
20748   vl_api_fib_path_t *fp;
20749   int i;
20750
20751   if (VAT_JSON_ARRAY != vam->json_tree.type)
20752     {
20753       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20754       vat_json_init_array (&vam->json_tree);
20755     }
20756   node = vat_json_array_add (&vam->json_tree);
20757
20758   vat_json_init_object (node);
20759   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20760   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20761   vat_json_object_add_ip6 (node, "prefix", ip6);
20762   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20763   vat_json_object_add_uint (node, "path_count", count);
20764   fp = mp->path;
20765   for (i = 0; i < count; i++)
20766     {
20767       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20768       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20769       vat_json_object_add_uint (node, "is_local", fp->is_local);
20770       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20771       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20772       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20773       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20774       if (fp->afi == IP46_TYPE_IP4)
20775         {
20776           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20777           vat_json_object_add_ip4 (node, "next_hop", ip4);
20778         }
20779       else if (fp->afi == IP46_TYPE_IP6)
20780         {
20781           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20782           vat_json_object_add_ip6 (node, "next_hop", ip6);
20783         }
20784     }
20785 }
20786
20787 static int
20788 api_ip6_fib_dump (vat_main_t * vam)
20789 {
20790   vl_api_ip6_fib_dump_t *mp;
20791   vl_api_control_ping_t *mp_ping;
20792   int ret;
20793
20794   M (IP6_FIB_DUMP, mp);
20795   S (mp);
20796
20797   /* Use a control ping for synchronization */
20798   MPING (CONTROL_PING, mp_ping);
20799   S (mp_ping);
20800
20801   W (ret);
20802   return ret;
20803 }
20804
20805 static int
20806 api_ip6_mfib_dump (vat_main_t * vam)
20807 {
20808   vl_api_ip6_mfib_dump_t *mp;
20809   vl_api_control_ping_t *mp_ping;
20810   int ret;
20811
20812   M (IP6_MFIB_DUMP, mp);
20813   S (mp);
20814
20815   /* Use a control ping for synchronization */
20816   MPING (CONTROL_PING, mp_ping);
20817   S (mp_ping);
20818
20819   W (ret);
20820   return ret;
20821 }
20822
20823 int
20824 api_classify_table_ids (vat_main_t * vam)
20825 {
20826   vl_api_classify_table_ids_t *mp;
20827   int ret;
20828
20829   /* Construct the API message */
20830   M (CLASSIFY_TABLE_IDS, mp);
20831   mp->context = 0;
20832
20833   S (mp);
20834   W (ret);
20835   return ret;
20836 }
20837
20838 int
20839 api_classify_table_by_interface (vat_main_t * vam)
20840 {
20841   unformat_input_t *input = vam->input;
20842   vl_api_classify_table_by_interface_t *mp;
20843
20844   u32 sw_if_index = ~0;
20845   int ret;
20846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20847     {
20848       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20849         ;
20850       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20851         ;
20852       else
20853         break;
20854     }
20855   if (sw_if_index == ~0)
20856     {
20857       errmsg ("missing interface name or sw_if_index");
20858       return -99;
20859     }
20860
20861   /* Construct the API message */
20862   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20863   mp->context = 0;
20864   mp->sw_if_index = ntohl (sw_if_index);
20865
20866   S (mp);
20867   W (ret);
20868   return ret;
20869 }
20870
20871 int
20872 api_classify_table_info (vat_main_t * vam)
20873 {
20874   unformat_input_t *input = vam->input;
20875   vl_api_classify_table_info_t *mp;
20876
20877   u32 table_id = ~0;
20878   int ret;
20879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20880     {
20881       if (unformat (input, "table_id %d", &table_id))
20882         ;
20883       else
20884         break;
20885     }
20886   if (table_id == ~0)
20887     {
20888       errmsg ("missing table id");
20889       return -99;
20890     }
20891
20892   /* Construct the API message */
20893   M (CLASSIFY_TABLE_INFO, mp);
20894   mp->context = 0;
20895   mp->table_id = ntohl (table_id);
20896
20897   S (mp);
20898   W (ret);
20899   return ret;
20900 }
20901
20902 int
20903 api_classify_session_dump (vat_main_t * vam)
20904 {
20905   unformat_input_t *input = vam->input;
20906   vl_api_classify_session_dump_t *mp;
20907   vl_api_control_ping_t *mp_ping;
20908
20909   u32 table_id = ~0;
20910   int ret;
20911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20912     {
20913       if (unformat (input, "table_id %d", &table_id))
20914         ;
20915       else
20916         break;
20917     }
20918   if (table_id == ~0)
20919     {
20920       errmsg ("missing table id");
20921       return -99;
20922     }
20923
20924   /* Construct the API message */
20925   M (CLASSIFY_SESSION_DUMP, mp);
20926   mp->context = 0;
20927   mp->table_id = ntohl (table_id);
20928   S (mp);
20929
20930   /* Use a control ping for synchronization */
20931   MPING (CONTROL_PING, mp_ping);
20932   S (mp_ping);
20933
20934   W (ret);
20935   return ret;
20936 }
20937
20938 static void
20939 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20940 {
20941   vat_main_t *vam = &vat_main;
20942
20943   print (vam->ofp, "collector_address %U, collector_port %d, "
20944          "src_address %U, vrf_id %d, path_mtu %u, "
20945          "template_interval %u, udp_checksum %d",
20946          format_ip4_address, mp->collector_address,
20947          ntohs (mp->collector_port),
20948          format_ip4_address, mp->src_address,
20949          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20950          ntohl (mp->template_interval), mp->udp_checksum);
20951
20952   vam->retval = 0;
20953   vam->result_ready = 1;
20954 }
20955
20956 static void
20957   vl_api_ipfix_exporter_details_t_handler_json
20958   (vl_api_ipfix_exporter_details_t * mp)
20959 {
20960   vat_main_t *vam = &vat_main;
20961   vat_json_node_t node;
20962   struct in_addr collector_address;
20963   struct in_addr src_address;
20964
20965   vat_json_init_object (&node);
20966   clib_memcpy (&collector_address, &mp->collector_address,
20967                sizeof (collector_address));
20968   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20969   vat_json_object_add_uint (&node, "collector_port",
20970                             ntohs (mp->collector_port));
20971   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20972   vat_json_object_add_ip4 (&node, "src_address", src_address);
20973   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20974   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20975   vat_json_object_add_uint (&node, "template_interval",
20976                             ntohl (mp->template_interval));
20977   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20978
20979   vat_json_print (vam->ofp, &node);
20980   vat_json_free (&node);
20981   vam->retval = 0;
20982   vam->result_ready = 1;
20983 }
20984
20985 int
20986 api_ipfix_exporter_dump (vat_main_t * vam)
20987 {
20988   vl_api_ipfix_exporter_dump_t *mp;
20989   int ret;
20990
20991   /* Construct the API message */
20992   M (IPFIX_EXPORTER_DUMP, mp);
20993   mp->context = 0;
20994
20995   S (mp);
20996   W (ret);
20997   return ret;
20998 }
20999
21000 static int
21001 api_ipfix_classify_stream_dump (vat_main_t * vam)
21002 {
21003   vl_api_ipfix_classify_stream_dump_t *mp;
21004   int ret;
21005
21006   /* Construct the API message */
21007   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21008   mp->context = 0;
21009
21010   S (mp);
21011   W (ret);
21012   return ret;
21013   /* NOTREACHED */
21014   return 0;
21015 }
21016
21017 static void
21018   vl_api_ipfix_classify_stream_details_t_handler
21019   (vl_api_ipfix_classify_stream_details_t * mp)
21020 {
21021   vat_main_t *vam = &vat_main;
21022   print (vam->ofp, "domain_id %d, src_port %d",
21023          ntohl (mp->domain_id), ntohs (mp->src_port));
21024   vam->retval = 0;
21025   vam->result_ready = 1;
21026 }
21027
21028 static void
21029   vl_api_ipfix_classify_stream_details_t_handler_json
21030   (vl_api_ipfix_classify_stream_details_t * mp)
21031 {
21032   vat_main_t *vam = &vat_main;
21033   vat_json_node_t node;
21034
21035   vat_json_init_object (&node);
21036   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21037   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21038
21039   vat_json_print (vam->ofp, &node);
21040   vat_json_free (&node);
21041   vam->retval = 0;
21042   vam->result_ready = 1;
21043 }
21044
21045 static int
21046 api_ipfix_classify_table_dump (vat_main_t * vam)
21047 {
21048   vl_api_ipfix_classify_table_dump_t *mp;
21049   vl_api_control_ping_t *mp_ping;
21050   int ret;
21051
21052   if (!vam->json_output)
21053     {
21054       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21055              "transport_protocol");
21056     }
21057
21058   /* Construct the API message */
21059   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21060
21061   /* send it... */
21062   S (mp);
21063
21064   /* Use a control ping for synchronization */
21065   MPING (CONTROL_PING, mp_ping);
21066   S (mp_ping);
21067
21068   W (ret);
21069   return ret;
21070 }
21071
21072 static void
21073   vl_api_ipfix_classify_table_details_t_handler
21074   (vl_api_ipfix_classify_table_details_t * mp)
21075 {
21076   vat_main_t *vam = &vat_main;
21077   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21078          mp->transport_protocol);
21079 }
21080
21081 static void
21082   vl_api_ipfix_classify_table_details_t_handler_json
21083   (vl_api_ipfix_classify_table_details_t * mp)
21084 {
21085   vat_json_node_t *node = NULL;
21086   vat_main_t *vam = &vat_main;
21087
21088   if (VAT_JSON_ARRAY != vam->json_tree.type)
21089     {
21090       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21091       vat_json_init_array (&vam->json_tree);
21092     }
21093
21094   node = vat_json_array_add (&vam->json_tree);
21095   vat_json_init_object (node);
21096
21097   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21098   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21099   vat_json_object_add_uint (node, "transport_protocol",
21100                             mp->transport_protocol);
21101 }
21102
21103 static int
21104 api_sw_interface_span_enable_disable (vat_main_t * vam)
21105 {
21106   unformat_input_t *i = vam->input;
21107   vl_api_sw_interface_span_enable_disable_t *mp;
21108   u32 src_sw_if_index = ~0;
21109   u32 dst_sw_if_index = ~0;
21110   u8 state = 3;
21111   int ret;
21112   u8 is_l2 = 0;
21113
21114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21115     {
21116       if (unformat
21117           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21118         ;
21119       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21120         ;
21121       else
21122         if (unformat
21123             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21124         ;
21125       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21126         ;
21127       else if (unformat (i, "disable"))
21128         state = 0;
21129       else if (unformat (i, "rx"))
21130         state = 1;
21131       else if (unformat (i, "tx"))
21132         state = 2;
21133       else if (unformat (i, "both"))
21134         state = 3;
21135       else if (unformat (i, "l2"))
21136         is_l2 = 1;
21137       else
21138         break;
21139     }
21140
21141   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21142
21143   mp->sw_if_index_from = htonl (src_sw_if_index);
21144   mp->sw_if_index_to = htonl (dst_sw_if_index);
21145   mp->state = state;
21146   mp->is_l2 = is_l2;
21147
21148   S (mp);
21149   W (ret);
21150   return ret;
21151 }
21152
21153 static void
21154 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21155                                             * mp)
21156 {
21157   vat_main_t *vam = &vat_main;
21158   u8 *sw_if_from_name = 0;
21159   u8 *sw_if_to_name = 0;
21160   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21161   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21162   char *states[] = { "none", "rx", "tx", "both" };
21163   hash_pair_t *p;
21164
21165   /* *INDENT-OFF* */
21166   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21167   ({
21168     if ((u32) p->value[0] == sw_if_index_from)
21169       {
21170         sw_if_from_name = (u8 *)(p->key);
21171         if (sw_if_to_name)
21172           break;
21173       }
21174     if ((u32) p->value[0] == sw_if_index_to)
21175       {
21176         sw_if_to_name = (u8 *)(p->key);
21177         if (sw_if_from_name)
21178           break;
21179       }
21180   }));
21181   /* *INDENT-ON* */
21182   print (vam->ofp, "%20s => %20s (%s) %s",
21183          sw_if_from_name, sw_if_to_name, states[mp->state],
21184          mp->is_l2 ? "l2" : "device");
21185 }
21186
21187 static void
21188   vl_api_sw_interface_span_details_t_handler_json
21189   (vl_api_sw_interface_span_details_t * mp)
21190 {
21191   vat_main_t *vam = &vat_main;
21192   vat_json_node_t *node = NULL;
21193   u8 *sw_if_from_name = 0;
21194   u8 *sw_if_to_name = 0;
21195   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21196   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21197   hash_pair_t *p;
21198
21199   /* *INDENT-OFF* */
21200   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21201   ({
21202     if ((u32) p->value[0] == sw_if_index_from)
21203       {
21204         sw_if_from_name = (u8 *)(p->key);
21205         if (sw_if_to_name)
21206           break;
21207       }
21208     if ((u32) p->value[0] == sw_if_index_to)
21209       {
21210         sw_if_to_name = (u8 *)(p->key);
21211         if (sw_if_from_name)
21212           break;
21213       }
21214   }));
21215   /* *INDENT-ON* */
21216
21217   if (VAT_JSON_ARRAY != vam->json_tree.type)
21218     {
21219       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21220       vat_json_init_array (&vam->json_tree);
21221     }
21222   node = vat_json_array_add (&vam->json_tree);
21223
21224   vat_json_init_object (node);
21225   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21226   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21227   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21228   if (0 != sw_if_to_name)
21229     {
21230       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21231     }
21232   vat_json_object_add_uint (node, "state", mp->state);
21233   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21234 }
21235
21236 static int
21237 api_sw_interface_span_dump (vat_main_t * vam)
21238 {
21239   unformat_input_t *input = vam->input;
21240   vl_api_sw_interface_span_dump_t *mp;
21241   vl_api_control_ping_t *mp_ping;
21242   u8 is_l2 = 0;
21243   int ret;
21244
21245   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21246     {
21247       if (unformat (input, "l2"))
21248         is_l2 = 1;
21249       else
21250         break;
21251     }
21252
21253   M (SW_INTERFACE_SPAN_DUMP, mp);
21254   mp->is_l2 = is_l2;
21255   S (mp);
21256
21257   /* Use a control ping for synchronization */
21258   MPING (CONTROL_PING, mp_ping);
21259   S (mp_ping);
21260
21261   W (ret);
21262   return ret;
21263 }
21264
21265 int
21266 api_pg_create_interface (vat_main_t * vam)
21267 {
21268   unformat_input_t *input = vam->input;
21269   vl_api_pg_create_interface_t *mp;
21270
21271   u32 if_id = ~0;
21272   int ret;
21273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21274     {
21275       if (unformat (input, "if_id %d", &if_id))
21276         ;
21277       else
21278         break;
21279     }
21280   if (if_id == ~0)
21281     {
21282       errmsg ("missing pg interface index");
21283       return -99;
21284     }
21285
21286   /* Construct the API message */
21287   M (PG_CREATE_INTERFACE, mp);
21288   mp->context = 0;
21289   mp->interface_id = ntohl (if_id);
21290
21291   S (mp);
21292   W (ret);
21293   return ret;
21294 }
21295
21296 int
21297 api_pg_capture (vat_main_t * vam)
21298 {
21299   unformat_input_t *input = vam->input;
21300   vl_api_pg_capture_t *mp;
21301
21302   u32 if_id = ~0;
21303   u8 enable = 1;
21304   u32 count = 1;
21305   u8 pcap_file_set = 0;
21306   u8 *pcap_file = 0;
21307   int ret;
21308   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21309     {
21310       if (unformat (input, "if_id %d", &if_id))
21311         ;
21312       else if (unformat (input, "pcap %s", &pcap_file))
21313         pcap_file_set = 1;
21314       else if (unformat (input, "count %d", &count))
21315         ;
21316       else if (unformat (input, "disable"))
21317         enable = 0;
21318       else
21319         break;
21320     }
21321   if (if_id == ~0)
21322     {
21323       errmsg ("missing pg interface index");
21324       return -99;
21325     }
21326   if (pcap_file_set > 0)
21327     {
21328       if (vec_len (pcap_file) > 255)
21329         {
21330           errmsg ("pcap file name is too long");
21331           return -99;
21332         }
21333     }
21334
21335   u32 name_len = vec_len (pcap_file);
21336   /* Construct the API message */
21337   M (PG_CAPTURE, mp);
21338   mp->context = 0;
21339   mp->interface_id = ntohl (if_id);
21340   mp->is_enabled = enable;
21341   mp->count = ntohl (count);
21342   mp->pcap_name_length = ntohl (name_len);
21343   if (pcap_file_set != 0)
21344     {
21345       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21346     }
21347   vec_free (pcap_file);
21348
21349   S (mp);
21350   W (ret);
21351   return ret;
21352 }
21353
21354 int
21355 api_pg_enable_disable (vat_main_t * vam)
21356 {
21357   unformat_input_t *input = vam->input;
21358   vl_api_pg_enable_disable_t *mp;
21359
21360   u8 enable = 1;
21361   u8 stream_name_set = 0;
21362   u8 *stream_name = 0;
21363   int ret;
21364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21365     {
21366       if (unformat (input, "stream %s", &stream_name))
21367         stream_name_set = 1;
21368       else if (unformat (input, "disable"))
21369         enable = 0;
21370       else
21371         break;
21372     }
21373
21374   if (stream_name_set > 0)
21375     {
21376       if (vec_len (stream_name) > 255)
21377         {
21378           errmsg ("stream name too long");
21379           return -99;
21380         }
21381     }
21382
21383   u32 name_len = vec_len (stream_name);
21384   /* Construct the API message */
21385   M (PG_ENABLE_DISABLE, mp);
21386   mp->context = 0;
21387   mp->is_enabled = enable;
21388   if (stream_name_set != 0)
21389     {
21390       mp->stream_name_length = ntohl (name_len);
21391       clib_memcpy (mp->stream_name, stream_name, name_len);
21392     }
21393   vec_free (stream_name);
21394
21395   S (mp);
21396   W (ret);
21397   return ret;
21398 }
21399
21400 int
21401 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21402 {
21403   unformat_input_t *input = vam->input;
21404   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21405
21406   u16 *low_ports = 0;
21407   u16 *high_ports = 0;
21408   u16 this_low;
21409   u16 this_hi;
21410   ip4_address_t ip4_addr;
21411   ip6_address_t ip6_addr;
21412   u32 length;
21413   u32 tmp, tmp2;
21414   u8 prefix_set = 0;
21415   u32 vrf_id = ~0;
21416   u8 is_add = 1;
21417   u8 is_ipv6 = 0;
21418   int ret;
21419
21420   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21421     {
21422       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21423         {
21424           prefix_set = 1;
21425         }
21426       else
21427         if (unformat
21428             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21429         {
21430           prefix_set = 1;
21431           is_ipv6 = 1;
21432         }
21433       else if (unformat (input, "vrf %d", &vrf_id))
21434         ;
21435       else if (unformat (input, "del"))
21436         is_add = 0;
21437       else if (unformat (input, "port %d", &tmp))
21438         {
21439           if (tmp == 0 || tmp > 65535)
21440             {
21441               errmsg ("port %d out of range", tmp);
21442               return -99;
21443             }
21444           this_low = tmp;
21445           this_hi = this_low + 1;
21446           vec_add1 (low_ports, this_low);
21447           vec_add1 (high_ports, this_hi);
21448         }
21449       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21450         {
21451           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21452             {
21453               errmsg ("incorrect range parameters");
21454               return -99;
21455             }
21456           this_low = tmp;
21457           /* Note: in debug CLI +1 is added to high before
21458              passing to real fn that does "the work"
21459              (ip_source_and_port_range_check_add_del).
21460              This fn is a wrapper around the binary API fn a
21461              control plane will call, which expects this increment
21462              to have occurred. Hence letting the binary API control
21463              plane fn do the increment for consistency between VAT
21464              and other control planes.
21465            */
21466           this_hi = tmp2;
21467           vec_add1 (low_ports, this_low);
21468           vec_add1 (high_ports, this_hi);
21469         }
21470       else
21471         break;
21472     }
21473
21474   if (prefix_set == 0)
21475     {
21476       errmsg ("<address>/<mask> not specified");
21477       return -99;
21478     }
21479
21480   if (vrf_id == ~0)
21481     {
21482       errmsg ("VRF ID required, not specified");
21483       return -99;
21484     }
21485
21486   if (vrf_id == 0)
21487     {
21488       errmsg
21489         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21490       return -99;
21491     }
21492
21493   if (vec_len (low_ports) == 0)
21494     {
21495       errmsg ("At least one port or port range required");
21496       return -99;
21497     }
21498
21499   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21500
21501   mp->is_add = is_add;
21502
21503   if (is_ipv6)
21504     {
21505       mp->is_ipv6 = 1;
21506       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21507     }
21508   else
21509     {
21510       mp->is_ipv6 = 0;
21511       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21512     }
21513
21514   mp->mask_length = length;
21515   mp->number_of_ranges = vec_len (low_ports);
21516
21517   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21518   vec_free (low_ports);
21519
21520   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21521   vec_free (high_ports);
21522
21523   mp->vrf_id = ntohl (vrf_id);
21524
21525   S (mp);
21526   W (ret);
21527   return ret;
21528 }
21529
21530 int
21531 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21532 {
21533   unformat_input_t *input = vam->input;
21534   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21535   u32 sw_if_index = ~0;
21536   int vrf_set = 0;
21537   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21538   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21539   u8 is_add = 1;
21540   int ret;
21541
21542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21543     {
21544       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21545         ;
21546       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21547         ;
21548       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21549         vrf_set = 1;
21550       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21551         vrf_set = 1;
21552       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21553         vrf_set = 1;
21554       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21555         vrf_set = 1;
21556       else if (unformat (input, "del"))
21557         is_add = 0;
21558       else
21559         break;
21560     }
21561
21562   if (sw_if_index == ~0)
21563     {
21564       errmsg ("Interface required but not specified");
21565       return -99;
21566     }
21567
21568   if (vrf_set == 0)
21569     {
21570       errmsg ("VRF ID required but not specified");
21571       return -99;
21572     }
21573
21574   if (tcp_out_vrf_id == 0
21575       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21576     {
21577       errmsg
21578         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21579       return -99;
21580     }
21581
21582   /* Construct the API message */
21583   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21584
21585   mp->sw_if_index = ntohl (sw_if_index);
21586   mp->is_add = is_add;
21587   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21588   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21589   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21590   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21591
21592   /* send it... */
21593   S (mp);
21594
21595   /* Wait for a reply... */
21596   W (ret);
21597   return ret;
21598 }
21599
21600 static int
21601 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21602 {
21603   unformat_input_t *i = vam->input;
21604   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21605   u32 local_sa_id = 0;
21606   u32 remote_sa_id = 0;
21607   ip4_address_t src_address;
21608   ip4_address_t dst_address;
21609   u8 is_add = 1;
21610   int ret;
21611
21612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21613     {
21614       if (unformat (i, "local_sa %d", &local_sa_id))
21615         ;
21616       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21617         ;
21618       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21619         ;
21620       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21621         ;
21622       else if (unformat (i, "del"))
21623         is_add = 0;
21624       else
21625         {
21626           clib_warning ("parse error '%U'", format_unformat_error, i);
21627           return -99;
21628         }
21629     }
21630
21631   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21632
21633   mp->local_sa_id = ntohl (local_sa_id);
21634   mp->remote_sa_id = ntohl (remote_sa_id);
21635   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21636   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21637   mp->is_add = is_add;
21638
21639   S (mp);
21640   W (ret);
21641   return ret;
21642 }
21643
21644 static int
21645 api_punt (vat_main_t * vam)
21646 {
21647   unformat_input_t *i = vam->input;
21648   vl_api_punt_t *mp;
21649   u32 ipv = ~0;
21650   u32 protocol = ~0;
21651   u32 port = ~0;
21652   int is_add = 1;
21653   int ret;
21654
21655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21656     {
21657       if (unformat (i, "ip %d", &ipv))
21658         ;
21659       else if (unformat (i, "protocol %d", &protocol))
21660         ;
21661       else if (unformat (i, "port %d", &port))
21662         ;
21663       else if (unformat (i, "del"))
21664         is_add = 0;
21665       else
21666         {
21667           clib_warning ("parse error '%U'", format_unformat_error, i);
21668           return -99;
21669         }
21670     }
21671
21672   M (PUNT, mp);
21673
21674   mp->is_add = (u8) is_add;
21675   mp->ipv = (u8) ipv;
21676   mp->l4_protocol = (u8) protocol;
21677   mp->l4_port = htons ((u16) port);
21678
21679   S (mp);
21680   W (ret);
21681   return ret;
21682 }
21683
21684 static void vl_api_ipsec_gre_tunnel_details_t_handler
21685   (vl_api_ipsec_gre_tunnel_details_t * mp)
21686 {
21687   vat_main_t *vam = &vat_main;
21688
21689   print (vam->ofp, "%11d%15U%15U%14d%14d",
21690          ntohl (mp->sw_if_index),
21691          format_ip4_address, &mp->src_address,
21692          format_ip4_address, &mp->dst_address,
21693          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21694 }
21695
21696 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21697   (vl_api_ipsec_gre_tunnel_details_t * mp)
21698 {
21699   vat_main_t *vam = &vat_main;
21700   vat_json_node_t *node = NULL;
21701   struct in_addr ip4;
21702
21703   if (VAT_JSON_ARRAY != vam->json_tree.type)
21704     {
21705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21706       vat_json_init_array (&vam->json_tree);
21707     }
21708   node = vat_json_array_add (&vam->json_tree);
21709
21710   vat_json_init_object (node);
21711   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21712   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21713   vat_json_object_add_ip4 (node, "src_address", ip4);
21714   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21715   vat_json_object_add_ip4 (node, "dst_address", ip4);
21716   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21717   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21718 }
21719
21720 static int
21721 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21722 {
21723   unformat_input_t *i = vam->input;
21724   vl_api_ipsec_gre_tunnel_dump_t *mp;
21725   vl_api_control_ping_t *mp_ping;
21726   u32 sw_if_index;
21727   u8 sw_if_index_set = 0;
21728   int ret;
21729
21730   /* Parse args required to build the message */
21731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21732     {
21733       if (unformat (i, "sw_if_index %d", &sw_if_index))
21734         sw_if_index_set = 1;
21735       else
21736         break;
21737     }
21738
21739   if (sw_if_index_set == 0)
21740     {
21741       sw_if_index = ~0;
21742     }
21743
21744   if (!vam->json_output)
21745     {
21746       print (vam->ofp, "%11s%15s%15s%14s%14s",
21747              "sw_if_index", "src_address", "dst_address",
21748              "local_sa_id", "remote_sa_id");
21749     }
21750
21751   /* Get list of gre-tunnel interfaces */
21752   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21753
21754   mp->sw_if_index = htonl (sw_if_index);
21755
21756   S (mp);
21757
21758   /* Use a control ping for synchronization */
21759   MPING (CONTROL_PING, mp_ping);
21760   S (mp_ping);
21761
21762   W (ret);
21763   return ret;
21764 }
21765
21766 static int
21767 api_delete_subif (vat_main_t * vam)
21768 {
21769   unformat_input_t *i = vam->input;
21770   vl_api_delete_subif_t *mp;
21771   u32 sw_if_index = ~0;
21772   int ret;
21773
21774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21775     {
21776       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21777         ;
21778       if (unformat (i, "sw_if_index %d", &sw_if_index))
21779         ;
21780       else
21781         break;
21782     }
21783
21784   if (sw_if_index == ~0)
21785     {
21786       errmsg ("missing sw_if_index");
21787       return -99;
21788     }
21789
21790   /* Construct the API message */
21791   M (DELETE_SUBIF, mp);
21792   mp->sw_if_index = ntohl (sw_if_index);
21793
21794   S (mp);
21795   W (ret);
21796   return ret;
21797 }
21798
21799 #define foreach_pbb_vtr_op      \
21800 _("disable",  L2_VTR_DISABLED)  \
21801 _("pop",  L2_VTR_POP_2)         \
21802 _("push",  L2_VTR_PUSH_2)
21803
21804 static int
21805 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21806 {
21807   unformat_input_t *i = vam->input;
21808   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21809   u32 sw_if_index = ~0, vtr_op = ~0;
21810   u16 outer_tag = ~0;
21811   u8 dmac[6], smac[6];
21812   u8 dmac_set = 0, smac_set = 0;
21813   u16 vlanid = 0;
21814   u32 sid = ~0;
21815   u32 tmp;
21816   int ret;
21817
21818   /* Shut up coverity */
21819   memset (dmac, 0, sizeof (dmac));
21820   memset (smac, 0, sizeof (smac));
21821
21822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21823     {
21824       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21825         ;
21826       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21827         ;
21828       else if (unformat (i, "vtr_op %d", &vtr_op))
21829         ;
21830 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21831       foreach_pbb_vtr_op
21832 #undef _
21833         else if (unformat (i, "translate_pbb_stag"))
21834         {
21835           if (unformat (i, "%d", &tmp))
21836             {
21837               vtr_op = L2_VTR_TRANSLATE_2_1;
21838               outer_tag = tmp;
21839             }
21840           else
21841             {
21842               errmsg
21843                 ("translate_pbb_stag operation requires outer tag definition");
21844               return -99;
21845             }
21846         }
21847       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21848         dmac_set++;
21849       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21850         smac_set++;
21851       else if (unformat (i, "sid %d", &sid))
21852         ;
21853       else if (unformat (i, "vlanid %d", &tmp))
21854         vlanid = tmp;
21855       else
21856         {
21857           clib_warning ("parse error '%U'", format_unformat_error, i);
21858           return -99;
21859         }
21860     }
21861
21862   if ((sw_if_index == ~0) || (vtr_op == ~0))
21863     {
21864       errmsg ("missing sw_if_index or vtr operation");
21865       return -99;
21866     }
21867   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21868       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21869     {
21870       errmsg
21871         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21872       return -99;
21873     }
21874
21875   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21876   mp->sw_if_index = ntohl (sw_if_index);
21877   mp->vtr_op = ntohl (vtr_op);
21878   mp->outer_tag = ntohs (outer_tag);
21879   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21880   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21881   mp->b_vlanid = ntohs (vlanid);
21882   mp->i_sid = ntohl (sid);
21883
21884   S (mp);
21885   W (ret);
21886   return ret;
21887 }
21888
21889 static int
21890 api_flow_classify_set_interface (vat_main_t * vam)
21891 {
21892   unformat_input_t *i = vam->input;
21893   vl_api_flow_classify_set_interface_t *mp;
21894   u32 sw_if_index;
21895   int sw_if_index_set;
21896   u32 ip4_table_index = ~0;
21897   u32 ip6_table_index = ~0;
21898   u8 is_add = 1;
21899   int ret;
21900
21901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21902     {
21903       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21904         sw_if_index_set = 1;
21905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21906         sw_if_index_set = 1;
21907       else if (unformat (i, "del"))
21908         is_add = 0;
21909       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21910         ;
21911       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21912         ;
21913       else
21914         {
21915           clib_warning ("parse error '%U'", format_unformat_error, i);
21916           return -99;
21917         }
21918     }
21919
21920   if (sw_if_index_set == 0)
21921     {
21922       errmsg ("missing interface name or sw_if_index");
21923       return -99;
21924     }
21925
21926   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21927
21928   mp->sw_if_index = ntohl (sw_if_index);
21929   mp->ip4_table_index = ntohl (ip4_table_index);
21930   mp->ip6_table_index = ntohl (ip6_table_index);
21931   mp->is_add = is_add;
21932
21933   S (mp);
21934   W (ret);
21935   return ret;
21936 }
21937
21938 static int
21939 api_flow_classify_dump (vat_main_t * vam)
21940 {
21941   unformat_input_t *i = vam->input;
21942   vl_api_flow_classify_dump_t *mp;
21943   vl_api_control_ping_t *mp_ping;
21944   u8 type = FLOW_CLASSIFY_N_TABLES;
21945   int ret;
21946
21947   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21948     ;
21949   else
21950     {
21951       errmsg ("classify table type must be specified");
21952       return -99;
21953     }
21954
21955   if (!vam->json_output)
21956     {
21957       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21958     }
21959
21960   M (FLOW_CLASSIFY_DUMP, mp);
21961   mp->type = type;
21962   /* send it... */
21963   S (mp);
21964
21965   /* Use a control ping for synchronization */
21966   MPING (CONTROL_PING, mp_ping);
21967   S (mp_ping);
21968
21969   /* Wait for a reply... */
21970   W (ret);
21971   return ret;
21972 }
21973
21974 static int
21975 api_feature_enable_disable (vat_main_t * vam)
21976 {
21977   unformat_input_t *i = vam->input;
21978   vl_api_feature_enable_disable_t *mp;
21979   u8 *arc_name = 0;
21980   u8 *feature_name = 0;
21981   u32 sw_if_index = ~0;
21982   u8 enable = 1;
21983   int ret;
21984
21985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21986     {
21987       if (unformat (i, "arc_name %s", &arc_name))
21988         ;
21989       else if (unformat (i, "feature_name %s", &feature_name))
21990         ;
21991       else
21992         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21993         ;
21994       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21995         ;
21996       else if (unformat (i, "disable"))
21997         enable = 0;
21998       else
21999         break;
22000     }
22001
22002   if (arc_name == 0)
22003     {
22004       errmsg ("missing arc name");
22005       return -99;
22006     }
22007   if (vec_len (arc_name) > 63)
22008     {
22009       errmsg ("arc name too long");
22010     }
22011
22012   if (feature_name == 0)
22013     {
22014       errmsg ("missing feature name");
22015       return -99;
22016     }
22017   if (vec_len (feature_name) > 63)
22018     {
22019       errmsg ("feature name too long");
22020     }
22021
22022   if (sw_if_index == ~0)
22023     {
22024       errmsg ("missing interface name or sw_if_index");
22025       return -99;
22026     }
22027
22028   /* Construct the API message */
22029   M (FEATURE_ENABLE_DISABLE, mp);
22030   mp->sw_if_index = ntohl (sw_if_index);
22031   mp->enable = enable;
22032   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22033   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22034   vec_free (arc_name);
22035   vec_free (feature_name);
22036
22037   S (mp);
22038   W (ret);
22039   return ret;
22040 }
22041
22042 static int
22043 api_sw_interface_tag_add_del (vat_main_t * vam)
22044 {
22045   unformat_input_t *i = vam->input;
22046   vl_api_sw_interface_tag_add_del_t *mp;
22047   u32 sw_if_index = ~0;
22048   u8 *tag = 0;
22049   u8 enable = 1;
22050   int ret;
22051
22052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22053     {
22054       if (unformat (i, "tag %s", &tag))
22055         ;
22056       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22057         ;
22058       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22059         ;
22060       else if (unformat (i, "del"))
22061         enable = 0;
22062       else
22063         break;
22064     }
22065
22066   if (sw_if_index == ~0)
22067     {
22068       errmsg ("missing interface name or sw_if_index");
22069       return -99;
22070     }
22071
22072   if (enable && (tag == 0))
22073     {
22074       errmsg ("no tag specified");
22075       return -99;
22076     }
22077
22078   /* Construct the API message */
22079   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22080   mp->sw_if_index = ntohl (sw_if_index);
22081   mp->is_add = enable;
22082   if (enable)
22083     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22084   vec_free (tag);
22085
22086   S (mp);
22087   W (ret);
22088   return ret;
22089 }
22090
22091 static void vl_api_l2_xconnect_details_t_handler
22092   (vl_api_l2_xconnect_details_t * mp)
22093 {
22094   vat_main_t *vam = &vat_main;
22095
22096   print (vam->ofp, "%15d%15d",
22097          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22098 }
22099
22100 static void vl_api_l2_xconnect_details_t_handler_json
22101   (vl_api_l2_xconnect_details_t * mp)
22102 {
22103   vat_main_t *vam = &vat_main;
22104   vat_json_node_t *node = NULL;
22105
22106   if (VAT_JSON_ARRAY != vam->json_tree.type)
22107     {
22108       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22109       vat_json_init_array (&vam->json_tree);
22110     }
22111   node = vat_json_array_add (&vam->json_tree);
22112
22113   vat_json_init_object (node);
22114   vat_json_object_add_uint (node, "rx_sw_if_index",
22115                             ntohl (mp->rx_sw_if_index));
22116   vat_json_object_add_uint (node, "tx_sw_if_index",
22117                             ntohl (mp->tx_sw_if_index));
22118 }
22119
22120 static int
22121 api_l2_xconnect_dump (vat_main_t * vam)
22122 {
22123   vl_api_l2_xconnect_dump_t *mp;
22124   vl_api_control_ping_t *mp_ping;
22125   int ret;
22126
22127   if (!vam->json_output)
22128     {
22129       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22130     }
22131
22132   M (L2_XCONNECT_DUMP, mp);
22133
22134   S (mp);
22135
22136   /* Use a control ping for synchronization */
22137   MPING (CONTROL_PING, mp_ping);
22138   S (mp_ping);
22139
22140   W (ret);
22141   return ret;
22142 }
22143
22144 static int
22145 api_hw_interface_set_mtu (vat_main_t * vam)
22146 {
22147   unformat_input_t *i = vam->input;
22148   vl_api_hw_interface_set_mtu_t *mp;
22149   u32 sw_if_index = ~0;
22150   u32 mtu = 0;
22151   int ret;
22152
22153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22154     {
22155       if (unformat (i, "mtu %d", &mtu))
22156         ;
22157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22158         ;
22159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22160         ;
22161       else
22162         break;
22163     }
22164
22165   if (sw_if_index == ~0)
22166     {
22167       errmsg ("missing interface name or sw_if_index");
22168       return -99;
22169     }
22170
22171   if (mtu == 0)
22172     {
22173       errmsg ("no mtu specified");
22174       return -99;
22175     }
22176
22177   /* Construct the API message */
22178   M (HW_INTERFACE_SET_MTU, mp);
22179   mp->sw_if_index = ntohl (sw_if_index);
22180   mp->mtu = ntohs ((u16) mtu);
22181
22182   S (mp);
22183   W (ret);
22184   return ret;
22185 }
22186
22187 static int
22188 api_p2p_ethernet_add (vat_main_t * vam)
22189 {
22190   unformat_input_t *i = vam->input;
22191   vl_api_p2p_ethernet_add_t *mp;
22192   u32 parent_if_index = ~0;
22193   u32 sub_id = ~0;
22194   u8 remote_mac[6];
22195   u8 mac_set = 0;
22196   int ret;
22197
22198   memset (remote_mac, 0, sizeof (remote_mac));
22199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22200     {
22201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22202         ;
22203       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22204         ;
22205       else
22206         if (unformat
22207             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22208         mac_set++;
22209       else if (unformat (i, "sub_id %d", &sub_id))
22210         ;
22211       else
22212         {
22213           clib_warning ("parse error '%U'", format_unformat_error, i);
22214           return -99;
22215         }
22216     }
22217
22218   if (parent_if_index == ~0)
22219     {
22220       errmsg ("missing interface name or sw_if_index");
22221       return -99;
22222     }
22223   if (mac_set == 0)
22224     {
22225       errmsg ("missing remote mac address");
22226       return -99;
22227     }
22228   if (sub_id == ~0)
22229     {
22230       errmsg ("missing sub-interface id");
22231       return -99;
22232     }
22233
22234   M (P2P_ETHERNET_ADD, mp);
22235   mp->parent_if_index = ntohl (parent_if_index);
22236   mp->subif_id = ntohl (sub_id);
22237   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22238
22239   S (mp);
22240   W (ret);
22241   return ret;
22242 }
22243
22244 static int
22245 api_p2p_ethernet_del (vat_main_t * vam)
22246 {
22247   unformat_input_t *i = vam->input;
22248   vl_api_p2p_ethernet_del_t *mp;
22249   u32 parent_if_index = ~0;
22250   u8 remote_mac[6];
22251   u8 mac_set = 0;
22252   int ret;
22253
22254   memset (remote_mac, 0, sizeof (remote_mac));
22255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22256     {
22257       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22258         ;
22259       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22260         ;
22261       else
22262         if (unformat
22263             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22264         mac_set++;
22265       else
22266         {
22267           clib_warning ("parse error '%U'", format_unformat_error, i);
22268           return -99;
22269         }
22270     }
22271
22272   if (parent_if_index == ~0)
22273     {
22274       errmsg ("missing interface name or sw_if_index");
22275       return -99;
22276     }
22277   if (mac_set == 0)
22278     {
22279       errmsg ("missing remote mac address");
22280       return -99;
22281     }
22282
22283   M (P2P_ETHERNET_DEL, mp);
22284   mp->parent_if_index = ntohl (parent_if_index);
22285   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22286
22287   S (mp);
22288   W (ret);
22289   return ret;
22290 }
22291
22292 static int
22293 api_lldp_config (vat_main_t * vam)
22294 {
22295   unformat_input_t *i = vam->input;
22296   vl_api_lldp_config_t *mp;
22297   int tx_hold = 0;
22298   int tx_interval = 0;
22299   u8 *sys_name = NULL;
22300   int ret;
22301
22302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22303     {
22304       if (unformat (i, "system-name %s", &sys_name))
22305         ;
22306       else if (unformat (i, "tx-hold %d", &tx_hold))
22307         ;
22308       else if (unformat (i, "tx-interval %d", &tx_interval))
22309         ;
22310       else
22311         {
22312           clib_warning ("parse error '%U'", format_unformat_error, i);
22313           return -99;
22314         }
22315     }
22316
22317   vec_add1 (sys_name, 0);
22318
22319   M (LLDP_CONFIG, mp);
22320   mp->tx_hold = htonl (tx_hold);
22321   mp->tx_interval = htonl (tx_interval);
22322   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22323   vec_free (sys_name);
22324
22325   S (mp);
22326   W (ret);
22327   return ret;
22328 }
22329
22330 static int
22331 api_sw_interface_set_lldp (vat_main_t * vam)
22332 {
22333   unformat_input_t *i = vam->input;
22334   vl_api_sw_interface_set_lldp_t *mp;
22335   u32 sw_if_index = ~0;
22336   u32 enable = 1;
22337   u8 *port_desc = NULL, *mgmt_oid = NULL;
22338   ip4_address_t ip4_addr;
22339   ip6_address_t ip6_addr;
22340   int ret;
22341
22342   memset (&ip4_addr, 0, sizeof (ip4_addr));
22343   memset (&ip6_addr, 0, sizeof (ip6_addr));
22344
22345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22346     {
22347       if (unformat (i, "disable"))
22348         enable = 0;
22349       else
22350         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22351         ;
22352       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22353         ;
22354       else if (unformat (i, "port-desc %s", &port_desc))
22355         ;
22356       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22357         ;
22358       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22359         ;
22360       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22361         ;
22362       else
22363         break;
22364     }
22365
22366   if (sw_if_index == ~0)
22367     {
22368       errmsg ("missing interface name or sw_if_index");
22369       return -99;
22370     }
22371
22372   /* Construct the API message */
22373   vec_add1 (port_desc, 0);
22374   vec_add1 (mgmt_oid, 0);
22375   M (SW_INTERFACE_SET_LLDP, mp);
22376   mp->sw_if_index = ntohl (sw_if_index);
22377   mp->enable = enable;
22378   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22379   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22380   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22381   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22382   vec_free (port_desc);
22383   vec_free (mgmt_oid);
22384
22385   S (mp);
22386   W (ret);
22387   return ret;
22388 }
22389
22390 static int
22391 api_tcp_configure_src_addresses (vat_main_t * vam)
22392 {
22393   vl_api_tcp_configure_src_addresses_t *mp;
22394   unformat_input_t *i = vam->input;
22395   ip4_address_t v4first, v4last;
22396   ip6_address_t v6first, v6last;
22397   u8 range_set = 0;
22398   u32 vrf_id = 0;
22399   int ret;
22400
22401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22402     {
22403       if (unformat (i, "%U - %U",
22404                     unformat_ip4_address, &v4first,
22405                     unformat_ip4_address, &v4last))
22406         {
22407           if (range_set)
22408             {
22409               errmsg ("one range per message (range already set)");
22410               return -99;
22411             }
22412           range_set = 1;
22413         }
22414       else if (unformat (i, "%U - %U",
22415                          unformat_ip6_address, &v6first,
22416                          unformat_ip6_address, &v6last))
22417         {
22418           if (range_set)
22419             {
22420               errmsg ("one range per message (range already set)");
22421               return -99;
22422             }
22423           range_set = 2;
22424         }
22425       else if (unformat (i, "vrf %d", &vrf_id))
22426         ;
22427       else
22428         break;
22429     }
22430
22431   if (range_set == 0)
22432     {
22433       errmsg ("address range not set");
22434       return -99;
22435     }
22436
22437   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22438   mp->vrf_id = ntohl (vrf_id);
22439   /* ipv6? */
22440   if (range_set == 2)
22441     {
22442       mp->is_ipv6 = 1;
22443       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22444       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22445     }
22446   else
22447     {
22448       mp->is_ipv6 = 0;
22449       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22450       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22451     }
22452   S (mp);
22453   W (ret);
22454   return ret;
22455 }
22456
22457 static void vl_api_app_namespace_add_del_reply_t_handler
22458   (vl_api_app_namespace_add_del_reply_t * mp)
22459 {
22460   vat_main_t *vam = &vat_main;
22461   i32 retval = ntohl (mp->retval);
22462   if (vam->async_mode)
22463     {
22464       vam->async_errors += (retval < 0);
22465     }
22466   else
22467     {
22468       vam->retval = retval;
22469       if (retval == 0)
22470         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22471       vam->result_ready = 1;
22472     }
22473 }
22474
22475 static void vl_api_app_namespace_add_del_reply_t_handler_json
22476   (vl_api_app_namespace_add_del_reply_t * mp)
22477 {
22478   vat_main_t *vam = &vat_main;
22479   vat_json_node_t node;
22480
22481   vat_json_init_object (&node);
22482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22483   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22484
22485   vat_json_print (vam->ofp, &node);
22486   vat_json_free (&node);
22487
22488   vam->retval = ntohl (mp->retval);
22489   vam->result_ready = 1;
22490 }
22491
22492 static int
22493 api_app_namespace_add_del (vat_main_t * vam)
22494 {
22495   vl_api_app_namespace_add_del_t *mp;
22496   unformat_input_t *i = vam->input;
22497   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22498   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22499   u64 secret;
22500   int ret;
22501
22502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22503     {
22504       if (unformat (i, "id %_%v%_", &ns_id))
22505         ;
22506       else if (unformat (i, "secret %lu", &secret))
22507         secret_set = 1;
22508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22509         sw_if_index_set = 1;
22510       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22511         ;
22512       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22513         ;
22514       else
22515         break;
22516     }
22517   if (!ns_id || !secret_set || !sw_if_index_set)
22518     {
22519       errmsg ("namespace id, secret and sw_if_index must be set");
22520       return -99;
22521     }
22522   if (vec_len (ns_id) > 64)
22523     {
22524       errmsg ("namespace id too long");
22525       return -99;
22526     }
22527   M (APP_NAMESPACE_ADD_DEL, mp);
22528
22529   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22530   mp->namespace_id_len = vec_len (ns_id);
22531   mp->secret = clib_host_to_net_u64 (secret);
22532   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22533   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22534   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22535   vec_free (ns_id);
22536   S (mp);
22537   W (ret);
22538   return ret;
22539 }
22540
22541 static int
22542 api_sock_init_shm (vat_main_t * vam)
22543 {
22544 #if VPP_API_TEST_BUILTIN == 0
22545   unformat_input_t *i = vam->input;
22546   vl_api_shm_elem_config_t *config = 0;
22547   u64 size = 64 << 20;
22548   int rv;
22549
22550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22551     {
22552       if (unformat (i, "size %U", unformat_memory_size, &size))
22553         ;
22554       else
22555         break;
22556     }
22557
22558   /*
22559    * Canned custom ring allocator config.
22560    * Should probably parse all of this
22561    */
22562   vec_validate (config, 6);
22563   config[0].type = VL_API_VLIB_RING;
22564   config[0].size = 256;
22565   config[0].count = 32;
22566
22567   config[1].type = VL_API_VLIB_RING;
22568   config[1].size = 1024;
22569   config[1].count = 16;
22570
22571   config[2].type = VL_API_VLIB_RING;
22572   config[2].size = 4096;
22573   config[2].count = 2;
22574
22575   config[3].type = VL_API_CLIENT_RING;
22576   config[3].size = 256;
22577   config[3].count = 32;
22578
22579   config[4].type = VL_API_CLIENT_RING;
22580   config[4].size = 1024;
22581   config[4].count = 16;
22582
22583   config[5].type = VL_API_CLIENT_RING;
22584   config[5].size = 4096;
22585   config[5].count = 2;
22586
22587   config[6].type = VL_API_QUEUE;
22588   config[6].count = 128;
22589   config[6].size = sizeof (uword);
22590
22591   rv = vl_socket_client_init_shm (config);
22592   if (!rv)
22593     vam->client_index_invalid = 1;
22594   return rv;
22595 #else
22596   return -99;
22597 #endif
22598 }
22599
22600 static int
22601 api_dns_enable_disable (vat_main_t * vam)
22602 {
22603   unformat_input_t *line_input = vam->input;
22604   vl_api_dns_enable_disable_t *mp;
22605   u8 enable_disable = 1;
22606   int ret;
22607
22608   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22609     {
22610       if (unformat (line_input, "disable"))
22611         enable_disable = 0;
22612       if (unformat (line_input, "enable"))
22613         enable_disable = 1;
22614       else
22615         break;
22616     }
22617
22618   /* Construct the API message */
22619   M (DNS_ENABLE_DISABLE, mp);
22620   mp->enable = enable_disable;
22621
22622   /* send it... */
22623   S (mp);
22624   /* Wait for the reply */
22625   W (ret);
22626   return ret;
22627 }
22628
22629 static int
22630 api_dns_resolve_name (vat_main_t * vam)
22631 {
22632   unformat_input_t *line_input = vam->input;
22633   vl_api_dns_resolve_name_t *mp;
22634   u8 *name = 0;
22635   int ret;
22636
22637   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22638     {
22639       if (unformat (line_input, "%s", &name))
22640         ;
22641       else
22642         break;
22643     }
22644
22645   if (vec_len (name) > 127)
22646     {
22647       errmsg ("name too long");
22648       return -99;
22649     }
22650
22651   /* Construct the API message */
22652   M (DNS_RESOLVE_NAME, mp);
22653   memcpy (mp->name, name, vec_len (name));
22654   vec_free (name);
22655
22656   /* send it... */
22657   S (mp);
22658   /* Wait for the reply */
22659   W (ret);
22660   return ret;
22661 }
22662
22663 static int
22664 api_dns_resolve_ip (vat_main_t * vam)
22665 {
22666   unformat_input_t *line_input = vam->input;
22667   vl_api_dns_resolve_ip_t *mp;
22668   int is_ip6 = -1;
22669   ip4_address_t addr4;
22670   ip6_address_t addr6;
22671   int ret;
22672
22673   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22674     {
22675       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22676         is_ip6 = 1;
22677       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22678         is_ip6 = 0;
22679       else
22680         break;
22681     }
22682
22683   if (is_ip6 == -1)
22684     {
22685       errmsg ("missing address");
22686       return -99;
22687     }
22688
22689   /* Construct the API message */
22690   M (DNS_RESOLVE_IP, mp);
22691   mp->is_ip6 = is_ip6;
22692   if (is_ip6)
22693     memcpy (mp->address, &addr6, sizeof (addr6));
22694   else
22695     memcpy (mp->address, &addr4, sizeof (addr4));
22696
22697   /* send it... */
22698   S (mp);
22699   /* Wait for the reply */
22700   W (ret);
22701   return ret;
22702 }
22703
22704 static int
22705 api_dns_name_server_add_del (vat_main_t * vam)
22706 {
22707   unformat_input_t *i = vam->input;
22708   vl_api_dns_name_server_add_del_t *mp;
22709   u8 is_add = 1;
22710   ip6_address_t ip6_server;
22711   ip4_address_t ip4_server;
22712   int ip6_set = 0;
22713   int ip4_set = 0;
22714   int ret = 0;
22715
22716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22717     {
22718       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22719         ip6_set = 1;
22720       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22721         ip4_set = 1;
22722       else if (unformat (i, "del"))
22723         is_add = 0;
22724       else
22725         {
22726           clib_warning ("parse error '%U'", format_unformat_error, i);
22727           return -99;
22728         }
22729     }
22730
22731   if (ip4_set && ip6_set)
22732     {
22733       errmsg ("Only one server address allowed per message");
22734       return -99;
22735     }
22736   if ((ip4_set + ip6_set) == 0)
22737     {
22738       errmsg ("Server address required");
22739       return -99;
22740     }
22741
22742   /* Construct the API message */
22743   M (DNS_NAME_SERVER_ADD_DEL, mp);
22744
22745   if (ip6_set)
22746     {
22747       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22748       mp->is_ip6 = 1;
22749     }
22750   else
22751     {
22752       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22753       mp->is_ip6 = 0;
22754     }
22755
22756   mp->is_add = is_add;
22757
22758   /* send it... */
22759   S (mp);
22760
22761   /* Wait for a reply, return good/bad news  */
22762   W (ret);
22763   return ret;
22764 }
22765
22766 static void
22767 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22768 {
22769   vat_main_t *vam = &vat_main;
22770
22771   if (mp->is_ip4)
22772     {
22773       print (vam->ofp,
22774              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22775              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22776              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22777              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22778              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22779              clib_net_to_host_u32 (mp->action_index), mp->tag);
22780     }
22781   else
22782     {
22783       print (vam->ofp,
22784              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22785              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22786              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22787              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22788              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22789              clib_net_to_host_u32 (mp->action_index), mp->tag);
22790     }
22791 }
22792
22793 static void
22794 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22795                                              mp)
22796 {
22797   vat_main_t *vam = &vat_main;
22798   vat_json_node_t *node = NULL;
22799   struct in6_addr ip6;
22800   struct in_addr ip4;
22801
22802   if (VAT_JSON_ARRAY != vam->json_tree.type)
22803     {
22804       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22805       vat_json_init_array (&vam->json_tree);
22806     }
22807   node = vat_json_array_add (&vam->json_tree);
22808   vat_json_init_object (node);
22809
22810   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22811   vat_json_object_add_uint (node, "appns_index",
22812                             clib_net_to_host_u32 (mp->appns_index));
22813   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22814   vat_json_object_add_uint (node, "scope", mp->scope);
22815   vat_json_object_add_uint (node, "action_index",
22816                             clib_net_to_host_u32 (mp->action_index));
22817   vat_json_object_add_uint (node, "lcl_port",
22818                             clib_net_to_host_u16 (mp->lcl_port));
22819   vat_json_object_add_uint (node, "rmt_port",
22820                             clib_net_to_host_u16 (mp->rmt_port));
22821   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22822   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22823   vat_json_object_add_string_copy (node, "tag", mp->tag);
22824   if (mp->is_ip4)
22825     {
22826       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22827       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22828       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22829       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22830     }
22831   else
22832     {
22833       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22834       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22835       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22836       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22837     }
22838 }
22839
22840 static int
22841 api_session_rule_add_del (vat_main_t * vam)
22842 {
22843   vl_api_session_rule_add_del_t *mp;
22844   unformat_input_t *i = vam->input;
22845   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22846   u32 appns_index = 0, scope = 0;
22847   ip4_address_t lcl_ip4, rmt_ip4;
22848   ip6_address_t lcl_ip6, rmt_ip6;
22849   u8 is_ip4 = 1, conn_set = 0;
22850   u8 is_add = 1, *tag = 0;
22851   int ret;
22852
22853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22854     {
22855       if (unformat (i, "del"))
22856         is_add = 0;
22857       else if (unformat (i, "add"))
22858         ;
22859       else if (unformat (i, "proto tcp"))
22860         proto = 0;
22861       else if (unformat (i, "proto udp"))
22862         proto = 1;
22863       else if (unformat (i, "appns %d", &appns_index))
22864         ;
22865       else if (unformat (i, "scope %d", &scope))
22866         ;
22867       else if (unformat (i, "tag %_%v%_", &tag))
22868         ;
22869       else
22870         if (unformat
22871             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22872              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22873              &rmt_port))
22874         {
22875           is_ip4 = 1;
22876           conn_set = 1;
22877         }
22878       else
22879         if (unformat
22880             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22881              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22882              &rmt_port))
22883         {
22884           is_ip4 = 0;
22885           conn_set = 1;
22886         }
22887       else if (unformat (i, "action %d", &action))
22888         ;
22889       else
22890         break;
22891     }
22892   if (proto == ~0 || !conn_set || action == ~0)
22893     {
22894       errmsg ("transport proto, connection and action must be set");
22895       return -99;
22896     }
22897
22898   if (scope > 3)
22899     {
22900       errmsg ("scope should be 0-3");
22901       return -99;
22902     }
22903
22904   M (SESSION_RULE_ADD_DEL, mp);
22905
22906   mp->is_ip4 = is_ip4;
22907   mp->transport_proto = proto;
22908   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22909   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22910   mp->lcl_plen = lcl_plen;
22911   mp->rmt_plen = rmt_plen;
22912   mp->action_index = clib_host_to_net_u32 (action);
22913   mp->appns_index = clib_host_to_net_u32 (appns_index);
22914   mp->scope = scope;
22915   mp->is_add = is_add;
22916   if (is_ip4)
22917     {
22918       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22919       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22920     }
22921   else
22922     {
22923       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22924       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22925     }
22926   if (tag)
22927     {
22928       clib_memcpy (mp->tag, tag, vec_len (tag));
22929       vec_free (tag);
22930     }
22931
22932   S (mp);
22933   W (ret);
22934   return ret;
22935 }
22936
22937 static int
22938 api_session_rules_dump (vat_main_t * vam)
22939 {
22940   vl_api_session_rules_dump_t *mp;
22941   vl_api_control_ping_t *mp_ping;
22942   int ret;
22943
22944   if (!vam->json_output)
22945     {
22946       print (vam->ofp, "%=20s", "Session Rules");
22947     }
22948
22949   M (SESSION_RULES_DUMP, mp);
22950   /* send it... */
22951   S (mp);
22952
22953   /* Use a control ping for synchronization */
22954   MPING (CONTROL_PING, mp_ping);
22955   S (mp_ping);
22956
22957   /* Wait for a reply... */
22958   W (ret);
22959   return ret;
22960 }
22961
22962 static int
22963 api_ip_container_proxy_add_del (vat_main_t * vam)
22964 {
22965   vl_api_ip_container_proxy_add_del_t *mp;
22966   unformat_input_t *i = vam->input;
22967   u32 plen = ~0, sw_if_index = ~0;
22968   ip4_address_t ip4;
22969   ip6_address_t ip6;
22970   u8 is_ip4 = 1;
22971   u8 is_add = 1;
22972   int ret;
22973
22974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22975     {
22976       if (unformat (i, "del"))
22977         is_add = 0;
22978       else if (unformat (i, "add"))
22979         ;
22980       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22981         {
22982           is_ip4 = 1;
22983           plen = 32;
22984         }
22985       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22986         {
22987           is_ip4 = 0;
22988           plen = 128;
22989         }
22990       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22991         ;
22992       else
22993         break;
22994     }
22995   if (sw_if_index == ~0 || plen == ~0)
22996     {
22997       errmsg ("address and sw_if_index must be set");
22998       return -99;
22999     }
23000
23001   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23002
23003   mp->is_ip4 = is_ip4;
23004   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23005   mp->plen = plen;
23006   mp->is_add = is_add;
23007   if (is_ip4)
23008     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23009   else
23010     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23011
23012   S (mp);
23013   W (ret);
23014   return ret;
23015 }
23016
23017 static int
23018 api_qos_record_enable_disable (vat_main_t * vam)
23019 {
23020   unformat_input_t *i = vam->input;
23021   vl_api_qos_record_enable_disable_t *mp;
23022   u32 sw_if_index, qs = 0xff;
23023   u8 sw_if_index_set = 0;
23024   u8 enable = 1;
23025   int ret;
23026
23027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23028     {
23029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23030         sw_if_index_set = 1;
23031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23032         sw_if_index_set = 1;
23033       else if (unformat (i, "%U", unformat_qos_source, &qs))
23034         ;
23035       else if (unformat (i, "disable"))
23036         enable = 0;
23037       else
23038         {
23039           clib_warning ("parse error '%U'", format_unformat_error, i);
23040           return -99;
23041         }
23042     }
23043
23044   if (sw_if_index_set == 0)
23045     {
23046       errmsg ("missing interface name or sw_if_index");
23047       return -99;
23048     }
23049   if (qs == 0xff)
23050     {
23051       errmsg ("input location must be specified");
23052       return -99;
23053     }
23054
23055   M (QOS_RECORD_ENABLE_DISABLE, mp);
23056
23057   mp->sw_if_index = ntohl (sw_if_index);
23058   mp->input_source = qs;
23059   mp->enable = enable;
23060
23061   S (mp);
23062   W (ret);
23063   return ret;
23064 }
23065
23066
23067 static int
23068 q_or_quit (vat_main_t * vam)
23069 {
23070 #if VPP_API_TEST_BUILTIN == 0
23071   longjmp (vam->jump_buf, 1);
23072 #endif
23073   return 0;                     /* not so much */
23074 }
23075
23076 static int
23077 q (vat_main_t * vam)
23078 {
23079   return q_or_quit (vam);
23080 }
23081
23082 static int
23083 quit (vat_main_t * vam)
23084 {
23085   return q_or_quit (vam);
23086 }
23087
23088 static int
23089 comment (vat_main_t * vam)
23090 {
23091   return 0;
23092 }
23093
23094 static int
23095 statseg (vat_main_t * vam)
23096 {
23097   ssvm_private_t *ssvmp = &vam->stat_segment;
23098   ssvm_shared_header_t *shared_header = ssvmp->sh;
23099   vlib_counter_t **counters;
23100   u64 thread0_index1_packets;
23101   u64 thread0_index1_bytes;
23102   f64 vector_rate, input_rate;
23103   uword *p;
23104
23105   uword *counter_vector_by_name;
23106   if (vam->stat_segment_lockp == 0)
23107     {
23108       errmsg ("Stat segment not mapped...");
23109       return -99;
23110     }
23111
23112   /* look up "/if/rx for sw_if_index 1 as a test */
23113
23114   clib_spinlock_lock (vam->stat_segment_lockp);
23115
23116   counter_vector_by_name = (uword *) shared_header->opaque[1];
23117
23118   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23119   if (p == 0)
23120     {
23121       clib_spinlock_unlock (vam->stat_segment_lockp);
23122       errmsg ("/if/tx not found?");
23123       return -99;
23124     }
23125
23126   /* Fish per-thread vector of combined counters from shared memory */
23127   counters = (vlib_counter_t **) p[0];
23128
23129   if (vec_len (counters[0]) < 2)
23130     {
23131       clib_spinlock_unlock (vam->stat_segment_lockp);
23132       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23133       return -99;
23134     }
23135
23136   /* Read thread 0 sw_if_index 1 counter */
23137   thread0_index1_packets = counters[0][1].packets;
23138   thread0_index1_bytes = counters[0][1].bytes;
23139
23140   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23141   if (p == 0)
23142     {
23143       clib_spinlock_unlock (vam->stat_segment_lockp);
23144       errmsg ("vector_rate not found?");
23145       return -99;
23146     }
23147
23148   vector_rate = *(f64 *) (p[0]);
23149   p = hash_get_mem (counter_vector_by_name, "input_rate");
23150   if (p == 0)
23151     {
23152       clib_spinlock_unlock (vam->stat_segment_lockp);
23153       errmsg ("input_rate not found?");
23154       return -99;
23155     }
23156   input_rate = *(f64 *) (p[0]);
23157
23158   clib_spinlock_unlock (vam->stat_segment_lockp);
23159
23160   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23161          vector_rate, input_rate);
23162   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23163          thread0_index1_packets, thread0_index1_bytes);
23164
23165   return 0;
23166 }
23167
23168 static int
23169 cmd_cmp (void *a1, void *a2)
23170 {
23171   u8 **c1 = a1;
23172   u8 **c2 = a2;
23173
23174   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23175 }
23176
23177 static int
23178 help (vat_main_t * vam)
23179 {
23180   u8 **cmds = 0;
23181   u8 *name = 0;
23182   hash_pair_t *p;
23183   unformat_input_t *i = vam->input;
23184   int j;
23185
23186   if (unformat (i, "%s", &name))
23187     {
23188       uword *hs;
23189
23190       vec_add1 (name, 0);
23191
23192       hs = hash_get_mem (vam->help_by_name, name);
23193       if (hs)
23194         print (vam->ofp, "usage: %s %s", name, hs[0]);
23195       else
23196         print (vam->ofp, "No such msg / command '%s'", name);
23197       vec_free (name);
23198       return 0;
23199     }
23200
23201   print (vam->ofp, "Help is available for the following:");
23202
23203     /* *INDENT-OFF* */
23204     hash_foreach_pair (p, vam->function_by_name,
23205     ({
23206       vec_add1 (cmds, (u8 *)(p->key));
23207     }));
23208     /* *INDENT-ON* */
23209
23210   vec_sort_with_function (cmds, cmd_cmp);
23211
23212   for (j = 0; j < vec_len (cmds); j++)
23213     print (vam->ofp, "%s", cmds[j]);
23214
23215   vec_free (cmds);
23216   return 0;
23217 }
23218
23219 static int
23220 set (vat_main_t * vam)
23221 {
23222   u8 *name = 0, *value = 0;
23223   unformat_input_t *i = vam->input;
23224
23225   if (unformat (i, "%s", &name))
23226     {
23227       /* The input buffer is a vector, not a string. */
23228       value = vec_dup (i->buffer);
23229       vec_delete (value, i->index, 0);
23230       /* Almost certainly has a trailing newline */
23231       if (value[vec_len (value) - 1] == '\n')
23232         value[vec_len (value) - 1] = 0;
23233       /* Make sure it's a proper string, one way or the other */
23234       vec_add1 (value, 0);
23235       (void) clib_macro_set_value (&vam->macro_main,
23236                                    (char *) name, (char *) value);
23237     }
23238   else
23239     errmsg ("usage: set <name> <value>");
23240
23241   vec_free (name);
23242   vec_free (value);
23243   return 0;
23244 }
23245
23246 static int
23247 unset (vat_main_t * vam)
23248 {
23249   u8 *name = 0;
23250
23251   if (unformat (vam->input, "%s", &name))
23252     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23253       errmsg ("unset: %s wasn't set", name);
23254   vec_free (name);
23255   return 0;
23256 }
23257
23258 typedef struct
23259 {
23260   u8 *name;
23261   u8 *value;
23262 } macro_sort_t;
23263
23264
23265 static int
23266 macro_sort_cmp (void *a1, void *a2)
23267 {
23268   macro_sort_t *s1 = a1;
23269   macro_sort_t *s2 = a2;
23270
23271   return strcmp ((char *) (s1->name), (char *) (s2->name));
23272 }
23273
23274 static int
23275 dump_macro_table (vat_main_t * vam)
23276 {
23277   macro_sort_t *sort_me = 0, *sm;
23278   int i;
23279   hash_pair_t *p;
23280
23281     /* *INDENT-OFF* */
23282     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23283     ({
23284       vec_add2 (sort_me, sm, 1);
23285       sm->name = (u8 *)(p->key);
23286       sm->value = (u8 *) (p->value[0]);
23287     }));
23288     /* *INDENT-ON* */
23289
23290   vec_sort_with_function (sort_me, macro_sort_cmp);
23291
23292   if (vec_len (sort_me))
23293     print (vam->ofp, "%-15s%s", "Name", "Value");
23294   else
23295     print (vam->ofp, "The macro table is empty...");
23296
23297   for (i = 0; i < vec_len (sort_me); i++)
23298     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23299   return 0;
23300 }
23301
23302 static int
23303 dump_node_table (vat_main_t * vam)
23304 {
23305   int i, j;
23306   vlib_node_t *node, *next_node;
23307
23308   if (vec_len (vam->graph_nodes) == 0)
23309     {
23310       print (vam->ofp, "Node table empty, issue get_node_graph...");
23311       return 0;
23312     }
23313
23314   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23315     {
23316       node = vam->graph_nodes[0][i];
23317       print (vam->ofp, "[%d] %s", i, node->name);
23318       for (j = 0; j < vec_len (node->next_nodes); j++)
23319         {
23320           if (node->next_nodes[j] != ~0)
23321             {
23322               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23323               print (vam->ofp, "  [%d] %s", j, next_node->name);
23324             }
23325         }
23326     }
23327   return 0;
23328 }
23329
23330 static int
23331 value_sort_cmp (void *a1, void *a2)
23332 {
23333   name_sort_t *n1 = a1;
23334   name_sort_t *n2 = a2;
23335
23336   if (n1->value < n2->value)
23337     return -1;
23338   if (n1->value > n2->value)
23339     return 1;
23340   return 0;
23341 }
23342
23343
23344 static int
23345 dump_msg_api_table (vat_main_t * vam)
23346 {
23347   api_main_t *am = &api_main;
23348   name_sort_t *nses = 0, *ns;
23349   hash_pair_t *hp;
23350   int i;
23351
23352   /* *INDENT-OFF* */
23353   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23354   ({
23355     vec_add2 (nses, ns, 1);
23356     ns->name = (u8 *)(hp->key);
23357     ns->value = (u32) hp->value[0];
23358   }));
23359   /* *INDENT-ON* */
23360
23361   vec_sort_with_function (nses, value_sort_cmp);
23362
23363   for (i = 0; i < vec_len (nses); i++)
23364     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23365   vec_free (nses);
23366   return 0;
23367 }
23368
23369 static int
23370 get_msg_id (vat_main_t * vam)
23371 {
23372   u8 *name_and_crc;
23373   u32 message_index;
23374
23375   if (unformat (vam->input, "%s", &name_and_crc))
23376     {
23377       message_index = vl_msg_api_get_msg_index (name_and_crc);
23378       if (message_index == ~0)
23379         {
23380           print (vam->ofp, " '%s' not found", name_and_crc);
23381           return 0;
23382         }
23383       print (vam->ofp, " '%s' has message index %d",
23384              name_and_crc, message_index);
23385       return 0;
23386     }
23387   errmsg ("name_and_crc required...");
23388   return 0;
23389 }
23390
23391 static int
23392 search_node_table (vat_main_t * vam)
23393 {
23394   unformat_input_t *line_input = vam->input;
23395   u8 *node_to_find;
23396   int j;
23397   vlib_node_t *node, *next_node;
23398   uword *p;
23399
23400   if (vam->graph_node_index_by_name == 0)
23401     {
23402       print (vam->ofp, "Node table empty, issue get_node_graph...");
23403       return 0;
23404     }
23405
23406   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23407     {
23408       if (unformat (line_input, "%s", &node_to_find))
23409         {
23410           vec_add1 (node_to_find, 0);
23411           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23412           if (p == 0)
23413             {
23414               print (vam->ofp, "%s not found...", node_to_find);
23415               goto out;
23416             }
23417           node = vam->graph_nodes[0][p[0]];
23418           print (vam->ofp, "[%d] %s", p[0], node->name);
23419           for (j = 0; j < vec_len (node->next_nodes); j++)
23420             {
23421               if (node->next_nodes[j] != ~0)
23422                 {
23423                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23424                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23425                 }
23426             }
23427         }
23428
23429       else
23430         {
23431           clib_warning ("parse error '%U'", format_unformat_error,
23432                         line_input);
23433           return -99;
23434         }
23435
23436     out:
23437       vec_free (node_to_find);
23438
23439     }
23440
23441   return 0;
23442 }
23443
23444
23445 static int
23446 script (vat_main_t * vam)
23447 {
23448 #if (VPP_API_TEST_BUILTIN==0)
23449   u8 *s = 0;
23450   char *save_current_file;
23451   unformat_input_t save_input;
23452   jmp_buf save_jump_buf;
23453   u32 save_line_number;
23454
23455   FILE *new_fp, *save_ifp;
23456
23457   if (unformat (vam->input, "%s", &s))
23458     {
23459       new_fp = fopen ((char *) s, "r");
23460       if (new_fp == 0)
23461         {
23462           errmsg ("Couldn't open script file %s", s);
23463           vec_free (s);
23464           return -99;
23465         }
23466     }
23467   else
23468     {
23469       errmsg ("Missing script name");
23470       return -99;
23471     }
23472
23473   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23474   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23475   save_ifp = vam->ifp;
23476   save_line_number = vam->input_line_number;
23477   save_current_file = (char *) vam->current_file;
23478
23479   vam->input_line_number = 0;
23480   vam->ifp = new_fp;
23481   vam->current_file = s;
23482   do_one_file (vam);
23483
23484   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23485   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23486   vam->ifp = save_ifp;
23487   vam->input_line_number = save_line_number;
23488   vam->current_file = (u8 *) save_current_file;
23489   vec_free (s);
23490
23491   return 0;
23492 #else
23493   clib_warning ("use the exec command...");
23494   return -99;
23495 #endif
23496 }
23497
23498 static int
23499 echo (vat_main_t * vam)
23500 {
23501   print (vam->ofp, "%v", vam->input->buffer);
23502   return 0;
23503 }
23504
23505 /* List of API message constructors, CLI names map to api_xxx */
23506 #define foreach_vpe_api_msg                                             \
23507 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23508 _(sw_interface_dump,"")                                                 \
23509 _(sw_interface_set_flags,                                               \
23510   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23511 _(sw_interface_add_del_address,                                         \
23512   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23513 _(sw_interface_set_rx_mode,                                             \
23514   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23515 _(sw_interface_set_table,                                               \
23516   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23517 _(sw_interface_set_mpls_enable,                                         \
23518   "<intfc> | sw_if_index [disable | dis]")                              \
23519 _(sw_interface_set_vpath,                                               \
23520   "<intfc> | sw_if_index <id> enable | disable")                        \
23521 _(sw_interface_set_vxlan_bypass,                                        \
23522   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23523 _(sw_interface_set_geneve_bypass,                                       \
23524   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23525 _(sw_interface_set_l2_xconnect,                                         \
23526   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23527   "enable | disable")                                                   \
23528 _(sw_interface_set_l2_bridge,                                           \
23529   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23530   "[shg <split-horizon-group>] [bvi]\n"                                 \
23531   "enable | disable")                                                   \
23532 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23533 _(bridge_domain_add_del,                                                \
23534   "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") \
23535 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23536 _(l2fib_add_del,                                                        \
23537   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23538 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23539 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23540 _(l2_flags,                                                             \
23541   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23542 _(bridge_flags,                                                         \
23543   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23544 _(tap_connect,                                                          \
23545   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23546 _(tap_modify,                                                           \
23547   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23548 _(tap_delete,                                                           \
23549   "<vpp-if-name> | sw_if_index <id>")                                   \
23550 _(sw_interface_tap_dump, "")                                            \
23551 _(tap_create_v2,                                                        \
23552   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23553 _(tap_delete_v2,                                                        \
23554   "<vpp-if-name> | sw_if_index <id>")                                   \
23555 _(sw_interface_tap_v2_dump, "")                                         \
23556 _(bond_create,                                                          \
23557   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23558   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23559 _(bond_delete,                                                          \
23560   "<vpp-if-name> | sw_if_index <id>")                                   \
23561 _(bond_enslave,                                                         \
23562   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23563 _(bond_detach_slave,                                                    \
23564   "sw_if_index <n>")                                                    \
23565 _(sw_interface_bond_dump, "")                                           \
23566 _(sw_interface_slave_dump,                                              \
23567   "<vpp-if-name> | sw_if_index <id>")                                   \
23568 _(ip_table_add_del,                                                     \
23569   "table-id <n> [ipv6]\n")                                              \
23570 _(ip_add_del_route,                                                     \
23571   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23572   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23573   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23574   "[multipath] [count <n>]")                                            \
23575 _(ip_mroute_add_del,                                                    \
23576   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23577   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23578 _(mpls_table_add_del,                                                   \
23579   "table-id <n>\n")                                                     \
23580 _(mpls_route_add_del,                                                   \
23581   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23582   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23583   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23584   "[multipath] [count <n>]")                                            \
23585 _(mpls_ip_bind_unbind,                                                  \
23586   "<label> <addr/len>")                                                 \
23587 _(mpls_tunnel_add_del,                                                  \
23588   " via <addr> [table-id <n>]\n"                                        \
23589   "sw_if_index <id>] [l2]  [del]")                                      \
23590 _(bier_table_add_del,                                                   \
23591   "<label> <sub-domain> <set> <bsl> [del]")                             \
23592 _(bier_route_add_del,                                                   \
23593   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23594   "[<intfc> | sw_if_index <id>]"                                        \
23595   "[weight <n>] [del] [multipath]")                                     \
23596 _(proxy_arp_add_del,                                                    \
23597   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23598 _(proxy_arp_intfc_enable_disable,                                       \
23599   "<intfc> | sw_if_index <id> enable | disable")                        \
23600 _(sw_interface_set_unnumbered,                                          \
23601   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23602 _(ip_neighbor_add_del,                                                  \
23603   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23604   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23605 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23606 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23607   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23608   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23609   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23610 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23611 _(reset_fib, "vrf <n> [ipv6]")                                          \
23612 _(dhcp_proxy_config,                                                    \
23613   "svr <v46-address> src <v46-address>\n"                               \
23614    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23615 _(dhcp_proxy_set_vss,                                                   \
23616   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23617 _(dhcp_proxy_dump, "ip6")                                               \
23618 _(dhcp_client_config,                                                   \
23619   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23620 _(set_ip_flow_hash,                                                     \
23621   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23622 _(sw_interface_ip6_enable_disable,                                      \
23623   "<intfc> | sw_if_index <id> enable | disable")                        \
23624 _(sw_interface_ip6_set_link_local_address,                              \
23625   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23626 _(ip6nd_proxy_add_del,                                                  \
23627   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23628 _(ip6nd_proxy_dump, "")                                                 \
23629 _(sw_interface_ip6nd_ra_prefix,                                         \
23630   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23631   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23632   "[nolink] [isno]")                                                    \
23633 _(sw_interface_ip6nd_ra_config,                                         \
23634   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23635   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23636   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23637 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23638 _(l2_patch_add_del,                                                     \
23639   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23640   "enable | disable")                                                   \
23641 _(sr_localsid_add_del,                                                  \
23642   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23643   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23644 _(classify_add_del_table,                                               \
23645   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23646   " [del] [del-chain] mask <mask-value>\n"                              \
23647   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23648   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23649 _(classify_add_del_session,                                             \
23650   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23651   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23652   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23653   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23654 _(classify_set_interface_ip_table,                                      \
23655   "<intfc> | sw_if_index <nn> table <nn>")                              \
23656 _(classify_set_interface_l2_tables,                                     \
23657   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23658   "  [other-table <nn>]")                                               \
23659 _(get_node_index, "node <node-name")                                    \
23660 _(add_node_next, "node <node-name> next <next-node-name>")              \
23661 _(l2tpv3_create_tunnel,                                                 \
23662   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23663   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23664   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23665 _(l2tpv3_set_tunnel_cookies,                                            \
23666   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23667   "[new_remote_cookie <nn>]\n")                                         \
23668 _(l2tpv3_interface_enable_disable,                                      \
23669   "<intfc> | sw_if_index <nn> enable | disable")                        \
23670 _(l2tpv3_set_lookup_key,                                                \
23671   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23672 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23673 _(vxlan_offload_rx,                                                     \
23674   "hw { <interface name> | hw_if_index <nn>} "                          \
23675   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23676 _(vxlan_add_del_tunnel,                                                 \
23677   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23678   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23679   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23680 _(geneve_add_del_tunnel,                                                \
23681   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23682   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23683   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23684 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23685 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23686 _(gre_add_del_tunnel,                                                   \
23687   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23688   "[teb | erspan <session-id>] [del]")                                  \
23689 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23690 _(l2_fib_clear_table, "")                                               \
23691 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23692 _(l2_interface_vlan_tag_rewrite,                                        \
23693   "<intfc> | sw_if_index <nn> \n"                                       \
23694   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23695   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23696 _(create_vhost_user_if,                                                 \
23697         "socket <filename> [server] [renumber <dev_instance>] "         \
23698         "[mac <mac_address>]")                                          \
23699 _(modify_vhost_user_if,                                                 \
23700         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23701         "[server] [renumber <dev_instance>]")                           \
23702 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23703 _(sw_interface_vhost_user_dump, "")                                     \
23704 _(show_version, "")                                                     \
23705 _(vxlan_gpe_add_del_tunnel,                                             \
23706   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23707   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23708   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23709   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23710 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23711 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23712 _(interface_name_renumber,                                              \
23713   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23714 _(input_acl_set_interface,                                              \
23715   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23716   "  [l2-table <nn>] [del]")                                            \
23717 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23718 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23719   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23720 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23721 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23722 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23723 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23724 _(ip_dump, "ipv4 | ipv6")                                               \
23725 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23726 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23727   "  spid_id <n> ")                                                     \
23728 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23729   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23730   "  integ_alg <alg> integ_key <hex>")                                  \
23731 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23732   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23733   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23734   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23735 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23736 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23737   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23738   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23739   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23740   "  [instance <n>]")     \
23741 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23742 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23743   "  <alg> <hex>\n")                                                    \
23744 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23745 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23746 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23747   "(auth_data 0x<data> | auth_data <data>)")                            \
23748 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23749   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23750 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23751   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23752   "(local|remote)")                                                     \
23753 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23754 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23755 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23756 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23757 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23758 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23759 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23760 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23761 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23762 _(delete_loopback,"sw_if_index <nn>")                                   \
23763 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23764 _(map_add_domain,                                                       \
23765   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23766   "ip6-src <ip6addr> "                                                  \
23767   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23768 _(map_del_domain, "index <n>")                                          \
23769 _(map_add_del_rule,                                                     \
23770   "index <n> psid <n> dst <ip6addr> [del]")                             \
23771 _(map_domain_dump, "")                                                  \
23772 _(map_rule_dump, "index <map-domain>")                                  \
23773 _(want_interface_events,  "enable|disable")                             \
23774 _(want_stats,"enable|disable")                                          \
23775 _(get_first_msg_id, "client <name>")                                    \
23776 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23777 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23778   "fib-id <nn> [ip4][ip6][default]")                                    \
23779 _(get_node_graph, " ")                                                  \
23780 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23781 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23782 _(ioam_disable, "")                                                     \
23783 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23784                             " sw_if_index <sw_if_index> p <priority> "  \
23785                             "w <weight>] [del]")                        \
23786 _(one_add_del_locator, "locator-set <locator_name> "                    \
23787                         "iface <intf> | sw_if_index <sw_if_index> "     \
23788                         "p <priority> w <weight> [del]")                \
23789 _(one_add_del_local_eid,"vni <vni> eid "                                \
23790                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23791                          "locator-set <locator_name> [del]"             \
23792                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23793 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23794 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23795 _(one_enable_disable, "enable|disable")                                 \
23796 _(one_map_register_enable_disable, "enable|disable")                    \
23797 _(one_map_register_fallback_threshold, "<value>")                       \
23798 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23799 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23800                                "[seid <seid>] "                         \
23801                                "rloc <locator> p <prio> "               \
23802                                "w <weight> [rloc <loc> ... ] "          \
23803                                "action <action> [del-all]")             \
23804 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23805                           "<local-eid>")                                \
23806 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23807 _(one_use_petr, "ip-address> | disable")                                \
23808 _(one_map_request_mode, "src-dst|dst-only")                             \
23809 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23810 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23811 _(one_locator_set_dump, "[local | remote]")                             \
23812 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23813 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23814                        "[local] | [remote]")                            \
23815 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23816 _(one_ndp_bd_get, "")                                                   \
23817 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23818 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23819 _(one_l2_arp_bd_get, "")                                                \
23820 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23821 _(one_stats_enable_disable, "enable|disalbe")                           \
23822 _(show_one_stats_enable_disable, "")                                    \
23823 _(one_eid_table_vni_dump, "")                                           \
23824 _(one_eid_table_map_dump, "l2|l3")                                      \
23825 _(one_map_resolver_dump, "")                                            \
23826 _(one_map_server_dump, "")                                              \
23827 _(one_adjacencies_get, "vni <vni>")                                     \
23828 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23829 _(show_one_rloc_probe_state, "")                                        \
23830 _(show_one_map_register_state, "")                                      \
23831 _(show_one_status, "")                                                  \
23832 _(one_stats_dump, "")                                                   \
23833 _(one_stats_flush, "")                                                  \
23834 _(one_get_map_request_itr_rlocs, "")                                    \
23835 _(one_map_register_set_ttl, "<ttl>")                                    \
23836 _(one_set_transport_protocol, "udp|api")                                \
23837 _(one_get_transport_protocol, "")                                       \
23838 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23839 _(one_show_xtr_mode, "")                                                \
23840 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23841 _(one_show_pitr_mode, "")                                               \
23842 _(one_enable_disable_petr_mode, "enable|disable")                       \
23843 _(one_show_petr_mode, "")                                               \
23844 _(show_one_nsh_mapping, "")                                             \
23845 _(show_one_pitr, "")                                                    \
23846 _(show_one_use_petr, "")                                                \
23847 _(show_one_map_request_mode, "")                                        \
23848 _(show_one_map_register_ttl, "")                                        \
23849 _(show_one_map_register_fallback_threshold, "")                         \
23850 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23851                             " sw_if_index <sw_if_index> p <priority> "  \
23852                             "w <weight>] [del]")                        \
23853 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23854                         "iface <intf> | sw_if_index <sw_if_index> "     \
23855                         "p <priority> w <weight> [del]")                \
23856 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23857                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23858                          "locator-set <locator_name> [del]"             \
23859                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23860 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23861 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23862 _(lisp_enable_disable, "enable|disable")                                \
23863 _(lisp_map_register_enable_disable, "enable|disable")                   \
23864 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23865 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23866                                "[seid <seid>] "                         \
23867                                "rloc <locator> p <prio> "               \
23868                                "w <weight> [rloc <loc> ... ] "          \
23869                                "action <action> [del-all]")             \
23870 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23871                           "<local-eid>")                                \
23872 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23873 _(lisp_use_petr, "<ip-address> | disable")                              \
23874 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23875 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23876 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23877 _(lisp_locator_set_dump, "[local | remote]")                            \
23878 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23879 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23880                        "[local] | [remote]")                            \
23881 _(lisp_eid_table_vni_dump, "")                                          \
23882 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23883 _(lisp_map_resolver_dump, "")                                           \
23884 _(lisp_map_server_dump, "")                                             \
23885 _(lisp_adjacencies_get, "vni <vni>")                                    \
23886 _(gpe_fwd_entry_vnis_get, "")                                           \
23887 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23888 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23889                                 "[table <table-id>]")                   \
23890 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23891 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23892 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23893 _(gpe_get_encap_mode, "")                                               \
23894 _(lisp_gpe_add_del_iface, "up|down")                                    \
23895 _(lisp_gpe_enable_disable, "enable|disable")                            \
23896 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23897   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23898 _(show_lisp_rloc_probe_state, "")                                       \
23899 _(show_lisp_map_register_state, "")                                     \
23900 _(show_lisp_status, "")                                                 \
23901 _(lisp_get_map_request_itr_rlocs, "")                                   \
23902 _(show_lisp_pitr, "")                                                   \
23903 _(show_lisp_use_petr, "")                                               \
23904 _(show_lisp_map_request_mode, "")                                       \
23905 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23906 _(af_packet_delete, "name <host interface name>")                       \
23907 _(af_packet_dump, "")                                                   \
23908 _(policer_add_del, "name <policer name> <params> [del]")                \
23909 _(policer_dump, "[name <policer name>]")                                \
23910 _(policer_classify_set_interface,                                       \
23911   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23912   "  [l2-table <nn>] [del]")                                            \
23913 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23914 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23915     "[master|slave]")                                                   \
23916 _(netmap_delete, "name <interface name>")                               \
23917 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23918 _(mpls_fib_dump, "")                                                    \
23919 _(classify_table_ids, "")                                               \
23920 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23921 _(classify_table_info, "table_id <nn>")                                 \
23922 _(classify_session_dump, "table_id <nn>")                               \
23923 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23924     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23925     "[template_interval <nn>] [udp_checksum]")                          \
23926 _(ipfix_exporter_dump, "")                                              \
23927 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23928 _(ipfix_classify_stream_dump, "")                                       \
23929 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23930 _(ipfix_classify_table_dump, "")                                        \
23931 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23932 _(sw_interface_span_dump, "[l2]")                                           \
23933 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23934 _(pg_create_interface, "if_id <nn>")                                    \
23935 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23936 _(pg_enable_disable, "[stream <id>] disable")                           \
23937 _(ip_source_and_port_range_check_add_del,                               \
23938   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23939 _(ip_source_and_port_range_check_interface_add_del,                     \
23940   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23941   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23942 _(ipsec_gre_add_del_tunnel,                                             \
23943   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23944 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23945 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23946 _(l2_interface_pbb_tag_rewrite,                                         \
23947   "<intfc> | sw_if_index <nn> \n"                                       \
23948   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23949   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23950 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23951 _(flow_classify_set_interface,                                          \
23952   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23953 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23954 _(ip_fib_dump, "")                                                      \
23955 _(ip_mfib_dump, "")                                                     \
23956 _(ip6_fib_dump, "")                                                     \
23957 _(ip6_mfib_dump, "")                                                    \
23958 _(feature_enable_disable, "arc_name <arc_name> "                        \
23959   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23960 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23961 "[disable]")                                                            \
23962 _(l2_xconnect_dump, "")                                                 \
23963 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23964 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23965 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23966 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23967 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23968 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23969 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23970   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23971 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23972 _(sock_init_shm, "size <nnn>")                                          \
23973 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23974 _(dns_enable_disable, "[enable][disable]")                              \
23975 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23976 _(dns_resolve_name, "<hostname>")                                       \
23977 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23978 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23979 _(dns_resolve_name, "<hostname>")                                       \
23980 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23981   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23982 _(session_rules_dump, "")                                               \
23983 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23984 _(output_acl_set_interface,                                             \
23985   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23986   "  [l2-table <nn>] [del]")                                            \
23987 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23988
23989 /* List of command functions, CLI names map directly to functions */
23990 #define foreach_cli_function                                    \
23991 _(comment, "usage: comment <ignore-rest-of-line>")              \
23992 _(dump_interface_table, "usage: dump_interface_table")          \
23993 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23994 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23995 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23996 _(dump_stats_table, "usage: dump_stats_table")                  \
23997 _(dump_macro_table, "usage: dump_macro_table ")                 \
23998 _(dump_node_table, "usage: dump_node_table")                    \
23999 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24000 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24001 _(echo, "usage: echo <message>")                                \
24002 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24003 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24004 _(help, "usage: help")                                          \
24005 _(q, "usage: quit")                                             \
24006 _(quit, "usage: quit")                                          \
24007 _(search_node_table, "usage: search_node_table <name>...")      \
24008 _(set, "usage: set <variable-name> <value>")                    \
24009 _(script, "usage: script <file-name>")                          \
24010 _(statseg, "usage: statseg");                                   \
24011 _(unset, "usage: unset <variable-name>")
24012
24013 #define _(N,n)                                  \
24014     static void vl_api_##n##_t_handler_uni      \
24015     (vl_api_##n##_t * mp)                       \
24016     {                                           \
24017         vat_main_t * vam = &vat_main;           \
24018         if (vam->json_output) {                 \
24019             vl_api_##n##_t_handler_json(mp);    \
24020         } else {                                \
24021             vl_api_##n##_t_handler(mp);         \
24022         }                                       \
24023     }
24024 foreach_vpe_api_reply_msg;
24025 #if VPP_API_TEST_BUILTIN == 0
24026 foreach_standalone_reply_msg;
24027 #endif
24028 #undef _
24029
24030 void
24031 vat_api_hookup (vat_main_t * vam)
24032 {
24033 #define _(N,n)                                                  \
24034     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24035                            vl_api_##n##_t_handler_uni,          \
24036                            vl_noop_handler,                     \
24037                            vl_api_##n##_t_endian,               \
24038                            vl_api_##n##_t_print,                \
24039                            sizeof(vl_api_##n##_t), 1);
24040   foreach_vpe_api_reply_msg;
24041 #if VPP_API_TEST_BUILTIN == 0
24042   foreach_standalone_reply_msg;
24043 #endif
24044 #undef _
24045
24046 #if (VPP_API_TEST_BUILTIN==0)
24047   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24048
24049   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24050
24051   vam->function_by_name = hash_create_string (0, sizeof (uword));
24052
24053   vam->help_by_name = hash_create_string (0, sizeof (uword));
24054 #endif
24055
24056   /* API messages we can send */
24057 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24058   foreach_vpe_api_msg;
24059 #undef _
24060
24061   /* Help strings */
24062 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24063   foreach_vpe_api_msg;
24064 #undef _
24065
24066   /* CLI functions */
24067 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24068   foreach_cli_function;
24069 #undef _
24070
24071   /* Help strings */
24072 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24073   foreach_cli_function;
24074 #undef _
24075 }
24076
24077 #if VPP_API_TEST_BUILTIN
24078 static clib_error_t *
24079 vat_api_hookup_shim (vlib_main_t * vm)
24080 {
24081   vat_api_hookup (&vat_main);
24082   return 0;
24083 }
24084
24085 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24086 #endif
24087
24088 /*
24089  * fd.io coding-style-patch-verification: ON
24090  *
24091  * Local Variables:
24092  * eval: (c-set-style "gnu")
24093  * End:
24094  */