vxlan:offload RX flow
[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); i++)
3092         {
3093           node = vam->graph_nodes[i];
3094           vec_free (node->name);
3095           vec_free (node->next_nodes);
3096           vec_free (node);
3097         }
3098       vec_free (vam->graph_nodes);
3099     }
3100
3101   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3102   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3103   vec_free (pvt_copy);
3104
3105   for (i = 0; i < vec_len (vam->graph_nodes); i++)
3106     {
3107       node = vam->graph_nodes[i];
3108       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3109     }
3110 }
3111
3112 static void vl_api_get_node_graph_reply_t_handler_json
3113   (vl_api_get_node_graph_reply_t * mp)
3114 {
3115   vat_main_t *vam = &vat_main;
3116   api_main_t *am = &api_main;
3117   void *oldheap;
3118   vat_json_node_t node;
3119   u8 *reply;
3120
3121   /* $$$$ make this real? */
3122   vat_json_init_object (&node);
3123   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3124   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3125
3126   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3127
3128   /* Toss the shared-memory original... */
3129   pthread_mutex_lock (&am->vlib_rp->mutex);
3130   oldheap = svm_push_data_heap (am->vlib_rp);
3131
3132   vec_free (reply);
3133
3134   svm_pop_heap (oldheap);
3135   pthread_mutex_unlock (&am->vlib_rp->mutex);
3136
3137   vat_json_print (vam->ofp, &node);
3138   vat_json_free (&node);
3139
3140   vam->retval = ntohl (mp->retval);
3141   vam->result_ready = 1;
3142 }
3143
3144 static void
3145 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3146 {
3147   vat_main_t *vam = &vat_main;
3148   u8 *s = 0;
3149
3150   if (mp->local)
3151     {
3152       s = format (s, "%=16d%=16d%=16d",
3153                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3154     }
3155   else
3156     {
3157       s = format (s, "%=16U%=16d%=16d",
3158                   mp->is_ipv6 ? format_ip6_address :
3159                   format_ip4_address,
3160                   mp->ip_address, mp->priority, mp->weight);
3161     }
3162
3163   print (vam->ofp, "%v", s);
3164   vec_free (s);
3165 }
3166
3167 static void
3168 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3169 {
3170   vat_main_t *vam = &vat_main;
3171   vat_json_node_t *node = NULL;
3172   struct in6_addr ip6;
3173   struct in_addr ip4;
3174
3175   if (VAT_JSON_ARRAY != vam->json_tree.type)
3176     {
3177       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3178       vat_json_init_array (&vam->json_tree);
3179     }
3180   node = vat_json_array_add (&vam->json_tree);
3181   vat_json_init_object (node);
3182
3183   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3184   vat_json_object_add_uint (node, "priority", mp->priority);
3185   vat_json_object_add_uint (node, "weight", mp->weight);
3186
3187   if (mp->local)
3188     vat_json_object_add_uint (node, "sw_if_index",
3189                               clib_net_to_host_u32 (mp->sw_if_index));
3190   else
3191     {
3192       if (mp->is_ipv6)
3193         {
3194           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3195           vat_json_object_add_ip6 (node, "address", ip6);
3196         }
3197       else
3198         {
3199           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3200           vat_json_object_add_ip4 (node, "address", ip4);
3201         }
3202     }
3203 }
3204
3205 static void
3206 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3207                                           mp)
3208 {
3209   vat_main_t *vam = &vat_main;
3210   u8 *ls_name = 0;
3211
3212   ls_name = format (0, "%s", mp->ls_name);
3213
3214   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3215          ls_name);
3216   vec_free (ls_name);
3217 }
3218
3219 static void
3220   vl_api_one_locator_set_details_t_handler_json
3221   (vl_api_one_locator_set_details_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   vat_json_node_t *node = 0;
3225   u8 *ls_name = 0;
3226
3227   ls_name = format (0, "%s", mp->ls_name);
3228   vec_add1 (ls_name, 0);
3229
3230   if (VAT_JSON_ARRAY != vam->json_tree.type)
3231     {
3232       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3233       vat_json_init_array (&vam->json_tree);
3234     }
3235   node = vat_json_array_add (&vam->json_tree);
3236
3237   vat_json_init_object (node);
3238   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3239   vat_json_object_add_uint (node, "ls_index",
3240                             clib_net_to_host_u32 (mp->ls_index));
3241   vec_free (ls_name);
3242 }
3243
3244 typedef struct
3245 {
3246   u32 spi;
3247   u8 si;
3248 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3249
3250 uword
3251 unformat_nsh_address (unformat_input_t * input, va_list * args)
3252 {
3253   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3254   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3255 }
3256
3257 u8 *
3258 format_nsh_address_vat (u8 * s, va_list * args)
3259 {
3260   nsh_t *a = va_arg (*args, nsh_t *);
3261   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3262 }
3263
3264 static u8 *
3265 format_lisp_flat_eid (u8 * s, va_list * args)
3266 {
3267   u32 type = va_arg (*args, u32);
3268   u8 *eid = va_arg (*args, u8 *);
3269   u32 eid_len = va_arg (*args, u32);
3270
3271   switch (type)
3272     {
3273     case 0:
3274       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3275     case 1:
3276       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3277     case 2:
3278       return format (s, "%U", format_ethernet_address, eid);
3279     case 3:
3280       return format (s, "%U", format_nsh_address_vat, eid);
3281     }
3282   return 0;
3283 }
3284
3285 static u8 *
3286 format_lisp_eid_vat (u8 * s, va_list * args)
3287 {
3288   u32 type = va_arg (*args, u32);
3289   u8 *eid = va_arg (*args, u8 *);
3290   u32 eid_len = va_arg (*args, u32);
3291   u8 *seid = va_arg (*args, u8 *);
3292   u32 seid_len = va_arg (*args, u32);
3293   u32 is_src_dst = va_arg (*args, u32);
3294
3295   if (is_src_dst)
3296     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3297
3298   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3299
3300   return s;
3301 }
3302
3303 static void
3304 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3305 {
3306   vat_main_t *vam = &vat_main;
3307   u8 *s = 0, *eid = 0;
3308
3309   if (~0 == mp->locator_set_index)
3310     s = format (0, "action: %d", mp->action);
3311   else
3312     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3313
3314   eid = format (0, "%U", format_lisp_eid_vat,
3315                 mp->eid_type,
3316                 mp->eid,
3317                 mp->eid_prefix_len,
3318                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3319   vec_add1 (eid, 0);
3320
3321   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3322          clib_net_to_host_u32 (mp->vni),
3323          eid,
3324          mp->is_local ? "local" : "remote",
3325          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3326          clib_net_to_host_u16 (mp->key_id), mp->key);
3327
3328   vec_free (s);
3329   vec_free (eid);
3330 }
3331
3332 static void
3333 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3334                                              * mp)
3335 {
3336   vat_main_t *vam = &vat_main;
3337   vat_json_node_t *node = 0;
3338   u8 *eid = 0;
3339
3340   if (VAT_JSON_ARRAY != vam->json_tree.type)
3341     {
3342       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3343       vat_json_init_array (&vam->json_tree);
3344     }
3345   node = vat_json_array_add (&vam->json_tree);
3346
3347   vat_json_init_object (node);
3348   if (~0 == mp->locator_set_index)
3349     vat_json_object_add_uint (node, "action", mp->action);
3350   else
3351     vat_json_object_add_uint (node, "locator_set_index",
3352                               clib_net_to_host_u32 (mp->locator_set_index));
3353
3354   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3355   if (mp->eid_type == 3)
3356     {
3357       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3358       vat_json_init_object (nsh_json);
3359       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3360       vat_json_object_add_uint (nsh_json, "spi",
3361                                 clib_net_to_host_u32 (nsh->spi));
3362       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3363     }
3364   else
3365     {
3366       eid = format (0, "%U", format_lisp_eid_vat,
3367                     mp->eid_type,
3368                     mp->eid,
3369                     mp->eid_prefix_len,
3370                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3371       vec_add1 (eid, 0);
3372       vat_json_object_add_string_copy (node, "eid", eid);
3373       vec_free (eid);
3374     }
3375   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3376   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3377   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3378
3379   if (mp->key_id)
3380     {
3381       vat_json_object_add_uint (node, "key_id",
3382                                 clib_net_to_host_u16 (mp->key_id));
3383       vat_json_object_add_string_copy (node, "key", mp->key);
3384     }
3385 }
3386
3387 static void
3388 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3389 {
3390   vat_main_t *vam = &vat_main;
3391   u8 *seid = 0, *deid = 0;
3392   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3393
3394   deid = format (0, "%U", format_lisp_eid_vat,
3395                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3396
3397   seid = format (0, "%U", format_lisp_eid_vat,
3398                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3399
3400   vec_add1 (deid, 0);
3401   vec_add1 (seid, 0);
3402
3403   if (mp->is_ip4)
3404     format_ip_address_fcn = format_ip4_address;
3405   else
3406     format_ip_address_fcn = format_ip6_address;
3407
3408
3409   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3410          clib_net_to_host_u32 (mp->vni),
3411          seid, deid,
3412          format_ip_address_fcn, mp->lloc,
3413          format_ip_address_fcn, mp->rloc,
3414          clib_net_to_host_u32 (mp->pkt_count),
3415          clib_net_to_host_u32 (mp->bytes));
3416
3417   vec_free (deid);
3418   vec_free (seid);
3419 }
3420
3421 static void
3422 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3423 {
3424   struct in6_addr ip6;
3425   struct in_addr ip4;
3426   vat_main_t *vam = &vat_main;
3427   vat_json_node_t *node = 0;
3428   u8 *deid = 0, *seid = 0;
3429
3430   if (VAT_JSON_ARRAY != vam->json_tree.type)
3431     {
3432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3433       vat_json_init_array (&vam->json_tree);
3434     }
3435   node = vat_json_array_add (&vam->json_tree);
3436
3437   vat_json_init_object (node);
3438   deid = format (0, "%U", format_lisp_eid_vat,
3439                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3440
3441   seid = format (0, "%U", format_lisp_eid_vat,
3442                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3443
3444   vec_add1 (deid, 0);
3445   vec_add1 (seid, 0);
3446
3447   vat_json_object_add_string_copy (node, "seid", seid);
3448   vat_json_object_add_string_copy (node, "deid", deid);
3449   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3450
3451   if (mp->is_ip4)
3452     {
3453       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3454       vat_json_object_add_ip4 (node, "lloc", ip4);
3455       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3456       vat_json_object_add_ip4 (node, "rloc", ip4);
3457     }
3458   else
3459     {
3460       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3461       vat_json_object_add_ip6 (node, "lloc", ip6);
3462       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3463       vat_json_object_add_ip6 (node, "rloc", ip6);
3464     }
3465   vat_json_object_add_uint (node, "pkt_count",
3466                             clib_net_to_host_u32 (mp->pkt_count));
3467   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3468
3469   vec_free (deid);
3470   vec_free (seid);
3471 }
3472
3473 static void
3474   vl_api_one_eid_table_map_details_t_handler
3475   (vl_api_one_eid_table_map_details_t * mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478
3479   u8 *line = format (0, "%=10d%=10d",
3480                      clib_net_to_host_u32 (mp->vni),
3481                      clib_net_to_host_u32 (mp->dp_table));
3482   print (vam->ofp, "%v", line);
3483   vec_free (line);
3484 }
3485
3486 static void
3487   vl_api_one_eid_table_map_details_t_handler_json
3488   (vl_api_one_eid_table_map_details_t * mp)
3489 {
3490   vat_main_t *vam = &vat_main;
3491   vat_json_node_t *node = NULL;
3492
3493   if (VAT_JSON_ARRAY != vam->json_tree.type)
3494     {
3495       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3496       vat_json_init_array (&vam->json_tree);
3497     }
3498   node = vat_json_array_add (&vam->json_tree);
3499   vat_json_init_object (node);
3500   vat_json_object_add_uint (node, "dp_table",
3501                             clib_net_to_host_u32 (mp->dp_table));
3502   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3503 }
3504
3505 static void
3506   vl_api_one_eid_table_vni_details_t_handler
3507   (vl_api_one_eid_table_vni_details_t * mp)
3508 {
3509   vat_main_t *vam = &vat_main;
3510
3511   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3512   print (vam->ofp, "%v", line);
3513   vec_free (line);
3514 }
3515
3516 static void
3517   vl_api_one_eid_table_vni_details_t_handler_json
3518   (vl_api_one_eid_table_vni_details_t * mp)
3519 {
3520   vat_main_t *vam = &vat_main;
3521   vat_json_node_t *node = NULL;
3522
3523   if (VAT_JSON_ARRAY != vam->json_tree.type)
3524     {
3525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3526       vat_json_init_array (&vam->json_tree);
3527     }
3528   node = vat_json_array_add (&vam->json_tree);
3529   vat_json_init_object (node);
3530   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3531 }
3532
3533 static void
3534   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3535   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3536 {
3537   vat_main_t *vam = &vat_main;
3538   int retval = clib_net_to_host_u32 (mp->retval);
3539
3540   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3541   print (vam->ofp, "fallback threshold value: %d", mp->value);
3542
3543   vam->retval = retval;
3544   vam->result_ready = 1;
3545 }
3546
3547 static void
3548   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3549   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3550 {
3551   vat_main_t *vam = &vat_main;
3552   vat_json_node_t _node, *node = &_node;
3553   int retval = clib_net_to_host_u32 (mp->retval);
3554
3555   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3556   vat_json_init_object (node);
3557   vat_json_object_add_uint (node, "value", mp->value);
3558
3559   vat_json_print (vam->ofp, node);
3560   vat_json_free (node);
3561
3562   vam->retval = retval;
3563   vam->result_ready = 1;
3564 }
3565
3566 static void
3567   vl_api_show_one_map_register_state_reply_t_handler
3568   (vl_api_show_one_map_register_state_reply_t * mp)
3569 {
3570   vat_main_t *vam = &vat_main;
3571   int retval = clib_net_to_host_u32 (mp->retval);
3572
3573   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3574
3575   vam->retval = retval;
3576   vam->result_ready = 1;
3577 }
3578
3579 static void
3580   vl_api_show_one_map_register_state_reply_t_handler_json
3581   (vl_api_show_one_map_register_state_reply_t * mp)
3582 {
3583   vat_main_t *vam = &vat_main;
3584   vat_json_node_t _node, *node = &_node;
3585   int retval = clib_net_to_host_u32 (mp->retval);
3586
3587   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3588
3589   vat_json_init_object (node);
3590   vat_json_object_add_string_copy (node, "state", s);
3591
3592   vat_json_print (vam->ofp, node);
3593   vat_json_free (node);
3594
3595   vam->retval = retval;
3596   vam->result_ready = 1;
3597   vec_free (s);
3598 }
3599
3600 static void
3601   vl_api_show_one_rloc_probe_state_reply_t_handler
3602   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3603 {
3604   vat_main_t *vam = &vat_main;
3605   int retval = clib_net_to_host_u32 (mp->retval);
3606
3607   if (retval)
3608     goto end;
3609
3610   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3611 end:
3612   vam->retval = retval;
3613   vam->result_ready = 1;
3614 }
3615
3616 static void
3617   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3618   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3619 {
3620   vat_main_t *vam = &vat_main;
3621   vat_json_node_t _node, *node = &_node;
3622   int retval = clib_net_to_host_u32 (mp->retval);
3623
3624   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3625   vat_json_init_object (node);
3626   vat_json_object_add_string_copy (node, "state", s);
3627
3628   vat_json_print (vam->ofp, node);
3629   vat_json_free (node);
3630
3631   vam->retval = retval;
3632   vam->result_ready = 1;
3633   vec_free (s);
3634 }
3635
3636 static void
3637   vl_api_show_one_stats_enable_disable_reply_t_handler
3638   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3639 {
3640   vat_main_t *vam = &vat_main;
3641   int retval = clib_net_to_host_u32 (mp->retval);
3642
3643   if (retval)
3644     goto end;
3645
3646   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3647 end:
3648   vam->retval = retval;
3649   vam->result_ready = 1;
3650 }
3651
3652 static void
3653   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3654   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3655 {
3656   vat_main_t *vam = &vat_main;
3657   vat_json_node_t _node, *node = &_node;
3658   int retval = clib_net_to_host_u32 (mp->retval);
3659
3660   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3661   vat_json_init_object (node);
3662   vat_json_object_add_string_copy (node, "state", s);
3663
3664   vat_json_print (vam->ofp, node);
3665   vat_json_free (node);
3666
3667   vam->retval = retval;
3668   vam->result_ready = 1;
3669   vec_free (s);
3670 }
3671
3672 static void
3673 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3674 {
3675   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3676   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3677   e->vni = clib_net_to_host_u32 (e->vni);
3678 }
3679
3680 static void
3681   gpe_fwd_entries_get_reply_t_net_to_host
3682   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3683 {
3684   u32 i;
3685
3686   mp->count = clib_net_to_host_u32 (mp->count);
3687   for (i = 0; i < mp->count; i++)
3688     {
3689       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3690     }
3691 }
3692
3693 static u8 *
3694 format_gpe_encap_mode (u8 * s, va_list * args)
3695 {
3696   u32 mode = va_arg (*args, u32);
3697
3698   switch (mode)
3699     {
3700     case 0:
3701       return format (s, "lisp");
3702     case 1:
3703       return format (s, "vxlan");
3704     }
3705   return 0;
3706 }
3707
3708 static void
3709   vl_api_gpe_get_encap_mode_reply_t_handler
3710   (vl_api_gpe_get_encap_mode_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713
3714   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3715   vam->retval = ntohl (mp->retval);
3716   vam->result_ready = 1;
3717 }
3718
3719 static void
3720   vl_api_gpe_get_encap_mode_reply_t_handler_json
3721   (vl_api_gpe_get_encap_mode_reply_t * mp)
3722 {
3723   vat_main_t *vam = &vat_main;
3724   vat_json_node_t node;
3725
3726   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3727   vec_add1 (encap_mode, 0);
3728
3729   vat_json_init_object (&node);
3730   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3731
3732   vec_free (encap_mode);
3733   vat_json_print (vam->ofp, &node);
3734   vat_json_free (&node);
3735
3736   vam->retval = ntohl (mp->retval);
3737   vam->result_ready = 1;
3738 }
3739
3740 static void
3741   vl_api_gpe_fwd_entry_path_details_t_handler
3742   (vl_api_gpe_fwd_entry_path_details_t * mp)
3743 {
3744   vat_main_t *vam = &vat_main;
3745   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3746
3747   if (mp->lcl_loc.is_ip4)
3748     format_ip_address_fcn = format_ip4_address;
3749   else
3750     format_ip_address_fcn = format_ip6_address;
3751
3752   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3753          format_ip_address_fcn, &mp->lcl_loc,
3754          format_ip_address_fcn, &mp->rmt_loc);
3755 }
3756
3757 static void
3758 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3759 {
3760   struct in6_addr ip6;
3761   struct in_addr ip4;
3762
3763   if (loc->is_ip4)
3764     {
3765       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3766       vat_json_object_add_ip4 (n, "address", ip4);
3767     }
3768   else
3769     {
3770       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3771       vat_json_object_add_ip6 (n, "address", ip6);
3772     }
3773   vat_json_object_add_uint (n, "weight", loc->weight);
3774 }
3775
3776 static void
3777   vl_api_gpe_fwd_entry_path_details_t_handler_json
3778   (vl_api_gpe_fwd_entry_path_details_t * mp)
3779 {
3780   vat_main_t *vam = &vat_main;
3781   vat_json_node_t *node = NULL;
3782   vat_json_node_t *loc_node;
3783
3784   if (VAT_JSON_ARRAY != vam->json_tree.type)
3785     {
3786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3787       vat_json_init_array (&vam->json_tree);
3788     }
3789   node = vat_json_array_add (&vam->json_tree);
3790   vat_json_init_object (node);
3791
3792   loc_node = vat_json_object_add (node, "local_locator");
3793   vat_json_init_object (loc_node);
3794   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3795
3796   loc_node = vat_json_object_add (node, "remote_locator");
3797   vat_json_init_object (loc_node);
3798   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3799 }
3800
3801 static void
3802   vl_api_gpe_fwd_entries_get_reply_t_handler
3803   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3804 {
3805   vat_main_t *vam = &vat_main;
3806   u32 i;
3807   int retval = clib_net_to_host_u32 (mp->retval);
3808   vl_api_gpe_fwd_entry_t *e;
3809
3810   if (retval)
3811     goto end;
3812
3813   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3814
3815   for (i = 0; i < mp->count; i++)
3816     {
3817       e = &mp->entries[i];
3818       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3819              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3820              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3821     }
3822
3823 end:
3824   vam->retval = retval;
3825   vam->result_ready = 1;
3826 }
3827
3828 static void
3829   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3830   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3831 {
3832   u8 *s = 0;
3833   vat_main_t *vam = &vat_main;
3834   vat_json_node_t *e = 0, root;
3835   u32 i;
3836   int retval = clib_net_to_host_u32 (mp->retval);
3837   vl_api_gpe_fwd_entry_t *fwd;
3838
3839   if (retval)
3840     goto end;
3841
3842   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3843   vat_json_init_array (&root);
3844
3845   for (i = 0; i < mp->count; i++)
3846     {
3847       e = vat_json_array_add (&root);
3848       fwd = &mp->entries[i];
3849
3850       vat_json_init_object (e);
3851       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3852       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3853       vat_json_object_add_int (e, "vni", fwd->vni);
3854       vat_json_object_add_int (e, "action", fwd->action);
3855
3856       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3857                   fwd->leid_prefix_len);
3858       vec_add1 (s, 0);
3859       vat_json_object_add_string_copy (e, "leid", s);
3860       vec_free (s);
3861
3862       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3863                   fwd->reid_prefix_len);
3864       vec_add1 (s, 0);
3865       vat_json_object_add_string_copy (e, "reid", s);
3866       vec_free (s);
3867     }
3868
3869   vat_json_print (vam->ofp, &root);
3870   vat_json_free (&root);
3871
3872 end:
3873   vam->retval = retval;
3874   vam->result_ready = 1;
3875 }
3876
3877 static void
3878   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3879   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3880 {
3881   vat_main_t *vam = &vat_main;
3882   u32 i, n;
3883   int retval = clib_net_to_host_u32 (mp->retval);
3884   vl_api_gpe_native_fwd_rpath_t *r;
3885
3886   if (retval)
3887     goto end;
3888
3889   n = clib_net_to_host_u32 (mp->count);
3890
3891   for (i = 0; i < n; i++)
3892     {
3893       r = &mp->entries[i];
3894       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3895              clib_net_to_host_u32 (r->fib_index),
3896              clib_net_to_host_u32 (r->nh_sw_if_index),
3897              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3898     }
3899
3900 end:
3901   vam->retval = retval;
3902   vam->result_ready = 1;
3903 }
3904
3905 static void
3906   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3907   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3908 {
3909   vat_main_t *vam = &vat_main;
3910   vat_json_node_t root, *e;
3911   u32 i, n;
3912   int retval = clib_net_to_host_u32 (mp->retval);
3913   vl_api_gpe_native_fwd_rpath_t *r;
3914   u8 *s;
3915
3916   if (retval)
3917     goto end;
3918
3919   n = clib_net_to_host_u32 (mp->count);
3920   vat_json_init_array (&root);
3921
3922   for (i = 0; i < n; i++)
3923     {
3924       e = vat_json_array_add (&root);
3925       vat_json_init_object (e);
3926       r = &mp->entries[i];
3927       s =
3928         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3929                 r->nh_addr);
3930       vec_add1 (s, 0);
3931       vat_json_object_add_string_copy (e, "ip4", s);
3932       vec_free (s);
3933
3934       vat_json_object_add_uint (e, "fib_index",
3935                                 clib_net_to_host_u32 (r->fib_index));
3936       vat_json_object_add_uint (e, "nh_sw_if_index",
3937                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3938     }
3939
3940   vat_json_print (vam->ofp, &root);
3941   vat_json_free (&root);
3942
3943 end:
3944   vam->retval = retval;
3945   vam->result_ready = 1;
3946 }
3947
3948 static void
3949   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3950   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3951 {
3952   vat_main_t *vam = &vat_main;
3953   u32 i, n;
3954   int retval = clib_net_to_host_u32 (mp->retval);
3955
3956   if (retval)
3957     goto end;
3958
3959   n = clib_net_to_host_u32 (mp->count);
3960
3961   for (i = 0; i < n; i++)
3962     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3963
3964 end:
3965   vam->retval = retval;
3966   vam->result_ready = 1;
3967 }
3968
3969 static void
3970   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3971   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3972 {
3973   vat_main_t *vam = &vat_main;
3974   vat_json_node_t root;
3975   u32 i, n;
3976   int retval = clib_net_to_host_u32 (mp->retval);
3977
3978   if (retval)
3979     goto end;
3980
3981   n = clib_net_to_host_u32 (mp->count);
3982   vat_json_init_array (&root);
3983
3984   for (i = 0; i < n; i++)
3985     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3986
3987   vat_json_print (vam->ofp, &root);
3988   vat_json_free (&root);
3989
3990 end:
3991   vam->retval = retval;
3992   vam->result_ready = 1;
3993 }
3994
3995 static void
3996   vl_api_one_ndp_entries_get_reply_t_handler
3997   (vl_api_one_ndp_entries_get_reply_t * mp)
3998 {
3999   vat_main_t *vam = &vat_main;
4000   u32 i, n;
4001   int retval = clib_net_to_host_u32 (mp->retval);
4002
4003   if (retval)
4004     goto end;
4005
4006   n = clib_net_to_host_u32 (mp->count);
4007
4008   for (i = 0; i < n; i++)
4009     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
4010            format_ethernet_address, mp->entries[i].mac);
4011
4012 end:
4013   vam->retval = retval;
4014   vam->result_ready = 1;
4015 }
4016
4017 static void
4018   vl_api_one_ndp_entries_get_reply_t_handler_json
4019   (vl_api_one_ndp_entries_get_reply_t * mp)
4020 {
4021   u8 *s = 0;
4022   vat_main_t *vam = &vat_main;
4023   vat_json_node_t *e = 0, root;
4024   u32 i, n;
4025   int retval = clib_net_to_host_u32 (mp->retval);
4026   vl_api_one_ndp_entry_t *arp_entry;
4027
4028   if (retval)
4029     goto end;
4030
4031   n = clib_net_to_host_u32 (mp->count);
4032   vat_json_init_array (&root);
4033
4034   for (i = 0; i < n; i++)
4035     {
4036       e = vat_json_array_add (&root);
4037       arp_entry = &mp->entries[i];
4038
4039       vat_json_init_object (e);
4040       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4041       vec_add1 (s, 0);
4042
4043       vat_json_object_add_string_copy (e, "mac", s);
4044       vec_free (s);
4045
4046       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4047       vec_add1 (s, 0);
4048       vat_json_object_add_string_copy (e, "ip6", s);
4049       vec_free (s);
4050     }
4051
4052   vat_json_print (vam->ofp, &root);
4053   vat_json_free (&root);
4054
4055 end:
4056   vam->retval = retval;
4057   vam->result_ready = 1;
4058 }
4059
4060 static void
4061   vl_api_one_l2_arp_entries_get_reply_t_handler
4062   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4063 {
4064   vat_main_t *vam = &vat_main;
4065   u32 i, n;
4066   int retval = clib_net_to_host_u32 (mp->retval);
4067
4068   if (retval)
4069     goto end;
4070
4071   n = clib_net_to_host_u32 (mp->count);
4072
4073   for (i = 0; i < n; i++)
4074     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4075            format_ethernet_address, mp->entries[i].mac);
4076
4077 end:
4078   vam->retval = retval;
4079   vam->result_ready = 1;
4080 }
4081
4082 static void
4083   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4084   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4085 {
4086   u8 *s = 0;
4087   vat_main_t *vam = &vat_main;
4088   vat_json_node_t *e = 0, root;
4089   u32 i, n;
4090   int retval = clib_net_to_host_u32 (mp->retval);
4091   vl_api_one_l2_arp_entry_t *arp_entry;
4092
4093   if (retval)
4094     goto end;
4095
4096   n = clib_net_to_host_u32 (mp->count);
4097   vat_json_init_array (&root);
4098
4099   for (i = 0; i < n; i++)
4100     {
4101       e = vat_json_array_add (&root);
4102       arp_entry = &mp->entries[i];
4103
4104       vat_json_init_object (e);
4105       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4106       vec_add1 (s, 0);
4107
4108       vat_json_object_add_string_copy (e, "mac", s);
4109       vec_free (s);
4110
4111       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4112       vec_add1 (s, 0);
4113       vat_json_object_add_string_copy (e, "ip4", s);
4114       vec_free (s);
4115     }
4116
4117   vat_json_print (vam->ofp, &root);
4118   vat_json_free (&root);
4119
4120 end:
4121   vam->retval = retval;
4122   vam->result_ready = 1;
4123 }
4124
4125 static void
4126 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4127 {
4128   vat_main_t *vam = &vat_main;
4129   u32 i, n;
4130   int retval = clib_net_to_host_u32 (mp->retval);
4131
4132   if (retval)
4133     goto end;
4134
4135   n = clib_net_to_host_u32 (mp->count);
4136
4137   for (i = 0; i < n; i++)
4138     {
4139       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4140     }
4141
4142 end:
4143   vam->retval = retval;
4144   vam->result_ready = 1;
4145 }
4146
4147 static void
4148   vl_api_one_ndp_bd_get_reply_t_handler_json
4149   (vl_api_one_ndp_bd_get_reply_t * mp)
4150 {
4151   vat_main_t *vam = &vat_main;
4152   vat_json_node_t root;
4153   u32 i, n;
4154   int retval = clib_net_to_host_u32 (mp->retval);
4155
4156   if (retval)
4157     goto end;
4158
4159   n = clib_net_to_host_u32 (mp->count);
4160   vat_json_init_array (&root);
4161
4162   for (i = 0; i < n; i++)
4163     {
4164       vat_json_array_add_uint (&root,
4165                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4166     }
4167
4168   vat_json_print (vam->ofp, &root);
4169   vat_json_free (&root);
4170
4171 end:
4172   vam->retval = retval;
4173   vam->result_ready = 1;
4174 }
4175
4176 static void
4177   vl_api_one_l2_arp_bd_get_reply_t_handler
4178   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4179 {
4180   vat_main_t *vam = &vat_main;
4181   u32 i, n;
4182   int retval = clib_net_to_host_u32 (mp->retval);
4183
4184   if (retval)
4185     goto end;
4186
4187   n = clib_net_to_host_u32 (mp->count);
4188
4189   for (i = 0; i < n; i++)
4190     {
4191       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4192     }
4193
4194 end:
4195   vam->retval = retval;
4196   vam->result_ready = 1;
4197 }
4198
4199 static void
4200   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4201   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4202 {
4203   vat_main_t *vam = &vat_main;
4204   vat_json_node_t root;
4205   u32 i, n;
4206   int retval = clib_net_to_host_u32 (mp->retval);
4207
4208   if (retval)
4209     goto end;
4210
4211   n = clib_net_to_host_u32 (mp->count);
4212   vat_json_init_array (&root);
4213
4214   for (i = 0; i < n; i++)
4215     {
4216       vat_json_array_add_uint (&root,
4217                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4218     }
4219
4220   vat_json_print (vam->ofp, &root);
4221   vat_json_free (&root);
4222
4223 end:
4224   vam->retval = retval;
4225   vam->result_ready = 1;
4226 }
4227
4228 static void
4229   vl_api_one_adjacencies_get_reply_t_handler
4230   (vl_api_one_adjacencies_get_reply_t * mp)
4231 {
4232   vat_main_t *vam = &vat_main;
4233   u32 i, n;
4234   int retval = clib_net_to_host_u32 (mp->retval);
4235   vl_api_one_adjacency_t *a;
4236
4237   if (retval)
4238     goto end;
4239
4240   n = clib_net_to_host_u32 (mp->count);
4241
4242   for (i = 0; i < n; i++)
4243     {
4244       a = &mp->adjacencies[i];
4245       print (vam->ofp, "%U %40U",
4246              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4247              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4248     }
4249
4250 end:
4251   vam->retval = retval;
4252   vam->result_ready = 1;
4253 }
4254
4255 static void
4256   vl_api_one_adjacencies_get_reply_t_handler_json
4257   (vl_api_one_adjacencies_get_reply_t * mp)
4258 {
4259   u8 *s = 0;
4260   vat_main_t *vam = &vat_main;
4261   vat_json_node_t *e = 0, root;
4262   u32 i, n;
4263   int retval = clib_net_to_host_u32 (mp->retval);
4264   vl_api_one_adjacency_t *a;
4265
4266   if (retval)
4267     goto end;
4268
4269   n = clib_net_to_host_u32 (mp->count);
4270   vat_json_init_array (&root);
4271
4272   for (i = 0; i < n; i++)
4273     {
4274       e = vat_json_array_add (&root);
4275       a = &mp->adjacencies[i];
4276
4277       vat_json_init_object (e);
4278       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4279                   a->leid_prefix_len);
4280       vec_add1 (s, 0);
4281       vat_json_object_add_string_copy (e, "leid", s);
4282       vec_free (s);
4283
4284       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4285                   a->reid_prefix_len);
4286       vec_add1 (s, 0);
4287       vat_json_object_add_string_copy (e, "reid", s);
4288       vec_free (s);
4289     }
4290
4291   vat_json_print (vam->ofp, &root);
4292   vat_json_free (&root);
4293
4294 end:
4295   vam->retval = retval;
4296   vam->result_ready = 1;
4297 }
4298
4299 static void
4300 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4301 {
4302   vat_main_t *vam = &vat_main;
4303
4304   print (vam->ofp, "%=20U",
4305          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4306          mp->ip_address);
4307 }
4308
4309 static void
4310   vl_api_one_map_server_details_t_handler_json
4311   (vl_api_one_map_server_details_t * mp)
4312 {
4313   vat_main_t *vam = &vat_main;
4314   vat_json_node_t *node = NULL;
4315   struct in6_addr ip6;
4316   struct in_addr ip4;
4317
4318   if (VAT_JSON_ARRAY != vam->json_tree.type)
4319     {
4320       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4321       vat_json_init_array (&vam->json_tree);
4322     }
4323   node = vat_json_array_add (&vam->json_tree);
4324
4325   vat_json_init_object (node);
4326   if (mp->is_ipv6)
4327     {
4328       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4329       vat_json_object_add_ip6 (node, "map-server", ip6);
4330     }
4331   else
4332     {
4333       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4334       vat_json_object_add_ip4 (node, "map-server", ip4);
4335     }
4336 }
4337
4338 static void
4339 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4340                                            * mp)
4341 {
4342   vat_main_t *vam = &vat_main;
4343
4344   print (vam->ofp, "%=20U",
4345          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4346          mp->ip_address);
4347 }
4348
4349 static void
4350   vl_api_one_map_resolver_details_t_handler_json
4351   (vl_api_one_map_resolver_details_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   vat_json_node_t *node = NULL;
4355   struct in6_addr ip6;
4356   struct in_addr ip4;
4357
4358   if (VAT_JSON_ARRAY != vam->json_tree.type)
4359     {
4360       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4361       vat_json_init_array (&vam->json_tree);
4362     }
4363   node = vat_json_array_add (&vam->json_tree);
4364
4365   vat_json_init_object (node);
4366   if (mp->is_ipv6)
4367     {
4368       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4369       vat_json_object_add_ip6 (node, "map resolver", ip6);
4370     }
4371   else
4372     {
4373       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4374       vat_json_object_add_ip4 (node, "map resolver", ip4);
4375     }
4376 }
4377
4378 static void
4379 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4380 {
4381   vat_main_t *vam = &vat_main;
4382   i32 retval = ntohl (mp->retval);
4383
4384   if (0 <= retval)
4385     {
4386       print (vam->ofp, "feature: %s\ngpe: %s",
4387              mp->feature_status ? "enabled" : "disabled",
4388              mp->gpe_status ? "enabled" : "disabled");
4389     }
4390
4391   vam->retval = retval;
4392   vam->result_ready = 1;
4393 }
4394
4395 static void
4396   vl_api_show_one_status_reply_t_handler_json
4397   (vl_api_show_one_status_reply_t * mp)
4398 {
4399   vat_main_t *vam = &vat_main;
4400   vat_json_node_t node;
4401   u8 *gpe_status = NULL;
4402   u8 *feature_status = NULL;
4403
4404   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4405   feature_status = format (0, "%s",
4406                            mp->feature_status ? "enabled" : "disabled");
4407   vec_add1 (gpe_status, 0);
4408   vec_add1 (feature_status, 0);
4409
4410   vat_json_init_object (&node);
4411   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4412   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4413
4414   vec_free (gpe_status);
4415   vec_free (feature_status);
4416
4417   vat_json_print (vam->ofp, &node);
4418   vat_json_free (&node);
4419
4420   vam->retval = ntohl (mp->retval);
4421   vam->result_ready = 1;
4422 }
4423
4424 static void
4425   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4426   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4427 {
4428   vat_main_t *vam = &vat_main;
4429   i32 retval = ntohl (mp->retval);
4430
4431   if (retval >= 0)
4432     {
4433       print (vam->ofp, "%=20s", mp->locator_set_name);
4434     }
4435
4436   vam->retval = retval;
4437   vam->result_ready = 1;
4438 }
4439
4440 static void
4441   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4442   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4443 {
4444   vat_main_t *vam = &vat_main;
4445   vat_json_node_t *node = NULL;
4446
4447   if (VAT_JSON_ARRAY != vam->json_tree.type)
4448     {
4449       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4450       vat_json_init_array (&vam->json_tree);
4451     }
4452   node = vat_json_array_add (&vam->json_tree);
4453
4454   vat_json_init_object (node);
4455   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4456
4457   vat_json_print (vam->ofp, node);
4458   vat_json_free (node);
4459
4460   vam->retval = ntohl (mp->retval);
4461   vam->result_ready = 1;
4462 }
4463
4464 static u8 *
4465 format_lisp_map_request_mode (u8 * s, va_list * args)
4466 {
4467   u32 mode = va_arg (*args, u32);
4468
4469   switch (mode)
4470     {
4471     case 0:
4472       return format (0, "dst-only");
4473     case 1:
4474       return format (0, "src-dst");
4475     }
4476   return 0;
4477 }
4478
4479 static void
4480   vl_api_show_one_map_request_mode_reply_t_handler
4481   (vl_api_show_one_map_request_mode_reply_t * mp)
4482 {
4483   vat_main_t *vam = &vat_main;
4484   i32 retval = ntohl (mp->retval);
4485
4486   if (0 <= retval)
4487     {
4488       u32 mode = mp->mode;
4489       print (vam->ofp, "map_request_mode: %U",
4490              format_lisp_map_request_mode, mode);
4491     }
4492
4493   vam->retval = retval;
4494   vam->result_ready = 1;
4495 }
4496
4497 static void
4498   vl_api_show_one_map_request_mode_reply_t_handler_json
4499   (vl_api_show_one_map_request_mode_reply_t * mp)
4500 {
4501   vat_main_t *vam = &vat_main;
4502   vat_json_node_t node;
4503   u8 *s = 0;
4504   u32 mode;
4505
4506   mode = mp->mode;
4507   s = format (0, "%U", format_lisp_map_request_mode, mode);
4508   vec_add1 (s, 0);
4509
4510   vat_json_init_object (&node);
4511   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4512   vat_json_print (vam->ofp, &node);
4513   vat_json_free (&node);
4514
4515   vec_free (s);
4516   vam->retval = ntohl (mp->retval);
4517   vam->result_ready = 1;
4518 }
4519
4520 static void
4521   vl_api_one_show_xtr_mode_reply_t_handler
4522   (vl_api_one_show_xtr_mode_reply_t * mp)
4523 {
4524   vat_main_t *vam = &vat_main;
4525   i32 retval = ntohl (mp->retval);
4526
4527   if (0 <= retval)
4528     {
4529       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4530     }
4531
4532   vam->retval = retval;
4533   vam->result_ready = 1;
4534 }
4535
4536 static void
4537   vl_api_one_show_xtr_mode_reply_t_handler_json
4538   (vl_api_one_show_xtr_mode_reply_t * mp)
4539 {
4540   vat_main_t *vam = &vat_main;
4541   vat_json_node_t node;
4542   u8 *status = 0;
4543
4544   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4545   vec_add1 (status, 0);
4546
4547   vat_json_init_object (&node);
4548   vat_json_object_add_string_copy (&node, "status", status);
4549
4550   vec_free (status);
4551
4552   vat_json_print (vam->ofp, &node);
4553   vat_json_free (&node);
4554
4555   vam->retval = ntohl (mp->retval);
4556   vam->result_ready = 1;
4557 }
4558
4559 static void
4560   vl_api_one_show_pitr_mode_reply_t_handler
4561   (vl_api_one_show_pitr_mode_reply_t * mp)
4562 {
4563   vat_main_t *vam = &vat_main;
4564   i32 retval = ntohl (mp->retval);
4565
4566   if (0 <= retval)
4567     {
4568       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4569     }
4570
4571   vam->retval = retval;
4572   vam->result_ready = 1;
4573 }
4574
4575 static void
4576   vl_api_one_show_pitr_mode_reply_t_handler_json
4577   (vl_api_one_show_pitr_mode_reply_t * mp)
4578 {
4579   vat_main_t *vam = &vat_main;
4580   vat_json_node_t node;
4581   u8 *status = 0;
4582
4583   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4584   vec_add1 (status, 0);
4585
4586   vat_json_init_object (&node);
4587   vat_json_object_add_string_copy (&node, "status", status);
4588
4589   vec_free (status);
4590
4591   vat_json_print (vam->ofp, &node);
4592   vat_json_free (&node);
4593
4594   vam->retval = ntohl (mp->retval);
4595   vam->result_ready = 1;
4596 }
4597
4598 static void
4599   vl_api_one_show_petr_mode_reply_t_handler
4600   (vl_api_one_show_petr_mode_reply_t * mp)
4601 {
4602   vat_main_t *vam = &vat_main;
4603   i32 retval = ntohl (mp->retval);
4604
4605   if (0 <= retval)
4606     {
4607       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4608     }
4609
4610   vam->retval = retval;
4611   vam->result_ready = 1;
4612 }
4613
4614 static void
4615   vl_api_one_show_petr_mode_reply_t_handler_json
4616   (vl_api_one_show_petr_mode_reply_t * mp)
4617 {
4618   vat_main_t *vam = &vat_main;
4619   vat_json_node_t node;
4620   u8 *status = 0;
4621
4622   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4623   vec_add1 (status, 0);
4624
4625   vat_json_init_object (&node);
4626   vat_json_object_add_string_copy (&node, "status", status);
4627
4628   vec_free (status);
4629
4630   vat_json_print (vam->ofp, &node);
4631   vat_json_free (&node);
4632
4633   vam->retval = ntohl (mp->retval);
4634   vam->result_ready = 1;
4635 }
4636
4637 static void
4638   vl_api_show_one_use_petr_reply_t_handler
4639   (vl_api_show_one_use_petr_reply_t * mp)
4640 {
4641   vat_main_t *vam = &vat_main;
4642   i32 retval = ntohl (mp->retval);
4643
4644   if (0 <= retval)
4645     {
4646       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4647       if (mp->status)
4648         {
4649           print (vam->ofp, "Proxy-ETR address; %U",
4650                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4651                  mp->address);
4652         }
4653     }
4654
4655   vam->retval = retval;
4656   vam->result_ready = 1;
4657 }
4658
4659 static void
4660   vl_api_show_one_use_petr_reply_t_handler_json
4661   (vl_api_show_one_use_petr_reply_t * mp)
4662 {
4663   vat_main_t *vam = &vat_main;
4664   vat_json_node_t node;
4665   u8 *status = 0;
4666   struct in_addr ip4;
4667   struct in6_addr ip6;
4668
4669   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4670   vec_add1 (status, 0);
4671
4672   vat_json_init_object (&node);
4673   vat_json_object_add_string_copy (&node, "status", status);
4674   if (mp->status)
4675     {
4676       if (mp->is_ip4)
4677         {
4678           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4679           vat_json_object_add_ip6 (&node, "address", ip6);
4680         }
4681       else
4682         {
4683           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4684           vat_json_object_add_ip4 (&node, "address", ip4);
4685         }
4686     }
4687
4688   vec_free (status);
4689
4690   vat_json_print (vam->ofp, &node);
4691   vat_json_free (&node);
4692
4693   vam->retval = ntohl (mp->retval);
4694   vam->result_ready = 1;
4695 }
4696
4697 static void
4698   vl_api_show_one_nsh_mapping_reply_t_handler
4699   (vl_api_show_one_nsh_mapping_reply_t * mp)
4700 {
4701   vat_main_t *vam = &vat_main;
4702   i32 retval = ntohl (mp->retval);
4703
4704   if (0 <= retval)
4705     {
4706       print (vam->ofp, "%-20s%-16s",
4707              mp->is_set ? "set" : "not-set",
4708              mp->is_set ? (char *) mp->locator_set_name : "");
4709     }
4710
4711   vam->retval = retval;
4712   vam->result_ready = 1;
4713 }
4714
4715 static void
4716   vl_api_show_one_nsh_mapping_reply_t_handler_json
4717   (vl_api_show_one_nsh_mapping_reply_t * mp)
4718 {
4719   vat_main_t *vam = &vat_main;
4720   vat_json_node_t node;
4721   u8 *status = 0;
4722
4723   status = format (0, "%s", mp->is_set ? "yes" : "no");
4724   vec_add1 (status, 0);
4725
4726   vat_json_init_object (&node);
4727   vat_json_object_add_string_copy (&node, "is_set", status);
4728   if (mp->is_set)
4729     {
4730       vat_json_object_add_string_copy (&node, "locator_set",
4731                                        mp->locator_set_name);
4732     }
4733
4734   vec_free (status);
4735
4736   vat_json_print (vam->ofp, &node);
4737   vat_json_free (&node);
4738
4739   vam->retval = ntohl (mp->retval);
4740   vam->result_ready = 1;
4741 }
4742
4743 static void
4744   vl_api_show_one_map_register_ttl_reply_t_handler
4745   (vl_api_show_one_map_register_ttl_reply_t * mp)
4746 {
4747   vat_main_t *vam = &vat_main;
4748   i32 retval = ntohl (mp->retval);
4749
4750   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4751
4752   if (0 <= retval)
4753     {
4754       print (vam->ofp, "ttl: %u", mp->ttl);
4755     }
4756
4757   vam->retval = retval;
4758   vam->result_ready = 1;
4759 }
4760
4761 static void
4762   vl_api_show_one_map_register_ttl_reply_t_handler_json
4763   (vl_api_show_one_map_register_ttl_reply_t * mp)
4764 {
4765   vat_main_t *vam = &vat_main;
4766   vat_json_node_t node;
4767
4768   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4769   vat_json_init_object (&node);
4770   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4771
4772   vat_json_print (vam->ofp, &node);
4773   vat_json_free (&node);
4774
4775   vam->retval = ntohl (mp->retval);
4776   vam->result_ready = 1;
4777 }
4778
4779 static void
4780 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4781 {
4782   vat_main_t *vam = &vat_main;
4783   i32 retval = ntohl (mp->retval);
4784
4785   if (0 <= retval)
4786     {
4787       print (vam->ofp, "%-20s%-16s",
4788              mp->status ? "enabled" : "disabled",
4789              mp->status ? (char *) mp->locator_set_name : "");
4790     }
4791
4792   vam->retval = retval;
4793   vam->result_ready = 1;
4794 }
4795
4796 static void
4797 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4798 {
4799   vat_main_t *vam = &vat_main;
4800   vat_json_node_t node;
4801   u8 *status = 0;
4802
4803   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4804   vec_add1 (status, 0);
4805
4806   vat_json_init_object (&node);
4807   vat_json_object_add_string_copy (&node, "status", status);
4808   if (mp->status)
4809     {
4810       vat_json_object_add_string_copy (&node, "locator_set",
4811                                        mp->locator_set_name);
4812     }
4813
4814   vec_free (status);
4815
4816   vat_json_print (vam->ofp, &node);
4817   vat_json_free (&node);
4818
4819   vam->retval = ntohl (mp->retval);
4820   vam->result_ready = 1;
4821 }
4822
4823 static u8 *
4824 format_policer_type (u8 * s, va_list * va)
4825 {
4826   u32 i = va_arg (*va, u32);
4827
4828   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4829     s = format (s, "1r2c");
4830   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4831     s = format (s, "1r3c");
4832   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4833     s = format (s, "2r3c-2698");
4834   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4835     s = format (s, "2r3c-4115");
4836   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4837     s = format (s, "2r3c-mef5cf1");
4838   else
4839     s = format (s, "ILLEGAL");
4840   return s;
4841 }
4842
4843 static u8 *
4844 format_policer_rate_type (u8 * s, va_list * va)
4845 {
4846   u32 i = va_arg (*va, u32);
4847
4848   if (i == SSE2_QOS_RATE_KBPS)
4849     s = format (s, "kbps");
4850   else if (i == SSE2_QOS_RATE_PPS)
4851     s = format (s, "pps");
4852   else
4853     s = format (s, "ILLEGAL");
4854   return s;
4855 }
4856
4857 static u8 *
4858 format_policer_round_type (u8 * s, va_list * va)
4859 {
4860   u32 i = va_arg (*va, u32);
4861
4862   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4863     s = format (s, "closest");
4864   else if (i == SSE2_QOS_ROUND_TO_UP)
4865     s = format (s, "up");
4866   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4867     s = format (s, "down");
4868   else
4869     s = format (s, "ILLEGAL");
4870   return s;
4871 }
4872
4873 static u8 *
4874 format_policer_action_type (u8 * s, va_list * va)
4875 {
4876   u32 i = va_arg (*va, u32);
4877
4878   if (i == SSE2_QOS_ACTION_DROP)
4879     s = format (s, "drop");
4880   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4881     s = format (s, "transmit");
4882   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4883     s = format (s, "mark-and-transmit");
4884   else
4885     s = format (s, "ILLEGAL");
4886   return s;
4887 }
4888
4889 static u8 *
4890 format_dscp (u8 * s, va_list * va)
4891 {
4892   u32 i = va_arg (*va, u32);
4893   char *t = 0;
4894
4895   switch (i)
4896     {
4897 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4898       foreach_vnet_dscp
4899 #undef _
4900     default:
4901       return format (s, "ILLEGAL");
4902     }
4903   s = format (s, "%s", t);
4904   return s;
4905 }
4906
4907 static void
4908 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4909 {
4910   vat_main_t *vam = &vat_main;
4911   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4912
4913   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4914     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4915   else
4916     conform_dscp_str = format (0, "");
4917
4918   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4919     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4920   else
4921     exceed_dscp_str = format (0, "");
4922
4923   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4924     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4925   else
4926     violate_dscp_str = format (0, "");
4927
4928   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4929          "rate type %U, round type %U, %s rate, %s color-aware, "
4930          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4931          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4932          "conform action %U%s, exceed action %U%s, violate action %U%s",
4933          mp->name,
4934          format_policer_type, mp->type,
4935          ntohl (mp->cir),
4936          ntohl (mp->eir),
4937          clib_net_to_host_u64 (mp->cb),
4938          clib_net_to_host_u64 (mp->eb),
4939          format_policer_rate_type, mp->rate_type,
4940          format_policer_round_type, mp->round_type,
4941          mp->single_rate ? "single" : "dual",
4942          mp->color_aware ? "is" : "not",
4943          ntohl (mp->cir_tokens_per_period),
4944          ntohl (mp->pir_tokens_per_period),
4945          ntohl (mp->scale),
4946          ntohl (mp->current_limit),
4947          ntohl (mp->current_bucket),
4948          ntohl (mp->extended_limit),
4949          ntohl (mp->extended_bucket),
4950          clib_net_to_host_u64 (mp->last_update_time),
4951          format_policer_action_type, mp->conform_action_type,
4952          conform_dscp_str,
4953          format_policer_action_type, mp->exceed_action_type,
4954          exceed_dscp_str,
4955          format_policer_action_type, mp->violate_action_type,
4956          violate_dscp_str);
4957
4958   vec_free (conform_dscp_str);
4959   vec_free (exceed_dscp_str);
4960   vec_free (violate_dscp_str);
4961 }
4962
4963 static void vl_api_policer_details_t_handler_json
4964   (vl_api_policer_details_t * mp)
4965 {
4966   vat_main_t *vam = &vat_main;
4967   vat_json_node_t *node;
4968   u8 *rate_type_str, *round_type_str, *type_str;
4969   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4970
4971   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4972   round_type_str =
4973     format (0, "%U", format_policer_round_type, mp->round_type);
4974   type_str = format (0, "%U", format_policer_type, mp->type);
4975   conform_action_str = format (0, "%U", format_policer_action_type,
4976                                mp->conform_action_type);
4977   exceed_action_str = format (0, "%U", format_policer_action_type,
4978                               mp->exceed_action_type);
4979   violate_action_str = format (0, "%U", format_policer_action_type,
4980                                mp->violate_action_type);
4981
4982   if (VAT_JSON_ARRAY != vam->json_tree.type)
4983     {
4984       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4985       vat_json_init_array (&vam->json_tree);
4986     }
4987   node = vat_json_array_add (&vam->json_tree);
4988
4989   vat_json_init_object (node);
4990   vat_json_object_add_string_copy (node, "name", mp->name);
4991   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4992   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4993   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4994   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4995   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4996   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4997   vat_json_object_add_string_copy (node, "type", type_str);
4998   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4999   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
5000   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
5001   vat_json_object_add_uint (node, "cir_tokens_per_period",
5002                             ntohl (mp->cir_tokens_per_period));
5003   vat_json_object_add_uint (node, "eir_tokens_per_period",
5004                             ntohl (mp->pir_tokens_per_period));
5005   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
5006   vat_json_object_add_uint (node, "current_bucket",
5007                             ntohl (mp->current_bucket));
5008   vat_json_object_add_uint (node, "extended_limit",
5009                             ntohl (mp->extended_limit));
5010   vat_json_object_add_uint (node, "extended_bucket",
5011                             ntohl (mp->extended_bucket));
5012   vat_json_object_add_uint (node, "last_update_time",
5013                             ntohl (mp->last_update_time));
5014   vat_json_object_add_string_copy (node, "conform_action",
5015                                    conform_action_str);
5016   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5017     {
5018       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5019       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5020       vec_free (dscp_str);
5021     }
5022   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5023   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5024     {
5025       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5026       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5027       vec_free (dscp_str);
5028     }
5029   vat_json_object_add_string_copy (node, "violate_action",
5030                                    violate_action_str);
5031   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5032     {
5033       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5034       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5035       vec_free (dscp_str);
5036     }
5037
5038   vec_free (rate_type_str);
5039   vec_free (round_type_str);
5040   vec_free (type_str);
5041   vec_free (conform_action_str);
5042   vec_free (exceed_action_str);
5043   vec_free (violate_action_str);
5044 }
5045
5046 static void
5047 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5048                                            mp)
5049 {
5050   vat_main_t *vam = &vat_main;
5051   int i, count = ntohl (mp->count);
5052
5053   if (count > 0)
5054     print (vam->ofp, "classify table ids (%d) : ", count);
5055   for (i = 0; i < count; i++)
5056     {
5057       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5058       print (vam->ofp, (i < count - 1) ? "," : "");
5059     }
5060   vam->retval = ntohl (mp->retval);
5061   vam->result_ready = 1;
5062 }
5063
5064 static void
5065   vl_api_classify_table_ids_reply_t_handler_json
5066   (vl_api_classify_table_ids_reply_t * mp)
5067 {
5068   vat_main_t *vam = &vat_main;
5069   int i, count = ntohl (mp->count);
5070
5071   if (count > 0)
5072     {
5073       vat_json_node_t node;
5074
5075       vat_json_init_object (&node);
5076       for (i = 0; i < count; i++)
5077         {
5078           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5079         }
5080       vat_json_print (vam->ofp, &node);
5081       vat_json_free (&node);
5082     }
5083   vam->retval = ntohl (mp->retval);
5084   vam->result_ready = 1;
5085 }
5086
5087 static void
5088   vl_api_classify_table_by_interface_reply_t_handler
5089   (vl_api_classify_table_by_interface_reply_t * mp)
5090 {
5091   vat_main_t *vam = &vat_main;
5092   u32 table_id;
5093
5094   table_id = ntohl (mp->l2_table_id);
5095   if (table_id != ~0)
5096     print (vam->ofp, "l2 table id : %d", table_id);
5097   else
5098     print (vam->ofp, "l2 table id : No input ACL tables configured");
5099   table_id = ntohl (mp->ip4_table_id);
5100   if (table_id != ~0)
5101     print (vam->ofp, "ip4 table id : %d", table_id);
5102   else
5103     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5104   table_id = ntohl (mp->ip6_table_id);
5105   if (table_id != ~0)
5106     print (vam->ofp, "ip6 table id : %d", table_id);
5107   else
5108     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5109   vam->retval = ntohl (mp->retval);
5110   vam->result_ready = 1;
5111 }
5112
5113 static void
5114   vl_api_classify_table_by_interface_reply_t_handler_json
5115   (vl_api_classify_table_by_interface_reply_t * mp)
5116 {
5117   vat_main_t *vam = &vat_main;
5118   vat_json_node_t node;
5119
5120   vat_json_init_object (&node);
5121
5122   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5123   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5124   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5125
5126   vat_json_print (vam->ofp, &node);
5127   vat_json_free (&node);
5128
5129   vam->retval = ntohl (mp->retval);
5130   vam->result_ready = 1;
5131 }
5132
5133 static void vl_api_policer_add_del_reply_t_handler
5134   (vl_api_policer_add_del_reply_t * mp)
5135 {
5136   vat_main_t *vam = &vat_main;
5137   i32 retval = ntohl (mp->retval);
5138   if (vam->async_mode)
5139     {
5140       vam->async_errors += (retval < 0);
5141     }
5142   else
5143     {
5144       vam->retval = retval;
5145       vam->result_ready = 1;
5146       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5147         /*
5148          * Note: this is just barely thread-safe, depends on
5149          * the main thread spinning waiting for an answer...
5150          */
5151         errmsg ("policer index %d", ntohl (mp->policer_index));
5152     }
5153 }
5154
5155 static void vl_api_policer_add_del_reply_t_handler_json
5156   (vl_api_policer_add_del_reply_t * mp)
5157 {
5158   vat_main_t *vam = &vat_main;
5159   vat_json_node_t node;
5160
5161   vat_json_init_object (&node);
5162   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5163   vat_json_object_add_uint (&node, "policer_index",
5164                             ntohl (mp->policer_index));
5165
5166   vat_json_print (vam->ofp, &node);
5167   vat_json_free (&node);
5168
5169   vam->retval = ntohl (mp->retval);
5170   vam->result_ready = 1;
5171 }
5172
5173 /* Format hex dump. */
5174 u8 *
5175 format_hex_bytes (u8 * s, va_list * va)
5176 {
5177   u8 *bytes = va_arg (*va, u8 *);
5178   int n_bytes = va_arg (*va, int);
5179   uword i;
5180
5181   /* Print short or long form depending on byte count. */
5182   uword short_form = n_bytes <= 32;
5183   u32 indent = format_get_indent (s);
5184
5185   if (n_bytes == 0)
5186     return s;
5187
5188   for (i = 0; i < n_bytes; i++)
5189     {
5190       if (!short_form && (i % 32) == 0)
5191         s = format (s, "%08x: ", i);
5192       s = format (s, "%02x", bytes[i]);
5193       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5194         s = format (s, "\n%U", format_white_space, indent);
5195     }
5196
5197   return s;
5198 }
5199
5200 static void
5201 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5202                                             * mp)
5203 {
5204   vat_main_t *vam = &vat_main;
5205   i32 retval = ntohl (mp->retval);
5206   if (retval == 0)
5207     {
5208       print (vam->ofp, "classify table info :");
5209       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5210              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5211              ntohl (mp->miss_next_index));
5212       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5213              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5214              ntohl (mp->match_n_vectors));
5215       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5216              ntohl (mp->mask_length));
5217     }
5218   vam->retval = retval;
5219   vam->result_ready = 1;
5220 }
5221
5222 static void
5223   vl_api_classify_table_info_reply_t_handler_json
5224   (vl_api_classify_table_info_reply_t * mp)
5225 {
5226   vat_main_t *vam = &vat_main;
5227   vat_json_node_t node;
5228
5229   i32 retval = ntohl (mp->retval);
5230   if (retval == 0)
5231     {
5232       vat_json_init_object (&node);
5233
5234       vat_json_object_add_int (&node, "sessions",
5235                                ntohl (mp->active_sessions));
5236       vat_json_object_add_int (&node, "nexttbl",
5237                                ntohl (mp->next_table_index));
5238       vat_json_object_add_int (&node, "nextnode",
5239                                ntohl (mp->miss_next_index));
5240       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5241       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5242       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5243       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5244                       ntohl (mp->mask_length), 0);
5245       vat_json_object_add_string_copy (&node, "mask", s);
5246
5247       vat_json_print (vam->ofp, &node);
5248       vat_json_free (&node);
5249     }
5250   vam->retval = ntohl (mp->retval);
5251   vam->result_ready = 1;
5252 }
5253
5254 static void
5255 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5256                                            mp)
5257 {
5258   vat_main_t *vam = &vat_main;
5259
5260   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5261          ntohl (mp->hit_next_index), ntohl (mp->advance),
5262          ntohl (mp->opaque_index));
5263   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5264          ntohl (mp->match_length));
5265 }
5266
5267 static void
5268   vl_api_classify_session_details_t_handler_json
5269   (vl_api_classify_session_details_t * mp)
5270 {
5271   vat_main_t *vam = &vat_main;
5272   vat_json_node_t *node = NULL;
5273
5274   if (VAT_JSON_ARRAY != vam->json_tree.type)
5275     {
5276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5277       vat_json_init_array (&vam->json_tree);
5278     }
5279   node = vat_json_array_add (&vam->json_tree);
5280
5281   vat_json_init_object (node);
5282   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5283   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5284   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5285   u8 *s =
5286     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5287             0);
5288   vat_json_object_add_string_copy (node, "match", s);
5289 }
5290
5291 static void vl_api_pg_create_interface_reply_t_handler
5292   (vl_api_pg_create_interface_reply_t * mp)
5293 {
5294   vat_main_t *vam = &vat_main;
5295
5296   vam->retval = ntohl (mp->retval);
5297   vam->result_ready = 1;
5298 }
5299
5300 static void vl_api_pg_create_interface_reply_t_handler_json
5301   (vl_api_pg_create_interface_reply_t * mp)
5302 {
5303   vat_main_t *vam = &vat_main;
5304   vat_json_node_t node;
5305
5306   i32 retval = ntohl (mp->retval);
5307   if (retval == 0)
5308     {
5309       vat_json_init_object (&node);
5310
5311       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5312
5313       vat_json_print (vam->ofp, &node);
5314       vat_json_free (&node);
5315     }
5316   vam->retval = ntohl (mp->retval);
5317   vam->result_ready = 1;
5318 }
5319
5320 static void vl_api_policer_classify_details_t_handler
5321   (vl_api_policer_classify_details_t * mp)
5322 {
5323   vat_main_t *vam = &vat_main;
5324
5325   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5326          ntohl (mp->table_index));
5327 }
5328
5329 static void vl_api_policer_classify_details_t_handler_json
5330   (vl_api_policer_classify_details_t * mp)
5331 {
5332   vat_main_t *vam = &vat_main;
5333   vat_json_node_t *node;
5334
5335   if (VAT_JSON_ARRAY != vam->json_tree.type)
5336     {
5337       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5338       vat_json_init_array (&vam->json_tree);
5339     }
5340   node = vat_json_array_add (&vam->json_tree);
5341
5342   vat_json_init_object (node);
5343   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5344   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5345 }
5346
5347 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5348   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5349 {
5350   vat_main_t *vam = &vat_main;
5351   i32 retval = ntohl (mp->retval);
5352   if (vam->async_mode)
5353     {
5354       vam->async_errors += (retval < 0);
5355     }
5356   else
5357     {
5358       vam->retval = retval;
5359       vam->sw_if_index = ntohl (mp->sw_if_index);
5360       vam->result_ready = 1;
5361     }
5362   vam->regenerate_interface_table = 1;
5363 }
5364
5365 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5366   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5367 {
5368   vat_main_t *vam = &vat_main;
5369   vat_json_node_t node;
5370
5371   vat_json_init_object (&node);
5372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5373   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5374
5375   vat_json_print (vam->ofp, &node);
5376   vat_json_free (&node);
5377
5378   vam->retval = ntohl (mp->retval);
5379   vam->result_ready = 1;
5380 }
5381
5382 static void vl_api_flow_classify_details_t_handler
5383   (vl_api_flow_classify_details_t * mp)
5384 {
5385   vat_main_t *vam = &vat_main;
5386
5387   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5388          ntohl (mp->table_index));
5389 }
5390
5391 static void vl_api_flow_classify_details_t_handler_json
5392   (vl_api_flow_classify_details_t * mp)
5393 {
5394   vat_main_t *vam = &vat_main;
5395   vat_json_node_t *node;
5396
5397   if (VAT_JSON_ARRAY != vam->json_tree.type)
5398     {
5399       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5400       vat_json_init_array (&vam->json_tree);
5401     }
5402   node = vat_json_array_add (&vam->json_tree);
5403
5404   vat_json_init_object (node);
5405   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5406   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5407 }
5408
5409 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5410 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5411 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5412 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5413 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5414 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5415 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5416 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5417 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5418 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5419 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5420 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5421 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5422 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5423 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5424 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5425 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5426 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5427 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5428 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5429 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5430 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5431
5432 /*
5433  * Generate boilerplate reply handlers, which
5434  * dig the return value out of the xxx_reply_t API message,
5435  * stick it into vam->retval, and set vam->result_ready
5436  *
5437  * Could also do this by pointing N message decode slots at
5438  * a single function, but that could break in subtle ways.
5439  */
5440
5441 #define foreach_standard_reply_retval_handler           \
5442 _(sw_interface_set_flags_reply)                         \
5443 _(sw_interface_add_del_address_reply)                   \
5444 _(sw_interface_set_rx_mode_reply)                       \
5445 _(sw_interface_set_table_reply)                         \
5446 _(sw_interface_set_mpls_enable_reply)                   \
5447 _(sw_interface_set_vpath_reply)                         \
5448 _(sw_interface_set_vxlan_bypass_reply)                  \
5449 _(sw_interface_set_geneve_bypass_reply)                 \
5450 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5451 _(sw_interface_set_l2_bridge_reply)                     \
5452 _(bridge_domain_add_del_reply)                          \
5453 _(sw_interface_set_l2_xconnect_reply)                   \
5454 _(l2fib_add_del_reply)                                  \
5455 _(l2fib_flush_int_reply)                                \
5456 _(l2fib_flush_bd_reply)                                 \
5457 _(ip_add_del_route_reply)                               \
5458 _(ip_table_add_del_reply)                               \
5459 _(ip_mroute_add_del_reply)                              \
5460 _(mpls_route_add_del_reply)                             \
5461 _(mpls_table_add_del_reply)                             \
5462 _(mpls_ip_bind_unbind_reply)                            \
5463 _(bier_route_add_del_reply)                             \
5464 _(bier_table_add_del_reply)                             \
5465 _(proxy_arp_add_del_reply)                              \
5466 _(proxy_arp_intfc_enable_disable_reply)                 \
5467 _(sw_interface_set_unnumbered_reply)                    \
5468 _(ip_neighbor_add_del_reply)                            \
5469 _(oam_add_del_reply)                                    \
5470 _(reset_fib_reply)                                      \
5471 _(dhcp_proxy_config_reply)                              \
5472 _(dhcp_proxy_set_vss_reply)                             \
5473 _(dhcp_client_config_reply)                             \
5474 _(set_ip_flow_hash_reply)                               \
5475 _(sw_interface_ip6_enable_disable_reply)                \
5476 _(sw_interface_ip6_set_link_local_address_reply)        \
5477 _(ip6nd_proxy_add_del_reply)                            \
5478 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5479 _(sw_interface_ip6nd_ra_config_reply)                   \
5480 _(set_arp_neighbor_limit_reply)                         \
5481 _(l2_patch_add_del_reply)                               \
5482 _(sr_policy_add_reply)                                  \
5483 _(sr_policy_mod_reply)                                  \
5484 _(sr_policy_del_reply)                                  \
5485 _(sr_localsid_add_del_reply)                            \
5486 _(sr_steering_add_del_reply)                            \
5487 _(classify_add_del_session_reply)                       \
5488 _(classify_set_interface_ip_table_reply)                \
5489 _(classify_set_interface_l2_tables_reply)               \
5490 _(l2tpv3_set_tunnel_cookies_reply)                      \
5491 _(l2tpv3_interface_enable_disable_reply)                \
5492 _(l2tpv3_set_lookup_key_reply)                          \
5493 _(l2_fib_clear_table_reply)                             \
5494 _(l2_interface_efp_filter_reply)                        \
5495 _(l2_interface_vlan_tag_rewrite_reply)                  \
5496 _(modify_vhost_user_if_reply)                           \
5497 _(delete_vhost_user_if_reply)                           \
5498 _(ip_probe_neighbor_reply)                              \
5499 _(ip_scan_neighbor_enable_disable_reply)                \
5500 _(want_ip4_arp_events_reply)                            \
5501 _(want_ip6_nd_events_reply)                             \
5502 _(want_l2_macs_events_reply)                            \
5503 _(input_acl_set_interface_reply)                        \
5504 _(ipsec_spd_add_del_reply)                              \
5505 _(ipsec_interface_add_del_spd_reply)                    \
5506 _(ipsec_spd_add_del_entry_reply)                        \
5507 _(ipsec_sad_add_del_entry_reply)                        \
5508 _(ipsec_sa_set_key_reply)                               \
5509 _(ipsec_tunnel_if_add_del_reply)                        \
5510 _(ipsec_tunnel_if_set_key_reply)                        \
5511 _(ipsec_tunnel_if_set_sa_reply)                         \
5512 _(ikev2_profile_add_del_reply)                          \
5513 _(ikev2_profile_set_auth_reply)                         \
5514 _(ikev2_profile_set_id_reply)                           \
5515 _(ikev2_profile_set_ts_reply)                           \
5516 _(ikev2_set_local_key_reply)                            \
5517 _(ikev2_set_responder_reply)                            \
5518 _(ikev2_set_ike_transforms_reply)                       \
5519 _(ikev2_set_esp_transforms_reply)                       \
5520 _(ikev2_set_sa_lifetime_reply)                          \
5521 _(ikev2_initiate_sa_init_reply)                         \
5522 _(ikev2_initiate_del_ike_sa_reply)                      \
5523 _(ikev2_initiate_del_child_sa_reply)                    \
5524 _(ikev2_initiate_rekey_child_sa_reply)                  \
5525 _(delete_loopback_reply)                                \
5526 _(bd_ip_mac_add_del_reply)                              \
5527 _(map_del_domain_reply)                                 \
5528 _(map_add_del_rule_reply)                               \
5529 _(want_interface_events_reply)                          \
5530 _(want_stats_reply)                                     \
5531 _(cop_interface_enable_disable_reply)                   \
5532 _(cop_whitelist_enable_disable_reply)                   \
5533 _(sw_interface_clear_stats_reply)                       \
5534 _(ioam_enable_reply)                                    \
5535 _(ioam_disable_reply)                                   \
5536 _(one_add_del_locator_reply)                            \
5537 _(one_add_del_local_eid_reply)                          \
5538 _(one_add_del_remote_mapping_reply)                     \
5539 _(one_add_del_adjacency_reply)                          \
5540 _(one_add_del_map_resolver_reply)                       \
5541 _(one_add_del_map_server_reply)                         \
5542 _(one_enable_disable_reply)                             \
5543 _(one_rloc_probe_enable_disable_reply)                  \
5544 _(one_map_register_enable_disable_reply)                \
5545 _(one_map_register_set_ttl_reply)                       \
5546 _(one_set_transport_protocol_reply)                     \
5547 _(one_map_register_fallback_threshold_reply)            \
5548 _(one_pitr_set_locator_set_reply)                       \
5549 _(one_map_request_mode_reply)                           \
5550 _(one_add_del_map_request_itr_rlocs_reply)              \
5551 _(one_eid_table_add_del_map_reply)                      \
5552 _(one_use_petr_reply)                                   \
5553 _(one_stats_enable_disable_reply)                       \
5554 _(one_add_del_l2_arp_entry_reply)                       \
5555 _(one_add_del_ndp_entry_reply)                          \
5556 _(one_stats_flush_reply)                                \
5557 _(one_enable_disable_xtr_mode_reply)                    \
5558 _(one_enable_disable_pitr_mode_reply)                   \
5559 _(one_enable_disable_petr_mode_reply)                   \
5560 _(gpe_enable_disable_reply)                             \
5561 _(gpe_set_encap_mode_reply)                             \
5562 _(gpe_add_del_iface_reply)                              \
5563 _(gpe_add_del_native_fwd_rpath_reply)                   \
5564 _(af_packet_delete_reply)                               \
5565 _(policer_classify_set_interface_reply)                 \
5566 _(netmap_create_reply)                                  \
5567 _(netmap_delete_reply)                                  \
5568 _(set_ipfix_exporter_reply)                             \
5569 _(set_ipfix_classify_stream_reply)                      \
5570 _(ipfix_classify_table_add_del_reply)                   \
5571 _(flow_classify_set_interface_reply)                    \
5572 _(sw_interface_span_enable_disable_reply)               \
5573 _(pg_capture_reply)                                     \
5574 _(pg_enable_disable_reply)                              \
5575 _(ip_source_and_port_range_check_add_del_reply)         \
5576 _(ip_source_and_port_range_check_interface_add_del_reply)\
5577 _(delete_subif_reply)                                   \
5578 _(l2_interface_pbb_tag_rewrite_reply)                   \
5579 _(punt_reply)                                           \
5580 _(feature_enable_disable_reply)                         \
5581 _(sw_interface_tag_add_del_reply)                       \
5582 _(hw_interface_set_mtu_reply)                           \
5583 _(p2p_ethernet_add_reply)                               \
5584 _(p2p_ethernet_del_reply)                               \
5585 _(lldp_config_reply)                                    \
5586 _(sw_interface_set_lldp_reply)                          \
5587 _(tcp_configure_src_addresses_reply)                    \
5588 _(dns_enable_disable_reply)                             \
5589 _(dns_name_server_add_del_reply)                        \
5590 _(session_rule_add_del_reply)                           \
5591 _(ip_container_proxy_add_del_reply)                     \
5592 _(output_acl_set_interface_reply)                       \
5593 _(qos_record_enable_disable_reply)
5594
5595 #define _(n)                                    \
5596     static void vl_api_##n##_t_handler          \
5597     (vl_api_##n##_t * mp)                       \
5598     {                                           \
5599         vat_main_t * vam = &vat_main;           \
5600         i32 retval = ntohl(mp->retval);         \
5601         if (vam->async_mode) {                  \
5602             vam->async_errors += (retval < 0);  \
5603         } else {                                \
5604             vam->retval = retval;               \
5605             vam->result_ready = 1;              \
5606         }                                       \
5607     }
5608 foreach_standard_reply_retval_handler;
5609 #undef _
5610
5611 #define _(n)                                    \
5612     static void vl_api_##n##_t_handler_json     \
5613     (vl_api_##n##_t * mp)                       \
5614     {                                           \
5615         vat_main_t * vam = &vat_main;           \
5616         vat_json_node_t node;                   \
5617         vat_json_init_object(&node);            \
5618         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5619         vat_json_print(vam->ofp, &node);        \
5620         vam->retval = ntohl(mp->retval);        \
5621         vam->result_ready = 1;                  \
5622     }
5623 foreach_standard_reply_retval_handler;
5624 #undef _
5625
5626 /*
5627  * Table of message reply handlers, must include boilerplate handlers
5628  * we just generated
5629  */
5630
5631 #define foreach_vpe_api_reply_msg                                       \
5632 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5633 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5634 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5635 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5636 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5637 _(CLI_REPLY, cli_reply)                                                 \
5638 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5639 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5640   sw_interface_add_del_address_reply)                                   \
5641 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5642 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5643 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5644 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5645 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5646 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5647 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5648 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5649   sw_interface_set_l2_xconnect_reply)                                   \
5650 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5651   sw_interface_set_l2_bridge_reply)                                     \
5652 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5653 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5654 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5655 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5656 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5657 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5658 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5659 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5660 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5661 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5662 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5663 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5664 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5665 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5666 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5667 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5668 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5669 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5670 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5671 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5672 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5673 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5674 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5675 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5676 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5677 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5678 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5679 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5680 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5681 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5682 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5683   proxy_arp_intfc_enable_disable_reply)                                 \
5684 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5685 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5686   sw_interface_set_unnumbered_reply)                                    \
5687 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5688 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5689 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5690 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5691 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5692 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5693 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5694 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5695 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5696 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5697 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5698   sw_interface_ip6_enable_disable_reply)                                \
5699 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5700   sw_interface_ip6_set_link_local_address_reply)                        \
5701 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5702 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5703 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5704   sw_interface_ip6nd_ra_prefix_reply)                                   \
5705 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5706   sw_interface_ip6nd_ra_config_reply)                                   \
5707 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5708 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5709 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5710 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5711 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5712 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5713 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5714 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5715 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5716 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5717 classify_set_interface_ip_table_reply)                                  \
5718 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5719   classify_set_interface_l2_tables_reply)                               \
5720 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5721 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5722 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5723 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5724 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5725   l2tpv3_interface_enable_disable_reply)                                \
5726 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5727 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5728 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5729 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5730 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5731 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5732 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5733 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5734 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5735 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5736 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5737 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5738 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5739 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5740 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5741 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5742 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5743 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5744 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5745 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5746 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5747 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5748 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5749 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5750 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5751 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5752 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5753 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5754 _(L2_MACS_EVENT, l2_macs_event)                                         \
5755 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5756 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5757 _(IP_DETAILS, ip_details)                                               \
5758 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5759 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5760 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5761 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5762 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5763 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5764 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5765 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5766 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5767 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5768 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5769 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5770 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5771 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5772 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5773 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5774 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5775 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5776 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5777 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5778 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5779 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5780 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5781 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5782 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5783 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5784 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5785 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5786 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5787 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5788 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5789 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5790 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5791 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5792 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5793 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5794 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5795 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5796 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5797 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5798 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5799 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5800 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5801 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5802 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5803 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5804 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5805 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5806   one_map_register_enable_disable_reply)                                \
5807 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5808 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5809 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5810 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5811   one_map_register_fallback_threshold_reply)                            \
5812 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5813   one_rloc_probe_enable_disable_reply)                                  \
5814 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5815 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5816 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5817 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5818 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5819 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5820 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5821 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5822 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5823 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5824 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5825 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5826 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5827 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5828 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5829 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5830   show_one_stats_enable_disable_reply)                                  \
5831 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5832 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5833 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5834 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5835 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5836 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5837 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5838 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5839   one_enable_disable_pitr_mode_reply)                                   \
5840 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5841   one_enable_disable_petr_mode_reply)                                   \
5842 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5843 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5844 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5845 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5846 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5847 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5848 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5849 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5850 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5851 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5852 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5853 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5854   gpe_add_del_native_fwd_rpath_reply)                                   \
5855 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5856   gpe_fwd_entry_path_details)                                           \
5857 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5858 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5859   one_add_del_map_request_itr_rlocs_reply)                              \
5860 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5861   one_get_map_request_itr_rlocs_reply)                                  \
5862 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5863 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5864 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5865 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5866 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5867 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5868   show_one_map_register_state_reply)                                    \
5869 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5870 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5871   show_one_map_register_fallback_threshold_reply)                       \
5872 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5873 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5874 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5875 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5876 _(POLICER_DETAILS, policer_details)                                     \
5877 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5878 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5879 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5880 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5881 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5882 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5883 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5884 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5885 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5886 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5887 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5888 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5889 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5890 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5891 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5892 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5893 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5894 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5895 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5896 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5897 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5898 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5899 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5900 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5901 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5902  ip_source_and_port_range_check_add_del_reply)                          \
5903 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5904  ip_source_and_port_range_check_interface_add_del_reply)                \
5905 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5906 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5907 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5908 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5909 _(PUNT_REPLY, punt_reply)                                               \
5910 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5911 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5912 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5913 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5914 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5915 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5916 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5917 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5918 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5919 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5920 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5921 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5922 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5923 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5924 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5925 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5926 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5927 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5928 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5929 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5930 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5931 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5932 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)     \
5933 _(MAP_STATS_SEGMENT_REPLY, map_stats_segment_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 next_hop;
10762
10763   bool nexthop_set = 0;
10764
10765   int ret;
10766
10767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10768     {
10769       if (unformat (i, "del"))
10770         is_del = 1;
10771       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10772       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10773         nexthop_set = 1;
10774       else if (unformat (i, "behavior %u", &behavior));
10775       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10776       else if (unformat (i, "fib-table %u", &fib_table));
10777       else if (unformat (i, "end.psp %u", &behavior));
10778       else
10779         break;
10780     }
10781
10782   M (SR_LOCALSID_ADD_DEL, mp);
10783
10784   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10785   if (nexthop_set)
10786     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10787   mp->behavior = behavior;
10788   mp->sw_if_index = ntohl (sw_if_index);
10789   mp->fib_table = ntohl (fib_table);
10790   mp->end_psp = end_psp;
10791   mp->is_del = is_del;
10792
10793   S (mp);
10794   W (ret);
10795   return ret;
10796 }
10797
10798 static int
10799 api_ioam_enable (vat_main_t * vam)
10800 {
10801   unformat_input_t *input = vam->input;
10802   vl_api_ioam_enable_t *mp;
10803   u32 id = 0;
10804   int has_trace_option = 0;
10805   int has_pot_option = 0;
10806   int has_seqno_option = 0;
10807   int has_analyse_option = 0;
10808   int ret;
10809
10810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10811     {
10812       if (unformat (input, "trace"))
10813         has_trace_option = 1;
10814       else if (unformat (input, "pot"))
10815         has_pot_option = 1;
10816       else if (unformat (input, "seqno"))
10817         has_seqno_option = 1;
10818       else if (unformat (input, "analyse"))
10819         has_analyse_option = 1;
10820       else
10821         break;
10822     }
10823   M (IOAM_ENABLE, mp);
10824   mp->id = htons (id);
10825   mp->seqno = has_seqno_option;
10826   mp->analyse = has_analyse_option;
10827   mp->pot_enable = has_pot_option;
10828   mp->trace_enable = has_trace_option;
10829
10830   S (mp);
10831   W (ret);
10832   return ret;
10833 }
10834
10835
10836 static int
10837 api_ioam_disable (vat_main_t * vam)
10838 {
10839   vl_api_ioam_disable_t *mp;
10840   int ret;
10841
10842   M (IOAM_DISABLE, mp);
10843   S (mp);
10844   W (ret);
10845   return ret;
10846 }
10847
10848 #define foreach_tcp_proto_field                 \
10849 _(src_port)                                     \
10850 _(dst_port)
10851
10852 #define foreach_udp_proto_field                 \
10853 _(src_port)                                     \
10854 _(dst_port)
10855
10856 #define foreach_ip4_proto_field                 \
10857 _(src_address)                                  \
10858 _(dst_address)                                  \
10859 _(tos)                                          \
10860 _(length)                                       \
10861 _(fragment_id)                                  \
10862 _(ttl)                                          \
10863 _(protocol)                                     \
10864 _(checksum)
10865
10866 typedef struct
10867 {
10868   u16 src_port, dst_port;
10869 } tcpudp_header_t;
10870
10871 #if VPP_API_TEST_BUILTIN == 0
10872 uword
10873 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10874 {
10875   u8 **maskp = va_arg (*args, u8 **);
10876   u8 *mask = 0;
10877   u8 found_something = 0;
10878   tcp_header_t *tcp;
10879
10880 #define _(a) u8 a=0;
10881   foreach_tcp_proto_field;
10882 #undef _
10883
10884   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10885     {
10886       if (0);
10887 #define _(a) else if (unformat (input, #a)) a=1;
10888       foreach_tcp_proto_field
10889 #undef _
10890         else
10891         break;
10892     }
10893
10894 #define _(a) found_something += a;
10895   foreach_tcp_proto_field;
10896 #undef _
10897
10898   if (found_something == 0)
10899     return 0;
10900
10901   vec_validate (mask, sizeof (*tcp) - 1);
10902
10903   tcp = (tcp_header_t *) mask;
10904
10905 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10906   foreach_tcp_proto_field;
10907 #undef _
10908
10909   *maskp = mask;
10910   return 1;
10911 }
10912
10913 uword
10914 unformat_udp_mask (unformat_input_t * input, va_list * args)
10915 {
10916   u8 **maskp = va_arg (*args, u8 **);
10917   u8 *mask = 0;
10918   u8 found_something = 0;
10919   udp_header_t *udp;
10920
10921 #define _(a) u8 a=0;
10922   foreach_udp_proto_field;
10923 #undef _
10924
10925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10926     {
10927       if (0);
10928 #define _(a) else if (unformat (input, #a)) a=1;
10929       foreach_udp_proto_field
10930 #undef _
10931         else
10932         break;
10933     }
10934
10935 #define _(a) found_something += a;
10936   foreach_udp_proto_field;
10937 #undef _
10938
10939   if (found_something == 0)
10940     return 0;
10941
10942   vec_validate (mask, sizeof (*udp) - 1);
10943
10944   udp = (udp_header_t *) mask;
10945
10946 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10947   foreach_udp_proto_field;
10948 #undef _
10949
10950   *maskp = mask;
10951   return 1;
10952 }
10953
10954 uword
10955 unformat_l4_mask (unformat_input_t * input, va_list * args)
10956 {
10957   u8 **maskp = va_arg (*args, u8 **);
10958   u16 src_port = 0, dst_port = 0;
10959   tcpudp_header_t *tcpudp;
10960
10961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10962     {
10963       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10964         return 1;
10965       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10966         return 1;
10967       else if (unformat (input, "src_port"))
10968         src_port = 0xFFFF;
10969       else if (unformat (input, "dst_port"))
10970         dst_port = 0xFFFF;
10971       else
10972         return 0;
10973     }
10974
10975   if (!src_port && !dst_port)
10976     return 0;
10977
10978   u8 *mask = 0;
10979   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10980
10981   tcpudp = (tcpudp_header_t *) mask;
10982   tcpudp->src_port = src_port;
10983   tcpudp->dst_port = dst_port;
10984
10985   *maskp = mask;
10986
10987   return 1;
10988 }
10989
10990 uword
10991 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10992 {
10993   u8 **maskp = va_arg (*args, u8 **);
10994   u8 *mask = 0;
10995   u8 found_something = 0;
10996   ip4_header_t *ip;
10997
10998 #define _(a) u8 a=0;
10999   foreach_ip4_proto_field;
11000 #undef _
11001   u8 version = 0;
11002   u8 hdr_length = 0;
11003
11004
11005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11006     {
11007       if (unformat (input, "version"))
11008         version = 1;
11009       else if (unformat (input, "hdr_length"))
11010         hdr_length = 1;
11011       else if (unformat (input, "src"))
11012         src_address = 1;
11013       else if (unformat (input, "dst"))
11014         dst_address = 1;
11015       else if (unformat (input, "proto"))
11016         protocol = 1;
11017
11018 #define _(a) else if (unformat (input, #a)) a=1;
11019       foreach_ip4_proto_field
11020 #undef _
11021         else
11022         break;
11023     }
11024
11025 #define _(a) found_something += a;
11026   foreach_ip4_proto_field;
11027 #undef _
11028
11029   if (found_something == 0)
11030     return 0;
11031
11032   vec_validate (mask, sizeof (*ip) - 1);
11033
11034   ip = (ip4_header_t *) mask;
11035
11036 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11037   foreach_ip4_proto_field;
11038 #undef _
11039
11040   ip->ip_version_and_header_length = 0;
11041
11042   if (version)
11043     ip->ip_version_and_header_length |= 0xF0;
11044
11045   if (hdr_length)
11046     ip->ip_version_and_header_length |= 0x0F;
11047
11048   *maskp = mask;
11049   return 1;
11050 }
11051
11052 #define foreach_ip6_proto_field                 \
11053 _(src_address)                                  \
11054 _(dst_address)                                  \
11055 _(payload_length)                               \
11056 _(hop_limit)                                    \
11057 _(protocol)
11058
11059 uword
11060 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11061 {
11062   u8 **maskp = va_arg (*args, u8 **);
11063   u8 *mask = 0;
11064   u8 found_something = 0;
11065   ip6_header_t *ip;
11066   u32 ip_version_traffic_class_and_flow_label;
11067
11068 #define _(a) u8 a=0;
11069   foreach_ip6_proto_field;
11070 #undef _
11071   u8 version = 0;
11072   u8 traffic_class = 0;
11073   u8 flow_label = 0;
11074
11075   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11076     {
11077       if (unformat (input, "version"))
11078         version = 1;
11079       else if (unformat (input, "traffic-class"))
11080         traffic_class = 1;
11081       else if (unformat (input, "flow-label"))
11082         flow_label = 1;
11083       else if (unformat (input, "src"))
11084         src_address = 1;
11085       else if (unformat (input, "dst"))
11086         dst_address = 1;
11087       else if (unformat (input, "proto"))
11088         protocol = 1;
11089
11090 #define _(a) else if (unformat (input, #a)) a=1;
11091       foreach_ip6_proto_field
11092 #undef _
11093         else
11094         break;
11095     }
11096
11097 #define _(a) found_something += a;
11098   foreach_ip6_proto_field;
11099 #undef _
11100
11101   if (found_something == 0)
11102     return 0;
11103
11104   vec_validate (mask, sizeof (*ip) - 1);
11105
11106   ip = (ip6_header_t *) mask;
11107
11108 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11109   foreach_ip6_proto_field;
11110 #undef _
11111
11112   ip_version_traffic_class_and_flow_label = 0;
11113
11114   if (version)
11115     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11116
11117   if (traffic_class)
11118     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11119
11120   if (flow_label)
11121     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11122
11123   ip->ip_version_traffic_class_and_flow_label =
11124     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11125
11126   *maskp = mask;
11127   return 1;
11128 }
11129
11130 uword
11131 unformat_l3_mask (unformat_input_t * input, va_list * args)
11132 {
11133   u8 **maskp = va_arg (*args, u8 **);
11134
11135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11136     {
11137       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11138         return 1;
11139       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11140         return 1;
11141       else
11142         break;
11143     }
11144   return 0;
11145 }
11146
11147 uword
11148 unformat_l2_mask (unformat_input_t * input, va_list * args)
11149 {
11150   u8 **maskp = va_arg (*args, u8 **);
11151   u8 *mask = 0;
11152   u8 src = 0;
11153   u8 dst = 0;
11154   u8 proto = 0;
11155   u8 tag1 = 0;
11156   u8 tag2 = 0;
11157   u8 ignore_tag1 = 0;
11158   u8 ignore_tag2 = 0;
11159   u8 cos1 = 0;
11160   u8 cos2 = 0;
11161   u8 dot1q = 0;
11162   u8 dot1ad = 0;
11163   int len = 14;
11164
11165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11166     {
11167       if (unformat (input, "src"))
11168         src = 1;
11169       else if (unformat (input, "dst"))
11170         dst = 1;
11171       else if (unformat (input, "proto"))
11172         proto = 1;
11173       else if (unformat (input, "tag1"))
11174         tag1 = 1;
11175       else if (unformat (input, "tag2"))
11176         tag2 = 1;
11177       else if (unformat (input, "ignore-tag1"))
11178         ignore_tag1 = 1;
11179       else if (unformat (input, "ignore-tag2"))
11180         ignore_tag2 = 1;
11181       else if (unformat (input, "cos1"))
11182         cos1 = 1;
11183       else if (unformat (input, "cos2"))
11184         cos2 = 1;
11185       else if (unformat (input, "dot1q"))
11186         dot1q = 1;
11187       else if (unformat (input, "dot1ad"))
11188         dot1ad = 1;
11189       else
11190         break;
11191     }
11192   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11193        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11194     return 0;
11195
11196   if (tag1 || ignore_tag1 || cos1 || dot1q)
11197     len = 18;
11198   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11199     len = 22;
11200
11201   vec_validate (mask, len - 1);
11202
11203   if (dst)
11204     memset (mask, 0xff, 6);
11205
11206   if (src)
11207     memset (mask + 6, 0xff, 6);
11208
11209   if (tag2 || dot1ad)
11210     {
11211       /* inner vlan tag */
11212       if (tag2)
11213         {
11214           mask[19] = 0xff;
11215           mask[18] = 0x0f;
11216         }
11217       if (cos2)
11218         mask[18] |= 0xe0;
11219       if (proto)
11220         mask[21] = mask[20] = 0xff;
11221       if (tag1)
11222         {
11223           mask[15] = 0xff;
11224           mask[14] = 0x0f;
11225         }
11226       if (cos1)
11227         mask[14] |= 0xe0;
11228       *maskp = mask;
11229       return 1;
11230     }
11231   if (tag1 | dot1q)
11232     {
11233       if (tag1)
11234         {
11235           mask[15] = 0xff;
11236           mask[14] = 0x0f;
11237         }
11238       if (cos1)
11239         mask[14] |= 0xe0;
11240       if (proto)
11241         mask[16] = mask[17] = 0xff;
11242
11243       *maskp = mask;
11244       return 1;
11245     }
11246   if (cos2)
11247     mask[18] |= 0xe0;
11248   if (cos1)
11249     mask[14] |= 0xe0;
11250   if (proto)
11251     mask[12] = mask[13] = 0xff;
11252
11253   *maskp = mask;
11254   return 1;
11255 }
11256
11257 uword
11258 unformat_classify_mask (unformat_input_t * input, va_list * args)
11259 {
11260   u8 **maskp = va_arg (*args, u8 **);
11261   u32 *skipp = va_arg (*args, u32 *);
11262   u32 *matchp = va_arg (*args, u32 *);
11263   u32 match;
11264   u8 *mask = 0;
11265   u8 *l2 = 0;
11266   u8 *l3 = 0;
11267   u8 *l4 = 0;
11268   int i;
11269
11270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11271     {
11272       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11273         ;
11274       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11275         ;
11276       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11277         ;
11278       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11279         ;
11280       else
11281         break;
11282     }
11283
11284   if (l4 && !l3)
11285     {
11286       vec_free (mask);
11287       vec_free (l2);
11288       vec_free (l4);
11289       return 0;
11290     }
11291
11292   if (mask || l2 || l3 || l4)
11293     {
11294       if (l2 || l3 || l4)
11295         {
11296           /* "With a free Ethernet header in every package" */
11297           if (l2 == 0)
11298             vec_validate (l2, 13);
11299           mask = l2;
11300           if (vec_len (l3))
11301             {
11302               vec_append (mask, l3);
11303               vec_free (l3);
11304             }
11305           if (vec_len (l4))
11306             {
11307               vec_append (mask, l4);
11308               vec_free (l4);
11309             }
11310         }
11311
11312       /* Scan forward looking for the first significant mask octet */
11313       for (i = 0; i < vec_len (mask); i++)
11314         if (mask[i])
11315           break;
11316
11317       /* compute (skip, match) params */
11318       *skipp = i / sizeof (u32x4);
11319       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11320
11321       /* Pad mask to an even multiple of the vector size */
11322       while (vec_len (mask) % sizeof (u32x4))
11323         vec_add1 (mask, 0);
11324
11325       match = vec_len (mask) / sizeof (u32x4);
11326
11327       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11328         {
11329           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11330           if (*tmp || *(tmp + 1))
11331             break;
11332           match--;
11333         }
11334       if (match == 0)
11335         clib_warning ("BUG: match 0");
11336
11337       _vec_len (mask) = match * sizeof (u32x4);
11338
11339       *matchp = match;
11340       *maskp = mask;
11341
11342       return 1;
11343     }
11344
11345   return 0;
11346 }
11347 #endif /* VPP_API_TEST_BUILTIN */
11348
11349 #define foreach_l2_next                         \
11350 _(drop, DROP)                                   \
11351 _(ethernet, ETHERNET_INPUT)                     \
11352 _(ip4, IP4_INPUT)                               \
11353 _(ip6, IP6_INPUT)
11354
11355 uword
11356 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11357 {
11358   u32 *miss_next_indexp = va_arg (*args, u32 *);
11359   u32 next_index = 0;
11360   u32 tmp;
11361
11362 #define _(n,N) \
11363   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11364   foreach_l2_next;
11365 #undef _
11366
11367   if (unformat (input, "%d", &tmp))
11368     {
11369       next_index = tmp;
11370       goto out;
11371     }
11372
11373   return 0;
11374
11375 out:
11376   *miss_next_indexp = next_index;
11377   return 1;
11378 }
11379
11380 #define foreach_ip_next                         \
11381 _(drop, DROP)                                   \
11382 _(local, LOCAL)                                 \
11383 _(rewrite, REWRITE)
11384
11385 uword
11386 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11387 {
11388   u32 *miss_next_indexp = va_arg (*args, u32 *);
11389   u32 next_index = 0;
11390   u32 tmp;
11391
11392 #define _(n,N) \
11393   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11394   foreach_ip_next;
11395 #undef _
11396
11397   if (unformat (input, "%d", &tmp))
11398     {
11399       next_index = tmp;
11400       goto out;
11401     }
11402
11403   return 0;
11404
11405 out:
11406   *miss_next_indexp = next_index;
11407   return 1;
11408 }
11409
11410 #define foreach_acl_next                        \
11411 _(deny, DENY)
11412
11413 uword
11414 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11415 {
11416   u32 *miss_next_indexp = va_arg (*args, u32 *);
11417   u32 next_index = 0;
11418   u32 tmp;
11419
11420 #define _(n,N) \
11421   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11422   foreach_acl_next;
11423 #undef _
11424
11425   if (unformat (input, "permit"))
11426     {
11427       next_index = ~0;
11428       goto out;
11429     }
11430   else if (unformat (input, "%d", &tmp))
11431     {
11432       next_index = tmp;
11433       goto out;
11434     }
11435
11436   return 0;
11437
11438 out:
11439   *miss_next_indexp = next_index;
11440   return 1;
11441 }
11442
11443 uword
11444 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11445 {
11446   u32 *r = va_arg (*args, u32 *);
11447
11448   if (unformat (input, "conform-color"))
11449     *r = POLICE_CONFORM;
11450   else if (unformat (input, "exceed-color"))
11451     *r = POLICE_EXCEED;
11452   else
11453     return 0;
11454
11455   return 1;
11456 }
11457
11458 static int
11459 api_classify_add_del_table (vat_main_t * vam)
11460 {
11461   unformat_input_t *i = vam->input;
11462   vl_api_classify_add_del_table_t *mp;
11463
11464   u32 nbuckets = 2;
11465   u32 skip = ~0;
11466   u32 match = ~0;
11467   int is_add = 1;
11468   int del_chain = 0;
11469   u32 table_index = ~0;
11470   u32 next_table_index = ~0;
11471   u32 miss_next_index = ~0;
11472   u32 memory_size = 32 << 20;
11473   u8 *mask = 0;
11474   u32 current_data_flag = 0;
11475   int current_data_offset = 0;
11476   int ret;
11477
11478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11479     {
11480       if (unformat (i, "del"))
11481         is_add = 0;
11482       else if (unformat (i, "del-chain"))
11483         {
11484           is_add = 0;
11485           del_chain = 1;
11486         }
11487       else if (unformat (i, "buckets %d", &nbuckets))
11488         ;
11489       else if (unformat (i, "memory_size %d", &memory_size))
11490         ;
11491       else if (unformat (i, "skip %d", &skip))
11492         ;
11493       else if (unformat (i, "match %d", &match))
11494         ;
11495       else if (unformat (i, "table %d", &table_index))
11496         ;
11497       else if (unformat (i, "mask %U", unformat_classify_mask,
11498                          &mask, &skip, &match))
11499         ;
11500       else if (unformat (i, "next-table %d", &next_table_index))
11501         ;
11502       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11503                          &miss_next_index))
11504         ;
11505       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11506                          &miss_next_index))
11507         ;
11508       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11509                          &miss_next_index))
11510         ;
11511       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11512         ;
11513       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11514         ;
11515       else
11516         break;
11517     }
11518
11519   if (is_add && mask == 0)
11520     {
11521       errmsg ("Mask required");
11522       return -99;
11523     }
11524
11525   if (is_add && skip == ~0)
11526     {
11527       errmsg ("skip count required");
11528       return -99;
11529     }
11530
11531   if (is_add && match == ~0)
11532     {
11533       errmsg ("match count required");
11534       return -99;
11535     }
11536
11537   if (!is_add && table_index == ~0)
11538     {
11539       errmsg ("table index required for delete");
11540       return -99;
11541     }
11542
11543   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11544
11545   mp->is_add = is_add;
11546   mp->del_chain = del_chain;
11547   mp->table_index = ntohl (table_index);
11548   mp->nbuckets = ntohl (nbuckets);
11549   mp->memory_size = ntohl (memory_size);
11550   mp->skip_n_vectors = ntohl (skip);
11551   mp->match_n_vectors = ntohl (match);
11552   mp->next_table_index = ntohl (next_table_index);
11553   mp->miss_next_index = ntohl (miss_next_index);
11554   mp->current_data_flag = ntohl (current_data_flag);
11555   mp->current_data_offset = ntohl (current_data_offset);
11556   clib_memcpy (mp->mask, mask, vec_len (mask));
11557
11558   vec_free (mask);
11559
11560   S (mp);
11561   W (ret);
11562   return ret;
11563 }
11564
11565 #if VPP_API_TEST_BUILTIN == 0
11566 uword
11567 unformat_l4_match (unformat_input_t * input, va_list * args)
11568 {
11569   u8 **matchp = va_arg (*args, u8 **);
11570
11571   u8 *proto_header = 0;
11572   int src_port = 0;
11573   int dst_port = 0;
11574
11575   tcpudp_header_t h;
11576
11577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11578     {
11579       if (unformat (input, "src_port %d", &src_port))
11580         ;
11581       else if (unformat (input, "dst_port %d", &dst_port))
11582         ;
11583       else
11584         return 0;
11585     }
11586
11587   h.src_port = clib_host_to_net_u16 (src_port);
11588   h.dst_port = clib_host_to_net_u16 (dst_port);
11589   vec_validate (proto_header, sizeof (h) - 1);
11590   memcpy (proto_header, &h, sizeof (h));
11591
11592   *matchp = proto_header;
11593
11594   return 1;
11595 }
11596
11597 uword
11598 unformat_ip4_match (unformat_input_t * input, va_list * args)
11599 {
11600   u8 **matchp = va_arg (*args, u8 **);
11601   u8 *match = 0;
11602   ip4_header_t *ip;
11603   int version = 0;
11604   u32 version_val;
11605   int hdr_length = 0;
11606   u32 hdr_length_val;
11607   int src = 0, dst = 0;
11608   ip4_address_t src_val, dst_val;
11609   int proto = 0;
11610   u32 proto_val;
11611   int tos = 0;
11612   u32 tos_val;
11613   int length = 0;
11614   u32 length_val;
11615   int fragment_id = 0;
11616   u32 fragment_id_val;
11617   int ttl = 0;
11618   int ttl_val;
11619   int checksum = 0;
11620   u32 checksum_val;
11621
11622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11623     {
11624       if (unformat (input, "version %d", &version_val))
11625         version = 1;
11626       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11627         hdr_length = 1;
11628       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11629         src = 1;
11630       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11631         dst = 1;
11632       else if (unformat (input, "proto %d", &proto_val))
11633         proto = 1;
11634       else if (unformat (input, "tos %d", &tos_val))
11635         tos = 1;
11636       else if (unformat (input, "length %d", &length_val))
11637         length = 1;
11638       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11639         fragment_id = 1;
11640       else if (unformat (input, "ttl %d", &ttl_val))
11641         ttl = 1;
11642       else if (unformat (input, "checksum %d", &checksum_val))
11643         checksum = 1;
11644       else
11645         break;
11646     }
11647
11648   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11649       + ttl + checksum == 0)
11650     return 0;
11651
11652   /*
11653    * Aligned because we use the real comparison functions
11654    */
11655   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11656
11657   ip = (ip4_header_t *) match;
11658
11659   /* These are realistically matched in practice */
11660   if (src)
11661     ip->src_address.as_u32 = src_val.as_u32;
11662
11663   if (dst)
11664     ip->dst_address.as_u32 = dst_val.as_u32;
11665
11666   if (proto)
11667     ip->protocol = proto_val;
11668
11669
11670   /* These are not, but they're included for completeness */
11671   if (version)
11672     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11673
11674   if (hdr_length)
11675     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11676
11677   if (tos)
11678     ip->tos = tos_val;
11679
11680   if (length)
11681     ip->length = clib_host_to_net_u16 (length_val);
11682
11683   if (ttl)
11684     ip->ttl = ttl_val;
11685
11686   if (checksum)
11687     ip->checksum = clib_host_to_net_u16 (checksum_val);
11688
11689   *matchp = match;
11690   return 1;
11691 }
11692
11693 uword
11694 unformat_ip6_match (unformat_input_t * input, va_list * args)
11695 {
11696   u8 **matchp = va_arg (*args, u8 **);
11697   u8 *match = 0;
11698   ip6_header_t *ip;
11699   int version = 0;
11700   u32 version_val;
11701   u8 traffic_class = 0;
11702   u32 traffic_class_val = 0;
11703   u8 flow_label = 0;
11704   u8 flow_label_val;
11705   int src = 0, dst = 0;
11706   ip6_address_t src_val, dst_val;
11707   int proto = 0;
11708   u32 proto_val;
11709   int payload_length = 0;
11710   u32 payload_length_val;
11711   int hop_limit = 0;
11712   int hop_limit_val;
11713   u32 ip_version_traffic_class_and_flow_label;
11714
11715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11716     {
11717       if (unformat (input, "version %d", &version_val))
11718         version = 1;
11719       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11720         traffic_class = 1;
11721       else if (unformat (input, "flow_label %d", &flow_label_val))
11722         flow_label = 1;
11723       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11724         src = 1;
11725       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11726         dst = 1;
11727       else if (unformat (input, "proto %d", &proto_val))
11728         proto = 1;
11729       else if (unformat (input, "payload_length %d", &payload_length_val))
11730         payload_length = 1;
11731       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11732         hop_limit = 1;
11733       else
11734         break;
11735     }
11736
11737   if (version + traffic_class + flow_label + src + dst + proto +
11738       payload_length + hop_limit == 0)
11739     return 0;
11740
11741   /*
11742    * Aligned because we use the real comparison functions
11743    */
11744   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11745
11746   ip = (ip6_header_t *) match;
11747
11748   if (src)
11749     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11750
11751   if (dst)
11752     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11753
11754   if (proto)
11755     ip->protocol = proto_val;
11756
11757   ip_version_traffic_class_and_flow_label = 0;
11758
11759   if (version)
11760     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11761
11762   if (traffic_class)
11763     ip_version_traffic_class_and_flow_label |=
11764       (traffic_class_val & 0xFF) << 20;
11765
11766   if (flow_label)
11767     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11768
11769   ip->ip_version_traffic_class_and_flow_label =
11770     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11771
11772   if (payload_length)
11773     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11774
11775   if (hop_limit)
11776     ip->hop_limit = hop_limit_val;
11777
11778   *matchp = match;
11779   return 1;
11780 }
11781
11782 uword
11783 unformat_l3_match (unformat_input_t * input, va_list * args)
11784 {
11785   u8 **matchp = va_arg (*args, u8 **);
11786
11787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11788     {
11789       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11790         return 1;
11791       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11792         return 1;
11793       else
11794         break;
11795     }
11796   return 0;
11797 }
11798
11799 uword
11800 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11801 {
11802   u8 *tagp = va_arg (*args, u8 *);
11803   u32 tag;
11804
11805   if (unformat (input, "%d", &tag))
11806     {
11807       tagp[0] = (tag >> 8) & 0x0F;
11808       tagp[1] = tag & 0xFF;
11809       return 1;
11810     }
11811
11812   return 0;
11813 }
11814
11815 uword
11816 unformat_l2_match (unformat_input_t * input, va_list * args)
11817 {
11818   u8 **matchp = va_arg (*args, u8 **);
11819   u8 *match = 0;
11820   u8 src = 0;
11821   u8 src_val[6];
11822   u8 dst = 0;
11823   u8 dst_val[6];
11824   u8 proto = 0;
11825   u16 proto_val;
11826   u8 tag1 = 0;
11827   u8 tag1_val[2];
11828   u8 tag2 = 0;
11829   u8 tag2_val[2];
11830   int len = 14;
11831   u8 ignore_tag1 = 0;
11832   u8 ignore_tag2 = 0;
11833   u8 cos1 = 0;
11834   u8 cos2 = 0;
11835   u32 cos1_val = 0;
11836   u32 cos2_val = 0;
11837
11838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11839     {
11840       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11841         src = 1;
11842       else
11843         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11844         dst = 1;
11845       else if (unformat (input, "proto %U",
11846                          unformat_ethernet_type_host_byte_order, &proto_val))
11847         proto = 1;
11848       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11849         tag1 = 1;
11850       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11851         tag2 = 1;
11852       else if (unformat (input, "ignore-tag1"))
11853         ignore_tag1 = 1;
11854       else if (unformat (input, "ignore-tag2"))
11855         ignore_tag2 = 1;
11856       else if (unformat (input, "cos1 %d", &cos1_val))
11857         cos1 = 1;
11858       else if (unformat (input, "cos2 %d", &cos2_val))
11859         cos2 = 1;
11860       else
11861         break;
11862     }
11863   if ((src + dst + proto + tag1 + tag2 +
11864        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11865     return 0;
11866
11867   if (tag1 || ignore_tag1 || cos1)
11868     len = 18;
11869   if (tag2 || ignore_tag2 || cos2)
11870     len = 22;
11871
11872   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11873
11874   if (dst)
11875     clib_memcpy (match, dst_val, 6);
11876
11877   if (src)
11878     clib_memcpy (match + 6, src_val, 6);
11879
11880   if (tag2)
11881     {
11882       /* inner vlan tag */
11883       match[19] = tag2_val[1];
11884       match[18] = tag2_val[0];
11885       if (cos2)
11886         match[18] |= (cos2_val & 0x7) << 5;
11887       if (proto)
11888         {
11889           match[21] = proto_val & 0xff;
11890           match[20] = proto_val >> 8;
11891         }
11892       if (tag1)
11893         {
11894           match[15] = tag1_val[1];
11895           match[14] = tag1_val[0];
11896         }
11897       if (cos1)
11898         match[14] |= (cos1_val & 0x7) << 5;
11899       *matchp = match;
11900       return 1;
11901     }
11902   if (tag1)
11903     {
11904       match[15] = tag1_val[1];
11905       match[14] = tag1_val[0];
11906       if (proto)
11907         {
11908           match[17] = proto_val & 0xff;
11909           match[16] = proto_val >> 8;
11910         }
11911       if (cos1)
11912         match[14] |= (cos1_val & 0x7) << 5;
11913
11914       *matchp = match;
11915       return 1;
11916     }
11917   if (cos2)
11918     match[18] |= (cos2_val & 0x7) << 5;
11919   if (cos1)
11920     match[14] |= (cos1_val & 0x7) << 5;
11921   if (proto)
11922     {
11923       match[13] = proto_val & 0xff;
11924       match[12] = proto_val >> 8;
11925     }
11926
11927   *matchp = match;
11928   return 1;
11929 }
11930
11931 uword
11932 unformat_qos_source (unformat_input_t * input, va_list * args)
11933 {
11934   int *qs = va_arg (*args, int *);
11935
11936   if (unformat (input, "ip"))
11937     *qs = QOS_SOURCE_IP;
11938   else if (unformat (input, "mpls"))
11939     *qs = QOS_SOURCE_MPLS;
11940   else if (unformat (input, "ext"))
11941     *qs = QOS_SOURCE_EXT;
11942   else if (unformat (input, "vlan"))
11943     *qs = QOS_SOURCE_VLAN;
11944   else
11945     return 0;
11946
11947   return 1;
11948 }
11949 #endif
11950
11951 uword
11952 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11953 {
11954   u8 **matchp = va_arg (*args, u8 **);
11955   u32 skip_n_vectors = va_arg (*args, u32);
11956   u32 match_n_vectors = va_arg (*args, u32);
11957
11958   u8 *match = 0;
11959   u8 *l2 = 0;
11960   u8 *l3 = 0;
11961   u8 *l4 = 0;
11962
11963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11964     {
11965       if (unformat (input, "hex %U", unformat_hex_string, &match))
11966         ;
11967       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11968         ;
11969       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11970         ;
11971       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11972         ;
11973       else
11974         break;
11975     }
11976
11977   if (l4 && !l3)
11978     {
11979       vec_free (match);
11980       vec_free (l2);
11981       vec_free (l4);
11982       return 0;
11983     }
11984
11985   if (match || l2 || l3 || l4)
11986     {
11987       if (l2 || l3 || l4)
11988         {
11989           /* "Win a free Ethernet header in every packet" */
11990           if (l2 == 0)
11991             vec_validate_aligned (l2, 13, sizeof (u32x4));
11992           match = l2;
11993           if (vec_len (l3))
11994             {
11995               vec_append_aligned (match, l3, sizeof (u32x4));
11996               vec_free (l3);
11997             }
11998           if (vec_len (l4))
11999             {
12000               vec_append_aligned (match, l4, sizeof (u32x4));
12001               vec_free (l4);
12002             }
12003         }
12004
12005       /* Make sure the vector is big enough even if key is all 0's */
12006       vec_validate_aligned
12007         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12008          sizeof (u32x4));
12009
12010       /* Set size, include skipped vectors */
12011       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12012
12013       *matchp = match;
12014
12015       return 1;
12016     }
12017
12018   return 0;
12019 }
12020
12021 static int
12022 api_classify_add_del_session (vat_main_t * vam)
12023 {
12024   unformat_input_t *i = vam->input;
12025   vl_api_classify_add_del_session_t *mp;
12026   int is_add = 1;
12027   u32 table_index = ~0;
12028   u32 hit_next_index = ~0;
12029   u32 opaque_index = ~0;
12030   u8 *match = 0;
12031   i32 advance = 0;
12032   u32 skip_n_vectors = 0;
12033   u32 match_n_vectors = 0;
12034   u32 action = 0;
12035   u32 metadata = 0;
12036   int ret;
12037
12038   /*
12039    * Warning: you have to supply skip_n and match_n
12040    * because the API client cant simply look at the classify
12041    * table object.
12042    */
12043
12044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12045     {
12046       if (unformat (i, "del"))
12047         is_add = 0;
12048       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12049                          &hit_next_index))
12050         ;
12051       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12052                          &hit_next_index))
12053         ;
12054       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12055                          &hit_next_index))
12056         ;
12057       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12058         ;
12059       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12060         ;
12061       else if (unformat (i, "opaque-index %d", &opaque_index))
12062         ;
12063       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12064         ;
12065       else if (unformat (i, "match_n %d", &match_n_vectors))
12066         ;
12067       else if (unformat (i, "match %U", api_unformat_classify_match,
12068                          &match, skip_n_vectors, match_n_vectors))
12069         ;
12070       else if (unformat (i, "advance %d", &advance))
12071         ;
12072       else if (unformat (i, "table-index %d", &table_index))
12073         ;
12074       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12075         action = 1;
12076       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12077         action = 2;
12078       else if (unformat (i, "action %d", &action))
12079         ;
12080       else if (unformat (i, "metadata %d", &metadata))
12081         ;
12082       else
12083         break;
12084     }
12085
12086   if (table_index == ~0)
12087     {
12088       errmsg ("Table index required");
12089       return -99;
12090     }
12091
12092   if (is_add && match == 0)
12093     {
12094       errmsg ("Match value required");
12095       return -99;
12096     }
12097
12098   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12099
12100   mp->is_add = is_add;
12101   mp->table_index = ntohl (table_index);
12102   mp->hit_next_index = ntohl (hit_next_index);
12103   mp->opaque_index = ntohl (opaque_index);
12104   mp->advance = ntohl (advance);
12105   mp->action = action;
12106   mp->metadata = ntohl (metadata);
12107   clib_memcpy (mp->match, match, vec_len (match));
12108   vec_free (match);
12109
12110   S (mp);
12111   W (ret);
12112   return ret;
12113 }
12114
12115 static int
12116 api_classify_set_interface_ip_table (vat_main_t * vam)
12117 {
12118   unformat_input_t *i = vam->input;
12119   vl_api_classify_set_interface_ip_table_t *mp;
12120   u32 sw_if_index;
12121   int sw_if_index_set;
12122   u32 table_index = ~0;
12123   u8 is_ipv6 = 0;
12124   int ret;
12125
12126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12127     {
12128       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12129         sw_if_index_set = 1;
12130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12131         sw_if_index_set = 1;
12132       else if (unformat (i, "table %d", &table_index))
12133         ;
12134       else
12135         {
12136           clib_warning ("parse error '%U'", format_unformat_error, i);
12137           return -99;
12138         }
12139     }
12140
12141   if (sw_if_index_set == 0)
12142     {
12143       errmsg ("missing interface name or sw_if_index");
12144       return -99;
12145     }
12146
12147
12148   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12149
12150   mp->sw_if_index = ntohl (sw_if_index);
12151   mp->table_index = ntohl (table_index);
12152   mp->is_ipv6 = is_ipv6;
12153
12154   S (mp);
12155   W (ret);
12156   return ret;
12157 }
12158
12159 static int
12160 api_classify_set_interface_l2_tables (vat_main_t * vam)
12161 {
12162   unformat_input_t *i = vam->input;
12163   vl_api_classify_set_interface_l2_tables_t *mp;
12164   u32 sw_if_index;
12165   int sw_if_index_set;
12166   u32 ip4_table_index = ~0;
12167   u32 ip6_table_index = ~0;
12168   u32 other_table_index = ~0;
12169   u32 is_input = 1;
12170   int ret;
12171
12172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12173     {
12174       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12175         sw_if_index_set = 1;
12176       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12177         sw_if_index_set = 1;
12178       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12179         ;
12180       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12181         ;
12182       else if (unformat (i, "other-table %d", &other_table_index))
12183         ;
12184       else if (unformat (i, "is-input %d", &is_input))
12185         ;
12186       else
12187         {
12188           clib_warning ("parse error '%U'", format_unformat_error, i);
12189           return -99;
12190         }
12191     }
12192
12193   if (sw_if_index_set == 0)
12194     {
12195       errmsg ("missing interface name or sw_if_index");
12196       return -99;
12197     }
12198
12199
12200   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12201
12202   mp->sw_if_index = ntohl (sw_if_index);
12203   mp->ip4_table_index = ntohl (ip4_table_index);
12204   mp->ip6_table_index = ntohl (ip6_table_index);
12205   mp->other_table_index = ntohl (other_table_index);
12206   mp->is_input = (u8) is_input;
12207
12208   S (mp);
12209   W (ret);
12210   return ret;
12211 }
12212
12213 static int
12214 api_set_ipfix_exporter (vat_main_t * vam)
12215 {
12216   unformat_input_t *i = vam->input;
12217   vl_api_set_ipfix_exporter_t *mp;
12218   ip4_address_t collector_address;
12219   u8 collector_address_set = 0;
12220   u32 collector_port = ~0;
12221   ip4_address_t src_address;
12222   u8 src_address_set = 0;
12223   u32 vrf_id = ~0;
12224   u32 path_mtu = ~0;
12225   u32 template_interval = ~0;
12226   u8 udp_checksum = 0;
12227   int ret;
12228
12229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12230     {
12231       if (unformat (i, "collector_address %U", unformat_ip4_address,
12232                     &collector_address))
12233         collector_address_set = 1;
12234       else if (unformat (i, "collector_port %d", &collector_port))
12235         ;
12236       else if (unformat (i, "src_address %U", unformat_ip4_address,
12237                          &src_address))
12238         src_address_set = 1;
12239       else if (unformat (i, "vrf_id %d", &vrf_id))
12240         ;
12241       else if (unformat (i, "path_mtu %d", &path_mtu))
12242         ;
12243       else if (unformat (i, "template_interval %d", &template_interval))
12244         ;
12245       else if (unformat (i, "udp_checksum"))
12246         udp_checksum = 1;
12247       else
12248         break;
12249     }
12250
12251   if (collector_address_set == 0)
12252     {
12253       errmsg ("collector_address required");
12254       return -99;
12255     }
12256
12257   if (src_address_set == 0)
12258     {
12259       errmsg ("src_address required");
12260       return -99;
12261     }
12262
12263   M (SET_IPFIX_EXPORTER, mp);
12264
12265   memcpy (mp->collector_address, collector_address.data,
12266           sizeof (collector_address.data));
12267   mp->collector_port = htons ((u16) collector_port);
12268   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12269   mp->vrf_id = htonl (vrf_id);
12270   mp->path_mtu = htonl (path_mtu);
12271   mp->template_interval = htonl (template_interval);
12272   mp->udp_checksum = udp_checksum;
12273
12274   S (mp);
12275   W (ret);
12276   return ret;
12277 }
12278
12279 static int
12280 api_set_ipfix_classify_stream (vat_main_t * vam)
12281 {
12282   unformat_input_t *i = vam->input;
12283   vl_api_set_ipfix_classify_stream_t *mp;
12284   u32 domain_id = 0;
12285   u32 src_port = UDP_DST_PORT_ipfix;
12286   int ret;
12287
12288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12289     {
12290       if (unformat (i, "domain %d", &domain_id))
12291         ;
12292       else if (unformat (i, "src_port %d", &src_port))
12293         ;
12294       else
12295         {
12296           errmsg ("unknown input `%U'", format_unformat_error, i);
12297           return -99;
12298         }
12299     }
12300
12301   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12302
12303   mp->domain_id = htonl (domain_id);
12304   mp->src_port = htons ((u16) src_port);
12305
12306   S (mp);
12307   W (ret);
12308   return ret;
12309 }
12310
12311 static int
12312 api_ipfix_classify_table_add_del (vat_main_t * vam)
12313 {
12314   unformat_input_t *i = vam->input;
12315   vl_api_ipfix_classify_table_add_del_t *mp;
12316   int is_add = -1;
12317   u32 classify_table_index = ~0;
12318   u8 ip_version = 0;
12319   u8 transport_protocol = 255;
12320   int ret;
12321
12322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12323     {
12324       if (unformat (i, "add"))
12325         is_add = 1;
12326       else if (unformat (i, "del"))
12327         is_add = 0;
12328       else if (unformat (i, "table %d", &classify_table_index))
12329         ;
12330       else if (unformat (i, "ip4"))
12331         ip_version = 4;
12332       else if (unformat (i, "ip6"))
12333         ip_version = 6;
12334       else if (unformat (i, "tcp"))
12335         transport_protocol = 6;
12336       else if (unformat (i, "udp"))
12337         transport_protocol = 17;
12338       else
12339         {
12340           errmsg ("unknown input `%U'", format_unformat_error, i);
12341           return -99;
12342         }
12343     }
12344
12345   if (is_add == -1)
12346     {
12347       errmsg ("expecting: add|del");
12348       return -99;
12349     }
12350   if (classify_table_index == ~0)
12351     {
12352       errmsg ("classifier table not specified");
12353       return -99;
12354     }
12355   if (ip_version == 0)
12356     {
12357       errmsg ("IP version not specified");
12358       return -99;
12359     }
12360
12361   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12362
12363   mp->is_add = is_add;
12364   mp->table_id = htonl (classify_table_index);
12365   mp->ip_version = ip_version;
12366   mp->transport_protocol = transport_protocol;
12367
12368   S (mp);
12369   W (ret);
12370   return ret;
12371 }
12372
12373 static int
12374 api_get_node_index (vat_main_t * vam)
12375 {
12376   unformat_input_t *i = vam->input;
12377   vl_api_get_node_index_t *mp;
12378   u8 *name = 0;
12379   int ret;
12380
12381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12382     {
12383       if (unformat (i, "node %s", &name))
12384         ;
12385       else
12386         break;
12387     }
12388   if (name == 0)
12389     {
12390       errmsg ("node name required");
12391       return -99;
12392     }
12393   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12394     {
12395       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12396       return -99;
12397     }
12398
12399   M (GET_NODE_INDEX, mp);
12400   clib_memcpy (mp->node_name, name, vec_len (name));
12401   vec_free (name);
12402
12403   S (mp);
12404   W (ret);
12405   return ret;
12406 }
12407
12408 static int
12409 api_get_next_index (vat_main_t * vam)
12410 {
12411   unformat_input_t *i = vam->input;
12412   vl_api_get_next_index_t *mp;
12413   u8 *node_name = 0, *next_node_name = 0;
12414   int ret;
12415
12416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12417     {
12418       if (unformat (i, "node-name %s", &node_name))
12419         ;
12420       else if (unformat (i, "next-node-name %s", &next_node_name))
12421         break;
12422     }
12423
12424   if (node_name == 0)
12425     {
12426       errmsg ("node name required");
12427       return -99;
12428     }
12429   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12430     {
12431       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12432       return -99;
12433     }
12434
12435   if (next_node_name == 0)
12436     {
12437       errmsg ("next node name required");
12438       return -99;
12439     }
12440   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12441     {
12442       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12443       return -99;
12444     }
12445
12446   M (GET_NEXT_INDEX, mp);
12447   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12448   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12449   vec_free (node_name);
12450   vec_free (next_node_name);
12451
12452   S (mp);
12453   W (ret);
12454   return ret;
12455 }
12456
12457 static int
12458 api_add_node_next (vat_main_t * vam)
12459 {
12460   unformat_input_t *i = vam->input;
12461   vl_api_add_node_next_t *mp;
12462   u8 *name = 0;
12463   u8 *next = 0;
12464   int ret;
12465
12466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12467     {
12468       if (unformat (i, "node %s", &name))
12469         ;
12470       else if (unformat (i, "next %s", &next))
12471         ;
12472       else
12473         break;
12474     }
12475   if (name == 0)
12476     {
12477       errmsg ("node name required");
12478       return -99;
12479     }
12480   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12481     {
12482       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12483       return -99;
12484     }
12485   if (next == 0)
12486     {
12487       errmsg ("next node required");
12488       return -99;
12489     }
12490   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12491     {
12492       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12493       return -99;
12494     }
12495
12496   M (ADD_NODE_NEXT, mp);
12497   clib_memcpy (mp->node_name, name, vec_len (name));
12498   clib_memcpy (mp->next_name, next, vec_len (next));
12499   vec_free (name);
12500   vec_free (next);
12501
12502   S (mp);
12503   W (ret);
12504   return ret;
12505 }
12506
12507 static int
12508 api_l2tpv3_create_tunnel (vat_main_t * vam)
12509 {
12510   unformat_input_t *i = vam->input;
12511   ip6_address_t client_address, our_address;
12512   int client_address_set = 0;
12513   int our_address_set = 0;
12514   u32 local_session_id = 0;
12515   u32 remote_session_id = 0;
12516   u64 local_cookie = 0;
12517   u64 remote_cookie = 0;
12518   u8 l2_sublayer_present = 0;
12519   vl_api_l2tpv3_create_tunnel_t *mp;
12520   int ret;
12521
12522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12523     {
12524       if (unformat (i, "client_address %U", unformat_ip6_address,
12525                     &client_address))
12526         client_address_set = 1;
12527       else if (unformat (i, "our_address %U", unformat_ip6_address,
12528                          &our_address))
12529         our_address_set = 1;
12530       else if (unformat (i, "local_session_id %d", &local_session_id))
12531         ;
12532       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12533         ;
12534       else if (unformat (i, "local_cookie %lld", &local_cookie))
12535         ;
12536       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12537         ;
12538       else if (unformat (i, "l2-sublayer-present"))
12539         l2_sublayer_present = 1;
12540       else
12541         break;
12542     }
12543
12544   if (client_address_set == 0)
12545     {
12546       errmsg ("client_address required");
12547       return -99;
12548     }
12549
12550   if (our_address_set == 0)
12551     {
12552       errmsg ("our_address required");
12553       return -99;
12554     }
12555
12556   M (L2TPV3_CREATE_TUNNEL, mp);
12557
12558   clib_memcpy (mp->client_address, client_address.as_u8,
12559                sizeof (mp->client_address));
12560
12561   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12562
12563   mp->local_session_id = ntohl (local_session_id);
12564   mp->remote_session_id = ntohl (remote_session_id);
12565   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12566   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12567   mp->l2_sublayer_present = l2_sublayer_present;
12568   mp->is_ipv6 = 1;
12569
12570   S (mp);
12571   W (ret);
12572   return ret;
12573 }
12574
12575 static int
12576 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12577 {
12578   unformat_input_t *i = vam->input;
12579   u32 sw_if_index;
12580   u8 sw_if_index_set = 0;
12581   u64 new_local_cookie = 0;
12582   u64 new_remote_cookie = 0;
12583   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12584   int ret;
12585
12586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12587     {
12588       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12589         sw_if_index_set = 1;
12590       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12591         sw_if_index_set = 1;
12592       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12593         ;
12594       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12595         ;
12596       else
12597         break;
12598     }
12599
12600   if (sw_if_index_set == 0)
12601     {
12602       errmsg ("missing interface name or sw_if_index");
12603       return -99;
12604     }
12605
12606   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12607
12608   mp->sw_if_index = ntohl (sw_if_index);
12609   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12610   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12611
12612   S (mp);
12613   W (ret);
12614   return ret;
12615 }
12616
12617 static int
12618 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12619 {
12620   unformat_input_t *i = vam->input;
12621   vl_api_l2tpv3_interface_enable_disable_t *mp;
12622   u32 sw_if_index;
12623   u8 sw_if_index_set = 0;
12624   u8 enable_disable = 1;
12625   int ret;
12626
12627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12628     {
12629       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12630         sw_if_index_set = 1;
12631       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12632         sw_if_index_set = 1;
12633       else if (unformat (i, "enable"))
12634         enable_disable = 1;
12635       else if (unformat (i, "disable"))
12636         enable_disable = 0;
12637       else
12638         break;
12639     }
12640
12641   if (sw_if_index_set == 0)
12642     {
12643       errmsg ("missing interface name or sw_if_index");
12644       return -99;
12645     }
12646
12647   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12648
12649   mp->sw_if_index = ntohl (sw_if_index);
12650   mp->enable_disable = enable_disable;
12651
12652   S (mp);
12653   W (ret);
12654   return ret;
12655 }
12656
12657 static int
12658 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12659 {
12660   unformat_input_t *i = vam->input;
12661   vl_api_l2tpv3_set_lookup_key_t *mp;
12662   u8 key = ~0;
12663   int ret;
12664
12665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12666     {
12667       if (unformat (i, "lookup_v6_src"))
12668         key = L2T_LOOKUP_SRC_ADDRESS;
12669       else if (unformat (i, "lookup_v6_dst"))
12670         key = L2T_LOOKUP_DST_ADDRESS;
12671       else if (unformat (i, "lookup_session_id"))
12672         key = L2T_LOOKUP_SESSION_ID;
12673       else
12674         break;
12675     }
12676
12677   if (key == (u8) ~ 0)
12678     {
12679       errmsg ("l2tp session lookup key unset");
12680       return -99;
12681     }
12682
12683   M (L2TPV3_SET_LOOKUP_KEY, mp);
12684
12685   mp->key = key;
12686
12687   S (mp);
12688   W (ret);
12689   return ret;
12690 }
12691
12692 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12693   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12694 {
12695   vat_main_t *vam = &vat_main;
12696
12697   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12698          format_ip6_address, mp->our_address,
12699          format_ip6_address, mp->client_address,
12700          clib_net_to_host_u32 (mp->sw_if_index));
12701
12702   print (vam->ofp,
12703          "   local cookies %016llx %016llx remote cookie %016llx",
12704          clib_net_to_host_u64 (mp->local_cookie[0]),
12705          clib_net_to_host_u64 (mp->local_cookie[1]),
12706          clib_net_to_host_u64 (mp->remote_cookie));
12707
12708   print (vam->ofp, "   local session-id %d remote session-id %d",
12709          clib_net_to_host_u32 (mp->local_session_id),
12710          clib_net_to_host_u32 (mp->remote_session_id));
12711
12712   print (vam->ofp, "   l2 specific sublayer %s\n",
12713          mp->l2_sublayer_present ? "preset" : "absent");
12714
12715 }
12716
12717 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12718   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12719 {
12720   vat_main_t *vam = &vat_main;
12721   vat_json_node_t *node = NULL;
12722   struct in6_addr addr;
12723
12724   if (VAT_JSON_ARRAY != vam->json_tree.type)
12725     {
12726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12727       vat_json_init_array (&vam->json_tree);
12728     }
12729   node = vat_json_array_add (&vam->json_tree);
12730
12731   vat_json_init_object (node);
12732
12733   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12734   vat_json_object_add_ip6 (node, "our_address", addr);
12735   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12736   vat_json_object_add_ip6 (node, "client_address", addr);
12737
12738   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12739   vat_json_init_array (lc);
12740   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12741   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12742   vat_json_object_add_uint (node, "remote_cookie",
12743                             clib_net_to_host_u64 (mp->remote_cookie));
12744
12745   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12746   vat_json_object_add_uint (node, "local_session_id",
12747                             clib_net_to_host_u32 (mp->local_session_id));
12748   vat_json_object_add_uint (node, "remote_session_id",
12749                             clib_net_to_host_u32 (mp->remote_session_id));
12750   vat_json_object_add_string_copy (node, "l2_sublayer",
12751                                    mp->l2_sublayer_present ? (u8 *) "present"
12752                                    : (u8 *) "absent");
12753 }
12754
12755 static int
12756 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12757 {
12758   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12759   vl_api_control_ping_t *mp_ping;
12760   int ret;
12761
12762   /* Get list of l2tpv3-tunnel interfaces */
12763   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12764   S (mp);
12765
12766   /* Use a control ping for synchronization */
12767   MPING (CONTROL_PING, mp_ping);
12768   S (mp_ping);
12769
12770   W (ret);
12771   return ret;
12772 }
12773
12774
12775 static void vl_api_sw_interface_tap_details_t_handler
12776   (vl_api_sw_interface_tap_details_t * mp)
12777 {
12778   vat_main_t *vam = &vat_main;
12779
12780   print (vam->ofp, "%-16s %d",
12781          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12782 }
12783
12784 static void vl_api_sw_interface_tap_details_t_handler_json
12785   (vl_api_sw_interface_tap_details_t * mp)
12786 {
12787   vat_main_t *vam = &vat_main;
12788   vat_json_node_t *node = NULL;
12789
12790   if (VAT_JSON_ARRAY != vam->json_tree.type)
12791     {
12792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12793       vat_json_init_array (&vam->json_tree);
12794     }
12795   node = vat_json_array_add (&vam->json_tree);
12796
12797   vat_json_init_object (node);
12798   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12799   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12800 }
12801
12802 static int
12803 api_sw_interface_tap_dump (vat_main_t * vam)
12804 {
12805   vl_api_sw_interface_tap_dump_t *mp;
12806   vl_api_control_ping_t *mp_ping;
12807   int ret;
12808
12809   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12810   /* Get list of tap interfaces */
12811   M (SW_INTERFACE_TAP_DUMP, mp);
12812   S (mp);
12813
12814   /* Use a control ping for synchronization */
12815   MPING (CONTROL_PING, mp_ping);
12816   S (mp_ping);
12817
12818   W (ret);
12819   return ret;
12820 }
12821
12822 static void vl_api_sw_interface_tap_v2_details_t_handler
12823   (vl_api_sw_interface_tap_v2_details_t * mp)
12824 {
12825   vat_main_t *vam = &vat_main;
12826
12827   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12828                     mp->host_ip4_prefix_len);
12829   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12830                     mp->host_ip6_prefix_len);
12831
12832   print (vam->ofp,
12833          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12834          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12835          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12836          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12837          mp->host_bridge, ip4, ip6);
12838
12839   vec_free (ip4);
12840   vec_free (ip6);
12841 }
12842
12843 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12844   (vl_api_sw_interface_tap_v2_details_t * mp)
12845 {
12846   vat_main_t *vam = &vat_main;
12847   vat_json_node_t *node = NULL;
12848
12849   if (VAT_JSON_ARRAY != vam->json_tree.type)
12850     {
12851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12852       vat_json_init_array (&vam->json_tree);
12853     }
12854   node = vat_json_array_add (&vam->json_tree);
12855
12856   vat_json_init_object (node);
12857   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12858   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12859   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12860   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12861   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12862   vat_json_object_add_string_copy (node, "host_mac_addr",
12863                                    format (0, "%U", format_ethernet_address,
12864                                            &mp->host_mac_addr));
12865   vat_json_object_add_string_copy (node, "host_namespace",
12866                                    mp->host_namespace);
12867   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12868   vat_json_object_add_string_copy (node, "host_ip4_addr",
12869                                    format (0, "%U/%d", format_ip4_address,
12870                                            mp->host_ip4_addr,
12871                                            mp->host_ip4_prefix_len));
12872   vat_json_object_add_string_copy (node, "host_ip6_addr",
12873                                    format (0, "%U/%d", format_ip6_address,
12874                                            mp->host_ip6_addr,
12875                                            mp->host_ip6_prefix_len));
12876
12877 }
12878
12879 static int
12880 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12881 {
12882   vl_api_sw_interface_tap_v2_dump_t *mp;
12883   vl_api_control_ping_t *mp_ping;
12884   int ret;
12885
12886   print (vam->ofp,
12887          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12888          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12889          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12890          "host_ip6_addr");
12891
12892   /* Get list of tap interfaces */
12893   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12894   S (mp);
12895
12896   /* Use a control ping for synchronization */
12897   MPING (CONTROL_PING, mp_ping);
12898   S (mp_ping);
12899
12900   W (ret);
12901   return ret;
12902 }
12903
12904 static int
12905 api_vxlan_offload_rx (vat_main_t * vam)
12906 {
12907   unformat_input_t *line_input = vam->input;
12908   vl_api_vxlan_offload_rx_t *mp;
12909   u32 hw_if_index = ~0, rx_if_index = ~0;
12910   u8 is_add = 1;
12911   int ret;
12912
12913   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12914     {
12915       if (unformat (line_input, "del"))
12916         is_add = 0;
12917       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12918                          &hw_if_index))
12919         ;
12920       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12921         ;
12922       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12923                          &rx_if_index))
12924         ;
12925       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12926         ;
12927       else
12928         {
12929           errmsg ("parse error '%U'", format_unformat_error, line_input);
12930           return -99;
12931         }
12932     }
12933
12934   if (hw_if_index == ~0)
12935     {
12936       errmsg ("no hw interface");
12937       return -99;
12938     }
12939
12940   if (rx_if_index == ~0)
12941     {
12942       errmsg ("no rx tunnel");
12943       return -99;
12944     }
12945
12946   M (VXLAN_OFFLOAD_RX, mp);
12947
12948   mp->hw_if_index = ntohl (hw_if_index);
12949   mp->sw_if_index = ntohl (rx_if_index);
12950   mp->enable = is_add;
12951
12952   S (mp);
12953   W (ret);
12954   return ret;
12955 }
12956
12957 static uword unformat_vxlan_decap_next
12958   (unformat_input_t * input, va_list * args)
12959 {
12960   u32 *result = va_arg (*args, u32 *);
12961   u32 tmp;
12962
12963   if (unformat (input, "l2"))
12964     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12965   else if (unformat (input, "%d", &tmp))
12966     *result = tmp;
12967   else
12968     return 0;
12969   return 1;
12970 }
12971
12972 static int
12973 api_vxlan_add_del_tunnel (vat_main_t * vam)
12974 {
12975   unformat_input_t *line_input = vam->input;
12976   vl_api_vxlan_add_del_tunnel_t *mp;
12977   ip46_address_t src, dst;
12978   u8 is_add = 1;
12979   u8 ipv4_set = 0, ipv6_set = 0;
12980   u8 src_set = 0;
12981   u8 dst_set = 0;
12982   u8 grp_set = 0;
12983   u32 instance = ~0;
12984   u32 mcast_sw_if_index = ~0;
12985   u32 encap_vrf_id = 0;
12986   u32 decap_next_index = ~0;
12987   u32 vni = 0;
12988   int ret;
12989
12990   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12991   memset (&src, 0, sizeof src);
12992   memset (&dst, 0, sizeof dst);
12993
12994   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12995     {
12996       if (unformat (line_input, "del"))
12997         is_add = 0;
12998       else if (unformat (line_input, "instance %d", &instance))
12999         ;
13000       else
13001         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13002         {
13003           ipv4_set = 1;
13004           src_set = 1;
13005         }
13006       else
13007         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13008         {
13009           ipv4_set = 1;
13010           dst_set = 1;
13011         }
13012       else
13013         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13014         {
13015           ipv6_set = 1;
13016           src_set = 1;
13017         }
13018       else
13019         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13020         {
13021           ipv6_set = 1;
13022           dst_set = 1;
13023         }
13024       else if (unformat (line_input, "group %U %U",
13025                          unformat_ip4_address, &dst.ip4,
13026                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13027         {
13028           grp_set = dst_set = 1;
13029           ipv4_set = 1;
13030         }
13031       else if (unformat (line_input, "group %U",
13032                          unformat_ip4_address, &dst.ip4))
13033         {
13034           grp_set = dst_set = 1;
13035           ipv4_set = 1;
13036         }
13037       else if (unformat (line_input, "group %U %U",
13038                          unformat_ip6_address, &dst.ip6,
13039                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13040         {
13041           grp_set = dst_set = 1;
13042           ipv6_set = 1;
13043         }
13044       else if (unformat (line_input, "group %U",
13045                          unformat_ip6_address, &dst.ip6))
13046         {
13047           grp_set = dst_set = 1;
13048           ipv6_set = 1;
13049         }
13050       else
13051         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13052         ;
13053       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13054         ;
13055       else if (unformat (line_input, "decap-next %U",
13056                          unformat_vxlan_decap_next, &decap_next_index))
13057         ;
13058       else if (unformat (line_input, "vni %d", &vni))
13059         ;
13060       else
13061         {
13062           errmsg ("parse error '%U'", format_unformat_error, line_input);
13063           return -99;
13064         }
13065     }
13066
13067   if (src_set == 0)
13068     {
13069       errmsg ("tunnel src address not specified");
13070       return -99;
13071     }
13072   if (dst_set == 0)
13073     {
13074       errmsg ("tunnel dst address not specified");
13075       return -99;
13076     }
13077
13078   if (grp_set && !ip46_address_is_multicast (&dst))
13079     {
13080       errmsg ("tunnel group address not multicast");
13081       return -99;
13082     }
13083   if (grp_set && mcast_sw_if_index == ~0)
13084     {
13085       errmsg ("tunnel nonexistent multicast device");
13086       return -99;
13087     }
13088   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13089     {
13090       errmsg ("tunnel dst address must be unicast");
13091       return -99;
13092     }
13093
13094
13095   if (ipv4_set && ipv6_set)
13096     {
13097       errmsg ("both IPv4 and IPv6 addresses specified");
13098       return -99;
13099     }
13100
13101   if ((vni == 0) || (vni >> 24))
13102     {
13103       errmsg ("vni not specified or out of range");
13104       return -99;
13105     }
13106
13107   M (VXLAN_ADD_DEL_TUNNEL, mp);
13108
13109   if (ipv6_set)
13110     {
13111       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13112       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13113     }
13114   else
13115     {
13116       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13117       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13118     }
13119
13120   mp->instance = htonl (instance);
13121   mp->encap_vrf_id = ntohl (encap_vrf_id);
13122   mp->decap_next_index = ntohl (decap_next_index);
13123   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13124   mp->vni = ntohl (vni);
13125   mp->is_add = is_add;
13126   mp->is_ipv6 = ipv6_set;
13127
13128   S (mp);
13129   W (ret);
13130   return ret;
13131 }
13132
13133 static void vl_api_vxlan_tunnel_details_t_handler
13134   (vl_api_vxlan_tunnel_details_t * mp)
13135 {
13136   vat_main_t *vam = &vat_main;
13137   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13138   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13139
13140   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13141          ntohl (mp->sw_if_index),
13142          ntohl (mp->instance),
13143          format_ip46_address, &src, IP46_TYPE_ANY,
13144          format_ip46_address, &dst, IP46_TYPE_ANY,
13145          ntohl (mp->encap_vrf_id),
13146          ntohl (mp->decap_next_index), ntohl (mp->vni),
13147          ntohl (mp->mcast_sw_if_index));
13148 }
13149
13150 static void vl_api_vxlan_tunnel_details_t_handler_json
13151   (vl_api_vxlan_tunnel_details_t * mp)
13152 {
13153   vat_main_t *vam = &vat_main;
13154   vat_json_node_t *node = NULL;
13155
13156   if (VAT_JSON_ARRAY != vam->json_tree.type)
13157     {
13158       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13159       vat_json_init_array (&vam->json_tree);
13160     }
13161   node = vat_json_array_add (&vam->json_tree);
13162
13163   vat_json_init_object (node);
13164   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13165
13166   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13167
13168   if (mp->is_ipv6)
13169     {
13170       struct in6_addr ip6;
13171
13172       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13173       vat_json_object_add_ip6 (node, "src_address", ip6);
13174       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13175       vat_json_object_add_ip6 (node, "dst_address", ip6);
13176     }
13177   else
13178     {
13179       struct in_addr ip4;
13180
13181       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13182       vat_json_object_add_ip4 (node, "src_address", ip4);
13183       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13184       vat_json_object_add_ip4 (node, "dst_address", ip4);
13185     }
13186   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13187   vat_json_object_add_uint (node, "decap_next_index",
13188                             ntohl (mp->decap_next_index));
13189   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13190   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13191   vat_json_object_add_uint (node, "mcast_sw_if_index",
13192                             ntohl (mp->mcast_sw_if_index));
13193 }
13194
13195 static int
13196 api_vxlan_tunnel_dump (vat_main_t * vam)
13197 {
13198   unformat_input_t *i = vam->input;
13199   vl_api_vxlan_tunnel_dump_t *mp;
13200   vl_api_control_ping_t *mp_ping;
13201   u32 sw_if_index;
13202   u8 sw_if_index_set = 0;
13203   int ret;
13204
13205   /* Parse args required to build the message */
13206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13207     {
13208       if (unformat (i, "sw_if_index %d", &sw_if_index))
13209         sw_if_index_set = 1;
13210       else
13211         break;
13212     }
13213
13214   if (sw_if_index_set == 0)
13215     {
13216       sw_if_index = ~0;
13217     }
13218
13219   if (!vam->json_output)
13220     {
13221       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13222              "sw_if_index", "instance", "src_address", "dst_address",
13223              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13224     }
13225
13226   /* Get list of vxlan-tunnel interfaces */
13227   M (VXLAN_TUNNEL_DUMP, mp);
13228
13229   mp->sw_if_index = htonl (sw_if_index);
13230
13231   S (mp);
13232
13233   /* Use a control ping for synchronization */
13234   MPING (CONTROL_PING, mp_ping);
13235   S (mp_ping);
13236
13237   W (ret);
13238   return ret;
13239 }
13240
13241 static uword unformat_geneve_decap_next
13242   (unformat_input_t * input, va_list * args)
13243 {
13244   u32 *result = va_arg (*args, u32 *);
13245   u32 tmp;
13246
13247   if (unformat (input, "l2"))
13248     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13249   else if (unformat (input, "%d", &tmp))
13250     *result = tmp;
13251   else
13252     return 0;
13253   return 1;
13254 }
13255
13256 static int
13257 api_geneve_add_del_tunnel (vat_main_t * vam)
13258 {
13259   unformat_input_t *line_input = vam->input;
13260   vl_api_geneve_add_del_tunnel_t *mp;
13261   ip46_address_t src, dst;
13262   u8 is_add = 1;
13263   u8 ipv4_set = 0, ipv6_set = 0;
13264   u8 src_set = 0;
13265   u8 dst_set = 0;
13266   u8 grp_set = 0;
13267   u32 mcast_sw_if_index = ~0;
13268   u32 encap_vrf_id = 0;
13269   u32 decap_next_index = ~0;
13270   u32 vni = 0;
13271   int ret;
13272
13273   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13274   memset (&src, 0, sizeof src);
13275   memset (&dst, 0, sizeof dst);
13276
13277   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13278     {
13279       if (unformat (line_input, "del"))
13280         is_add = 0;
13281       else
13282         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13283         {
13284           ipv4_set = 1;
13285           src_set = 1;
13286         }
13287       else
13288         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13289         {
13290           ipv4_set = 1;
13291           dst_set = 1;
13292         }
13293       else
13294         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13295         {
13296           ipv6_set = 1;
13297           src_set = 1;
13298         }
13299       else
13300         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13301         {
13302           ipv6_set = 1;
13303           dst_set = 1;
13304         }
13305       else if (unformat (line_input, "group %U %U",
13306                          unformat_ip4_address, &dst.ip4,
13307                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13308         {
13309           grp_set = dst_set = 1;
13310           ipv4_set = 1;
13311         }
13312       else if (unformat (line_input, "group %U",
13313                          unformat_ip4_address, &dst.ip4))
13314         {
13315           grp_set = dst_set = 1;
13316           ipv4_set = 1;
13317         }
13318       else if (unformat (line_input, "group %U %U",
13319                          unformat_ip6_address, &dst.ip6,
13320                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13321         {
13322           grp_set = dst_set = 1;
13323           ipv6_set = 1;
13324         }
13325       else if (unformat (line_input, "group %U",
13326                          unformat_ip6_address, &dst.ip6))
13327         {
13328           grp_set = dst_set = 1;
13329           ipv6_set = 1;
13330         }
13331       else
13332         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13333         ;
13334       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13335         ;
13336       else if (unformat (line_input, "decap-next %U",
13337                          unformat_geneve_decap_next, &decap_next_index))
13338         ;
13339       else if (unformat (line_input, "vni %d", &vni))
13340         ;
13341       else
13342         {
13343           errmsg ("parse error '%U'", format_unformat_error, line_input);
13344           return -99;
13345         }
13346     }
13347
13348   if (src_set == 0)
13349     {
13350       errmsg ("tunnel src address not specified");
13351       return -99;
13352     }
13353   if (dst_set == 0)
13354     {
13355       errmsg ("tunnel dst address not specified");
13356       return -99;
13357     }
13358
13359   if (grp_set && !ip46_address_is_multicast (&dst))
13360     {
13361       errmsg ("tunnel group address not multicast");
13362       return -99;
13363     }
13364   if (grp_set && mcast_sw_if_index == ~0)
13365     {
13366       errmsg ("tunnel nonexistent multicast device");
13367       return -99;
13368     }
13369   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13370     {
13371       errmsg ("tunnel dst address must be unicast");
13372       return -99;
13373     }
13374
13375
13376   if (ipv4_set && ipv6_set)
13377     {
13378       errmsg ("both IPv4 and IPv6 addresses specified");
13379       return -99;
13380     }
13381
13382   if ((vni == 0) || (vni >> 24))
13383     {
13384       errmsg ("vni not specified or out of range");
13385       return -99;
13386     }
13387
13388   M (GENEVE_ADD_DEL_TUNNEL, mp);
13389
13390   if (ipv6_set)
13391     {
13392       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13393       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13394     }
13395   else
13396     {
13397       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13398       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13399     }
13400   mp->encap_vrf_id = ntohl (encap_vrf_id);
13401   mp->decap_next_index = ntohl (decap_next_index);
13402   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13403   mp->vni = ntohl (vni);
13404   mp->is_add = is_add;
13405   mp->is_ipv6 = ipv6_set;
13406
13407   S (mp);
13408   W (ret);
13409   return ret;
13410 }
13411
13412 static void vl_api_geneve_tunnel_details_t_handler
13413   (vl_api_geneve_tunnel_details_t * mp)
13414 {
13415   vat_main_t *vam = &vat_main;
13416   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13417   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13418
13419   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13420          ntohl (mp->sw_if_index),
13421          format_ip46_address, &src, IP46_TYPE_ANY,
13422          format_ip46_address, &dst, IP46_TYPE_ANY,
13423          ntohl (mp->encap_vrf_id),
13424          ntohl (mp->decap_next_index), ntohl (mp->vni),
13425          ntohl (mp->mcast_sw_if_index));
13426 }
13427
13428 static void vl_api_geneve_tunnel_details_t_handler_json
13429   (vl_api_geneve_tunnel_details_t * mp)
13430 {
13431   vat_main_t *vam = &vat_main;
13432   vat_json_node_t *node = NULL;
13433
13434   if (VAT_JSON_ARRAY != vam->json_tree.type)
13435     {
13436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13437       vat_json_init_array (&vam->json_tree);
13438     }
13439   node = vat_json_array_add (&vam->json_tree);
13440
13441   vat_json_init_object (node);
13442   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13443   if (mp->is_ipv6)
13444     {
13445       struct in6_addr ip6;
13446
13447       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13448       vat_json_object_add_ip6 (node, "src_address", ip6);
13449       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13450       vat_json_object_add_ip6 (node, "dst_address", ip6);
13451     }
13452   else
13453     {
13454       struct in_addr ip4;
13455
13456       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13457       vat_json_object_add_ip4 (node, "src_address", ip4);
13458       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13459       vat_json_object_add_ip4 (node, "dst_address", ip4);
13460     }
13461   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13462   vat_json_object_add_uint (node, "decap_next_index",
13463                             ntohl (mp->decap_next_index));
13464   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13465   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13466   vat_json_object_add_uint (node, "mcast_sw_if_index",
13467                             ntohl (mp->mcast_sw_if_index));
13468 }
13469
13470 static int
13471 api_geneve_tunnel_dump (vat_main_t * vam)
13472 {
13473   unformat_input_t *i = vam->input;
13474   vl_api_geneve_tunnel_dump_t *mp;
13475   vl_api_control_ping_t *mp_ping;
13476   u32 sw_if_index;
13477   u8 sw_if_index_set = 0;
13478   int ret;
13479
13480   /* Parse args required to build the message */
13481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13482     {
13483       if (unformat (i, "sw_if_index %d", &sw_if_index))
13484         sw_if_index_set = 1;
13485       else
13486         break;
13487     }
13488
13489   if (sw_if_index_set == 0)
13490     {
13491       sw_if_index = ~0;
13492     }
13493
13494   if (!vam->json_output)
13495     {
13496       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13497              "sw_if_index", "local_address", "remote_address",
13498              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13499     }
13500
13501   /* Get list of geneve-tunnel interfaces */
13502   M (GENEVE_TUNNEL_DUMP, mp);
13503
13504   mp->sw_if_index = htonl (sw_if_index);
13505
13506   S (mp);
13507
13508   /* Use a control ping for synchronization */
13509   M (CONTROL_PING, mp_ping);
13510   S (mp_ping);
13511
13512   W (ret);
13513   return ret;
13514 }
13515
13516 static int
13517 api_gre_add_del_tunnel (vat_main_t * vam)
13518 {
13519   unformat_input_t *line_input = vam->input;
13520   vl_api_gre_add_del_tunnel_t *mp;
13521   ip4_address_t src4, dst4;
13522   ip6_address_t src6, dst6;
13523   u8 is_add = 1;
13524   u8 ipv4_set = 0;
13525   u8 ipv6_set = 0;
13526   u8 t_type = GRE_TUNNEL_TYPE_L3;
13527   u8 src_set = 0;
13528   u8 dst_set = 0;
13529   u32 outer_fib_id = 0;
13530   u32 session_id = 0;
13531   u32 instance = ~0;
13532   int ret;
13533
13534   memset (&src4, 0, sizeof src4);
13535   memset (&dst4, 0, sizeof dst4);
13536   memset (&src6, 0, sizeof src6);
13537   memset (&dst6, 0, sizeof dst6);
13538
13539   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13540     {
13541       if (unformat (line_input, "del"))
13542         is_add = 0;
13543       else if (unformat (line_input, "instance %d", &instance))
13544         ;
13545       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13546         {
13547           src_set = 1;
13548           ipv4_set = 1;
13549         }
13550       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13551         {
13552           dst_set = 1;
13553           ipv4_set = 1;
13554         }
13555       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13556         {
13557           src_set = 1;
13558           ipv6_set = 1;
13559         }
13560       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13561         {
13562           dst_set = 1;
13563           ipv6_set = 1;
13564         }
13565       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13566         ;
13567       else if (unformat (line_input, "teb"))
13568         t_type = GRE_TUNNEL_TYPE_TEB;
13569       else if (unformat (line_input, "erspan %d", &session_id))
13570         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13571       else
13572         {
13573           errmsg ("parse error '%U'", format_unformat_error, line_input);
13574           return -99;
13575         }
13576     }
13577
13578   if (src_set == 0)
13579     {
13580       errmsg ("tunnel src address not specified");
13581       return -99;
13582     }
13583   if (dst_set == 0)
13584     {
13585       errmsg ("tunnel dst address not specified");
13586       return -99;
13587     }
13588   if (ipv4_set && ipv6_set)
13589     {
13590       errmsg ("both IPv4 and IPv6 addresses specified");
13591       return -99;
13592     }
13593
13594
13595   M (GRE_ADD_DEL_TUNNEL, mp);
13596
13597   if (ipv4_set)
13598     {
13599       clib_memcpy (&mp->src_address, &src4, 4);
13600       clib_memcpy (&mp->dst_address, &dst4, 4);
13601     }
13602   else
13603     {
13604       clib_memcpy (&mp->src_address, &src6, 16);
13605       clib_memcpy (&mp->dst_address, &dst6, 16);
13606     }
13607   mp->instance = htonl (instance);
13608   mp->outer_fib_id = htonl (outer_fib_id);
13609   mp->is_add = is_add;
13610   mp->session_id = htons ((u16) session_id);
13611   mp->tunnel_type = t_type;
13612   mp->is_ipv6 = ipv6_set;
13613
13614   S (mp);
13615   W (ret);
13616   return ret;
13617 }
13618
13619 static void vl_api_gre_tunnel_details_t_handler
13620   (vl_api_gre_tunnel_details_t * mp)
13621 {
13622   vat_main_t *vam = &vat_main;
13623   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13624   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13625
13626   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13627          ntohl (mp->sw_if_index),
13628          ntohl (mp->instance),
13629          format_ip46_address, &src, IP46_TYPE_ANY,
13630          format_ip46_address, &dst, IP46_TYPE_ANY,
13631          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13632 }
13633
13634 static void vl_api_gre_tunnel_details_t_handler_json
13635   (vl_api_gre_tunnel_details_t * mp)
13636 {
13637   vat_main_t *vam = &vat_main;
13638   vat_json_node_t *node = NULL;
13639   struct in_addr ip4;
13640   struct in6_addr ip6;
13641
13642   if (VAT_JSON_ARRAY != vam->json_tree.type)
13643     {
13644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13645       vat_json_init_array (&vam->json_tree);
13646     }
13647   node = vat_json_array_add (&vam->json_tree);
13648
13649   vat_json_init_object (node);
13650   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13651   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13652   if (!mp->is_ipv6)
13653     {
13654       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13655       vat_json_object_add_ip4 (node, "src_address", ip4);
13656       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13657       vat_json_object_add_ip4 (node, "dst_address", ip4);
13658     }
13659   else
13660     {
13661       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13662       vat_json_object_add_ip6 (node, "src_address", ip6);
13663       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13664       vat_json_object_add_ip6 (node, "dst_address", ip6);
13665     }
13666   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13667   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13668   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13669   vat_json_object_add_uint (node, "session_id", mp->session_id);
13670 }
13671
13672 static int
13673 api_gre_tunnel_dump (vat_main_t * vam)
13674 {
13675   unformat_input_t *i = vam->input;
13676   vl_api_gre_tunnel_dump_t *mp;
13677   vl_api_control_ping_t *mp_ping;
13678   u32 sw_if_index;
13679   u8 sw_if_index_set = 0;
13680   int ret;
13681
13682   /* Parse args required to build the message */
13683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13684     {
13685       if (unformat (i, "sw_if_index %d", &sw_if_index))
13686         sw_if_index_set = 1;
13687       else
13688         break;
13689     }
13690
13691   if (sw_if_index_set == 0)
13692     {
13693       sw_if_index = ~0;
13694     }
13695
13696   if (!vam->json_output)
13697     {
13698       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13699              "sw_if_index", "instance", "src_address", "dst_address",
13700              "tunnel_type", "outer_fib_id", "session_id");
13701     }
13702
13703   /* Get list of gre-tunnel interfaces */
13704   M (GRE_TUNNEL_DUMP, mp);
13705
13706   mp->sw_if_index = htonl (sw_if_index);
13707
13708   S (mp);
13709
13710   /* Use a control ping for synchronization */
13711   MPING (CONTROL_PING, mp_ping);
13712   S (mp_ping);
13713
13714   W (ret);
13715   return ret;
13716 }
13717
13718 static int
13719 api_l2_fib_clear_table (vat_main_t * vam)
13720 {
13721 //  unformat_input_t * i = vam->input;
13722   vl_api_l2_fib_clear_table_t *mp;
13723   int ret;
13724
13725   M (L2_FIB_CLEAR_TABLE, mp);
13726
13727   S (mp);
13728   W (ret);
13729   return ret;
13730 }
13731
13732 static int
13733 api_l2_interface_efp_filter (vat_main_t * vam)
13734 {
13735   unformat_input_t *i = vam->input;
13736   vl_api_l2_interface_efp_filter_t *mp;
13737   u32 sw_if_index;
13738   u8 enable = 1;
13739   u8 sw_if_index_set = 0;
13740   int ret;
13741
13742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13743     {
13744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13745         sw_if_index_set = 1;
13746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13747         sw_if_index_set = 1;
13748       else if (unformat (i, "enable"))
13749         enable = 1;
13750       else if (unformat (i, "disable"))
13751         enable = 0;
13752       else
13753         {
13754           clib_warning ("parse error '%U'", format_unformat_error, i);
13755           return -99;
13756         }
13757     }
13758
13759   if (sw_if_index_set == 0)
13760     {
13761       errmsg ("missing sw_if_index");
13762       return -99;
13763     }
13764
13765   M (L2_INTERFACE_EFP_FILTER, mp);
13766
13767   mp->sw_if_index = ntohl (sw_if_index);
13768   mp->enable_disable = enable;
13769
13770   S (mp);
13771   W (ret);
13772   return ret;
13773 }
13774
13775 #define foreach_vtr_op                          \
13776 _("disable",  L2_VTR_DISABLED)                  \
13777 _("push-1",  L2_VTR_PUSH_1)                     \
13778 _("push-2",  L2_VTR_PUSH_2)                     \
13779 _("pop-1",  L2_VTR_POP_1)                       \
13780 _("pop-2",  L2_VTR_POP_2)                       \
13781 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13782 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13783 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13784 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13785
13786 static int
13787 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13788 {
13789   unformat_input_t *i = vam->input;
13790   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13791   u32 sw_if_index;
13792   u8 sw_if_index_set = 0;
13793   u8 vtr_op_set = 0;
13794   u32 vtr_op = 0;
13795   u32 push_dot1q = 1;
13796   u32 tag1 = ~0;
13797   u32 tag2 = ~0;
13798   int ret;
13799
13800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13801     {
13802       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13803         sw_if_index_set = 1;
13804       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13805         sw_if_index_set = 1;
13806       else if (unformat (i, "vtr_op %d", &vtr_op))
13807         vtr_op_set = 1;
13808 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13809       foreach_vtr_op
13810 #undef _
13811         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13812         ;
13813       else if (unformat (i, "tag1 %d", &tag1))
13814         ;
13815       else if (unformat (i, "tag2 %d", &tag2))
13816         ;
13817       else
13818         {
13819           clib_warning ("parse error '%U'", format_unformat_error, i);
13820           return -99;
13821         }
13822     }
13823
13824   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13825     {
13826       errmsg ("missing vtr operation or sw_if_index");
13827       return -99;
13828     }
13829
13830   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13831   mp->sw_if_index = ntohl (sw_if_index);
13832   mp->vtr_op = ntohl (vtr_op);
13833   mp->push_dot1q = ntohl (push_dot1q);
13834   mp->tag1 = ntohl (tag1);
13835   mp->tag2 = ntohl (tag2);
13836
13837   S (mp);
13838   W (ret);
13839   return ret;
13840 }
13841
13842 static int
13843 api_create_vhost_user_if (vat_main_t * vam)
13844 {
13845   unformat_input_t *i = vam->input;
13846   vl_api_create_vhost_user_if_t *mp;
13847   u8 *file_name;
13848   u8 is_server = 0;
13849   u8 file_name_set = 0;
13850   u32 custom_dev_instance = ~0;
13851   u8 hwaddr[6];
13852   u8 use_custom_mac = 0;
13853   u8 *tag = 0;
13854   int ret;
13855
13856   /* Shut up coverity */
13857   memset (hwaddr, 0, sizeof (hwaddr));
13858
13859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13860     {
13861       if (unformat (i, "socket %s", &file_name))
13862         {
13863           file_name_set = 1;
13864         }
13865       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13866         ;
13867       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13868         use_custom_mac = 1;
13869       else if (unformat (i, "server"))
13870         is_server = 1;
13871       else if (unformat (i, "tag %s", &tag))
13872         ;
13873       else
13874         break;
13875     }
13876
13877   if (file_name_set == 0)
13878     {
13879       errmsg ("missing socket file name");
13880       return -99;
13881     }
13882
13883   if (vec_len (file_name) > 255)
13884     {
13885       errmsg ("socket file name too long");
13886       return -99;
13887     }
13888   vec_add1 (file_name, 0);
13889
13890   M (CREATE_VHOST_USER_IF, mp);
13891
13892   mp->is_server = is_server;
13893   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13894   vec_free (file_name);
13895   if (custom_dev_instance != ~0)
13896     {
13897       mp->renumber = 1;
13898       mp->custom_dev_instance = ntohl (custom_dev_instance);
13899     }
13900   mp->use_custom_mac = use_custom_mac;
13901   clib_memcpy (mp->mac_address, hwaddr, 6);
13902   if (tag)
13903     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13904   vec_free (tag);
13905
13906   S (mp);
13907   W (ret);
13908   return ret;
13909 }
13910
13911 static int
13912 api_modify_vhost_user_if (vat_main_t * vam)
13913 {
13914   unformat_input_t *i = vam->input;
13915   vl_api_modify_vhost_user_if_t *mp;
13916   u8 *file_name;
13917   u8 is_server = 0;
13918   u8 file_name_set = 0;
13919   u32 custom_dev_instance = ~0;
13920   u8 sw_if_index_set = 0;
13921   u32 sw_if_index = (u32) ~ 0;
13922   int ret;
13923
13924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13925     {
13926       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13927         sw_if_index_set = 1;
13928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13929         sw_if_index_set = 1;
13930       else if (unformat (i, "socket %s", &file_name))
13931         {
13932           file_name_set = 1;
13933         }
13934       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13935         ;
13936       else if (unformat (i, "server"))
13937         is_server = 1;
13938       else
13939         break;
13940     }
13941
13942   if (sw_if_index_set == 0)
13943     {
13944       errmsg ("missing sw_if_index or interface name");
13945       return -99;
13946     }
13947
13948   if (file_name_set == 0)
13949     {
13950       errmsg ("missing socket file name");
13951       return -99;
13952     }
13953
13954   if (vec_len (file_name) > 255)
13955     {
13956       errmsg ("socket file name too long");
13957       return -99;
13958     }
13959   vec_add1 (file_name, 0);
13960
13961   M (MODIFY_VHOST_USER_IF, mp);
13962
13963   mp->sw_if_index = ntohl (sw_if_index);
13964   mp->is_server = is_server;
13965   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13966   vec_free (file_name);
13967   if (custom_dev_instance != ~0)
13968     {
13969       mp->renumber = 1;
13970       mp->custom_dev_instance = ntohl (custom_dev_instance);
13971     }
13972
13973   S (mp);
13974   W (ret);
13975   return ret;
13976 }
13977
13978 static int
13979 api_delete_vhost_user_if (vat_main_t * vam)
13980 {
13981   unformat_input_t *i = vam->input;
13982   vl_api_delete_vhost_user_if_t *mp;
13983   u32 sw_if_index = ~0;
13984   u8 sw_if_index_set = 0;
13985   int ret;
13986
13987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13988     {
13989       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13990         sw_if_index_set = 1;
13991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13992         sw_if_index_set = 1;
13993       else
13994         break;
13995     }
13996
13997   if (sw_if_index_set == 0)
13998     {
13999       errmsg ("missing sw_if_index or interface name");
14000       return -99;
14001     }
14002
14003
14004   M (DELETE_VHOST_USER_IF, mp);
14005
14006   mp->sw_if_index = ntohl (sw_if_index);
14007
14008   S (mp);
14009   W (ret);
14010   return ret;
14011 }
14012
14013 static void vl_api_sw_interface_vhost_user_details_t_handler
14014   (vl_api_sw_interface_vhost_user_details_t * mp)
14015 {
14016   vat_main_t *vam = &vat_main;
14017
14018   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14019          (char *) mp->interface_name,
14020          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14021          clib_net_to_host_u64 (mp->features), mp->is_server,
14022          ntohl (mp->num_regions), (char *) mp->sock_filename);
14023   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14024 }
14025
14026 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14027   (vl_api_sw_interface_vhost_user_details_t * mp)
14028 {
14029   vat_main_t *vam = &vat_main;
14030   vat_json_node_t *node = NULL;
14031
14032   if (VAT_JSON_ARRAY != vam->json_tree.type)
14033     {
14034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14035       vat_json_init_array (&vam->json_tree);
14036     }
14037   node = vat_json_array_add (&vam->json_tree);
14038
14039   vat_json_init_object (node);
14040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14041   vat_json_object_add_string_copy (node, "interface_name",
14042                                    mp->interface_name);
14043   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14044                             ntohl (mp->virtio_net_hdr_sz));
14045   vat_json_object_add_uint (node, "features",
14046                             clib_net_to_host_u64 (mp->features));
14047   vat_json_object_add_uint (node, "is_server", mp->is_server);
14048   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14049   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14050   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14051 }
14052
14053 static int
14054 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14055 {
14056   vl_api_sw_interface_vhost_user_dump_t *mp;
14057   vl_api_control_ping_t *mp_ping;
14058   int ret;
14059   print (vam->ofp,
14060          "Interface name            idx hdr_sz features server regions filename");
14061
14062   /* Get list of vhost-user interfaces */
14063   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14064   S (mp);
14065
14066   /* Use a control ping for synchronization */
14067   MPING (CONTROL_PING, mp_ping);
14068   S (mp_ping);
14069
14070   W (ret);
14071   return ret;
14072 }
14073
14074 static int
14075 api_show_version (vat_main_t * vam)
14076 {
14077   vl_api_show_version_t *mp;
14078   int ret;
14079
14080   M (SHOW_VERSION, mp);
14081
14082   S (mp);
14083   W (ret);
14084   return ret;
14085 }
14086
14087
14088 static int
14089 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14090 {
14091   unformat_input_t *line_input = vam->input;
14092   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14093   ip4_address_t local4, remote4;
14094   ip6_address_t local6, remote6;
14095   u8 is_add = 1;
14096   u8 ipv4_set = 0, ipv6_set = 0;
14097   u8 local_set = 0;
14098   u8 remote_set = 0;
14099   u8 grp_set = 0;
14100   u32 mcast_sw_if_index = ~0;
14101   u32 encap_vrf_id = 0;
14102   u32 decap_vrf_id = 0;
14103   u8 protocol = ~0;
14104   u32 vni;
14105   u8 vni_set = 0;
14106   int ret;
14107
14108   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14109   memset (&local4, 0, sizeof local4);
14110   memset (&remote4, 0, sizeof remote4);
14111   memset (&local6, 0, sizeof local6);
14112   memset (&remote6, 0, sizeof remote6);
14113
14114   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14115     {
14116       if (unformat (line_input, "del"))
14117         is_add = 0;
14118       else if (unformat (line_input, "local %U",
14119                          unformat_ip4_address, &local4))
14120         {
14121           local_set = 1;
14122           ipv4_set = 1;
14123         }
14124       else if (unformat (line_input, "remote %U",
14125                          unformat_ip4_address, &remote4))
14126         {
14127           remote_set = 1;
14128           ipv4_set = 1;
14129         }
14130       else if (unformat (line_input, "local %U",
14131                          unformat_ip6_address, &local6))
14132         {
14133           local_set = 1;
14134           ipv6_set = 1;
14135         }
14136       else if (unformat (line_input, "remote %U",
14137                          unformat_ip6_address, &remote6))
14138         {
14139           remote_set = 1;
14140           ipv6_set = 1;
14141         }
14142       else if (unformat (line_input, "group %U %U",
14143                          unformat_ip4_address, &remote4,
14144                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14145         {
14146           grp_set = remote_set = 1;
14147           ipv4_set = 1;
14148         }
14149       else if (unformat (line_input, "group %U",
14150                          unformat_ip4_address, &remote4))
14151         {
14152           grp_set = remote_set = 1;
14153           ipv4_set = 1;
14154         }
14155       else if (unformat (line_input, "group %U %U",
14156                          unformat_ip6_address, &remote6,
14157                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14158         {
14159           grp_set = remote_set = 1;
14160           ipv6_set = 1;
14161         }
14162       else if (unformat (line_input, "group %U",
14163                          unformat_ip6_address, &remote6))
14164         {
14165           grp_set = remote_set = 1;
14166           ipv6_set = 1;
14167         }
14168       else
14169         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14170         ;
14171       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14172         ;
14173       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14174         ;
14175       else if (unformat (line_input, "vni %d", &vni))
14176         vni_set = 1;
14177       else if (unformat (line_input, "next-ip4"))
14178         protocol = 1;
14179       else if (unformat (line_input, "next-ip6"))
14180         protocol = 2;
14181       else if (unformat (line_input, "next-ethernet"))
14182         protocol = 3;
14183       else if (unformat (line_input, "next-nsh"))
14184         protocol = 4;
14185       else
14186         {
14187           errmsg ("parse error '%U'", format_unformat_error, line_input);
14188           return -99;
14189         }
14190     }
14191
14192   if (local_set == 0)
14193     {
14194       errmsg ("tunnel local address not specified");
14195       return -99;
14196     }
14197   if (remote_set == 0)
14198     {
14199       errmsg ("tunnel remote address not specified");
14200       return -99;
14201     }
14202   if (grp_set && mcast_sw_if_index == ~0)
14203     {
14204       errmsg ("tunnel nonexistent multicast device");
14205       return -99;
14206     }
14207   if (ipv4_set && ipv6_set)
14208     {
14209       errmsg ("both IPv4 and IPv6 addresses specified");
14210       return -99;
14211     }
14212
14213   if (vni_set == 0)
14214     {
14215       errmsg ("vni not specified");
14216       return -99;
14217     }
14218
14219   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14220
14221
14222   if (ipv6_set)
14223     {
14224       clib_memcpy (&mp->local, &local6, sizeof (local6));
14225       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14226     }
14227   else
14228     {
14229       clib_memcpy (&mp->local, &local4, sizeof (local4));
14230       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14231     }
14232
14233   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14234   mp->encap_vrf_id = ntohl (encap_vrf_id);
14235   mp->decap_vrf_id = ntohl (decap_vrf_id);
14236   mp->protocol = protocol;
14237   mp->vni = ntohl (vni);
14238   mp->is_add = is_add;
14239   mp->is_ipv6 = ipv6_set;
14240
14241   S (mp);
14242   W (ret);
14243   return ret;
14244 }
14245
14246 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14247   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14248 {
14249   vat_main_t *vam = &vat_main;
14250   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14251   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14252
14253   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14254          ntohl (mp->sw_if_index),
14255          format_ip46_address, &local, IP46_TYPE_ANY,
14256          format_ip46_address, &remote, IP46_TYPE_ANY,
14257          ntohl (mp->vni), mp->protocol,
14258          ntohl (mp->mcast_sw_if_index),
14259          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14260 }
14261
14262
14263 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14264   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14265 {
14266   vat_main_t *vam = &vat_main;
14267   vat_json_node_t *node = NULL;
14268   struct in_addr ip4;
14269   struct in6_addr ip6;
14270
14271   if (VAT_JSON_ARRAY != vam->json_tree.type)
14272     {
14273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14274       vat_json_init_array (&vam->json_tree);
14275     }
14276   node = vat_json_array_add (&vam->json_tree);
14277
14278   vat_json_init_object (node);
14279   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14280   if (mp->is_ipv6)
14281     {
14282       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14283       vat_json_object_add_ip6 (node, "local", ip6);
14284       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14285       vat_json_object_add_ip6 (node, "remote", ip6);
14286     }
14287   else
14288     {
14289       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14290       vat_json_object_add_ip4 (node, "local", ip4);
14291       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14292       vat_json_object_add_ip4 (node, "remote", ip4);
14293     }
14294   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14295   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14296   vat_json_object_add_uint (node, "mcast_sw_if_index",
14297                             ntohl (mp->mcast_sw_if_index));
14298   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14299   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14300   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14301 }
14302
14303 static int
14304 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14305 {
14306   unformat_input_t *i = vam->input;
14307   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14308   vl_api_control_ping_t *mp_ping;
14309   u32 sw_if_index;
14310   u8 sw_if_index_set = 0;
14311   int ret;
14312
14313   /* Parse args required to build the message */
14314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14315     {
14316       if (unformat (i, "sw_if_index %d", &sw_if_index))
14317         sw_if_index_set = 1;
14318       else
14319         break;
14320     }
14321
14322   if (sw_if_index_set == 0)
14323     {
14324       sw_if_index = ~0;
14325     }
14326
14327   if (!vam->json_output)
14328     {
14329       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14330              "sw_if_index", "local", "remote", "vni",
14331              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14332     }
14333
14334   /* Get list of vxlan-tunnel interfaces */
14335   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14336
14337   mp->sw_if_index = htonl (sw_if_index);
14338
14339   S (mp);
14340
14341   /* Use a control ping for synchronization */
14342   MPING (CONTROL_PING, mp_ping);
14343   S (mp_ping);
14344
14345   W (ret);
14346   return ret;
14347 }
14348
14349 static void vl_api_l2_fib_table_details_t_handler
14350   (vl_api_l2_fib_table_details_t * mp)
14351 {
14352   vat_main_t *vam = &vat_main;
14353
14354   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14355          "       %d       %d     %d",
14356          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14357          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14358          mp->bvi_mac);
14359 }
14360
14361 static void vl_api_l2_fib_table_details_t_handler_json
14362   (vl_api_l2_fib_table_details_t * mp)
14363 {
14364   vat_main_t *vam = &vat_main;
14365   vat_json_node_t *node = NULL;
14366
14367   if (VAT_JSON_ARRAY != vam->json_tree.type)
14368     {
14369       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14370       vat_json_init_array (&vam->json_tree);
14371     }
14372   node = vat_json_array_add (&vam->json_tree);
14373
14374   vat_json_init_object (node);
14375   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14376   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14377   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14378   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14379   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14380   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14381 }
14382
14383 static int
14384 api_l2_fib_table_dump (vat_main_t * vam)
14385 {
14386   unformat_input_t *i = vam->input;
14387   vl_api_l2_fib_table_dump_t *mp;
14388   vl_api_control_ping_t *mp_ping;
14389   u32 bd_id;
14390   u8 bd_id_set = 0;
14391   int ret;
14392
14393   /* Parse args required to build the message */
14394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14395     {
14396       if (unformat (i, "bd_id %d", &bd_id))
14397         bd_id_set = 1;
14398       else
14399         break;
14400     }
14401
14402   if (bd_id_set == 0)
14403     {
14404       errmsg ("missing bridge domain");
14405       return -99;
14406     }
14407
14408   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14409
14410   /* Get list of l2 fib entries */
14411   M (L2_FIB_TABLE_DUMP, mp);
14412
14413   mp->bd_id = ntohl (bd_id);
14414   S (mp);
14415
14416   /* Use a control ping for synchronization */
14417   MPING (CONTROL_PING, mp_ping);
14418   S (mp_ping);
14419
14420   W (ret);
14421   return ret;
14422 }
14423
14424
14425 static int
14426 api_interface_name_renumber (vat_main_t * vam)
14427 {
14428   unformat_input_t *line_input = vam->input;
14429   vl_api_interface_name_renumber_t *mp;
14430   u32 sw_if_index = ~0;
14431   u32 new_show_dev_instance = ~0;
14432   int ret;
14433
14434   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14435     {
14436       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14437                     &sw_if_index))
14438         ;
14439       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14440         ;
14441       else if (unformat (line_input, "new_show_dev_instance %d",
14442                          &new_show_dev_instance))
14443         ;
14444       else
14445         break;
14446     }
14447
14448   if (sw_if_index == ~0)
14449     {
14450       errmsg ("missing interface name or sw_if_index");
14451       return -99;
14452     }
14453
14454   if (new_show_dev_instance == ~0)
14455     {
14456       errmsg ("missing new_show_dev_instance");
14457       return -99;
14458     }
14459
14460   M (INTERFACE_NAME_RENUMBER, mp);
14461
14462   mp->sw_if_index = ntohl (sw_if_index);
14463   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14464
14465   S (mp);
14466   W (ret);
14467   return ret;
14468 }
14469
14470 static int
14471 api_ip_probe_neighbor (vat_main_t * vam)
14472 {
14473   unformat_input_t *i = vam->input;
14474   vl_api_ip_probe_neighbor_t *mp;
14475   u8 int_set = 0;
14476   u8 adr_set = 0;
14477   u8 is_ipv6 = 0;
14478   u8 dst_adr[16];
14479   u32 sw_if_index;
14480   int ret;
14481
14482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14483     {
14484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14485         int_set = 1;
14486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14487         int_set = 1;
14488       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14489         adr_set = 1;
14490       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14491         {
14492           adr_set = 1;
14493           is_ipv6 = 1;
14494         }
14495       else
14496         break;
14497     }
14498
14499   if (int_set == 0)
14500     {
14501       errmsg ("missing interface");
14502       return -99;
14503     }
14504
14505   if (adr_set == 0)
14506     {
14507       errmsg ("missing addresses");
14508       return -99;
14509     }
14510
14511   M (IP_PROBE_NEIGHBOR, mp);
14512
14513   mp->sw_if_index = ntohl (sw_if_index);
14514   mp->is_ipv6 = is_ipv6;
14515   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14516
14517   S (mp);
14518   W (ret);
14519   return ret;
14520 }
14521
14522 static int
14523 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14524 {
14525   unformat_input_t *i = vam->input;
14526   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14527   u8 mode = IP_SCAN_V46_NEIGHBORS;
14528   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14529   int ret;
14530
14531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14532     {
14533       if (unformat (i, "ip4"))
14534         mode = IP_SCAN_V4_NEIGHBORS;
14535       else if (unformat (i, "ip6"))
14536         mode = IP_SCAN_V6_NEIGHBORS;
14537       if (unformat (i, "both"))
14538         mode = IP_SCAN_V46_NEIGHBORS;
14539       else if (unformat (i, "disable"))
14540         mode = IP_SCAN_DISABLED;
14541       else if (unformat (i, "interval %d", &interval))
14542         ;
14543       else if (unformat (i, "max-time %d", &time))
14544         ;
14545       else if (unformat (i, "max-update %d", &update))
14546         ;
14547       else if (unformat (i, "delay %d", &delay))
14548         ;
14549       else if (unformat (i, "stale %d", &stale))
14550         ;
14551       else
14552         break;
14553     }
14554
14555   if (interval > 255)
14556     {
14557       errmsg ("interval cannot exceed 255 minutes.");
14558       return -99;
14559     }
14560   if (time > 255)
14561     {
14562       errmsg ("max-time cannot exceed 255 usec.");
14563       return -99;
14564     }
14565   if (update > 255)
14566     {
14567       errmsg ("max-update cannot exceed 255.");
14568       return -99;
14569     }
14570   if (delay > 255)
14571     {
14572       errmsg ("delay cannot exceed 255 msec.");
14573       return -99;
14574     }
14575   if (stale > 255)
14576     {
14577       errmsg ("stale cannot exceed 255 minutes.");
14578       return -99;
14579     }
14580
14581   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14582   mp->mode = mode;
14583   mp->scan_interval = interval;
14584   mp->max_proc_time = time;
14585   mp->max_update = update;
14586   mp->scan_int_delay = delay;
14587   mp->stale_threshold = stale;
14588
14589   S (mp);
14590   W (ret);
14591   return ret;
14592 }
14593
14594 static int
14595 api_want_ip4_arp_events (vat_main_t * vam)
14596 {
14597   unformat_input_t *line_input = vam->input;
14598   vl_api_want_ip4_arp_events_t *mp;
14599   ip4_address_t address;
14600   int address_set = 0;
14601   u32 enable_disable = 1;
14602   int ret;
14603
14604   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14605     {
14606       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14607         address_set = 1;
14608       else if (unformat (line_input, "del"))
14609         enable_disable = 0;
14610       else
14611         break;
14612     }
14613
14614   if (address_set == 0)
14615     {
14616       errmsg ("missing addresses");
14617       return -99;
14618     }
14619
14620   M (WANT_IP4_ARP_EVENTS, mp);
14621   mp->enable_disable = enable_disable;
14622   mp->pid = htonl (getpid ());
14623   mp->address = address.as_u32;
14624
14625   S (mp);
14626   W (ret);
14627   return ret;
14628 }
14629
14630 static int
14631 api_want_ip6_nd_events (vat_main_t * vam)
14632 {
14633   unformat_input_t *line_input = vam->input;
14634   vl_api_want_ip6_nd_events_t *mp;
14635   ip6_address_t address;
14636   int address_set = 0;
14637   u32 enable_disable = 1;
14638   int ret;
14639
14640   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14641     {
14642       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14643         address_set = 1;
14644       else if (unformat (line_input, "del"))
14645         enable_disable = 0;
14646       else
14647         break;
14648     }
14649
14650   if (address_set == 0)
14651     {
14652       errmsg ("missing addresses");
14653       return -99;
14654     }
14655
14656   M (WANT_IP6_ND_EVENTS, mp);
14657   mp->enable_disable = enable_disable;
14658   mp->pid = htonl (getpid ());
14659   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14660
14661   S (mp);
14662   W (ret);
14663   return ret;
14664 }
14665
14666 static int
14667 api_want_l2_macs_events (vat_main_t * vam)
14668 {
14669   unformat_input_t *line_input = vam->input;
14670   vl_api_want_l2_macs_events_t *mp;
14671   u8 enable_disable = 1;
14672   u32 scan_delay = 0;
14673   u32 max_macs_in_event = 0;
14674   u32 learn_limit = 0;
14675   int ret;
14676
14677   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14678     {
14679       if (unformat (line_input, "learn-limit %d", &learn_limit))
14680         ;
14681       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14682         ;
14683       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14684         ;
14685       else if (unformat (line_input, "disable"))
14686         enable_disable = 0;
14687       else
14688         break;
14689     }
14690
14691   M (WANT_L2_MACS_EVENTS, mp);
14692   mp->enable_disable = enable_disable;
14693   mp->pid = htonl (getpid ());
14694   mp->learn_limit = htonl (learn_limit);
14695   mp->scan_delay = (u8) scan_delay;
14696   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14697   S (mp);
14698   W (ret);
14699   return ret;
14700 }
14701
14702 static int
14703 api_input_acl_set_interface (vat_main_t * vam)
14704 {
14705   unformat_input_t *i = vam->input;
14706   vl_api_input_acl_set_interface_t *mp;
14707   u32 sw_if_index;
14708   int sw_if_index_set;
14709   u32 ip4_table_index = ~0;
14710   u32 ip6_table_index = ~0;
14711   u32 l2_table_index = ~0;
14712   u8 is_add = 1;
14713   int ret;
14714
14715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14716     {
14717       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14718         sw_if_index_set = 1;
14719       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14720         sw_if_index_set = 1;
14721       else if (unformat (i, "del"))
14722         is_add = 0;
14723       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14724         ;
14725       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14726         ;
14727       else if (unformat (i, "l2-table %d", &l2_table_index))
14728         ;
14729       else
14730         {
14731           clib_warning ("parse error '%U'", format_unformat_error, i);
14732           return -99;
14733         }
14734     }
14735
14736   if (sw_if_index_set == 0)
14737     {
14738       errmsg ("missing interface name or sw_if_index");
14739       return -99;
14740     }
14741
14742   M (INPUT_ACL_SET_INTERFACE, mp);
14743
14744   mp->sw_if_index = ntohl (sw_if_index);
14745   mp->ip4_table_index = ntohl (ip4_table_index);
14746   mp->ip6_table_index = ntohl (ip6_table_index);
14747   mp->l2_table_index = ntohl (l2_table_index);
14748   mp->is_add = is_add;
14749
14750   S (mp);
14751   W (ret);
14752   return ret;
14753 }
14754
14755 static int
14756 api_output_acl_set_interface (vat_main_t * vam)
14757 {
14758   unformat_input_t *i = vam->input;
14759   vl_api_output_acl_set_interface_t *mp;
14760   u32 sw_if_index;
14761   int sw_if_index_set;
14762   u32 ip4_table_index = ~0;
14763   u32 ip6_table_index = ~0;
14764   u32 l2_table_index = ~0;
14765   u8 is_add = 1;
14766   int ret;
14767
14768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14769     {
14770       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14771         sw_if_index_set = 1;
14772       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14773         sw_if_index_set = 1;
14774       else if (unformat (i, "del"))
14775         is_add = 0;
14776       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14777         ;
14778       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14779         ;
14780       else if (unformat (i, "l2-table %d", &l2_table_index))
14781         ;
14782       else
14783         {
14784           clib_warning ("parse error '%U'", format_unformat_error, i);
14785           return -99;
14786         }
14787     }
14788
14789   if (sw_if_index_set == 0)
14790     {
14791       errmsg ("missing interface name or sw_if_index");
14792       return -99;
14793     }
14794
14795   M (OUTPUT_ACL_SET_INTERFACE, mp);
14796
14797   mp->sw_if_index = ntohl (sw_if_index);
14798   mp->ip4_table_index = ntohl (ip4_table_index);
14799   mp->ip6_table_index = ntohl (ip6_table_index);
14800   mp->l2_table_index = ntohl (l2_table_index);
14801   mp->is_add = is_add;
14802
14803   S (mp);
14804   W (ret);
14805   return ret;
14806 }
14807
14808 static int
14809 api_ip_address_dump (vat_main_t * vam)
14810 {
14811   unformat_input_t *i = vam->input;
14812   vl_api_ip_address_dump_t *mp;
14813   vl_api_control_ping_t *mp_ping;
14814   u32 sw_if_index = ~0;
14815   u8 sw_if_index_set = 0;
14816   u8 ipv4_set = 0;
14817   u8 ipv6_set = 0;
14818   int ret;
14819
14820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14821     {
14822       if (unformat (i, "sw_if_index %d", &sw_if_index))
14823         sw_if_index_set = 1;
14824       else
14825         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14826         sw_if_index_set = 1;
14827       else if (unformat (i, "ipv4"))
14828         ipv4_set = 1;
14829       else if (unformat (i, "ipv6"))
14830         ipv6_set = 1;
14831       else
14832         break;
14833     }
14834
14835   if (ipv4_set && ipv6_set)
14836     {
14837       errmsg ("ipv4 and ipv6 flags cannot be both set");
14838       return -99;
14839     }
14840
14841   if ((!ipv4_set) && (!ipv6_set))
14842     {
14843       errmsg ("no ipv4 nor ipv6 flag set");
14844       return -99;
14845     }
14846
14847   if (sw_if_index_set == 0)
14848     {
14849       errmsg ("missing interface name or sw_if_index");
14850       return -99;
14851     }
14852
14853   vam->current_sw_if_index = sw_if_index;
14854   vam->is_ipv6 = ipv6_set;
14855
14856   M (IP_ADDRESS_DUMP, mp);
14857   mp->sw_if_index = ntohl (sw_if_index);
14858   mp->is_ipv6 = ipv6_set;
14859   S (mp);
14860
14861   /* Use a control ping for synchronization */
14862   MPING (CONTROL_PING, mp_ping);
14863   S (mp_ping);
14864
14865   W (ret);
14866   return ret;
14867 }
14868
14869 static int
14870 api_ip_dump (vat_main_t * vam)
14871 {
14872   vl_api_ip_dump_t *mp;
14873   vl_api_control_ping_t *mp_ping;
14874   unformat_input_t *in = vam->input;
14875   int ipv4_set = 0;
14876   int ipv6_set = 0;
14877   int is_ipv6;
14878   int i;
14879   int ret;
14880
14881   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14882     {
14883       if (unformat (in, "ipv4"))
14884         ipv4_set = 1;
14885       else if (unformat (in, "ipv6"))
14886         ipv6_set = 1;
14887       else
14888         break;
14889     }
14890
14891   if (ipv4_set && ipv6_set)
14892     {
14893       errmsg ("ipv4 and ipv6 flags cannot be both set");
14894       return -99;
14895     }
14896
14897   if ((!ipv4_set) && (!ipv6_set))
14898     {
14899       errmsg ("no ipv4 nor ipv6 flag set");
14900       return -99;
14901     }
14902
14903   is_ipv6 = ipv6_set;
14904   vam->is_ipv6 = is_ipv6;
14905
14906   /* free old data */
14907   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14908     {
14909       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14910     }
14911   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14912
14913   M (IP_DUMP, mp);
14914   mp->is_ipv6 = ipv6_set;
14915   S (mp);
14916
14917   /* Use a control ping for synchronization */
14918   MPING (CONTROL_PING, mp_ping);
14919   S (mp_ping);
14920
14921   W (ret);
14922   return ret;
14923 }
14924
14925 static int
14926 api_ipsec_spd_add_del (vat_main_t * vam)
14927 {
14928   unformat_input_t *i = vam->input;
14929   vl_api_ipsec_spd_add_del_t *mp;
14930   u32 spd_id = ~0;
14931   u8 is_add = 1;
14932   int ret;
14933
14934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14935     {
14936       if (unformat (i, "spd_id %d", &spd_id))
14937         ;
14938       else if (unformat (i, "del"))
14939         is_add = 0;
14940       else
14941         {
14942           clib_warning ("parse error '%U'", format_unformat_error, i);
14943           return -99;
14944         }
14945     }
14946   if (spd_id == ~0)
14947     {
14948       errmsg ("spd_id must be set");
14949       return -99;
14950     }
14951
14952   M (IPSEC_SPD_ADD_DEL, mp);
14953
14954   mp->spd_id = ntohl (spd_id);
14955   mp->is_add = is_add;
14956
14957   S (mp);
14958   W (ret);
14959   return ret;
14960 }
14961
14962 static int
14963 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14964 {
14965   unformat_input_t *i = vam->input;
14966   vl_api_ipsec_interface_add_del_spd_t *mp;
14967   u32 sw_if_index;
14968   u8 sw_if_index_set = 0;
14969   u32 spd_id = (u32) ~ 0;
14970   u8 is_add = 1;
14971   int ret;
14972
14973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14974     {
14975       if (unformat (i, "del"))
14976         is_add = 0;
14977       else if (unformat (i, "spd_id %d", &spd_id))
14978         ;
14979       else
14980         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14981         sw_if_index_set = 1;
14982       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14983         sw_if_index_set = 1;
14984       else
14985         {
14986           clib_warning ("parse error '%U'", format_unformat_error, i);
14987           return -99;
14988         }
14989
14990     }
14991
14992   if (spd_id == (u32) ~ 0)
14993     {
14994       errmsg ("spd_id must be set");
14995       return -99;
14996     }
14997
14998   if (sw_if_index_set == 0)
14999     {
15000       errmsg ("missing interface name or sw_if_index");
15001       return -99;
15002     }
15003
15004   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15005
15006   mp->spd_id = ntohl (spd_id);
15007   mp->sw_if_index = ntohl (sw_if_index);
15008   mp->is_add = is_add;
15009
15010   S (mp);
15011   W (ret);
15012   return ret;
15013 }
15014
15015 static int
15016 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15017 {
15018   unformat_input_t *i = vam->input;
15019   vl_api_ipsec_spd_add_del_entry_t *mp;
15020   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15021   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15022   i32 priority = 0;
15023   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15024   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15025   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15026   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15027   int ret;
15028
15029   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15030   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15031   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15032   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15033   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15034   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15035
15036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15037     {
15038       if (unformat (i, "del"))
15039         is_add = 0;
15040       if (unformat (i, "outbound"))
15041         is_outbound = 1;
15042       if (unformat (i, "inbound"))
15043         is_outbound = 0;
15044       else if (unformat (i, "spd_id %d", &spd_id))
15045         ;
15046       else if (unformat (i, "sa_id %d", &sa_id))
15047         ;
15048       else if (unformat (i, "priority %d", &priority))
15049         ;
15050       else if (unformat (i, "protocol %d", &protocol))
15051         ;
15052       else if (unformat (i, "lport_start %d", &lport_start))
15053         ;
15054       else if (unformat (i, "lport_stop %d", &lport_stop))
15055         ;
15056       else if (unformat (i, "rport_start %d", &rport_start))
15057         ;
15058       else if (unformat (i, "rport_stop %d", &rport_stop))
15059         ;
15060       else
15061         if (unformat
15062             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15063         {
15064           is_ipv6 = 0;
15065           is_ip_any = 0;
15066         }
15067       else
15068         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15069         {
15070           is_ipv6 = 0;
15071           is_ip_any = 0;
15072         }
15073       else
15074         if (unformat
15075             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15076         {
15077           is_ipv6 = 0;
15078           is_ip_any = 0;
15079         }
15080       else
15081         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15082         {
15083           is_ipv6 = 0;
15084           is_ip_any = 0;
15085         }
15086       else
15087         if (unformat
15088             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15089         {
15090           is_ipv6 = 1;
15091           is_ip_any = 0;
15092         }
15093       else
15094         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15095         {
15096           is_ipv6 = 1;
15097           is_ip_any = 0;
15098         }
15099       else
15100         if (unformat
15101             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15102         {
15103           is_ipv6 = 1;
15104           is_ip_any = 0;
15105         }
15106       else
15107         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15108         {
15109           is_ipv6 = 1;
15110           is_ip_any = 0;
15111         }
15112       else
15113         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15114         {
15115           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15116             {
15117               clib_warning ("unsupported action: 'resolve'");
15118               return -99;
15119             }
15120         }
15121       else
15122         {
15123           clib_warning ("parse error '%U'", format_unformat_error, i);
15124           return -99;
15125         }
15126
15127     }
15128
15129   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15130
15131   mp->spd_id = ntohl (spd_id);
15132   mp->priority = ntohl (priority);
15133   mp->is_outbound = is_outbound;
15134
15135   mp->is_ipv6 = is_ipv6;
15136   if (is_ipv6 || is_ip_any)
15137     {
15138       clib_memcpy (mp->remote_address_start, &raddr6_start,
15139                    sizeof (ip6_address_t));
15140       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15141                    sizeof (ip6_address_t));
15142       clib_memcpy (mp->local_address_start, &laddr6_start,
15143                    sizeof (ip6_address_t));
15144       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15145                    sizeof (ip6_address_t));
15146     }
15147   else
15148     {
15149       clib_memcpy (mp->remote_address_start, &raddr4_start,
15150                    sizeof (ip4_address_t));
15151       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15152                    sizeof (ip4_address_t));
15153       clib_memcpy (mp->local_address_start, &laddr4_start,
15154                    sizeof (ip4_address_t));
15155       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15156                    sizeof (ip4_address_t));
15157     }
15158   mp->protocol = (u8) protocol;
15159   mp->local_port_start = ntohs ((u16) lport_start);
15160   mp->local_port_stop = ntohs ((u16) lport_stop);
15161   mp->remote_port_start = ntohs ((u16) rport_start);
15162   mp->remote_port_stop = ntohs ((u16) rport_stop);
15163   mp->policy = (u8) policy;
15164   mp->sa_id = ntohl (sa_id);
15165   mp->is_add = is_add;
15166   mp->is_ip_any = is_ip_any;
15167   S (mp);
15168   W (ret);
15169   return ret;
15170 }
15171
15172 static int
15173 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15174 {
15175   unformat_input_t *i = vam->input;
15176   vl_api_ipsec_sad_add_del_entry_t *mp;
15177   u32 sad_id = 0, spi = 0;
15178   u8 *ck = 0, *ik = 0;
15179   u8 is_add = 1;
15180
15181   u8 protocol = IPSEC_PROTOCOL_AH;
15182   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15183   u32 crypto_alg = 0, integ_alg = 0;
15184   ip4_address_t tun_src4;
15185   ip4_address_t tun_dst4;
15186   ip6_address_t tun_src6;
15187   ip6_address_t tun_dst6;
15188   int ret;
15189
15190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15191     {
15192       if (unformat (i, "del"))
15193         is_add = 0;
15194       else if (unformat (i, "sad_id %d", &sad_id))
15195         ;
15196       else if (unformat (i, "spi %d", &spi))
15197         ;
15198       else if (unformat (i, "esp"))
15199         protocol = IPSEC_PROTOCOL_ESP;
15200       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15201         {
15202           is_tunnel = 1;
15203           is_tunnel_ipv6 = 0;
15204         }
15205       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15206         {
15207           is_tunnel = 1;
15208           is_tunnel_ipv6 = 0;
15209         }
15210       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15211         {
15212           is_tunnel = 1;
15213           is_tunnel_ipv6 = 1;
15214         }
15215       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15216         {
15217           is_tunnel = 1;
15218           is_tunnel_ipv6 = 1;
15219         }
15220       else
15221         if (unformat
15222             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15223         {
15224           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15225               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15226             {
15227               clib_warning ("unsupported crypto-alg: '%U'",
15228                             format_ipsec_crypto_alg, crypto_alg);
15229               return -99;
15230             }
15231         }
15232       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15233         ;
15234       else
15235         if (unformat
15236             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15237         {
15238           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15239               integ_alg >= IPSEC_INTEG_N_ALG)
15240             {
15241               clib_warning ("unsupported integ-alg: '%U'",
15242                             format_ipsec_integ_alg, integ_alg);
15243               return -99;
15244             }
15245         }
15246       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15247         ;
15248       else
15249         {
15250           clib_warning ("parse error '%U'", format_unformat_error, i);
15251           return -99;
15252         }
15253
15254     }
15255
15256   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15257
15258   mp->sad_id = ntohl (sad_id);
15259   mp->is_add = is_add;
15260   mp->protocol = protocol;
15261   mp->spi = ntohl (spi);
15262   mp->is_tunnel = is_tunnel;
15263   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15264   mp->crypto_algorithm = crypto_alg;
15265   mp->integrity_algorithm = integ_alg;
15266   mp->crypto_key_length = vec_len (ck);
15267   mp->integrity_key_length = vec_len (ik);
15268
15269   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15270     mp->crypto_key_length = sizeof (mp->crypto_key);
15271
15272   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15273     mp->integrity_key_length = sizeof (mp->integrity_key);
15274
15275   if (ck)
15276     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15277   if (ik)
15278     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15279
15280   if (is_tunnel)
15281     {
15282       if (is_tunnel_ipv6)
15283         {
15284           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15285                        sizeof (ip6_address_t));
15286           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15287                        sizeof (ip6_address_t));
15288         }
15289       else
15290         {
15291           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15292                        sizeof (ip4_address_t));
15293           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15294                        sizeof (ip4_address_t));
15295         }
15296     }
15297
15298   S (mp);
15299   W (ret);
15300   return ret;
15301 }
15302
15303 static int
15304 api_ipsec_sa_set_key (vat_main_t * vam)
15305 {
15306   unformat_input_t *i = vam->input;
15307   vl_api_ipsec_sa_set_key_t *mp;
15308   u32 sa_id;
15309   u8 *ck = 0, *ik = 0;
15310   int ret;
15311
15312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15313     {
15314       if (unformat (i, "sa_id %d", &sa_id))
15315         ;
15316       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15317         ;
15318       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15319         ;
15320       else
15321         {
15322           clib_warning ("parse error '%U'", format_unformat_error, i);
15323           return -99;
15324         }
15325     }
15326
15327   M (IPSEC_SA_SET_KEY, mp);
15328
15329   mp->sa_id = ntohl (sa_id);
15330   mp->crypto_key_length = vec_len (ck);
15331   mp->integrity_key_length = vec_len (ik);
15332
15333   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15334     mp->crypto_key_length = sizeof (mp->crypto_key);
15335
15336   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15337     mp->integrity_key_length = sizeof (mp->integrity_key);
15338
15339   if (ck)
15340     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15341   if (ik)
15342     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15343
15344   S (mp);
15345   W (ret);
15346   return ret;
15347 }
15348
15349 static int
15350 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15351 {
15352   unformat_input_t *i = vam->input;
15353   vl_api_ipsec_tunnel_if_add_del_t *mp;
15354   u32 local_spi = 0, remote_spi = 0;
15355   u32 crypto_alg = 0, integ_alg = 0;
15356   u8 *lck = NULL, *rck = NULL;
15357   u8 *lik = NULL, *rik = NULL;
15358   ip4_address_t local_ip = { {0} };
15359   ip4_address_t remote_ip = { {0} };
15360   u8 is_add = 1;
15361   u8 esn = 0;
15362   u8 anti_replay = 0;
15363   u8 renumber = 0;
15364   u32 instance = ~0;
15365   int ret;
15366
15367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15368     {
15369       if (unformat (i, "del"))
15370         is_add = 0;
15371       else if (unformat (i, "esn"))
15372         esn = 1;
15373       else if (unformat (i, "anti_replay"))
15374         anti_replay = 1;
15375       else if (unformat (i, "local_spi %d", &local_spi))
15376         ;
15377       else if (unformat (i, "remote_spi %d", &remote_spi))
15378         ;
15379       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15380         ;
15381       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15382         ;
15383       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15384         ;
15385       else
15386         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15387         ;
15388       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15389         ;
15390       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15391         ;
15392       else
15393         if (unformat
15394             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15395         {
15396           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15397               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15398             {
15399               errmsg ("unsupported crypto-alg: '%U'\n",
15400                       format_ipsec_crypto_alg, crypto_alg);
15401               return -99;
15402             }
15403         }
15404       else
15405         if (unformat
15406             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15407         {
15408           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15409               integ_alg >= IPSEC_INTEG_N_ALG)
15410             {
15411               errmsg ("unsupported integ-alg: '%U'\n",
15412                       format_ipsec_integ_alg, integ_alg);
15413               return -99;
15414             }
15415         }
15416       else if (unformat (i, "instance %u", &instance))
15417         renumber = 1;
15418       else
15419         {
15420           errmsg ("parse error '%U'\n", format_unformat_error, i);
15421           return -99;
15422         }
15423     }
15424
15425   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15426
15427   mp->is_add = is_add;
15428   mp->esn = esn;
15429   mp->anti_replay = anti_replay;
15430
15431   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15432   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15433
15434   mp->local_spi = htonl (local_spi);
15435   mp->remote_spi = htonl (remote_spi);
15436   mp->crypto_alg = (u8) crypto_alg;
15437
15438   mp->local_crypto_key_len = 0;
15439   if (lck)
15440     {
15441       mp->local_crypto_key_len = vec_len (lck);
15442       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15443         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15444       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15445     }
15446
15447   mp->remote_crypto_key_len = 0;
15448   if (rck)
15449     {
15450       mp->remote_crypto_key_len = vec_len (rck);
15451       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15452         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15453       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15454     }
15455
15456   mp->integ_alg = (u8) integ_alg;
15457
15458   mp->local_integ_key_len = 0;
15459   if (lik)
15460     {
15461       mp->local_integ_key_len = vec_len (lik);
15462       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15463         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15464       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15465     }
15466
15467   mp->remote_integ_key_len = 0;
15468   if (rik)
15469     {
15470       mp->remote_integ_key_len = vec_len (rik);
15471       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15472         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15473       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15474     }
15475
15476   if (renumber)
15477     {
15478       mp->renumber = renumber;
15479       mp->show_instance = ntohl (instance);
15480     }
15481
15482   S (mp);
15483   W (ret);
15484   return ret;
15485 }
15486
15487 static void
15488 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15489 {
15490   vat_main_t *vam = &vat_main;
15491
15492   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15493          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15494          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15495          "tunnel_src_addr %U tunnel_dst_addr %U "
15496          "salt %u seq_outbound %lu last_seq_inbound %lu "
15497          "replay_window %lu total_data_size %lu\n",
15498          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15499          mp->protocol,
15500          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15501          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15502          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15503          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15504          mp->tunnel_src_addr,
15505          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15506          mp->tunnel_dst_addr,
15507          ntohl (mp->salt),
15508          clib_net_to_host_u64 (mp->seq_outbound),
15509          clib_net_to_host_u64 (mp->last_seq_inbound),
15510          clib_net_to_host_u64 (mp->replay_window),
15511          clib_net_to_host_u64 (mp->total_data_size));
15512 }
15513
15514 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15515 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15516
15517 static void vl_api_ipsec_sa_details_t_handler_json
15518   (vl_api_ipsec_sa_details_t * mp)
15519 {
15520   vat_main_t *vam = &vat_main;
15521   vat_json_node_t *node = NULL;
15522   struct in_addr src_ip4, dst_ip4;
15523   struct in6_addr src_ip6, dst_ip6;
15524
15525   if (VAT_JSON_ARRAY != vam->json_tree.type)
15526     {
15527       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15528       vat_json_init_array (&vam->json_tree);
15529     }
15530   node = vat_json_array_add (&vam->json_tree);
15531
15532   vat_json_init_object (node);
15533   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15534   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15535   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15536   vat_json_object_add_uint (node, "proto", mp->protocol);
15537   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15538   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15539   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15540   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15541   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15542   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15543   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15544                              mp->crypto_key_len);
15545   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15546                              mp->integ_key_len);
15547   if (mp->is_tunnel_ip6)
15548     {
15549       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15550       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15551       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15552       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15553     }
15554   else
15555     {
15556       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15557       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15558       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15559       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15560     }
15561   vat_json_object_add_uint (node, "replay_window",
15562                             clib_net_to_host_u64 (mp->replay_window));
15563   vat_json_object_add_uint (node, "total_data_size",
15564                             clib_net_to_host_u64 (mp->total_data_size));
15565
15566 }
15567
15568 static int
15569 api_ipsec_sa_dump (vat_main_t * vam)
15570 {
15571   unformat_input_t *i = vam->input;
15572   vl_api_ipsec_sa_dump_t *mp;
15573   vl_api_control_ping_t *mp_ping;
15574   u32 sa_id = ~0;
15575   int ret;
15576
15577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15578     {
15579       if (unformat (i, "sa_id %d", &sa_id))
15580         ;
15581       else
15582         {
15583           clib_warning ("parse error '%U'", format_unformat_error, i);
15584           return -99;
15585         }
15586     }
15587
15588   M (IPSEC_SA_DUMP, mp);
15589
15590   mp->sa_id = ntohl (sa_id);
15591
15592   S (mp);
15593
15594   /* Use a control ping for synchronization */
15595   M (CONTROL_PING, mp_ping);
15596   S (mp_ping);
15597
15598   W (ret);
15599   return ret;
15600 }
15601
15602 static int
15603 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15604 {
15605   unformat_input_t *i = vam->input;
15606   vl_api_ipsec_tunnel_if_set_key_t *mp;
15607   u32 sw_if_index = ~0;
15608   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15609   u8 *key = 0;
15610   u32 alg = ~0;
15611   int ret;
15612
15613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15614     {
15615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15616         ;
15617       else
15618         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15619         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15620       else
15621         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15622         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15623       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15624         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15625       else
15626         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15627         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15628       else if (unformat (i, "%U", unformat_hex_string, &key))
15629         ;
15630       else
15631         {
15632           clib_warning ("parse error '%U'", format_unformat_error, i);
15633           return -99;
15634         }
15635     }
15636
15637   if (sw_if_index == ~0)
15638     {
15639       errmsg ("interface must be specified");
15640       return -99;
15641     }
15642
15643   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15644     {
15645       errmsg ("key type must be specified");
15646       return -99;
15647     }
15648
15649   if (alg == ~0)
15650     {
15651       errmsg ("algorithm must be specified");
15652       return -99;
15653     }
15654
15655   if (vec_len (key) == 0)
15656     {
15657       errmsg ("key must be specified");
15658       return -99;
15659     }
15660
15661   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15662
15663   mp->sw_if_index = htonl (sw_if_index);
15664   mp->alg = alg;
15665   mp->key_type = key_type;
15666   mp->key_len = vec_len (key);
15667   clib_memcpy (mp->key, key, vec_len (key));
15668
15669   S (mp);
15670   W (ret);
15671
15672   return ret;
15673 }
15674
15675 static int
15676 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15677 {
15678   unformat_input_t *i = vam->input;
15679   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15680   u32 sw_if_index = ~0;
15681   u32 sa_id = ~0;
15682   u8 is_outbound = (u8) ~ 0;
15683   int ret;
15684
15685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15686     {
15687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15688         ;
15689       else if (unformat (i, "sa_id %d", &sa_id))
15690         ;
15691       else if (unformat (i, "outbound"))
15692         is_outbound = 1;
15693       else if (unformat (i, "inbound"))
15694         is_outbound = 0;
15695       else
15696         {
15697           clib_warning ("parse error '%U'", format_unformat_error, i);
15698           return -99;
15699         }
15700     }
15701
15702   if (sw_if_index == ~0)
15703     {
15704       errmsg ("interface must be specified");
15705       return -99;
15706     }
15707
15708   if (sa_id == ~0)
15709     {
15710       errmsg ("SA ID must be specified");
15711       return -99;
15712     }
15713
15714   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15715
15716   mp->sw_if_index = htonl (sw_if_index);
15717   mp->sa_id = htonl (sa_id);
15718   mp->is_outbound = is_outbound;
15719
15720   S (mp);
15721   W (ret);
15722
15723   return ret;
15724 }
15725
15726 static int
15727 api_ikev2_profile_add_del (vat_main_t * vam)
15728 {
15729   unformat_input_t *i = vam->input;
15730   vl_api_ikev2_profile_add_del_t *mp;
15731   u8 is_add = 1;
15732   u8 *name = 0;
15733   int ret;
15734
15735   const char *valid_chars = "a-zA-Z0-9_";
15736
15737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15738     {
15739       if (unformat (i, "del"))
15740         is_add = 0;
15741       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15742         vec_add1 (name, 0);
15743       else
15744         {
15745           errmsg ("parse error '%U'", format_unformat_error, i);
15746           return -99;
15747         }
15748     }
15749
15750   if (!vec_len (name))
15751     {
15752       errmsg ("profile name must be specified");
15753       return -99;
15754     }
15755
15756   if (vec_len (name) > 64)
15757     {
15758       errmsg ("profile name too long");
15759       return -99;
15760     }
15761
15762   M (IKEV2_PROFILE_ADD_DEL, mp);
15763
15764   clib_memcpy (mp->name, name, vec_len (name));
15765   mp->is_add = is_add;
15766   vec_free (name);
15767
15768   S (mp);
15769   W (ret);
15770   return ret;
15771 }
15772
15773 static int
15774 api_ikev2_profile_set_auth (vat_main_t * vam)
15775 {
15776   unformat_input_t *i = vam->input;
15777   vl_api_ikev2_profile_set_auth_t *mp;
15778   u8 *name = 0;
15779   u8 *data = 0;
15780   u32 auth_method = 0;
15781   u8 is_hex = 0;
15782   int ret;
15783
15784   const char *valid_chars = "a-zA-Z0-9_";
15785
15786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15787     {
15788       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15789         vec_add1 (name, 0);
15790       else if (unformat (i, "auth_method %U",
15791                          unformat_ikev2_auth_method, &auth_method))
15792         ;
15793       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15794         is_hex = 1;
15795       else if (unformat (i, "auth_data %v", &data))
15796         ;
15797       else
15798         {
15799           errmsg ("parse error '%U'", format_unformat_error, i);
15800           return -99;
15801         }
15802     }
15803
15804   if (!vec_len (name))
15805     {
15806       errmsg ("profile name must be specified");
15807       return -99;
15808     }
15809
15810   if (vec_len (name) > 64)
15811     {
15812       errmsg ("profile name too long");
15813       return -99;
15814     }
15815
15816   if (!vec_len (data))
15817     {
15818       errmsg ("auth_data must be specified");
15819       return -99;
15820     }
15821
15822   if (!auth_method)
15823     {
15824       errmsg ("auth_method must be specified");
15825       return -99;
15826     }
15827
15828   M (IKEV2_PROFILE_SET_AUTH, mp);
15829
15830   mp->is_hex = is_hex;
15831   mp->auth_method = (u8) auth_method;
15832   mp->data_len = vec_len (data);
15833   clib_memcpy (mp->name, name, vec_len (name));
15834   clib_memcpy (mp->data, data, vec_len (data));
15835   vec_free (name);
15836   vec_free (data);
15837
15838   S (mp);
15839   W (ret);
15840   return ret;
15841 }
15842
15843 static int
15844 api_ikev2_profile_set_id (vat_main_t * vam)
15845 {
15846   unformat_input_t *i = vam->input;
15847   vl_api_ikev2_profile_set_id_t *mp;
15848   u8 *name = 0;
15849   u8 *data = 0;
15850   u8 is_local = 0;
15851   u32 id_type = 0;
15852   ip4_address_t ip4;
15853   int ret;
15854
15855   const char *valid_chars = "a-zA-Z0-9_";
15856
15857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15858     {
15859       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15860         vec_add1 (name, 0);
15861       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15862         ;
15863       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15864         {
15865           data = vec_new (u8, 4);
15866           clib_memcpy (data, ip4.as_u8, 4);
15867         }
15868       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15869         ;
15870       else if (unformat (i, "id_data %v", &data))
15871         ;
15872       else if (unformat (i, "local"))
15873         is_local = 1;
15874       else if (unformat (i, "remote"))
15875         is_local = 0;
15876       else
15877         {
15878           errmsg ("parse error '%U'", format_unformat_error, i);
15879           return -99;
15880         }
15881     }
15882
15883   if (!vec_len (name))
15884     {
15885       errmsg ("profile name must be specified");
15886       return -99;
15887     }
15888
15889   if (vec_len (name) > 64)
15890     {
15891       errmsg ("profile name too long");
15892       return -99;
15893     }
15894
15895   if (!vec_len (data))
15896     {
15897       errmsg ("id_data must be specified");
15898       return -99;
15899     }
15900
15901   if (!id_type)
15902     {
15903       errmsg ("id_type must be specified");
15904       return -99;
15905     }
15906
15907   M (IKEV2_PROFILE_SET_ID, mp);
15908
15909   mp->is_local = is_local;
15910   mp->id_type = (u8) id_type;
15911   mp->data_len = vec_len (data);
15912   clib_memcpy (mp->name, name, vec_len (name));
15913   clib_memcpy (mp->data, data, vec_len (data));
15914   vec_free (name);
15915   vec_free (data);
15916
15917   S (mp);
15918   W (ret);
15919   return ret;
15920 }
15921
15922 static int
15923 api_ikev2_profile_set_ts (vat_main_t * vam)
15924 {
15925   unformat_input_t *i = vam->input;
15926   vl_api_ikev2_profile_set_ts_t *mp;
15927   u8 *name = 0;
15928   u8 is_local = 0;
15929   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15930   ip4_address_t start_addr, end_addr;
15931
15932   const char *valid_chars = "a-zA-Z0-9_";
15933   int ret;
15934
15935   start_addr.as_u32 = 0;
15936   end_addr.as_u32 = (u32) ~ 0;
15937
15938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15939     {
15940       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15941         vec_add1 (name, 0);
15942       else if (unformat (i, "protocol %d", &proto))
15943         ;
15944       else if (unformat (i, "start_port %d", &start_port))
15945         ;
15946       else if (unformat (i, "end_port %d", &end_port))
15947         ;
15948       else
15949         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15950         ;
15951       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15952         ;
15953       else if (unformat (i, "local"))
15954         is_local = 1;
15955       else if (unformat (i, "remote"))
15956         is_local = 0;
15957       else
15958         {
15959           errmsg ("parse error '%U'", format_unformat_error, i);
15960           return -99;
15961         }
15962     }
15963
15964   if (!vec_len (name))
15965     {
15966       errmsg ("profile name must be specified");
15967       return -99;
15968     }
15969
15970   if (vec_len (name) > 64)
15971     {
15972       errmsg ("profile name too long");
15973       return -99;
15974     }
15975
15976   M (IKEV2_PROFILE_SET_TS, mp);
15977
15978   mp->is_local = is_local;
15979   mp->proto = (u8) proto;
15980   mp->start_port = (u16) start_port;
15981   mp->end_port = (u16) end_port;
15982   mp->start_addr = start_addr.as_u32;
15983   mp->end_addr = end_addr.as_u32;
15984   clib_memcpy (mp->name, name, vec_len (name));
15985   vec_free (name);
15986
15987   S (mp);
15988   W (ret);
15989   return ret;
15990 }
15991
15992 static int
15993 api_ikev2_set_local_key (vat_main_t * vam)
15994 {
15995   unformat_input_t *i = vam->input;
15996   vl_api_ikev2_set_local_key_t *mp;
15997   u8 *file = 0;
15998   int ret;
15999
16000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16001     {
16002       if (unformat (i, "file %v", &file))
16003         vec_add1 (file, 0);
16004       else
16005         {
16006           errmsg ("parse error '%U'", format_unformat_error, i);
16007           return -99;
16008         }
16009     }
16010
16011   if (!vec_len (file))
16012     {
16013       errmsg ("RSA key file must be specified");
16014       return -99;
16015     }
16016
16017   if (vec_len (file) > 256)
16018     {
16019       errmsg ("file name too long");
16020       return -99;
16021     }
16022
16023   M (IKEV2_SET_LOCAL_KEY, mp);
16024
16025   clib_memcpy (mp->key_file, file, vec_len (file));
16026   vec_free (file);
16027
16028   S (mp);
16029   W (ret);
16030   return ret;
16031 }
16032
16033 static int
16034 api_ikev2_set_responder (vat_main_t * vam)
16035 {
16036   unformat_input_t *i = vam->input;
16037   vl_api_ikev2_set_responder_t *mp;
16038   int ret;
16039   u8 *name = 0;
16040   u32 sw_if_index = ~0;
16041   ip4_address_t address;
16042
16043   const char *valid_chars = "a-zA-Z0-9_";
16044
16045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16046     {
16047       if (unformat
16048           (i, "%U interface %d address %U", unformat_token, valid_chars,
16049            &name, &sw_if_index, unformat_ip4_address, &address))
16050         vec_add1 (name, 0);
16051       else
16052         {
16053           errmsg ("parse error '%U'", format_unformat_error, i);
16054           return -99;
16055         }
16056     }
16057
16058   if (!vec_len (name))
16059     {
16060       errmsg ("profile name must be specified");
16061       return -99;
16062     }
16063
16064   if (vec_len (name) > 64)
16065     {
16066       errmsg ("profile name too long");
16067       return -99;
16068     }
16069
16070   M (IKEV2_SET_RESPONDER, mp);
16071
16072   clib_memcpy (mp->name, name, vec_len (name));
16073   vec_free (name);
16074
16075   mp->sw_if_index = sw_if_index;
16076   clib_memcpy (mp->address, &address, sizeof (address));
16077
16078   S (mp);
16079   W (ret);
16080   return ret;
16081 }
16082
16083 static int
16084 api_ikev2_set_ike_transforms (vat_main_t * vam)
16085 {
16086   unformat_input_t *i = vam->input;
16087   vl_api_ikev2_set_ike_transforms_t *mp;
16088   int ret;
16089   u8 *name = 0;
16090   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16091
16092   const char *valid_chars = "a-zA-Z0-9_";
16093
16094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16095     {
16096       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16097                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16098         vec_add1 (name, 0);
16099       else
16100         {
16101           errmsg ("parse error '%U'", format_unformat_error, i);
16102           return -99;
16103         }
16104     }
16105
16106   if (!vec_len (name))
16107     {
16108       errmsg ("profile name must be specified");
16109       return -99;
16110     }
16111
16112   if (vec_len (name) > 64)
16113     {
16114       errmsg ("profile name too long");
16115       return -99;
16116     }
16117
16118   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16119
16120   clib_memcpy (mp->name, name, vec_len (name));
16121   vec_free (name);
16122   mp->crypto_alg = crypto_alg;
16123   mp->crypto_key_size = crypto_key_size;
16124   mp->integ_alg = integ_alg;
16125   mp->dh_group = dh_group;
16126
16127   S (mp);
16128   W (ret);
16129   return ret;
16130 }
16131
16132
16133 static int
16134 api_ikev2_set_esp_transforms (vat_main_t * vam)
16135 {
16136   unformat_input_t *i = vam->input;
16137   vl_api_ikev2_set_esp_transforms_t *mp;
16138   int ret;
16139   u8 *name = 0;
16140   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16141
16142   const char *valid_chars = "a-zA-Z0-9_";
16143
16144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16147                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16148         vec_add1 (name, 0);
16149       else
16150         {
16151           errmsg ("parse error '%U'", format_unformat_error, i);
16152           return -99;
16153         }
16154     }
16155
16156   if (!vec_len (name))
16157     {
16158       errmsg ("profile name must be specified");
16159       return -99;
16160     }
16161
16162   if (vec_len (name) > 64)
16163     {
16164       errmsg ("profile name too long");
16165       return -99;
16166     }
16167
16168   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16169
16170   clib_memcpy (mp->name, name, vec_len (name));
16171   vec_free (name);
16172   mp->crypto_alg = crypto_alg;
16173   mp->crypto_key_size = crypto_key_size;
16174   mp->integ_alg = integ_alg;
16175   mp->dh_group = dh_group;
16176
16177   S (mp);
16178   W (ret);
16179   return ret;
16180 }
16181
16182 static int
16183 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16184 {
16185   unformat_input_t *i = vam->input;
16186   vl_api_ikev2_set_sa_lifetime_t *mp;
16187   int ret;
16188   u8 *name = 0;
16189   u64 lifetime, lifetime_maxdata;
16190   u32 lifetime_jitter, handover;
16191
16192   const char *valid_chars = "a-zA-Z0-9_";
16193
16194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16195     {
16196       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16197                     &lifetime, &lifetime_jitter, &handover,
16198                     &lifetime_maxdata))
16199         vec_add1 (name, 0);
16200       else
16201         {
16202           errmsg ("parse error '%U'", format_unformat_error, i);
16203           return -99;
16204         }
16205     }
16206
16207   if (!vec_len (name))
16208     {
16209       errmsg ("profile name must be specified");
16210       return -99;
16211     }
16212
16213   if (vec_len (name) > 64)
16214     {
16215       errmsg ("profile name too long");
16216       return -99;
16217     }
16218
16219   M (IKEV2_SET_SA_LIFETIME, mp);
16220
16221   clib_memcpy (mp->name, name, vec_len (name));
16222   vec_free (name);
16223   mp->lifetime = lifetime;
16224   mp->lifetime_jitter = lifetime_jitter;
16225   mp->handover = handover;
16226   mp->lifetime_maxdata = lifetime_maxdata;
16227
16228   S (mp);
16229   W (ret);
16230   return ret;
16231 }
16232
16233 static int
16234 api_ikev2_initiate_sa_init (vat_main_t * vam)
16235 {
16236   unformat_input_t *i = vam->input;
16237   vl_api_ikev2_initiate_sa_init_t *mp;
16238   int ret;
16239   u8 *name = 0;
16240
16241   const char *valid_chars = "a-zA-Z0-9_";
16242
16243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16244     {
16245       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16246         vec_add1 (name, 0);
16247       else
16248         {
16249           errmsg ("parse error '%U'", format_unformat_error, i);
16250           return -99;
16251         }
16252     }
16253
16254   if (!vec_len (name))
16255     {
16256       errmsg ("profile name must be specified");
16257       return -99;
16258     }
16259
16260   if (vec_len (name) > 64)
16261     {
16262       errmsg ("profile name too long");
16263       return -99;
16264     }
16265
16266   M (IKEV2_INITIATE_SA_INIT, mp);
16267
16268   clib_memcpy (mp->name, name, vec_len (name));
16269   vec_free (name);
16270
16271   S (mp);
16272   W (ret);
16273   return ret;
16274 }
16275
16276 static int
16277 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16278 {
16279   unformat_input_t *i = vam->input;
16280   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16281   int ret;
16282   u64 ispi;
16283
16284
16285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16286     {
16287       if (unformat (i, "%lx", &ispi))
16288         ;
16289       else
16290         {
16291           errmsg ("parse error '%U'", format_unformat_error, i);
16292           return -99;
16293         }
16294     }
16295
16296   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16297
16298   mp->ispi = ispi;
16299
16300   S (mp);
16301   W (ret);
16302   return ret;
16303 }
16304
16305 static int
16306 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16307 {
16308   unformat_input_t *i = vam->input;
16309   vl_api_ikev2_initiate_del_child_sa_t *mp;
16310   int ret;
16311   u32 ispi;
16312
16313
16314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16315     {
16316       if (unformat (i, "%x", &ispi))
16317         ;
16318       else
16319         {
16320           errmsg ("parse error '%U'", format_unformat_error, i);
16321           return -99;
16322         }
16323     }
16324
16325   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16326
16327   mp->ispi = ispi;
16328
16329   S (mp);
16330   W (ret);
16331   return ret;
16332 }
16333
16334 static int
16335 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16336 {
16337   unformat_input_t *i = vam->input;
16338   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16339   int ret;
16340   u32 ispi;
16341
16342
16343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16344     {
16345       if (unformat (i, "%x", &ispi))
16346         ;
16347       else
16348         {
16349           errmsg ("parse error '%U'", format_unformat_error, i);
16350           return -99;
16351         }
16352     }
16353
16354   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16355
16356   mp->ispi = ispi;
16357
16358   S (mp);
16359   W (ret);
16360   return ret;
16361 }
16362
16363 /*
16364  * MAP
16365  */
16366 static int
16367 api_map_add_domain (vat_main_t * vam)
16368 {
16369   unformat_input_t *i = vam->input;
16370   vl_api_map_add_domain_t *mp;
16371
16372   ip4_address_t ip4_prefix;
16373   ip6_address_t ip6_prefix;
16374   ip6_address_t ip6_src;
16375   u32 num_m_args = 0;
16376   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16377     0, psid_length = 0;
16378   u8 is_translation = 0;
16379   u32 mtu = 0;
16380   u32 ip6_src_len = 128;
16381   int ret;
16382
16383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16384     {
16385       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16386                     &ip4_prefix, &ip4_prefix_len))
16387         num_m_args++;
16388       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16389                          &ip6_prefix, &ip6_prefix_len))
16390         num_m_args++;
16391       else
16392         if (unformat
16393             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16394              &ip6_src_len))
16395         num_m_args++;
16396       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16397         num_m_args++;
16398       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16399         num_m_args++;
16400       else if (unformat (i, "psid-offset %d", &psid_offset))
16401         num_m_args++;
16402       else if (unformat (i, "psid-len %d", &psid_length))
16403         num_m_args++;
16404       else if (unformat (i, "mtu %d", &mtu))
16405         num_m_args++;
16406       else if (unformat (i, "map-t"))
16407         is_translation = 1;
16408       else
16409         {
16410           clib_warning ("parse error '%U'", format_unformat_error, i);
16411           return -99;
16412         }
16413     }
16414
16415   if (num_m_args < 3)
16416     {
16417       errmsg ("mandatory argument(s) missing");
16418       return -99;
16419     }
16420
16421   /* Construct the API message */
16422   M (MAP_ADD_DOMAIN, mp);
16423
16424   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16425   mp->ip4_prefix_len = ip4_prefix_len;
16426
16427   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16428   mp->ip6_prefix_len = ip6_prefix_len;
16429
16430   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16431   mp->ip6_src_prefix_len = ip6_src_len;
16432
16433   mp->ea_bits_len = ea_bits_len;
16434   mp->psid_offset = psid_offset;
16435   mp->psid_length = psid_length;
16436   mp->is_translation = is_translation;
16437   mp->mtu = htons (mtu);
16438
16439   /* send it... */
16440   S (mp);
16441
16442   /* Wait for a reply, return good/bad news  */
16443   W (ret);
16444   return ret;
16445 }
16446
16447 static int
16448 api_map_del_domain (vat_main_t * vam)
16449 {
16450   unformat_input_t *i = vam->input;
16451   vl_api_map_del_domain_t *mp;
16452
16453   u32 num_m_args = 0;
16454   u32 index;
16455   int ret;
16456
16457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16458     {
16459       if (unformat (i, "index %d", &index))
16460         num_m_args++;
16461       else
16462         {
16463           clib_warning ("parse error '%U'", format_unformat_error, i);
16464           return -99;
16465         }
16466     }
16467
16468   if (num_m_args != 1)
16469     {
16470       errmsg ("mandatory argument(s) missing");
16471       return -99;
16472     }
16473
16474   /* Construct the API message */
16475   M (MAP_DEL_DOMAIN, mp);
16476
16477   mp->index = ntohl (index);
16478
16479   /* send it... */
16480   S (mp);
16481
16482   /* Wait for a reply, return good/bad news  */
16483   W (ret);
16484   return ret;
16485 }
16486
16487 static int
16488 api_map_add_del_rule (vat_main_t * vam)
16489 {
16490   unformat_input_t *i = vam->input;
16491   vl_api_map_add_del_rule_t *mp;
16492   u8 is_add = 1;
16493   ip6_address_t ip6_dst;
16494   u32 num_m_args = 0, index, psid = 0;
16495   int ret;
16496
16497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16498     {
16499       if (unformat (i, "index %d", &index))
16500         num_m_args++;
16501       else if (unformat (i, "psid %d", &psid))
16502         num_m_args++;
16503       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16504         num_m_args++;
16505       else if (unformat (i, "del"))
16506         {
16507           is_add = 0;
16508         }
16509       else
16510         {
16511           clib_warning ("parse error '%U'", format_unformat_error, i);
16512           return -99;
16513         }
16514     }
16515
16516   /* Construct the API message */
16517   M (MAP_ADD_DEL_RULE, mp);
16518
16519   mp->index = ntohl (index);
16520   mp->is_add = is_add;
16521   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16522   mp->psid = ntohs (psid);
16523
16524   /* send it... */
16525   S (mp);
16526
16527   /* Wait for a reply, return good/bad news  */
16528   W (ret);
16529   return ret;
16530 }
16531
16532 static int
16533 api_map_domain_dump (vat_main_t * vam)
16534 {
16535   vl_api_map_domain_dump_t *mp;
16536   vl_api_control_ping_t *mp_ping;
16537   int ret;
16538
16539   /* Construct the API message */
16540   M (MAP_DOMAIN_DUMP, mp);
16541
16542   /* send it... */
16543   S (mp);
16544
16545   /* Use a control ping for synchronization */
16546   MPING (CONTROL_PING, mp_ping);
16547   S (mp_ping);
16548
16549   W (ret);
16550   return ret;
16551 }
16552
16553 static int
16554 api_map_rule_dump (vat_main_t * vam)
16555 {
16556   unformat_input_t *i = vam->input;
16557   vl_api_map_rule_dump_t *mp;
16558   vl_api_control_ping_t *mp_ping;
16559   u32 domain_index = ~0;
16560   int ret;
16561
16562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16563     {
16564       if (unformat (i, "index %u", &domain_index))
16565         ;
16566       else
16567         break;
16568     }
16569
16570   if (domain_index == ~0)
16571     {
16572       clib_warning ("parse error: domain index expected");
16573       return -99;
16574     }
16575
16576   /* Construct the API message */
16577   M (MAP_RULE_DUMP, mp);
16578
16579   mp->domain_index = htonl (domain_index);
16580
16581   /* send it... */
16582   S (mp);
16583
16584   /* Use a control ping for synchronization */
16585   MPING (CONTROL_PING, mp_ping);
16586   S (mp_ping);
16587
16588   W (ret);
16589   return ret;
16590 }
16591
16592 static void vl_api_map_add_domain_reply_t_handler
16593   (vl_api_map_add_domain_reply_t * mp)
16594 {
16595   vat_main_t *vam = &vat_main;
16596   i32 retval = ntohl (mp->retval);
16597
16598   if (vam->async_mode)
16599     {
16600       vam->async_errors += (retval < 0);
16601     }
16602   else
16603     {
16604       vam->retval = retval;
16605       vam->result_ready = 1;
16606     }
16607 }
16608
16609 static void vl_api_map_add_domain_reply_t_handler_json
16610   (vl_api_map_add_domain_reply_t * mp)
16611 {
16612   vat_main_t *vam = &vat_main;
16613   vat_json_node_t node;
16614
16615   vat_json_init_object (&node);
16616   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16617   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16618
16619   vat_json_print (vam->ofp, &node);
16620   vat_json_free (&node);
16621
16622   vam->retval = ntohl (mp->retval);
16623   vam->result_ready = 1;
16624 }
16625
16626 static int
16627 api_get_first_msg_id (vat_main_t * vam)
16628 {
16629   vl_api_get_first_msg_id_t *mp;
16630   unformat_input_t *i = vam->input;
16631   u8 *name;
16632   u8 name_set = 0;
16633   int ret;
16634
16635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16636     {
16637       if (unformat (i, "client %s", &name))
16638         name_set = 1;
16639       else
16640         break;
16641     }
16642
16643   if (name_set == 0)
16644     {
16645       errmsg ("missing client name");
16646       return -99;
16647     }
16648   vec_add1 (name, 0);
16649
16650   if (vec_len (name) > 63)
16651     {
16652       errmsg ("client name too long");
16653       return -99;
16654     }
16655
16656   M (GET_FIRST_MSG_ID, mp);
16657   clib_memcpy (mp->name, name, vec_len (name));
16658   S (mp);
16659   W (ret);
16660   return ret;
16661 }
16662
16663 static int
16664 api_cop_interface_enable_disable (vat_main_t * vam)
16665 {
16666   unformat_input_t *line_input = vam->input;
16667   vl_api_cop_interface_enable_disable_t *mp;
16668   u32 sw_if_index = ~0;
16669   u8 enable_disable = 1;
16670   int ret;
16671
16672   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16673     {
16674       if (unformat (line_input, "disable"))
16675         enable_disable = 0;
16676       if (unformat (line_input, "enable"))
16677         enable_disable = 1;
16678       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16679                          vam, &sw_if_index))
16680         ;
16681       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16682         ;
16683       else
16684         break;
16685     }
16686
16687   if (sw_if_index == ~0)
16688     {
16689       errmsg ("missing interface name or sw_if_index");
16690       return -99;
16691     }
16692
16693   /* Construct the API message */
16694   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16695   mp->sw_if_index = ntohl (sw_if_index);
16696   mp->enable_disable = enable_disable;
16697
16698   /* send it... */
16699   S (mp);
16700   /* Wait for the reply */
16701   W (ret);
16702   return ret;
16703 }
16704
16705 static int
16706 api_cop_whitelist_enable_disable (vat_main_t * vam)
16707 {
16708   unformat_input_t *line_input = vam->input;
16709   vl_api_cop_whitelist_enable_disable_t *mp;
16710   u32 sw_if_index = ~0;
16711   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16712   u32 fib_id = 0;
16713   int ret;
16714
16715   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16716     {
16717       if (unformat (line_input, "ip4"))
16718         ip4 = 1;
16719       else if (unformat (line_input, "ip6"))
16720         ip6 = 1;
16721       else if (unformat (line_input, "default"))
16722         default_cop = 1;
16723       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16724                          vam, &sw_if_index))
16725         ;
16726       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16727         ;
16728       else if (unformat (line_input, "fib-id %d", &fib_id))
16729         ;
16730       else
16731         break;
16732     }
16733
16734   if (sw_if_index == ~0)
16735     {
16736       errmsg ("missing interface name or sw_if_index");
16737       return -99;
16738     }
16739
16740   /* Construct the API message */
16741   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16742   mp->sw_if_index = ntohl (sw_if_index);
16743   mp->fib_id = ntohl (fib_id);
16744   mp->ip4 = ip4;
16745   mp->ip6 = ip6;
16746   mp->default_cop = default_cop;
16747
16748   /* send it... */
16749   S (mp);
16750   /* Wait for the reply */
16751   W (ret);
16752   return ret;
16753 }
16754
16755 static int
16756 api_get_node_graph (vat_main_t * vam)
16757 {
16758   vl_api_get_node_graph_t *mp;
16759   int ret;
16760
16761   M (GET_NODE_GRAPH, mp);
16762
16763   /* send it... */
16764   S (mp);
16765   /* Wait for the reply */
16766   W (ret);
16767   return ret;
16768 }
16769
16770 /* *INDENT-OFF* */
16771 /** Used for parsing LISP eids */
16772 typedef CLIB_PACKED(struct{
16773   u8 addr[16];   /**< eid address */
16774   u32 len;       /**< prefix length if IP */
16775   u8 type;      /**< type of eid */
16776 }) lisp_eid_vat_t;
16777 /* *INDENT-ON* */
16778
16779 static uword
16780 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16781 {
16782   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16783
16784   memset (a, 0, sizeof (a[0]));
16785
16786   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16787     {
16788       a->type = 0;              /* ipv4 type */
16789     }
16790   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16791     {
16792       a->type = 1;              /* ipv6 type */
16793     }
16794   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16795     {
16796       a->type = 2;              /* mac type */
16797     }
16798   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16799     {
16800       a->type = 3;              /* NSH type */
16801       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16802       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16803     }
16804   else
16805     {
16806       return 0;
16807     }
16808
16809   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16810     {
16811       return 0;
16812     }
16813
16814   return 1;
16815 }
16816
16817 static int
16818 lisp_eid_size_vat (u8 type)
16819 {
16820   switch (type)
16821     {
16822     case 0:
16823       return 4;
16824     case 1:
16825       return 16;
16826     case 2:
16827       return 6;
16828     case 3:
16829       return 5;
16830     }
16831   return 0;
16832 }
16833
16834 static void
16835 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16836 {
16837   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16838 }
16839
16840 static int
16841 api_one_add_del_locator_set (vat_main_t * vam)
16842 {
16843   unformat_input_t *input = vam->input;
16844   vl_api_one_add_del_locator_set_t *mp;
16845   u8 is_add = 1;
16846   u8 *locator_set_name = NULL;
16847   u8 locator_set_name_set = 0;
16848   vl_api_local_locator_t locator, *locators = 0;
16849   u32 sw_if_index, priority, weight;
16850   u32 data_len = 0;
16851
16852   int ret;
16853   /* Parse args required to build the message */
16854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16855     {
16856       if (unformat (input, "del"))
16857         {
16858           is_add = 0;
16859         }
16860       else if (unformat (input, "locator-set %s", &locator_set_name))
16861         {
16862           locator_set_name_set = 1;
16863         }
16864       else if (unformat (input, "sw_if_index %u p %u w %u",
16865                          &sw_if_index, &priority, &weight))
16866         {
16867           locator.sw_if_index = htonl (sw_if_index);
16868           locator.priority = priority;
16869           locator.weight = weight;
16870           vec_add1 (locators, locator);
16871         }
16872       else
16873         if (unformat
16874             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16875              &sw_if_index, &priority, &weight))
16876         {
16877           locator.sw_if_index = htonl (sw_if_index);
16878           locator.priority = priority;
16879           locator.weight = weight;
16880           vec_add1 (locators, locator);
16881         }
16882       else
16883         break;
16884     }
16885
16886   if (locator_set_name_set == 0)
16887     {
16888       errmsg ("missing locator-set name");
16889       vec_free (locators);
16890       return -99;
16891     }
16892
16893   if (vec_len (locator_set_name) > 64)
16894     {
16895       errmsg ("locator-set name too long");
16896       vec_free (locator_set_name);
16897       vec_free (locators);
16898       return -99;
16899     }
16900   vec_add1 (locator_set_name, 0);
16901
16902   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16903
16904   /* Construct the API message */
16905   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16906
16907   mp->is_add = is_add;
16908   clib_memcpy (mp->locator_set_name, locator_set_name,
16909                vec_len (locator_set_name));
16910   vec_free (locator_set_name);
16911
16912   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16913   if (locators)
16914     clib_memcpy (mp->locators, locators, data_len);
16915   vec_free (locators);
16916
16917   /* send it... */
16918   S (mp);
16919
16920   /* Wait for a reply... */
16921   W (ret);
16922   return ret;
16923 }
16924
16925 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16926
16927 static int
16928 api_one_add_del_locator (vat_main_t * vam)
16929 {
16930   unformat_input_t *input = vam->input;
16931   vl_api_one_add_del_locator_t *mp;
16932   u32 tmp_if_index = ~0;
16933   u32 sw_if_index = ~0;
16934   u8 sw_if_index_set = 0;
16935   u8 sw_if_index_if_name_set = 0;
16936   u32 priority = ~0;
16937   u8 priority_set = 0;
16938   u32 weight = ~0;
16939   u8 weight_set = 0;
16940   u8 is_add = 1;
16941   u8 *locator_set_name = NULL;
16942   u8 locator_set_name_set = 0;
16943   int ret;
16944
16945   /* Parse args required to build the message */
16946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16947     {
16948       if (unformat (input, "del"))
16949         {
16950           is_add = 0;
16951         }
16952       else if (unformat (input, "locator-set %s", &locator_set_name))
16953         {
16954           locator_set_name_set = 1;
16955         }
16956       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16957                          &tmp_if_index))
16958         {
16959           sw_if_index_if_name_set = 1;
16960           sw_if_index = tmp_if_index;
16961         }
16962       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16963         {
16964           sw_if_index_set = 1;
16965           sw_if_index = tmp_if_index;
16966         }
16967       else if (unformat (input, "p %d", &priority))
16968         {
16969           priority_set = 1;
16970         }
16971       else if (unformat (input, "w %d", &weight))
16972         {
16973           weight_set = 1;
16974         }
16975       else
16976         break;
16977     }
16978
16979   if (locator_set_name_set == 0)
16980     {
16981       errmsg ("missing locator-set name");
16982       return -99;
16983     }
16984
16985   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16986     {
16987       errmsg ("missing sw_if_index");
16988       vec_free (locator_set_name);
16989       return -99;
16990     }
16991
16992   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16993     {
16994       errmsg ("cannot use both params interface name and sw_if_index");
16995       vec_free (locator_set_name);
16996       return -99;
16997     }
16998
16999   if (priority_set == 0)
17000     {
17001       errmsg ("missing locator-set priority");
17002       vec_free (locator_set_name);
17003       return -99;
17004     }
17005
17006   if (weight_set == 0)
17007     {
17008       errmsg ("missing locator-set weight");
17009       vec_free (locator_set_name);
17010       return -99;
17011     }
17012
17013   if (vec_len (locator_set_name) > 64)
17014     {
17015       errmsg ("locator-set name too long");
17016       vec_free (locator_set_name);
17017       return -99;
17018     }
17019   vec_add1 (locator_set_name, 0);
17020
17021   /* Construct the API message */
17022   M (ONE_ADD_DEL_LOCATOR, mp);
17023
17024   mp->is_add = is_add;
17025   mp->sw_if_index = ntohl (sw_if_index);
17026   mp->priority = priority;
17027   mp->weight = weight;
17028   clib_memcpy (mp->locator_set_name, locator_set_name,
17029                vec_len (locator_set_name));
17030   vec_free (locator_set_name);
17031
17032   /* send it... */
17033   S (mp);
17034
17035   /* Wait for a reply... */
17036   W (ret);
17037   return ret;
17038 }
17039
17040 #define api_lisp_add_del_locator api_one_add_del_locator
17041
17042 uword
17043 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17044 {
17045   u32 *key_id = va_arg (*args, u32 *);
17046   u8 *s = 0;
17047
17048   if (unformat (input, "%s", &s))
17049     {
17050       if (!strcmp ((char *) s, "sha1"))
17051         key_id[0] = HMAC_SHA_1_96;
17052       else if (!strcmp ((char *) s, "sha256"))
17053         key_id[0] = HMAC_SHA_256_128;
17054       else
17055         {
17056           clib_warning ("invalid key_id: '%s'", s);
17057           key_id[0] = HMAC_NO_KEY;
17058         }
17059     }
17060   else
17061     return 0;
17062
17063   vec_free (s);
17064   return 1;
17065 }
17066
17067 static int
17068 api_one_add_del_local_eid (vat_main_t * vam)
17069 {
17070   unformat_input_t *input = vam->input;
17071   vl_api_one_add_del_local_eid_t *mp;
17072   u8 is_add = 1;
17073   u8 eid_set = 0;
17074   lisp_eid_vat_t _eid, *eid = &_eid;
17075   u8 *locator_set_name = 0;
17076   u8 locator_set_name_set = 0;
17077   u32 vni = 0;
17078   u16 key_id = 0;
17079   u8 *key = 0;
17080   int ret;
17081
17082   /* Parse args required to build the message */
17083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17084     {
17085       if (unformat (input, "del"))
17086         {
17087           is_add = 0;
17088         }
17089       else if (unformat (input, "vni %d", &vni))
17090         {
17091           ;
17092         }
17093       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17094         {
17095           eid_set = 1;
17096         }
17097       else if (unformat (input, "locator-set %s", &locator_set_name))
17098         {
17099           locator_set_name_set = 1;
17100         }
17101       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17102         ;
17103       else if (unformat (input, "secret-key %_%v%_", &key))
17104         ;
17105       else
17106         break;
17107     }
17108
17109   if (locator_set_name_set == 0)
17110     {
17111       errmsg ("missing locator-set name");
17112       return -99;
17113     }
17114
17115   if (0 == eid_set)
17116     {
17117       errmsg ("EID address not set!");
17118       vec_free (locator_set_name);
17119       return -99;
17120     }
17121
17122   if (key && (0 == key_id))
17123     {
17124       errmsg ("invalid key_id!");
17125       return -99;
17126     }
17127
17128   if (vec_len (key) > 64)
17129     {
17130       errmsg ("key too long");
17131       vec_free (key);
17132       return -99;
17133     }
17134
17135   if (vec_len (locator_set_name) > 64)
17136     {
17137       errmsg ("locator-set name too long");
17138       vec_free (locator_set_name);
17139       return -99;
17140     }
17141   vec_add1 (locator_set_name, 0);
17142
17143   /* Construct the API message */
17144   M (ONE_ADD_DEL_LOCAL_EID, mp);
17145
17146   mp->is_add = is_add;
17147   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17148   mp->eid_type = eid->type;
17149   mp->prefix_len = eid->len;
17150   mp->vni = clib_host_to_net_u32 (vni);
17151   mp->key_id = clib_host_to_net_u16 (key_id);
17152   clib_memcpy (mp->locator_set_name, locator_set_name,
17153                vec_len (locator_set_name));
17154   clib_memcpy (mp->key, key, vec_len (key));
17155
17156   vec_free (locator_set_name);
17157   vec_free (key);
17158
17159   /* send it... */
17160   S (mp);
17161
17162   /* Wait for a reply... */
17163   W (ret);
17164   return ret;
17165 }
17166
17167 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17168
17169 static int
17170 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17171 {
17172   u32 dp_table = 0, vni = 0;;
17173   unformat_input_t *input = vam->input;
17174   vl_api_gpe_add_del_fwd_entry_t *mp;
17175   u8 is_add = 1;
17176   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17177   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17178   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17179   u32 action = ~0, w;
17180   ip4_address_t rmt_rloc4, lcl_rloc4;
17181   ip6_address_t rmt_rloc6, lcl_rloc6;
17182   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17183   int ret;
17184
17185   memset (&rloc, 0, sizeof (rloc));
17186
17187   /* Parse args required to build the message */
17188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17189     {
17190       if (unformat (input, "del"))
17191         is_add = 0;
17192       else if (unformat (input, "add"))
17193         is_add = 1;
17194       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17195         {
17196           rmt_eid_set = 1;
17197         }
17198       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17199         {
17200           lcl_eid_set = 1;
17201         }
17202       else if (unformat (input, "vrf %d", &dp_table))
17203         ;
17204       else if (unformat (input, "bd %d", &dp_table))
17205         ;
17206       else if (unformat (input, "vni %d", &vni))
17207         ;
17208       else if (unformat (input, "w %d", &w))
17209         {
17210           if (!curr_rloc)
17211             {
17212               errmsg ("No RLOC configured for setting priority/weight!");
17213               return -99;
17214             }
17215           curr_rloc->weight = w;
17216         }
17217       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17218                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17219         {
17220           rloc.is_ip4 = 1;
17221
17222           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17223           rloc.weight = 0;
17224           vec_add1 (lcl_locs, rloc);
17225
17226           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17227           vec_add1 (rmt_locs, rloc);
17228           /* weight saved in rmt loc */
17229           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17230         }
17231       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17232                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17233         {
17234           rloc.is_ip4 = 0;
17235           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17236           rloc.weight = 0;
17237           vec_add1 (lcl_locs, rloc);
17238
17239           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17240           vec_add1 (rmt_locs, rloc);
17241           /* weight saved in rmt loc */
17242           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17243         }
17244       else if (unformat (input, "action %d", &action))
17245         {
17246           ;
17247         }
17248       else
17249         {
17250           clib_warning ("parse error '%U'", format_unformat_error, input);
17251           return -99;
17252         }
17253     }
17254
17255   if (!rmt_eid_set)
17256     {
17257       errmsg ("remote eid addresses not set");
17258       return -99;
17259     }
17260
17261   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17262     {
17263       errmsg ("eid types don't match");
17264       return -99;
17265     }
17266
17267   if (0 == rmt_locs && (u32) ~ 0 == action)
17268     {
17269       errmsg ("action not set for negative mapping");
17270       return -99;
17271     }
17272
17273   /* Construct the API message */
17274   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17275       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17276
17277   mp->is_add = is_add;
17278   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17279   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17280   mp->eid_type = rmt_eid->type;
17281   mp->dp_table = clib_host_to_net_u32 (dp_table);
17282   mp->vni = clib_host_to_net_u32 (vni);
17283   mp->rmt_len = rmt_eid->len;
17284   mp->lcl_len = lcl_eid->len;
17285   mp->action = action;
17286
17287   if (0 != rmt_locs && 0 != lcl_locs)
17288     {
17289       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17290       clib_memcpy (mp->locs, lcl_locs,
17291                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17292
17293       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17294       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17295                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17296     }
17297   vec_free (lcl_locs);
17298   vec_free (rmt_locs);
17299
17300   /* send it... */
17301   S (mp);
17302
17303   /* Wait for a reply... */
17304   W (ret);
17305   return ret;
17306 }
17307
17308 static int
17309 api_one_add_del_map_server (vat_main_t * vam)
17310 {
17311   unformat_input_t *input = vam->input;
17312   vl_api_one_add_del_map_server_t *mp;
17313   u8 is_add = 1;
17314   u8 ipv4_set = 0;
17315   u8 ipv6_set = 0;
17316   ip4_address_t ipv4;
17317   ip6_address_t ipv6;
17318   int ret;
17319
17320   /* Parse args required to build the message */
17321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17322     {
17323       if (unformat (input, "del"))
17324         {
17325           is_add = 0;
17326         }
17327       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17328         {
17329           ipv4_set = 1;
17330         }
17331       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17332         {
17333           ipv6_set = 1;
17334         }
17335       else
17336         break;
17337     }
17338
17339   if (ipv4_set && ipv6_set)
17340     {
17341       errmsg ("both eid v4 and v6 addresses set");
17342       return -99;
17343     }
17344
17345   if (!ipv4_set && !ipv6_set)
17346     {
17347       errmsg ("eid addresses not set");
17348       return -99;
17349     }
17350
17351   /* Construct the API message */
17352   M (ONE_ADD_DEL_MAP_SERVER, mp);
17353
17354   mp->is_add = is_add;
17355   if (ipv6_set)
17356     {
17357       mp->is_ipv6 = 1;
17358       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17359     }
17360   else
17361     {
17362       mp->is_ipv6 = 0;
17363       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17364     }
17365
17366   /* send it... */
17367   S (mp);
17368
17369   /* Wait for a reply... */
17370   W (ret);
17371   return ret;
17372 }
17373
17374 #define api_lisp_add_del_map_server api_one_add_del_map_server
17375
17376 static int
17377 api_one_add_del_map_resolver (vat_main_t * vam)
17378 {
17379   unformat_input_t *input = vam->input;
17380   vl_api_one_add_del_map_resolver_t *mp;
17381   u8 is_add = 1;
17382   u8 ipv4_set = 0;
17383   u8 ipv6_set = 0;
17384   ip4_address_t ipv4;
17385   ip6_address_t ipv6;
17386   int ret;
17387
17388   /* Parse args required to build the message */
17389   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17390     {
17391       if (unformat (input, "del"))
17392         {
17393           is_add = 0;
17394         }
17395       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17396         {
17397           ipv4_set = 1;
17398         }
17399       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17400         {
17401           ipv6_set = 1;
17402         }
17403       else
17404         break;
17405     }
17406
17407   if (ipv4_set && ipv6_set)
17408     {
17409       errmsg ("both eid v4 and v6 addresses set");
17410       return -99;
17411     }
17412
17413   if (!ipv4_set && !ipv6_set)
17414     {
17415       errmsg ("eid addresses not set");
17416       return -99;
17417     }
17418
17419   /* Construct the API message */
17420   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17421
17422   mp->is_add = is_add;
17423   if (ipv6_set)
17424     {
17425       mp->is_ipv6 = 1;
17426       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17427     }
17428   else
17429     {
17430       mp->is_ipv6 = 0;
17431       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17432     }
17433
17434   /* send it... */
17435   S (mp);
17436
17437   /* Wait for a reply... */
17438   W (ret);
17439   return ret;
17440 }
17441
17442 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17443
17444 static int
17445 api_lisp_gpe_enable_disable (vat_main_t * vam)
17446 {
17447   unformat_input_t *input = vam->input;
17448   vl_api_gpe_enable_disable_t *mp;
17449   u8 is_set = 0;
17450   u8 is_en = 1;
17451   int ret;
17452
17453   /* Parse args required to build the message */
17454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17455     {
17456       if (unformat (input, "enable"))
17457         {
17458           is_set = 1;
17459           is_en = 1;
17460         }
17461       else if (unformat (input, "disable"))
17462         {
17463           is_set = 1;
17464           is_en = 0;
17465         }
17466       else
17467         break;
17468     }
17469
17470   if (is_set == 0)
17471     {
17472       errmsg ("Value not set");
17473       return -99;
17474     }
17475
17476   /* Construct the API message */
17477   M (GPE_ENABLE_DISABLE, mp);
17478
17479   mp->is_en = is_en;
17480
17481   /* send it... */
17482   S (mp);
17483
17484   /* Wait for a reply... */
17485   W (ret);
17486   return ret;
17487 }
17488
17489 static int
17490 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17491 {
17492   unformat_input_t *input = vam->input;
17493   vl_api_one_rloc_probe_enable_disable_t *mp;
17494   u8 is_set = 0;
17495   u8 is_en = 0;
17496   int ret;
17497
17498   /* Parse args required to build the message */
17499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17500     {
17501       if (unformat (input, "enable"))
17502         {
17503           is_set = 1;
17504           is_en = 1;
17505         }
17506       else if (unformat (input, "disable"))
17507         is_set = 1;
17508       else
17509         break;
17510     }
17511
17512   if (!is_set)
17513     {
17514       errmsg ("Value not set");
17515       return -99;
17516     }
17517
17518   /* Construct the API message */
17519   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17520
17521   mp->is_enabled = is_en;
17522
17523   /* send it... */
17524   S (mp);
17525
17526   /* Wait for a reply... */
17527   W (ret);
17528   return ret;
17529 }
17530
17531 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17532
17533 static int
17534 api_one_map_register_enable_disable (vat_main_t * vam)
17535 {
17536   unformat_input_t *input = vam->input;
17537   vl_api_one_map_register_enable_disable_t *mp;
17538   u8 is_set = 0;
17539   u8 is_en = 0;
17540   int ret;
17541
17542   /* Parse args required to build the message */
17543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17544     {
17545       if (unformat (input, "enable"))
17546         {
17547           is_set = 1;
17548           is_en = 1;
17549         }
17550       else if (unformat (input, "disable"))
17551         is_set = 1;
17552       else
17553         break;
17554     }
17555
17556   if (!is_set)
17557     {
17558       errmsg ("Value not set");
17559       return -99;
17560     }
17561
17562   /* Construct the API message */
17563   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17564
17565   mp->is_enabled = is_en;
17566
17567   /* send it... */
17568   S (mp);
17569
17570   /* Wait for a reply... */
17571   W (ret);
17572   return ret;
17573 }
17574
17575 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17576
17577 static int
17578 api_one_enable_disable (vat_main_t * vam)
17579 {
17580   unformat_input_t *input = vam->input;
17581   vl_api_one_enable_disable_t *mp;
17582   u8 is_set = 0;
17583   u8 is_en = 0;
17584   int ret;
17585
17586   /* Parse args required to build the message */
17587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17588     {
17589       if (unformat (input, "enable"))
17590         {
17591           is_set = 1;
17592           is_en = 1;
17593         }
17594       else if (unformat (input, "disable"))
17595         {
17596           is_set = 1;
17597         }
17598       else
17599         break;
17600     }
17601
17602   if (!is_set)
17603     {
17604       errmsg ("Value not set");
17605       return -99;
17606     }
17607
17608   /* Construct the API message */
17609   M (ONE_ENABLE_DISABLE, mp);
17610
17611   mp->is_en = is_en;
17612
17613   /* send it... */
17614   S (mp);
17615
17616   /* Wait for a reply... */
17617   W (ret);
17618   return ret;
17619 }
17620
17621 #define api_lisp_enable_disable api_one_enable_disable
17622
17623 static int
17624 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17625 {
17626   unformat_input_t *input = vam->input;
17627   vl_api_one_enable_disable_xtr_mode_t *mp;
17628   u8 is_set = 0;
17629   u8 is_en = 0;
17630   int ret;
17631
17632   /* Parse args required to build the message */
17633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17634     {
17635       if (unformat (input, "enable"))
17636         {
17637           is_set = 1;
17638           is_en = 1;
17639         }
17640       else if (unformat (input, "disable"))
17641         {
17642           is_set = 1;
17643         }
17644       else
17645         break;
17646     }
17647
17648   if (!is_set)
17649     {
17650       errmsg ("Value not set");
17651       return -99;
17652     }
17653
17654   /* Construct the API message */
17655   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17656
17657   mp->is_en = is_en;
17658
17659   /* send it... */
17660   S (mp);
17661
17662   /* Wait for a reply... */
17663   W (ret);
17664   return ret;
17665 }
17666
17667 static int
17668 api_one_show_xtr_mode (vat_main_t * vam)
17669 {
17670   vl_api_one_show_xtr_mode_t *mp;
17671   int ret;
17672
17673   /* Construct the API message */
17674   M (ONE_SHOW_XTR_MODE, mp);
17675
17676   /* send it... */
17677   S (mp);
17678
17679   /* Wait for a reply... */
17680   W (ret);
17681   return ret;
17682 }
17683
17684 static int
17685 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17686 {
17687   unformat_input_t *input = vam->input;
17688   vl_api_one_enable_disable_pitr_mode_t *mp;
17689   u8 is_set = 0;
17690   u8 is_en = 0;
17691   int ret;
17692
17693   /* Parse args required to build the message */
17694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17695     {
17696       if (unformat (input, "enable"))
17697         {
17698           is_set = 1;
17699           is_en = 1;
17700         }
17701       else if (unformat (input, "disable"))
17702         {
17703           is_set = 1;
17704         }
17705       else
17706         break;
17707     }
17708
17709   if (!is_set)
17710     {
17711       errmsg ("Value not set");
17712       return -99;
17713     }
17714
17715   /* Construct the API message */
17716   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17717
17718   mp->is_en = is_en;
17719
17720   /* send it... */
17721   S (mp);
17722
17723   /* Wait for a reply... */
17724   W (ret);
17725   return ret;
17726 }
17727
17728 static int
17729 api_one_show_pitr_mode (vat_main_t * vam)
17730 {
17731   vl_api_one_show_pitr_mode_t *mp;
17732   int ret;
17733
17734   /* Construct the API message */
17735   M (ONE_SHOW_PITR_MODE, mp);
17736
17737   /* send it... */
17738   S (mp);
17739
17740   /* Wait for a reply... */
17741   W (ret);
17742   return ret;
17743 }
17744
17745 static int
17746 api_one_enable_disable_petr_mode (vat_main_t * vam)
17747 {
17748   unformat_input_t *input = vam->input;
17749   vl_api_one_enable_disable_petr_mode_t *mp;
17750   u8 is_set = 0;
17751   u8 is_en = 0;
17752   int ret;
17753
17754   /* Parse args required to build the message */
17755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17756     {
17757       if (unformat (input, "enable"))
17758         {
17759           is_set = 1;
17760           is_en = 1;
17761         }
17762       else if (unformat (input, "disable"))
17763         {
17764           is_set = 1;
17765         }
17766       else
17767         break;
17768     }
17769
17770   if (!is_set)
17771     {
17772       errmsg ("Value not set");
17773       return -99;
17774     }
17775
17776   /* Construct the API message */
17777   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17778
17779   mp->is_en = is_en;
17780
17781   /* send it... */
17782   S (mp);
17783
17784   /* Wait for a reply... */
17785   W (ret);
17786   return ret;
17787 }
17788
17789 static int
17790 api_one_show_petr_mode (vat_main_t * vam)
17791 {
17792   vl_api_one_show_petr_mode_t *mp;
17793   int ret;
17794
17795   /* Construct the API message */
17796   M (ONE_SHOW_PETR_MODE, mp);
17797
17798   /* send it... */
17799   S (mp);
17800
17801   /* Wait for a reply... */
17802   W (ret);
17803   return ret;
17804 }
17805
17806 static int
17807 api_show_one_map_register_state (vat_main_t * vam)
17808 {
17809   vl_api_show_one_map_register_state_t *mp;
17810   int ret;
17811
17812   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17813
17814   /* send */
17815   S (mp);
17816
17817   /* wait for reply */
17818   W (ret);
17819   return ret;
17820 }
17821
17822 #define api_show_lisp_map_register_state api_show_one_map_register_state
17823
17824 static int
17825 api_show_one_rloc_probe_state (vat_main_t * vam)
17826 {
17827   vl_api_show_one_rloc_probe_state_t *mp;
17828   int ret;
17829
17830   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17831
17832   /* send */
17833   S (mp);
17834
17835   /* wait for reply */
17836   W (ret);
17837   return ret;
17838 }
17839
17840 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17841
17842 static int
17843 api_one_add_del_ndp_entry (vat_main_t * vam)
17844 {
17845   vl_api_one_add_del_ndp_entry_t *mp;
17846   unformat_input_t *input = vam->input;
17847   u8 is_add = 1;
17848   u8 mac_set = 0;
17849   u8 bd_set = 0;
17850   u8 ip_set = 0;
17851   u8 mac[6] = { 0, };
17852   u8 ip6[16] = { 0, };
17853   u32 bd = ~0;
17854   int ret;
17855
17856   /* Parse args required to build the message */
17857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17858     {
17859       if (unformat (input, "del"))
17860         is_add = 0;
17861       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17862         mac_set = 1;
17863       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17864         ip_set = 1;
17865       else if (unformat (input, "bd %d", &bd))
17866         bd_set = 1;
17867       else
17868         {
17869           errmsg ("parse error '%U'", format_unformat_error, input);
17870           return -99;
17871         }
17872     }
17873
17874   if (!bd_set || !ip_set || (!mac_set && is_add))
17875     {
17876       errmsg ("Missing BD, IP or MAC!");
17877       return -99;
17878     }
17879
17880   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17881   mp->is_add = is_add;
17882   clib_memcpy (mp->mac, mac, 6);
17883   mp->bd = clib_host_to_net_u32 (bd);
17884   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17885
17886   /* send */
17887   S (mp);
17888
17889   /* wait for reply */
17890   W (ret);
17891   return ret;
17892 }
17893
17894 static int
17895 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17896 {
17897   vl_api_one_add_del_l2_arp_entry_t *mp;
17898   unformat_input_t *input = vam->input;
17899   u8 is_add = 1;
17900   u8 mac_set = 0;
17901   u8 bd_set = 0;
17902   u8 ip_set = 0;
17903   u8 mac[6] = { 0, };
17904   u32 ip4 = 0, bd = ~0;
17905   int ret;
17906
17907   /* Parse args required to build the message */
17908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17909     {
17910       if (unformat (input, "del"))
17911         is_add = 0;
17912       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17913         mac_set = 1;
17914       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17915         ip_set = 1;
17916       else if (unformat (input, "bd %d", &bd))
17917         bd_set = 1;
17918       else
17919         {
17920           errmsg ("parse error '%U'", format_unformat_error, input);
17921           return -99;
17922         }
17923     }
17924
17925   if (!bd_set || !ip_set || (!mac_set && is_add))
17926     {
17927       errmsg ("Missing BD, IP or MAC!");
17928       return -99;
17929     }
17930
17931   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17932   mp->is_add = is_add;
17933   clib_memcpy (mp->mac, mac, 6);
17934   mp->bd = clib_host_to_net_u32 (bd);
17935   mp->ip4 = ip4;
17936
17937   /* send */
17938   S (mp);
17939
17940   /* wait for reply */
17941   W (ret);
17942   return ret;
17943 }
17944
17945 static int
17946 api_one_ndp_bd_get (vat_main_t * vam)
17947 {
17948   vl_api_one_ndp_bd_get_t *mp;
17949   int ret;
17950
17951   M (ONE_NDP_BD_GET, mp);
17952
17953   /* send */
17954   S (mp);
17955
17956   /* wait for reply */
17957   W (ret);
17958   return ret;
17959 }
17960
17961 static int
17962 api_one_ndp_entries_get (vat_main_t * vam)
17963 {
17964   vl_api_one_ndp_entries_get_t *mp;
17965   unformat_input_t *input = vam->input;
17966   u8 bd_set = 0;
17967   u32 bd = ~0;
17968   int ret;
17969
17970   /* Parse args required to build the message */
17971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17972     {
17973       if (unformat (input, "bd %d", &bd))
17974         bd_set = 1;
17975       else
17976         {
17977           errmsg ("parse error '%U'", format_unformat_error, input);
17978           return -99;
17979         }
17980     }
17981
17982   if (!bd_set)
17983     {
17984       errmsg ("Expected bridge domain!");
17985       return -99;
17986     }
17987
17988   M (ONE_NDP_ENTRIES_GET, mp);
17989   mp->bd = clib_host_to_net_u32 (bd);
17990
17991   /* send */
17992   S (mp);
17993
17994   /* wait for reply */
17995   W (ret);
17996   return ret;
17997 }
17998
17999 static int
18000 api_one_l2_arp_bd_get (vat_main_t * vam)
18001 {
18002   vl_api_one_l2_arp_bd_get_t *mp;
18003   int ret;
18004
18005   M (ONE_L2_ARP_BD_GET, mp);
18006
18007   /* send */
18008   S (mp);
18009
18010   /* wait for reply */
18011   W (ret);
18012   return ret;
18013 }
18014
18015 static int
18016 api_one_l2_arp_entries_get (vat_main_t * vam)
18017 {
18018   vl_api_one_l2_arp_entries_get_t *mp;
18019   unformat_input_t *input = vam->input;
18020   u8 bd_set = 0;
18021   u32 bd = ~0;
18022   int ret;
18023
18024   /* Parse args required to build the message */
18025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18026     {
18027       if (unformat (input, "bd %d", &bd))
18028         bd_set = 1;
18029       else
18030         {
18031           errmsg ("parse error '%U'", format_unformat_error, input);
18032           return -99;
18033         }
18034     }
18035
18036   if (!bd_set)
18037     {
18038       errmsg ("Expected bridge domain!");
18039       return -99;
18040     }
18041
18042   M (ONE_L2_ARP_ENTRIES_GET, mp);
18043   mp->bd = clib_host_to_net_u32 (bd);
18044
18045   /* send */
18046   S (mp);
18047
18048   /* wait for reply */
18049   W (ret);
18050   return ret;
18051 }
18052
18053 static int
18054 api_one_stats_enable_disable (vat_main_t * vam)
18055 {
18056   vl_api_one_stats_enable_disable_t *mp;
18057   unformat_input_t *input = vam->input;
18058   u8 is_set = 0;
18059   u8 is_en = 0;
18060   int ret;
18061
18062   /* Parse args required to build the message */
18063   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18064     {
18065       if (unformat (input, "enable"))
18066         {
18067           is_set = 1;
18068           is_en = 1;
18069         }
18070       else if (unformat (input, "disable"))
18071         {
18072           is_set = 1;
18073         }
18074       else
18075         break;
18076     }
18077
18078   if (!is_set)
18079     {
18080       errmsg ("Value not set");
18081       return -99;
18082     }
18083
18084   M (ONE_STATS_ENABLE_DISABLE, mp);
18085   mp->is_en = is_en;
18086
18087   /* send */
18088   S (mp);
18089
18090   /* wait for reply */
18091   W (ret);
18092   return ret;
18093 }
18094
18095 static int
18096 api_show_one_stats_enable_disable (vat_main_t * vam)
18097 {
18098   vl_api_show_one_stats_enable_disable_t *mp;
18099   int ret;
18100
18101   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18102
18103   /* send */
18104   S (mp);
18105
18106   /* wait for reply */
18107   W (ret);
18108   return ret;
18109 }
18110
18111 static int
18112 api_show_one_map_request_mode (vat_main_t * vam)
18113 {
18114   vl_api_show_one_map_request_mode_t *mp;
18115   int ret;
18116
18117   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18118
18119   /* send */
18120   S (mp);
18121
18122   /* wait for reply */
18123   W (ret);
18124   return ret;
18125 }
18126
18127 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18128
18129 static int
18130 api_one_map_request_mode (vat_main_t * vam)
18131 {
18132   unformat_input_t *input = vam->input;
18133   vl_api_one_map_request_mode_t *mp;
18134   u8 mode = 0;
18135   int ret;
18136
18137   /* Parse args required to build the message */
18138   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18139     {
18140       if (unformat (input, "dst-only"))
18141         mode = 0;
18142       else if (unformat (input, "src-dst"))
18143         mode = 1;
18144       else
18145         {
18146           errmsg ("parse error '%U'", format_unformat_error, input);
18147           return -99;
18148         }
18149     }
18150
18151   M (ONE_MAP_REQUEST_MODE, mp);
18152
18153   mp->mode = mode;
18154
18155   /* send */
18156   S (mp);
18157
18158   /* wait for reply */
18159   W (ret);
18160   return ret;
18161 }
18162
18163 #define api_lisp_map_request_mode api_one_map_request_mode
18164
18165 /**
18166  * Enable/disable ONE proxy ITR.
18167  *
18168  * @param vam vpp API test context
18169  * @return return code
18170  */
18171 static int
18172 api_one_pitr_set_locator_set (vat_main_t * vam)
18173 {
18174   u8 ls_name_set = 0;
18175   unformat_input_t *input = vam->input;
18176   vl_api_one_pitr_set_locator_set_t *mp;
18177   u8 is_add = 1;
18178   u8 *ls_name = 0;
18179   int ret;
18180
18181   /* Parse args required to build the message */
18182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18183     {
18184       if (unformat (input, "del"))
18185         is_add = 0;
18186       else if (unformat (input, "locator-set %s", &ls_name))
18187         ls_name_set = 1;
18188       else
18189         {
18190           errmsg ("parse error '%U'", format_unformat_error, input);
18191           return -99;
18192         }
18193     }
18194
18195   if (!ls_name_set)
18196     {
18197       errmsg ("locator-set name not set!");
18198       return -99;
18199     }
18200
18201   M (ONE_PITR_SET_LOCATOR_SET, mp);
18202
18203   mp->is_add = is_add;
18204   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18205   vec_free (ls_name);
18206
18207   /* send */
18208   S (mp);
18209
18210   /* wait for reply */
18211   W (ret);
18212   return ret;
18213 }
18214
18215 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18216
18217 static int
18218 api_one_nsh_set_locator_set (vat_main_t * vam)
18219 {
18220   u8 ls_name_set = 0;
18221   unformat_input_t *input = vam->input;
18222   vl_api_one_nsh_set_locator_set_t *mp;
18223   u8 is_add = 1;
18224   u8 *ls_name = 0;
18225   int ret;
18226
18227   /* Parse args required to build the message */
18228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18229     {
18230       if (unformat (input, "del"))
18231         is_add = 0;
18232       else if (unformat (input, "ls %s", &ls_name))
18233         ls_name_set = 1;
18234       else
18235         {
18236           errmsg ("parse error '%U'", format_unformat_error, input);
18237           return -99;
18238         }
18239     }
18240
18241   if (!ls_name_set && is_add)
18242     {
18243       errmsg ("locator-set name not set!");
18244       return -99;
18245     }
18246
18247   M (ONE_NSH_SET_LOCATOR_SET, mp);
18248
18249   mp->is_add = is_add;
18250   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18251   vec_free (ls_name);
18252
18253   /* send */
18254   S (mp);
18255
18256   /* wait for reply */
18257   W (ret);
18258   return ret;
18259 }
18260
18261 static int
18262 api_show_one_pitr (vat_main_t * vam)
18263 {
18264   vl_api_show_one_pitr_t *mp;
18265   int ret;
18266
18267   if (!vam->json_output)
18268     {
18269       print (vam->ofp, "%=20s", "lisp status:");
18270     }
18271
18272   M (SHOW_ONE_PITR, mp);
18273   /* send it... */
18274   S (mp);
18275
18276   /* Wait for a reply... */
18277   W (ret);
18278   return ret;
18279 }
18280
18281 #define api_show_lisp_pitr api_show_one_pitr
18282
18283 static int
18284 api_one_use_petr (vat_main_t * vam)
18285 {
18286   unformat_input_t *input = vam->input;
18287   vl_api_one_use_petr_t *mp;
18288   u8 is_add = 0;
18289   ip_address_t ip;
18290   int ret;
18291
18292   memset (&ip, 0, sizeof (ip));
18293
18294   /* Parse args required to build the message */
18295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18296     {
18297       if (unformat (input, "disable"))
18298         is_add = 0;
18299       else
18300         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18301         {
18302           is_add = 1;
18303           ip_addr_version (&ip) = IP4;
18304         }
18305       else
18306         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18307         {
18308           is_add = 1;
18309           ip_addr_version (&ip) = IP6;
18310         }
18311       else
18312         {
18313           errmsg ("parse error '%U'", format_unformat_error, input);
18314           return -99;
18315         }
18316     }
18317
18318   M (ONE_USE_PETR, mp);
18319
18320   mp->is_add = is_add;
18321   if (is_add)
18322     {
18323       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18324       if (mp->is_ip4)
18325         clib_memcpy (mp->address, &ip, 4);
18326       else
18327         clib_memcpy (mp->address, &ip, 16);
18328     }
18329
18330   /* send */
18331   S (mp);
18332
18333   /* wait for reply */
18334   W (ret);
18335   return ret;
18336 }
18337
18338 #define api_lisp_use_petr api_one_use_petr
18339
18340 static int
18341 api_show_one_nsh_mapping (vat_main_t * vam)
18342 {
18343   vl_api_show_one_use_petr_t *mp;
18344   int ret;
18345
18346   if (!vam->json_output)
18347     {
18348       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18349     }
18350
18351   M (SHOW_ONE_NSH_MAPPING, mp);
18352   /* send it... */
18353   S (mp);
18354
18355   /* Wait for a reply... */
18356   W (ret);
18357   return ret;
18358 }
18359
18360 static int
18361 api_show_one_use_petr (vat_main_t * vam)
18362 {
18363   vl_api_show_one_use_petr_t *mp;
18364   int ret;
18365
18366   if (!vam->json_output)
18367     {
18368       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18369     }
18370
18371   M (SHOW_ONE_USE_PETR, mp);
18372   /* send it... */
18373   S (mp);
18374
18375   /* Wait for a reply... */
18376   W (ret);
18377   return ret;
18378 }
18379
18380 #define api_show_lisp_use_petr api_show_one_use_petr
18381
18382 /**
18383  * Add/delete mapping between vni and vrf
18384  */
18385 static int
18386 api_one_eid_table_add_del_map (vat_main_t * vam)
18387 {
18388   unformat_input_t *input = vam->input;
18389   vl_api_one_eid_table_add_del_map_t *mp;
18390   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18391   u32 vni, vrf, bd_index;
18392   int ret;
18393
18394   /* Parse args required to build the message */
18395   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18396     {
18397       if (unformat (input, "del"))
18398         is_add = 0;
18399       else if (unformat (input, "vrf %d", &vrf))
18400         vrf_set = 1;
18401       else if (unformat (input, "bd_index %d", &bd_index))
18402         bd_index_set = 1;
18403       else if (unformat (input, "vni %d", &vni))
18404         vni_set = 1;
18405       else
18406         break;
18407     }
18408
18409   if (!vni_set || (!vrf_set && !bd_index_set))
18410     {
18411       errmsg ("missing arguments!");
18412       return -99;
18413     }
18414
18415   if (vrf_set && bd_index_set)
18416     {
18417       errmsg ("error: both vrf and bd entered!");
18418       return -99;
18419     }
18420
18421   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18422
18423   mp->is_add = is_add;
18424   mp->vni = htonl (vni);
18425   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18426   mp->is_l2 = bd_index_set;
18427
18428   /* send */
18429   S (mp);
18430
18431   /* wait for reply */
18432   W (ret);
18433   return ret;
18434 }
18435
18436 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18437
18438 uword
18439 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18440 {
18441   u32 *action = va_arg (*args, u32 *);
18442   u8 *s = 0;
18443
18444   if (unformat (input, "%s", &s))
18445     {
18446       if (!strcmp ((char *) s, "no-action"))
18447         action[0] = 0;
18448       else if (!strcmp ((char *) s, "natively-forward"))
18449         action[0] = 1;
18450       else if (!strcmp ((char *) s, "send-map-request"))
18451         action[0] = 2;
18452       else if (!strcmp ((char *) s, "drop"))
18453         action[0] = 3;
18454       else
18455         {
18456           clib_warning ("invalid action: '%s'", s);
18457           action[0] = 3;
18458         }
18459     }
18460   else
18461     return 0;
18462
18463   vec_free (s);
18464   return 1;
18465 }
18466
18467 /**
18468  * Add/del remote mapping to/from ONE control plane
18469  *
18470  * @param vam vpp API test context
18471  * @return return code
18472  */
18473 static int
18474 api_one_add_del_remote_mapping (vat_main_t * vam)
18475 {
18476   unformat_input_t *input = vam->input;
18477   vl_api_one_add_del_remote_mapping_t *mp;
18478   u32 vni = 0;
18479   lisp_eid_vat_t _eid, *eid = &_eid;
18480   lisp_eid_vat_t _seid, *seid = &_seid;
18481   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18482   u32 action = ~0, p, w, data_len;
18483   ip4_address_t rloc4;
18484   ip6_address_t rloc6;
18485   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18486   int ret;
18487
18488   memset (&rloc, 0, sizeof (rloc));
18489
18490   /* Parse args required to build the message */
18491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18492     {
18493       if (unformat (input, "del-all"))
18494         {
18495           del_all = 1;
18496         }
18497       else if (unformat (input, "del"))
18498         {
18499           is_add = 0;
18500         }
18501       else if (unformat (input, "add"))
18502         {
18503           is_add = 1;
18504         }
18505       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18506         {
18507           eid_set = 1;
18508         }
18509       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18510         {
18511           seid_set = 1;
18512         }
18513       else if (unformat (input, "vni %d", &vni))
18514         {
18515           ;
18516         }
18517       else if (unformat (input, "p %d w %d", &p, &w))
18518         {
18519           if (!curr_rloc)
18520             {
18521               errmsg ("No RLOC configured for setting priority/weight!");
18522               return -99;
18523             }
18524           curr_rloc->priority = p;
18525           curr_rloc->weight = w;
18526         }
18527       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18528         {
18529           rloc.is_ip4 = 1;
18530           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18531           vec_add1 (rlocs, rloc);
18532           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18533         }
18534       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18535         {
18536           rloc.is_ip4 = 0;
18537           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18538           vec_add1 (rlocs, rloc);
18539           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18540         }
18541       else if (unformat (input, "action %U",
18542                          unformat_negative_mapping_action, &action))
18543         {
18544           ;
18545         }
18546       else
18547         {
18548           clib_warning ("parse error '%U'", format_unformat_error, input);
18549           return -99;
18550         }
18551     }
18552
18553   if (0 == eid_set)
18554     {
18555       errmsg ("missing params!");
18556       return -99;
18557     }
18558
18559   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18560     {
18561       errmsg ("no action set for negative map-reply!");
18562       return -99;
18563     }
18564
18565   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18566
18567   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18568   mp->is_add = is_add;
18569   mp->vni = htonl (vni);
18570   mp->action = (u8) action;
18571   mp->is_src_dst = seid_set;
18572   mp->eid_len = eid->len;
18573   mp->seid_len = seid->len;
18574   mp->del_all = del_all;
18575   mp->eid_type = eid->type;
18576   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18577   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18578
18579   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18580   clib_memcpy (mp->rlocs, rlocs, data_len);
18581   vec_free (rlocs);
18582
18583   /* send it... */
18584   S (mp);
18585
18586   /* Wait for a reply... */
18587   W (ret);
18588   return ret;
18589 }
18590
18591 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18592
18593 /**
18594  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18595  * forwarding entries in data-plane accordingly.
18596  *
18597  * @param vam vpp API test context
18598  * @return return code
18599  */
18600 static int
18601 api_one_add_del_adjacency (vat_main_t * vam)
18602 {
18603   unformat_input_t *input = vam->input;
18604   vl_api_one_add_del_adjacency_t *mp;
18605   u32 vni = 0;
18606   ip4_address_t leid4, reid4;
18607   ip6_address_t leid6, reid6;
18608   u8 reid_mac[6] = { 0 };
18609   u8 leid_mac[6] = { 0 };
18610   u8 reid_type, leid_type;
18611   u32 leid_len = 0, reid_len = 0, len;
18612   u8 is_add = 1;
18613   int ret;
18614
18615   leid_type = reid_type = (u8) ~ 0;
18616
18617   /* Parse args required to build the message */
18618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18619     {
18620       if (unformat (input, "del"))
18621         {
18622           is_add = 0;
18623         }
18624       else if (unformat (input, "add"))
18625         {
18626           is_add = 1;
18627         }
18628       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18629                          &reid4, &len))
18630         {
18631           reid_type = 0;        /* ipv4 */
18632           reid_len = len;
18633         }
18634       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18635                          &reid6, &len))
18636         {
18637           reid_type = 1;        /* ipv6 */
18638           reid_len = len;
18639         }
18640       else if (unformat (input, "reid %U", unformat_ethernet_address,
18641                          reid_mac))
18642         {
18643           reid_type = 2;        /* mac */
18644         }
18645       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18646                          &leid4, &len))
18647         {
18648           leid_type = 0;        /* ipv4 */
18649           leid_len = len;
18650         }
18651       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18652                          &leid6, &len))
18653         {
18654           leid_type = 1;        /* ipv6 */
18655           leid_len = len;
18656         }
18657       else if (unformat (input, "leid %U", unformat_ethernet_address,
18658                          leid_mac))
18659         {
18660           leid_type = 2;        /* mac */
18661         }
18662       else if (unformat (input, "vni %d", &vni))
18663         {
18664           ;
18665         }
18666       else
18667         {
18668           errmsg ("parse error '%U'", format_unformat_error, input);
18669           return -99;
18670         }
18671     }
18672
18673   if ((u8) ~ 0 == reid_type)
18674     {
18675       errmsg ("missing params!");
18676       return -99;
18677     }
18678
18679   if (leid_type != reid_type)
18680     {
18681       errmsg ("remote and local EIDs are of different types!");
18682       return -99;
18683     }
18684
18685   M (ONE_ADD_DEL_ADJACENCY, mp);
18686   mp->is_add = is_add;
18687   mp->vni = htonl (vni);
18688   mp->leid_len = leid_len;
18689   mp->reid_len = reid_len;
18690   mp->eid_type = reid_type;
18691
18692   switch (mp->eid_type)
18693     {
18694     case 0:
18695       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18696       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18697       break;
18698     case 1:
18699       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18700       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18701       break;
18702     case 2:
18703       clib_memcpy (mp->leid, leid_mac, 6);
18704       clib_memcpy (mp->reid, reid_mac, 6);
18705       break;
18706     default:
18707       errmsg ("unknown EID type %d!", mp->eid_type);
18708       return 0;
18709     }
18710
18711   /* send it... */
18712   S (mp);
18713
18714   /* Wait for a reply... */
18715   W (ret);
18716   return ret;
18717 }
18718
18719 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18720
18721 uword
18722 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18723 {
18724   u32 *mode = va_arg (*args, u32 *);
18725
18726   if (unformat (input, "lisp"))
18727     *mode = 0;
18728   else if (unformat (input, "vxlan"))
18729     *mode = 1;
18730   else
18731     return 0;
18732
18733   return 1;
18734 }
18735
18736 static int
18737 api_gpe_get_encap_mode (vat_main_t * vam)
18738 {
18739   vl_api_gpe_get_encap_mode_t *mp;
18740   int ret;
18741
18742   /* Construct the API message */
18743   M (GPE_GET_ENCAP_MODE, mp);
18744
18745   /* send it... */
18746   S (mp);
18747
18748   /* Wait for a reply... */
18749   W (ret);
18750   return ret;
18751 }
18752
18753 static int
18754 api_gpe_set_encap_mode (vat_main_t * vam)
18755 {
18756   unformat_input_t *input = vam->input;
18757   vl_api_gpe_set_encap_mode_t *mp;
18758   int ret;
18759   u32 mode = 0;
18760
18761   /* Parse args required to build the message */
18762   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18763     {
18764       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18765         ;
18766       else
18767         break;
18768     }
18769
18770   /* Construct the API message */
18771   M (GPE_SET_ENCAP_MODE, mp);
18772
18773   mp->mode = mode;
18774
18775   /* send it... */
18776   S (mp);
18777
18778   /* Wait for a reply... */
18779   W (ret);
18780   return ret;
18781 }
18782
18783 static int
18784 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18785 {
18786   unformat_input_t *input = vam->input;
18787   vl_api_gpe_add_del_iface_t *mp;
18788   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18789   u32 dp_table = 0, vni = 0;
18790   int ret;
18791
18792   /* Parse args required to build the message */
18793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18794     {
18795       if (unformat (input, "up"))
18796         {
18797           action_set = 1;
18798           is_add = 1;
18799         }
18800       else if (unformat (input, "down"))
18801         {
18802           action_set = 1;
18803           is_add = 0;
18804         }
18805       else if (unformat (input, "table_id %d", &dp_table))
18806         {
18807           dp_table_set = 1;
18808         }
18809       else if (unformat (input, "bd_id %d", &dp_table))
18810         {
18811           dp_table_set = 1;
18812           is_l2 = 1;
18813         }
18814       else if (unformat (input, "vni %d", &vni))
18815         {
18816           vni_set = 1;
18817         }
18818       else
18819         break;
18820     }
18821
18822   if (action_set == 0)
18823     {
18824       errmsg ("Action not set");
18825       return -99;
18826     }
18827   if (dp_table_set == 0 || vni_set == 0)
18828     {
18829       errmsg ("vni and dp_table must be set");
18830       return -99;
18831     }
18832
18833   /* Construct the API message */
18834   M (GPE_ADD_DEL_IFACE, mp);
18835
18836   mp->is_add = is_add;
18837   mp->dp_table = clib_host_to_net_u32 (dp_table);
18838   mp->is_l2 = is_l2;
18839   mp->vni = clib_host_to_net_u32 (vni);
18840
18841   /* send it... */
18842   S (mp);
18843
18844   /* Wait for a reply... */
18845   W (ret);
18846   return ret;
18847 }
18848
18849 static int
18850 api_one_map_register_fallback_threshold (vat_main_t * vam)
18851 {
18852   unformat_input_t *input = vam->input;
18853   vl_api_one_map_register_fallback_threshold_t *mp;
18854   u32 value = 0;
18855   u8 is_set = 0;
18856   int ret;
18857
18858   /* Parse args required to build the message */
18859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18860     {
18861       if (unformat (input, "%u", &value))
18862         is_set = 1;
18863       else
18864         {
18865           clib_warning ("parse error '%U'", format_unformat_error, input);
18866           return -99;
18867         }
18868     }
18869
18870   if (!is_set)
18871     {
18872       errmsg ("fallback threshold value is missing!");
18873       return -99;
18874     }
18875
18876   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18877   mp->value = clib_host_to_net_u32 (value);
18878
18879   /* send it... */
18880   S (mp);
18881
18882   /* Wait for a reply... */
18883   W (ret);
18884   return ret;
18885 }
18886
18887 static int
18888 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18889 {
18890   vl_api_show_one_map_register_fallback_threshold_t *mp;
18891   int ret;
18892
18893   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18894
18895   /* send it... */
18896   S (mp);
18897
18898   /* Wait for a reply... */
18899   W (ret);
18900   return ret;
18901 }
18902
18903 uword
18904 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18905 {
18906   u32 *proto = va_arg (*args, u32 *);
18907
18908   if (unformat (input, "udp"))
18909     *proto = 1;
18910   else if (unformat (input, "api"))
18911     *proto = 2;
18912   else
18913     return 0;
18914
18915   return 1;
18916 }
18917
18918 static int
18919 api_one_set_transport_protocol (vat_main_t * vam)
18920 {
18921   unformat_input_t *input = vam->input;
18922   vl_api_one_set_transport_protocol_t *mp;
18923   u8 is_set = 0;
18924   u32 protocol = 0;
18925   int ret;
18926
18927   /* Parse args required to build the message */
18928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18929     {
18930       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18931         is_set = 1;
18932       else
18933         {
18934           clib_warning ("parse error '%U'", format_unformat_error, input);
18935           return -99;
18936         }
18937     }
18938
18939   if (!is_set)
18940     {
18941       errmsg ("Transport protocol missing!");
18942       return -99;
18943     }
18944
18945   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18946   mp->protocol = (u8) protocol;
18947
18948   /* send it... */
18949   S (mp);
18950
18951   /* Wait for a reply... */
18952   W (ret);
18953   return ret;
18954 }
18955
18956 static int
18957 api_one_get_transport_protocol (vat_main_t * vam)
18958 {
18959   vl_api_one_get_transport_protocol_t *mp;
18960   int ret;
18961
18962   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18963
18964   /* send it... */
18965   S (mp);
18966
18967   /* Wait for a reply... */
18968   W (ret);
18969   return ret;
18970 }
18971
18972 static int
18973 api_one_map_register_set_ttl (vat_main_t * vam)
18974 {
18975   unformat_input_t *input = vam->input;
18976   vl_api_one_map_register_set_ttl_t *mp;
18977   u32 ttl = 0;
18978   u8 is_set = 0;
18979   int ret;
18980
18981   /* Parse args required to build the message */
18982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18983     {
18984       if (unformat (input, "%u", &ttl))
18985         is_set = 1;
18986       else
18987         {
18988           clib_warning ("parse error '%U'", format_unformat_error, input);
18989           return -99;
18990         }
18991     }
18992
18993   if (!is_set)
18994     {
18995       errmsg ("TTL value missing!");
18996       return -99;
18997     }
18998
18999   M (ONE_MAP_REGISTER_SET_TTL, mp);
19000   mp->ttl = clib_host_to_net_u32 (ttl);
19001
19002   /* send it... */
19003   S (mp);
19004
19005   /* Wait for a reply... */
19006   W (ret);
19007   return ret;
19008 }
19009
19010 static int
19011 api_show_one_map_register_ttl (vat_main_t * vam)
19012 {
19013   vl_api_show_one_map_register_ttl_t *mp;
19014   int ret;
19015
19016   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19017
19018   /* send it... */
19019   S (mp);
19020
19021   /* Wait for a reply... */
19022   W (ret);
19023   return ret;
19024 }
19025
19026 /**
19027  * Add/del map request itr rlocs from ONE control plane and updates
19028  *
19029  * @param vam vpp API test context
19030  * @return return code
19031  */
19032 static int
19033 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19034 {
19035   unformat_input_t *input = vam->input;
19036   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19037   u8 *locator_set_name = 0;
19038   u8 locator_set_name_set = 0;
19039   u8 is_add = 1;
19040   int ret;
19041
19042   /* Parse args required to build the message */
19043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19044     {
19045       if (unformat (input, "del"))
19046         {
19047           is_add = 0;
19048         }
19049       else if (unformat (input, "%_%v%_", &locator_set_name))
19050         {
19051           locator_set_name_set = 1;
19052         }
19053       else
19054         {
19055           clib_warning ("parse error '%U'", format_unformat_error, input);
19056           return -99;
19057         }
19058     }
19059
19060   if (is_add && !locator_set_name_set)
19061     {
19062       errmsg ("itr-rloc is not set!");
19063       return -99;
19064     }
19065
19066   if (is_add && vec_len (locator_set_name) > 64)
19067     {
19068       errmsg ("itr-rloc locator-set name too long");
19069       vec_free (locator_set_name);
19070       return -99;
19071     }
19072
19073   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19074   mp->is_add = is_add;
19075   if (is_add)
19076     {
19077       clib_memcpy (mp->locator_set_name, locator_set_name,
19078                    vec_len (locator_set_name));
19079     }
19080   else
19081     {
19082       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19083     }
19084   vec_free (locator_set_name);
19085
19086   /* send it... */
19087   S (mp);
19088
19089   /* Wait for a reply... */
19090   W (ret);
19091   return ret;
19092 }
19093
19094 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19095
19096 static int
19097 api_one_locator_dump (vat_main_t * vam)
19098 {
19099   unformat_input_t *input = vam->input;
19100   vl_api_one_locator_dump_t *mp;
19101   vl_api_control_ping_t *mp_ping;
19102   u8 is_index_set = 0, is_name_set = 0;
19103   u8 *ls_name = 0;
19104   u32 ls_index = ~0;
19105   int ret;
19106
19107   /* Parse args required to build the message */
19108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19109     {
19110       if (unformat (input, "ls_name %_%v%_", &ls_name))
19111         {
19112           is_name_set = 1;
19113         }
19114       else if (unformat (input, "ls_index %d", &ls_index))
19115         {
19116           is_index_set = 1;
19117         }
19118       else
19119         {
19120           errmsg ("parse error '%U'", format_unformat_error, input);
19121           return -99;
19122         }
19123     }
19124
19125   if (!is_index_set && !is_name_set)
19126     {
19127       errmsg ("error: expected one of index or name!");
19128       return -99;
19129     }
19130
19131   if (is_index_set && is_name_set)
19132     {
19133       errmsg ("error: only one param expected!");
19134       return -99;
19135     }
19136
19137   if (vec_len (ls_name) > 62)
19138     {
19139       errmsg ("error: locator set name too long!");
19140       return -99;
19141     }
19142
19143   if (!vam->json_output)
19144     {
19145       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19146     }
19147
19148   M (ONE_LOCATOR_DUMP, mp);
19149   mp->is_index_set = is_index_set;
19150
19151   if (is_index_set)
19152     mp->ls_index = clib_host_to_net_u32 (ls_index);
19153   else
19154     {
19155       vec_add1 (ls_name, 0);
19156       strncpy ((char *) mp->ls_name, (char *) ls_name,
19157                sizeof (mp->ls_name) - 1);
19158     }
19159
19160   /* send it... */
19161   S (mp);
19162
19163   /* Use a control ping for synchronization */
19164   MPING (CONTROL_PING, mp_ping);
19165   S (mp_ping);
19166
19167   /* Wait for a reply... */
19168   W (ret);
19169   return ret;
19170 }
19171
19172 #define api_lisp_locator_dump api_one_locator_dump
19173
19174 static int
19175 api_one_locator_set_dump (vat_main_t * vam)
19176 {
19177   vl_api_one_locator_set_dump_t *mp;
19178   vl_api_control_ping_t *mp_ping;
19179   unformat_input_t *input = vam->input;
19180   u8 filter = 0;
19181   int ret;
19182
19183   /* Parse args required to build the message */
19184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19185     {
19186       if (unformat (input, "local"))
19187         {
19188           filter = 1;
19189         }
19190       else if (unformat (input, "remote"))
19191         {
19192           filter = 2;
19193         }
19194       else
19195         {
19196           errmsg ("parse error '%U'", format_unformat_error, input);
19197           return -99;
19198         }
19199     }
19200
19201   if (!vam->json_output)
19202     {
19203       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19204     }
19205
19206   M (ONE_LOCATOR_SET_DUMP, mp);
19207
19208   mp->filter = filter;
19209
19210   /* send it... */
19211   S (mp);
19212
19213   /* Use a control ping for synchronization */
19214   MPING (CONTROL_PING, mp_ping);
19215   S (mp_ping);
19216
19217   /* Wait for a reply... */
19218   W (ret);
19219   return ret;
19220 }
19221
19222 #define api_lisp_locator_set_dump api_one_locator_set_dump
19223
19224 static int
19225 api_one_eid_table_map_dump (vat_main_t * vam)
19226 {
19227   u8 is_l2 = 0;
19228   u8 mode_set = 0;
19229   unformat_input_t *input = vam->input;
19230   vl_api_one_eid_table_map_dump_t *mp;
19231   vl_api_control_ping_t *mp_ping;
19232   int ret;
19233
19234   /* Parse args required to build the message */
19235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19236     {
19237       if (unformat (input, "l2"))
19238         {
19239           is_l2 = 1;
19240           mode_set = 1;
19241         }
19242       else if (unformat (input, "l3"))
19243         {
19244           is_l2 = 0;
19245           mode_set = 1;
19246         }
19247       else
19248         {
19249           errmsg ("parse error '%U'", format_unformat_error, input);
19250           return -99;
19251         }
19252     }
19253
19254   if (!mode_set)
19255     {
19256       errmsg ("expected one of 'l2' or 'l3' parameter!");
19257       return -99;
19258     }
19259
19260   if (!vam->json_output)
19261     {
19262       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19263     }
19264
19265   M (ONE_EID_TABLE_MAP_DUMP, mp);
19266   mp->is_l2 = is_l2;
19267
19268   /* send it... */
19269   S (mp);
19270
19271   /* Use a control ping for synchronization */
19272   MPING (CONTROL_PING, mp_ping);
19273   S (mp_ping);
19274
19275   /* Wait for a reply... */
19276   W (ret);
19277   return ret;
19278 }
19279
19280 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19281
19282 static int
19283 api_one_eid_table_vni_dump (vat_main_t * vam)
19284 {
19285   vl_api_one_eid_table_vni_dump_t *mp;
19286   vl_api_control_ping_t *mp_ping;
19287   int ret;
19288
19289   if (!vam->json_output)
19290     {
19291       print (vam->ofp, "VNI");
19292     }
19293
19294   M (ONE_EID_TABLE_VNI_DUMP, mp);
19295
19296   /* send it... */
19297   S (mp);
19298
19299   /* Use a control ping for synchronization */
19300   MPING (CONTROL_PING, mp_ping);
19301   S (mp_ping);
19302
19303   /* Wait for a reply... */
19304   W (ret);
19305   return ret;
19306 }
19307
19308 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19309
19310 static int
19311 api_one_eid_table_dump (vat_main_t * vam)
19312 {
19313   unformat_input_t *i = vam->input;
19314   vl_api_one_eid_table_dump_t *mp;
19315   vl_api_control_ping_t *mp_ping;
19316   struct in_addr ip4;
19317   struct in6_addr ip6;
19318   u8 mac[6];
19319   u8 eid_type = ~0, eid_set = 0;
19320   u32 prefix_length = ~0, t, vni = 0;
19321   u8 filter = 0;
19322   int ret;
19323   lisp_nsh_api_t nsh;
19324
19325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19326     {
19327       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19328         {
19329           eid_set = 1;
19330           eid_type = 0;
19331           prefix_length = t;
19332         }
19333       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19334         {
19335           eid_set = 1;
19336           eid_type = 1;
19337           prefix_length = t;
19338         }
19339       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19340         {
19341           eid_set = 1;
19342           eid_type = 2;
19343         }
19344       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19345         {
19346           eid_set = 1;
19347           eid_type = 3;
19348         }
19349       else if (unformat (i, "vni %d", &t))
19350         {
19351           vni = t;
19352         }
19353       else if (unformat (i, "local"))
19354         {
19355           filter = 1;
19356         }
19357       else if (unformat (i, "remote"))
19358         {
19359           filter = 2;
19360         }
19361       else
19362         {
19363           errmsg ("parse error '%U'", format_unformat_error, i);
19364           return -99;
19365         }
19366     }
19367
19368   if (!vam->json_output)
19369     {
19370       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19371              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19372     }
19373
19374   M (ONE_EID_TABLE_DUMP, mp);
19375
19376   mp->filter = filter;
19377   if (eid_set)
19378     {
19379       mp->eid_set = 1;
19380       mp->vni = htonl (vni);
19381       mp->eid_type = eid_type;
19382       switch (eid_type)
19383         {
19384         case 0:
19385           mp->prefix_length = prefix_length;
19386           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19387           break;
19388         case 1:
19389           mp->prefix_length = prefix_length;
19390           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19391           break;
19392         case 2:
19393           clib_memcpy (mp->eid, mac, sizeof (mac));
19394           break;
19395         case 3:
19396           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19397           break;
19398         default:
19399           errmsg ("unknown EID type %d!", eid_type);
19400           return -99;
19401         }
19402     }
19403
19404   /* send it... */
19405   S (mp);
19406
19407   /* Use a control ping for synchronization */
19408   MPING (CONTROL_PING, mp_ping);
19409   S (mp_ping);
19410
19411   /* Wait for a reply... */
19412   W (ret);
19413   return ret;
19414 }
19415
19416 #define api_lisp_eid_table_dump api_one_eid_table_dump
19417
19418 static int
19419 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19420 {
19421   unformat_input_t *i = vam->input;
19422   vl_api_gpe_fwd_entries_get_t *mp;
19423   u8 vni_set = 0;
19424   u32 vni = ~0;
19425   int ret;
19426
19427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19428     {
19429       if (unformat (i, "vni %d", &vni))
19430         {
19431           vni_set = 1;
19432         }
19433       else
19434         {
19435           errmsg ("parse error '%U'", format_unformat_error, i);
19436           return -99;
19437         }
19438     }
19439
19440   if (!vni_set)
19441     {
19442       errmsg ("vni not set!");
19443       return -99;
19444     }
19445
19446   if (!vam->json_output)
19447     {
19448       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19449              "leid", "reid");
19450     }
19451
19452   M (GPE_FWD_ENTRIES_GET, mp);
19453   mp->vni = clib_host_to_net_u32 (vni);
19454
19455   /* send it... */
19456   S (mp);
19457
19458   /* Wait for a reply... */
19459   W (ret);
19460   return ret;
19461 }
19462
19463 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19464 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19465 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19466 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19467 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19468 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19469 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19470 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19471
19472 static int
19473 api_one_adjacencies_get (vat_main_t * vam)
19474 {
19475   unformat_input_t *i = vam->input;
19476   vl_api_one_adjacencies_get_t *mp;
19477   u8 vni_set = 0;
19478   u32 vni = ~0;
19479   int ret;
19480
19481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19482     {
19483       if (unformat (i, "vni %d", &vni))
19484         {
19485           vni_set = 1;
19486         }
19487       else
19488         {
19489           errmsg ("parse error '%U'", format_unformat_error, i);
19490           return -99;
19491         }
19492     }
19493
19494   if (!vni_set)
19495     {
19496       errmsg ("vni not set!");
19497       return -99;
19498     }
19499
19500   if (!vam->json_output)
19501     {
19502       print (vam->ofp, "%s %40s", "leid", "reid");
19503     }
19504
19505   M (ONE_ADJACENCIES_GET, mp);
19506   mp->vni = clib_host_to_net_u32 (vni);
19507
19508   /* send it... */
19509   S (mp);
19510
19511   /* Wait for a reply... */
19512   W (ret);
19513   return ret;
19514 }
19515
19516 #define api_lisp_adjacencies_get api_one_adjacencies_get
19517
19518 static int
19519 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19520 {
19521   unformat_input_t *i = vam->input;
19522   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19523   int ret;
19524   u8 ip_family_set = 0, is_ip4 = 1;
19525
19526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19527     {
19528       if (unformat (i, "ip4"))
19529         {
19530           ip_family_set = 1;
19531           is_ip4 = 1;
19532         }
19533       else if (unformat (i, "ip6"))
19534         {
19535           ip_family_set = 1;
19536           is_ip4 = 0;
19537         }
19538       else
19539         {
19540           errmsg ("parse error '%U'", format_unformat_error, i);
19541           return -99;
19542         }
19543     }
19544
19545   if (!ip_family_set)
19546     {
19547       errmsg ("ip family not set!");
19548       return -99;
19549     }
19550
19551   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19552   mp->is_ip4 = is_ip4;
19553
19554   /* send it... */
19555   S (mp);
19556
19557   /* Wait for a reply... */
19558   W (ret);
19559   return ret;
19560 }
19561
19562 static int
19563 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19564 {
19565   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19566   int ret;
19567
19568   if (!vam->json_output)
19569     {
19570       print (vam->ofp, "VNIs");
19571     }
19572
19573   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19574
19575   /* send it... */
19576   S (mp);
19577
19578   /* Wait for a reply... */
19579   W (ret);
19580   return ret;
19581 }
19582
19583 static int
19584 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19585 {
19586   unformat_input_t *i = vam->input;
19587   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19588   int ret = 0;
19589   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19590   struct in_addr ip4;
19591   struct in6_addr ip6;
19592   u32 table_id = 0, nh_sw_if_index = ~0;
19593
19594   memset (&ip4, 0, sizeof (ip4));
19595   memset (&ip6, 0, sizeof (ip6));
19596
19597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19598     {
19599       if (unformat (i, "del"))
19600         is_add = 0;
19601       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19602                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19603         {
19604           ip_set = 1;
19605           is_ip4 = 1;
19606         }
19607       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19608                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19609         {
19610           ip_set = 1;
19611           is_ip4 = 0;
19612         }
19613       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19614         {
19615           ip_set = 1;
19616           is_ip4 = 1;
19617           nh_sw_if_index = ~0;
19618         }
19619       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19620         {
19621           ip_set = 1;
19622           is_ip4 = 0;
19623           nh_sw_if_index = ~0;
19624         }
19625       else if (unformat (i, "table %d", &table_id))
19626         ;
19627       else
19628         {
19629           errmsg ("parse error '%U'", format_unformat_error, i);
19630           return -99;
19631         }
19632     }
19633
19634   if (!ip_set)
19635     {
19636       errmsg ("nh addr not set!");
19637       return -99;
19638     }
19639
19640   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19641   mp->is_add = is_add;
19642   mp->table_id = clib_host_to_net_u32 (table_id);
19643   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19644   mp->is_ip4 = is_ip4;
19645   if (is_ip4)
19646     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19647   else
19648     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19649
19650   /* send it... */
19651   S (mp);
19652
19653   /* Wait for a reply... */
19654   W (ret);
19655   return ret;
19656 }
19657
19658 static int
19659 api_one_map_server_dump (vat_main_t * vam)
19660 {
19661   vl_api_one_map_server_dump_t *mp;
19662   vl_api_control_ping_t *mp_ping;
19663   int ret;
19664
19665   if (!vam->json_output)
19666     {
19667       print (vam->ofp, "%=20s", "Map server");
19668     }
19669
19670   M (ONE_MAP_SERVER_DUMP, mp);
19671   /* send it... */
19672   S (mp);
19673
19674   /* Use a control ping for synchronization */
19675   MPING (CONTROL_PING, mp_ping);
19676   S (mp_ping);
19677
19678   /* Wait for a reply... */
19679   W (ret);
19680   return ret;
19681 }
19682
19683 #define api_lisp_map_server_dump api_one_map_server_dump
19684
19685 static int
19686 api_one_map_resolver_dump (vat_main_t * vam)
19687 {
19688   vl_api_one_map_resolver_dump_t *mp;
19689   vl_api_control_ping_t *mp_ping;
19690   int ret;
19691
19692   if (!vam->json_output)
19693     {
19694       print (vam->ofp, "%=20s", "Map resolver");
19695     }
19696
19697   M (ONE_MAP_RESOLVER_DUMP, mp);
19698   /* send it... */
19699   S (mp);
19700
19701   /* Use a control ping for synchronization */
19702   MPING (CONTROL_PING, mp_ping);
19703   S (mp_ping);
19704
19705   /* Wait for a reply... */
19706   W (ret);
19707   return ret;
19708 }
19709
19710 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19711
19712 static int
19713 api_one_stats_flush (vat_main_t * vam)
19714 {
19715   vl_api_one_stats_flush_t *mp;
19716   int ret = 0;
19717
19718   M (ONE_STATS_FLUSH, mp);
19719   S (mp);
19720   W (ret);
19721   return ret;
19722 }
19723
19724 static int
19725 api_one_stats_dump (vat_main_t * vam)
19726 {
19727   vl_api_one_stats_dump_t *mp;
19728   vl_api_control_ping_t *mp_ping;
19729   int ret;
19730
19731   M (ONE_STATS_DUMP, mp);
19732   /* send it... */
19733   S (mp);
19734
19735   /* Use a control ping for synchronization */
19736   MPING (CONTROL_PING, mp_ping);
19737   S (mp_ping);
19738
19739   /* Wait for a reply... */
19740   W (ret);
19741   return ret;
19742 }
19743
19744 static int
19745 api_show_one_status (vat_main_t * vam)
19746 {
19747   vl_api_show_one_status_t *mp;
19748   int ret;
19749
19750   if (!vam->json_output)
19751     {
19752       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19753     }
19754
19755   M (SHOW_ONE_STATUS, mp);
19756   /* send it... */
19757   S (mp);
19758   /* Wait for a reply... */
19759   W (ret);
19760   return ret;
19761 }
19762
19763 #define api_show_lisp_status api_show_one_status
19764
19765 static int
19766 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19767 {
19768   vl_api_gpe_fwd_entry_path_dump_t *mp;
19769   vl_api_control_ping_t *mp_ping;
19770   unformat_input_t *i = vam->input;
19771   u32 fwd_entry_index = ~0;
19772   int ret;
19773
19774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19775     {
19776       if (unformat (i, "index %d", &fwd_entry_index))
19777         ;
19778       else
19779         break;
19780     }
19781
19782   if (~0 == fwd_entry_index)
19783     {
19784       errmsg ("no index specified!");
19785       return -99;
19786     }
19787
19788   if (!vam->json_output)
19789     {
19790       print (vam->ofp, "first line");
19791     }
19792
19793   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19794
19795   /* send it... */
19796   S (mp);
19797   /* Use a control ping for synchronization */
19798   MPING (CONTROL_PING, mp_ping);
19799   S (mp_ping);
19800
19801   /* Wait for a reply... */
19802   W (ret);
19803   return ret;
19804 }
19805
19806 static int
19807 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19808 {
19809   vl_api_one_get_map_request_itr_rlocs_t *mp;
19810   int ret;
19811
19812   if (!vam->json_output)
19813     {
19814       print (vam->ofp, "%=20s", "itr-rlocs:");
19815     }
19816
19817   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19818   /* send it... */
19819   S (mp);
19820   /* Wait for a reply... */
19821   W (ret);
19822   return ret;
19823 }
19824
19825 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19826
19827 static int
19828 api_af_packet_create (vat_main_t * vam)
19829 {
19830   unformat_input_t *i = vam->input;
19831   vl_api_af_packet_create_t *mp;
19832   u8 *host_if_name = 0;
19833   u8 hw_addr[6];
19834   u8 random_hw_addr = 1;
19835   int ret;
19836
19837   memset (hw_addr, 0, sizeof (hw_addr));
19838
19839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19840     {
19841       if (unformat (i, "name %s", &host_if_name))
19842         vec_add1 (host_if_name, 0);
19843       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19844         random_hw_addr = 0;
19845       else
19846         break;
19847     }
19848
19849   if (!vec_len (host_if_name))
19850     {
19851       errmsg ("host-interface name must be specified");
19852       return -99;
19853     }
19854
19855   if (vec_len (host_if_name) > 64)
19856     {
19857       errmsg ("host-interface name too long");
19858       return -99;
19859     }
19860
19861   M (AF_PACKET_CREATE, mp);
19862
19863   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19864   clib_memcpy (mp->hw_addr, hw_addr, 6);
19865   mp->use_random_hw_addr = random_hw_addr;
19866   vec_free (host_if_name);
19867
19868   S (mp);
19869
19870   /* *INDENT-OFF* */
19871   W2 (ret,
19872       ({
19873         if (ret == 0)
19874           fprintf (vam->ofp ? vam->ofp : stderr,
19875                    " new sw_if_index = %d\n", vam->sw_if_index);
19876       }));
19877   /* *INDENT-ON* */
19878   return ret;
19879 }
19880
19881 static int
19882 api_af_packet_delete (vat_main_t * vam)
19883 {
19884   unformat_input_t *i = vam->input;
19885   vl_api_af_packet_delete_t *mp;
19886   u8 *host_if_name = 0;
19887   int ret;
19888
19889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19890     {
19891       if (unformat (i, "name %s", &host_if_name))
19892         vec_add1 (host_if_name, 0);
19893       else
19894         break;
19895     }
19896
19897   if (!vec_len (host_if_name))
19898     {
19899       errmsg ("host-interface name must be specified");
19900       return -99;
19901     }
19902
19903   if (vec_len (host_if_name) > 64)
19904     {
19905       errmsg ("host-interface name too long");
19906       return -99;
19907     }
19908
19909   M (AF_PACKET_DELETE, mp);
19910
19911   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19912   vec_free (host_if_name);
19913
19914   S (mp);
19915   W (ret);
19916   return ret;
19917 }
19918
19919 static void vl_api_af_packet_details_t_handler
19920   (vl_api_af_packet_details_t * mp)
19921 {
19922   vat_main_t *vam = &vat_main;
19923
19924   print (vam->ofp, "%-16s %d",
19925          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19926 }
19927
19928 static void vl_api_af_packet_details_t_handler_json
19929   (vl_api_af_packet_details_t * mp)
19930 {
19931   vat_main_t *vam = &vat_main;
19932   vat_json_node_t *node = NULL;
19933
19934   if (VAT_JSON_ARRAY != vam->json_tree.type)
19935     {
19936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19937       vat_json_init_array (&vam->json_tree);
19938     }
19939   node = vat_json_array_add (&vam->json_tree);
19940
19941   vat_json_init_object (node);
19942   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19943   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19944 }
19945
19946 static int
19947 api_af_packet_dump (vat_main_t * vam)
19948 {
19949   vl_api_af_packet_dump_t *mp;
19950   vl_api_control_ping_t *mp_ping;
19951   int ret;
19952
19953   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19954   /* Get list of tap interfaces */
19955   M (AF_PACKET_DUMP, mp);
19956   S (mp);
19957
19958   /* Use a control ping for synchronization */
19959   MPING (CONTROL_PING, mp_ping);
19960   S (mp_ping);
19961
19962   W (ret);
19963   return ret;
19964 }
19965
19966 static int
19967 api_policer_add_del (vat_main_t * vam)
19968 {
19969   unformat_input_t *i = vam->input;
19970   vl_api_policer_add_del_t *mp;
19971   u8 is_add = 1;
19972   u8 *name = 0;
19973   u32 cir = 0;
19974   u32 eir = 0;
19975   u64 cb = 0;
19976   u64 eb = 0;
19977   u8 rate_type = 0;
19978   u8 round_type = 0;
19979   u8 type = 0;
19980   u8 color_aware = 0;
19981   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19982   int ret;
19983
19984   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19985   conform_action.dscp = 0;
19986   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19987   exceed_action.dscp = 0;
19988   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19989   violate_action.dscp = 0;
19990
19991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19992     {
19993       if (unformat (i, "del"))
19994         is_add = 0;
19995       else if (unformat (i, "name %s", &name))
19996         vec_add1 (name, 0);
19997       else if (unformat (i, "cir %u", &cir))
19998         ;
19999       else if (unformat (i, "eir %u", &eir))
20000         ;
20001       else if (unformat (i, "cb %u", &cb))
20002         ;
20003       else if (unformat (i, "eb %u", &eb))
20004         ;
20005       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20006                          &rate_type))
20007         ;
20008       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20009                          &round_type))
20010         ;
20011       else if (unformat (i, "type %U", unformat_policer_type, &type))
20012         ;
20013       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20014                          &conform_action))
20015         ;
20016       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20017                          &exceed_action))
20018         ;
20019       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20020                          &violate_action))
20021         ;
20022       else if (unformat (i, "color-aware"))
20023         color_aware = 1;
20024       else
20025         break;
20026     }
20027
20028   if (!vec_len (name))
20029     {
20030       errmsg ("policer name must be specified");
20031       return -99;
20032     }
20033
20034   if (vec_len (name) > 64)
20035     {
20036       errmsg ("policer name too long");
20037       return -99;
20038     }
20039
20040   M (POLICER_ADD_DEL, mp);
20041
20042   clib_memcpy (mp->name, name, vec_len (name));
20043   vec_free (name);
20044   mp->is_add = is_add;
20045   mp->cir = ntohl (cir);
20046   mp->eir = ntohl (eir);
20047   mp->cb = clib_net_to_host_u64 (cb);
20048   mp->eb = clib_net_to_host_u64 (eb);
20049   mp->rate_type = rate_type;
20050   mp->round_type = round_type;
20051   mp->type = type;
20052   mp->conform_action_type = conform_action.action_type;
20053   mp->conform_dscp = conform_action.dscp;
20054   mp->exceed_action_type = exceed_action.action_type;
20055   mp->exceed_dscp = exceed_action.dscp;
20056   mp->violate_action_type = violate_action.action_type;
20057   mp->violate_dscp = violate_action.dscp;
20058   mp->color_aware = color_aware;
20059
20060   S (mp);
20061   W (ret);
20062   return ret;
20063 }
20064
20065 static int
20066 api_policer_dump (vat_main_t * vam)
20067 {
20068   unformat_input_t *i = vam->input;
20069   vl_api_policer_dump_t *mp;
20070   vl_api_control_ping_t *mp_ping;
20071   u8 *match_name = 0;
20072   u8 match_name_valid = 0;
20073   int ret;
20074
20075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20076     {
20077       if (unformat (i, "name %s", &match_name))
20078         {
20079           vec_add1 (match_name, 0);
20080           match_name_valid = 1;
20081         }
20082       else
20083         break;
20084     }
20085
20086   M (POLICER_DUMP, mp);
20087   mp->match_name_valid = match_name_valid;
20088   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20089   vec_free (match_name);
20090   /* send it... */
20091   S (mp);
20092
20093   /* Use a control ping for synchronization */
20094   MPING (CONTROL_PING, mp_ping);
20095   S (mp_ping);
20096
20097   /* Wait for a reply... */
20098   W (ret);
20099   return ret;
20100 }
20101
20102 static int
20103 api_policer_classify_set_interface (vat_main_t * vam)
20104 {
20105   unformat_input_t *i = vam->input;
20106   vl_api_policer_classify_set_interface_t *mp;
20107   u32 sw_if_index;
20108   int sw_if_index_set;
20109   u32 ip4_table_index = ~0;
20110   u32 ip6_table_index = ~0;
20111   u32 l2_table_index = ~0;
20112   u8 is_add = 1;
20113   int ret;
20114
20115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20116     {
20117       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20118         sw_if_index_set = 1;
20119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20120         sw_if_index_set = 1;
20121       else if (unformat (i, "del"))
20122         is_add = 0;
20123       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20124         ;
20125       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20126         ;
20127       else if (unformat (i, "l2-table %d", &l2_table_index))
20128         ;
20129       else
20130         {
20131           clib_warning ("parse error '%U'", format_unformat_error, i);
20132           return -99;
20133         }
20134     }
20135
20136   if (sw_if_index_set == 0)
20137     {
20138       errmsg ("missing interface name or sw_if_index");
20139       return -99;
20140     }
20141
20142   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20143
20144   mp->sw_if_index = ntohl (sw_if_index);
20145   mp->ip4_table_index = ntohl (ip4_table_index);
20146   mp->ip6_table_index = ntohl (ip6_table_index);
20147   mp->l2_table_index = ntohl (l2_table_index);
20148   mp->is_add = is_add;
20149
20150   S (mp);
20151   W (ret);
20152   return ret;
20153 }
20154
20155 static int
20156 api_policer_classify_dump (vat_main_t * vam)
20157 {
20158   unformat_input_t *i = vam->input;
20159   vl_api_policer_classify_dump_t *mp;
20160   vl_api_control_ping_t *mp_ping;
20161   u8 type = POLICER_CLASSIFY_N_TABLES;
20162   int ret;
20163
20164   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20165     ;
20166   else
20167     {
20168       errmsg ("classify table type must be specified");
20169       return -99;
20170     }
20171
20172   if (!vam->json_output)
20173     {
20174       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20175     }
20176
20177   M (POLICER_CLASSIFY_DUMP, mp);
20178   mp->type = type;
20179   /* send it... */
20180   S (mp);
20181
20182   /* Use a control ping for synchronization */
20183   MPING (CONTROL_PING, mp_ping);
20184   S (mp_ping);
20185
20186   /* Wait for a reply... */
20187   W (ret);
20188   return ret;
20189 }
20190
20191 static int
20192 api_netmap_create (vat_main_t * vam)
20193 {
20194   unformat_input_t *i = vam->input;
20195   vl_api_netmap_create_t *mp;
20196   u8 *if_name = 0;
20197   u8 hw_addr[6];
20198   u8 random_hw_addr = 1;
20199   u8 is_pipe = 0;
20200   u8 is_master = 0;
20201   int ret;
20202
20203   memset (hw_addr, 0, sizeof (hw_addr));
20204
20205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20206     {
20207       if (unformat (i, "name %s", &if_name))
20208         vec_add1 (if_name, 0);
20209       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20210         random_hw_addr = 0;
20211       else if (unformat (i, "pipe"))
20212         is_pipe = 1;
20213       else if (unformat (i, "master"))
20214         is_master = 1;
20215       else if (unformat (i, "slave"))
20216         is_master = 0;
20217       else
20218         break;
20219     }
20220
20221   if (!vec_len (if_name))
20222     {
20223       errmsg ("interface name must be specified");
20224       return -99;
20225     }
20226
20227   if (vec_len (if_name) > 64)
20228     {
20229       errmsg ("interface name too long");
20230       return -99;
20231     }
20232
20233   M (NETMAP_CREATE, mp);
20234
20235   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20236   clib_memcpy (mp->hw_addr, hw_addr, 6);
20237   mp->use_random_hw_addr = random_hw_addr;
20238   mp->is_pipe = is_pipe;
20239   mp->is_master = is_master;
20240   vec_free (if_name);
20241
20242   S (mp);
20243   W (ret);
20244   return ret;
20245 }
20246
20247 static int
20248 api_netmap_delete (vat_main_t * vam)
20249 {
20250   unformat_input_t *i = vam->input;
20251   vl_api_netmap_delete_t *mp;
20252   u8 *if_name = 0;
20253   int ret;
20254
20255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20256     {
20257       if (unformat (i, "name %s", &if_name))
20258         vec_add1 (if_name, 0);
20259       else
20260         break;
20261     }
20262
20263   if (!vec_len (if_name))
20264     {
20265       errmsg ("interface name must be specified");
20266       return -99;
20267     }
20268
20269   if (vec_len (if_name) > 64)
20270     {
20271       errmsg ("interface name too long");
20272       return -99;
20273     }
20274
20275   M (NETMAP_DELETE, mp);
20276
20277   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20278   vec_free (if_name);
20279
20280   S (mp);
20281   W (ret);
20282   return ret;
20283 }
20284
20285 static void
20286 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20287 {
20288   if (fp->afi == IP46_TYPE_IP6)
20289     print (vam->ofp,
20290            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20291            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20292            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20293            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20294            format_ip6_address, fp->next_hop);
20295   else if (fp->afi == IP46_TYPE_IP4)
20296     print (vam->ofp,
20297            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20298            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20299            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20300            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20301            format_ip4_address, fp->next_hop);
20302 }
20303
20304 static void
20305 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20306                                  vl_api_fib_path_t * fp)
20307 {
20308   struct in_addr ip4;
20309   struct in6_addr ip6;
20310
20311   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20312   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20313   vat_json_object_add_uint (node, "is_local", fp->is_local);
20314   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20315   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20316   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20317   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20318   if (fp->afi == IP46_TYPE_IP4)
20319     {
20320       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20321       vat_json_object_add_ip4 (node, "next_hop", ip4);
20322     }
20323   else if (fp->afi == IP46_TYPE_IP6)
20324     {
20325       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20326       vat_json_object_add_ip6 (node, "next_hop", ip6);
20327     }
20328 }
20329
20330 static void
20331 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20332 {
20333   vat_main_t *vam = &vat_main;
20334   int count = ntohl (mp->mt_count);
20335   vl_api_fib_path_t *fp;
20336   i32 i;
20337
20338   print (vam->ofp, "[%d]: sw_if_index %d via:",
20339          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20340   fp = mp->mt_paths;
20341   for (i = 0; i < count; i++)
20342     {
20343       vl_api_mpls_fib_path_print (vam, fp);
20344       fp++;
20345     }
20346
20347   print (vam->ofp, "");
20348 }
20349
20350 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20351 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20352
20353 static void
20354 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20355 {
20356   vat_main_t *vam = &vat_main;
20357   vat_json_node_t *node = NULL;
20358   int count = ntohl (mp->mt_count);
20359   vl_api_fib_path_t *fp;
20360   i32 i;
20361
20362   if (VAT_JSON_ARRAY != vam->json_tree.type)
20363     {
20364       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20365       vat_json_init_array (&vam->json_tree);
20366     }
20367   node = vat_json_array_add (&vam->json_tree);
20368
20369   vat_json_init_object (node);
20370   vat_json_object_add_uint (node, "tunnel_index",
20371                             ntohl (mp->mt_tunnel_index));
20372   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20373
20374   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20375
20376   fp = mp->mt_paths;
20377   for (i = 0; i < count; i++)
20378     {
20379       vl_api_mpls_fib_path_json_print (node, fp);
20380       fp++;
20381     }
20382 }
20383
20384 static int
20385 api_mpls_tunnel_dump (vat_main_t * vam)
20386 {
20387   vl_api_mpls_tunnel_dump_t *mp;
20388   vl_api_control_ping_t *mp_ping;
20389   i32 index = -1;
20390   int ret;
20391
20392   /* Parse args required to build the message */
20393   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20394     {
20395       if (!unformat (vam->input, "tunnel_index %d", &index))
20396         {
20397           index = -1;
20398           break;
20399         }
20400     }
20401
20402   print (vam->ofp, "  tunnel_index %d", index);
20403
20404   M (MPLS_TUNNEL_DUMP, mp);
20405   mp->tunnel_index = htonl (index);
20406   S (mp);
20407
20408   /* Use a control ping for synchronization */
20409   MPING (CONTROL_PING, mp_ping);
20410   S (mp_ping);
20411
20412   W (ret);
20413   return ret;
20414 }
20415
20416 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20417 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20418
20419
20420 static void
20421 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20422 {
20423   vat_main_t *vam = &vat_main;
20424   int count = ntohl (mp->count);
20425   vl_api_fib_path_t *fp;
20426   int i;
20427
20428   print (vam->ofp,
20429          "table-id %d, label %u, ess_bit %u",
20430          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20431   fp = mp->path;
20432   for (i = 0; i < count; i++)
20433     {
20434       vl_api_mpls_fib_path_print (vam, fp);
20435       fp++;
20436     }
20437 }
20438
20439 static void vl_api_mpls_fib_details_t_handler_json
20440   (vl_api_mpls_fib_details_t * mp)
20441 {
20442   vat_main_t *vam = &vat_main;
20443   int count = ntohl (mp->count);
20444   vat_json_node_t *node = NULL;
20445   vl_api_fib_path_t *fp;
20446   int i;
20447
20448   if (VAT_JSON_ARRAY != vam->json_tree.type)
20449     {
20450       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20451       vat_json_init_array (&vam->json_tree);
20452     }
20453   node = vat_json_array_add (&vam->json_tree);
20454
20455   vat_json_init_object (node);
20456   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20457   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20458   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20459   vat_json_object_add_uint (node, "path_count", count);
20460   fp = mp->path;
20461   for (i = 0; i < count; i++)
20462     {
20463       vl_api_mpls_fib_path_json_print (node, fp);
20464       fp++;
20465     }
20466 }
20467
20468 static int
20469 api_mpls_fib_dump (vat_main_t * vam)
20470 {
20471   vl_api_mpls_fib_dump_t *mp;
20472   vl_api_control_ping_t *mp_ping;
20473   int ret;
20474
20475   M (MPLS_FIB_DUMP, mp);
20476   S (mp);
20477
20478   /* Use a control ping for synchronization */
20479   MPING (CONTROL_PING, mp_ping);
20480   S (mp_ping);
20481
20482   W (ret);
20483   return ret;
20484 }
20485
20486 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20487 #define vl_api_ip_fib_details_t_print vl_noop_handler
20488
20489 static void
20490 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20491 {
20492   vat_main_t *vam = &vat_main;
20493   int count = ntohl (mp->count);
20494   vl_api_fib_path_t *fp;
20495   int i;
20496
20497   print (vam->ofp,
20498          "table-id %d, prefix %U/%d",
20499          ntohl (mp->table_id), format_ip4_address, mp->address,
20500          mp->address_length);
20501   fp = mp->path;
20502   for (i = 0; i < count; i++)
20503     {
20504       if (fp->afi == IP46_TYPE_IP6)
20505         print (vam->ofp,
20506                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20507                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20508                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20509                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20510                format_ip6_address, fp->next_hop);
20511       else if (fp->afi == IP46_TYPE_IP4)
20512         print (vam->ofp,
20513                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20514                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20515                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20516                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20517                format_ip4_address, fp->next_hop);
20518       fp++;
20519     }
20520 }
20521
20522 static void vl_api_ip_fib_details_t_handler_json
20523   (vl_api_ip_fib_details_t * mp)
20524 {
20525   vat_main_t *vam = &vat_main;
20526   int count = ntohl (mp->count);
20527   vat_json_node_t *node = NULL;
20528   struct in_addr ip4;
20529   struct in6_addr ip6;
20530   vl_api_fib_path_t *fp;
20531   int i;
20532
20533   if (VAT_JSON_ARRAY != vam->json_tree.type)
20534     {
20535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20536       vat_json_init_array (&vam->json_tree);
20537     }
20538   node = vat_json_array_add (&vam->json_tree);
20539
20540   vat_json_init_object (node);
20541   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20542   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20543   vat_json_object_add_ip4 (node, "prefix", ip4);
20544   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20545   vat_json_object_add_uint (node, "path_count", count);
20546   fp = mp->path;
20547   for (i = 0; i < count; i++)
20548     {
20549       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20550       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20551       vat_json_object_add_uint (node, "is_local", fp->is_local);
20552       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20553       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20554       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20555       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20556       if (fp->afi == IP46_TYPE_IP4)
20557         {
20558           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20559           vat_json_object_add_ip4 (node, "next_hop", ip4);
20560         }
20561       else if (fp->afi == IP46_TYPE_IP6)
20562         {
20563           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20564           vat_json_object_add_ip6 (node, "next_hop", ip6);
20565         }
20566     }
20567 }
20568
20569 static int
20570 api_ip_fib_dump (vat_main_t * vam)
20571 {
20572   vl_api_ip_fib_dump_t *mp;
20573   vl_api_control_ping_t *mp_ping;
20574   int ret;
20575
20576   M (IP_FIB_DUMP, mp);
20577   S (mp);
20578
20579   /* Use a control ping for synchronization */
20580   MPING (CONTROL_PING, mp_ping);
20581   S (mp_ping);
20582
20583   W (ret);
20584   return ret;
20585 }
20586
20587 static int
20588 api_ip_mfib_dump (vat_main_t * vam)
20589 {
20590   vl_api_ip_mfib_dump_t *mp;
20591   vl_api_control_ping_t *mp_ping;
20592   int ret;
20593
20594   M (IP_MFIB_DUMP, mp);
20595   S (mp);
20596
20597   /* Use a control ping for synchronization */
20598   MPING (CONTROL_PING, mp_ping);
20599   S (mp_ping);
20600
20601   W (ret);
20602   return ret;
20603 }
20604
20605 static void vl_api_ip_neighbor_details_t_handler
20606   (vl_api_ip_neighbor_details_t * mp)
20607 {
20608   vat_main_t *vam = &vat_main;
20609
20610   print (vam->ofp, "%c %U %U",
20611          (mp->is_static) ? 'S' : 'D',
20612          format_ethernet_address, &mp->mac_address,
20613          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20614          &mp->ip_address);
20615 }
20616
20617 static void vl_api_ip_neighbor_details_t_handler_json
20618   (vl_api_ip_neighbor_details_t * mp)
20619 {
20620
20621   vat_main_t *vam = &vat_main;
20622   vat_json_node_t *node;
20623   struct in_addr ip4;
20624   struct in6_addr ip6;
20625
20626   if (VAT_JSON_ARRAY != vam->json_tree.type)
20627     {
20628       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20629       vat_json_init_array (&vam->json_tree);
20630     }
20631   node = vat_json_array_add (&vam->json_tree);
20632
20633   vat_json_init_object (node);
20634   vat_json_object_add_string_copy (node, "flag",
20635                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20636                                    "dynamic");
20637
20638   vat_json_object_add_string_copy (node, "link_layer",
20639                                    format (0, "%U", format_ethernet_address,
20640                                            &mp->mac_address));
20641
20642   if (mp->is_ipv6)
20643     {
20644       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20645       vat_json_object_add_ip6 (node, "ip_address", ip6);
20646     }
20647   else
20648     {
20649       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20650       vat_json_object_add_ip4 (node, "ip_address", ip4);
20651     }
20652 }
20653
20654 static int
20655 api_ip_neighbor_dump (vat_main_t * vam)
20656 {
20657   unformat_input_t *i = vam->input;
20658   vl_api_ip_neighbor_dump_t *mp;
20659   vl_api_control_ping_t *mp_ping;
20660   u8 is_ipv6 = 0;
20661   u32 sw_if_index = ~0;
20662   int ret;
20663
20664   /* Parse args required to build the message */
20665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20666     {
20667       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20668         ;
20669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20670         ;
20671       else if (unformat (i, "ip6"))
20672         is_ipv6 = 1;
20673       else
20674         break;
20675     }
20676
20677   if (sw_if_index == ~0)
20678     {
20679       errmsg ("missing interface name or sw_if_index");
20680       return -99;
20681     }
20682
20683   M (IP_NEIGHBOR_DUMP, mp);
20684   mp->is_ipv6 = (u8) is_ipv6;
20685   mp->sw_if_index = ntohl (sw_if_index);
20686   S (mp);
20687
20688   /* Use a control ping for synchronization */
20689   MPING (CONTROL_PING, mp_ping);
20690   S (mp_ping);
20691
20692   W (ret);
20693   return ret;
20694 }
20695
20696 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20697 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20698
20699 static void
20700 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20701 {
20702   vat_main_t *vam = &vat_main;
20703   int count = ntohl (mp->count);
20704   vl_api_fib_path_t *fp;
20705   int i;
20706
20707   print (vam->ofp,
20708          "table-id %d, prefix %U/%d",
20709          ntohl (mp->table_id), format_ip6_address, mp->address,
20710          mp->address_length);
20711   fp = mp->path;
20712   for (i = 0; i < count; i++)
20713     {
20714       if (fp->afi == IP46_TYPE_IP6)
20715         print (vam->ofp,
20716                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20717                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20718                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20719                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20720                format_ip6_address, fp->next_hop);
20721       else if (fp->afi == IP46_TYPE_IP4)
20722         print (vam->ofp,
20723                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20724                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20725                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20726                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20727                format_ip4_address, fp->next_hop);
20728       fp++;
20729     }
20730 }
20731
20732 static void vl_api_ip6_fib_details_t_handler_json
20733   (vl_api_ip6_fib_details_t * mp)
20734 {
20735   vat_main_t *vam = &vat_main;
20736   int count = ntohl (mp->count);
20737   vat_json_node_t *node = NULL;
20738   struct in_addr ip4;
20739   struct in6_addr ip6;
20740   vl_api_fib_path_t *fp;
20741   int i;
20742
20743   if (VAT_JSON_ARRAY != vam->json_tree.type)
20744     {
20745       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20746       vat_json_init_array (&vam->json_tree);
20747     }
20748   node = vat_json_array_add (&vam->json_tree);
20749
20750   vat_json_init_object (node);
20751   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20752   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20753   vat_json_object_add_ip6 (node, "prefix", ip6);
20754   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20755   vat_json_object_add_uint (node, "path_count", count);
20756   fp = mp->path;
20757   for (i = 0; i < count; i++)
20758     {
20759       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20760       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20761       vat_json_object_add_uint (node, "is_local", fp->is_local);
20762       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20763       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20764       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20765       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20766       if (fp->afi == IP46_TYPE_IP4)
20767         {
20768           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20769           vat_json_object_add_ip4 (node, "next_hop", ip4);
20770         }
20771       else if (fp->afi == IP46_TYPE_IP6)
20772         {
20773           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20774           vat_json_object_add_ip6 (node, "next_hop", ip6);
20775         }
20776     }
20777 }
20778
20779 static int
20780 api_ip6_fib_dump (vat_main_t * vam)
20781 {
20782   vl_api_ip6_fib_dump_t *mp;
20783   vl_api_control_ping_t *mp_ping;
20784   int ret;
20785
20786   M (IP6_FIB_DUMP, mp);
20787   S (mp);
20788
20789   /* Use a control ping for synchronization */
20790   MPING (CONTROL_PING, mp_ping);
20791   S (mp_ping);
20792
20793   W (ret);
20794   return ret;
20795 }
20796
20797 static int
20798 api_ip6_mfib_dump (vat_main_t * vam)
20799 {
20800   vl_api_ip6_mfib_dump_t *mp;
20801   vl_api_control_ping_t *mp_ping;
20802   int ret;
20803
20804   M (IP6_MFIB_DUMP, mp);
20805   S (mp);
20806
20807   /* Use a control ping for synchronization */
20808   MPING (CONTROL_PING, mp_ping);
20809   S (mp_ping);
20810
20811   W (ret);
20812   return ret;
20813 }
20814
20815 int
20816 api_classify_table_ids (vat_main_t * vam)
20817 {
20818   vl_api_classify_table_ids_t *mp;
20819   int ret;
20820
20821   /* Construct the API message */
20822   M (CLASSIFY_TABLE_IDS, mp);
20823   mp->context = 0;
20824
20825   S (mp);
20826   W (ret);
20827   return ret;
20828 }
20829
20830 int
20831 api_classify_table_by_interface (vat_main_t * vam)
20832 {
20833   unformat_input_t *input = vam->input;
20834   vl_api_classify_table_by_interface_t *mp;
20835
20836   u32 sw_if_index = ~0;
20837   int ret;
20838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20839     {
20840       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20841         ;
20842       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20843         ;
20844       else
20845         break;
20846     }
20847   if (sw_if_index == ~0)
20848     {
20849       errmsg ("missing interface name or sw_if_index");
20850       return -99;
20851     }
20852
20853   /* Construct the API message */
20854   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20855   mp->context = 0;
20856   mp->sw_if_index = ntohl (sw_if_index);
20857
20858   S (mp);
20859   W (ret);
20860   return ret;
20861 }
20862
20863 int
20864 api_classify_table_info (vat_main_t * vam)
20865 {
20866   unformat_input_t *input = vam->input;
20867   vl_api_classify_table_info_t *mp;
20868
20869   u32 table_id = ~0;
20870   int ret;
20871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20872     {
20873       if (unformat (input, "table_id %d", &table_id))
20874         ;
20875       else
20876         break;
20877     }
20878   if (table_id == ~0)
20879     {
20880       errmsg ("missing table id");
20881       return -99;
20882     }
20883
20884   /* Construct the API message */
20885   M (CLASSIFY_TABLE_INFO, mp);
20886   mp->context = 0;
20887   mp->table_id = ntohl (table_id);
20888
20889   S (mp);
20890   W (ret);
20891   return ret;
20892 }
20893
20894 int
20895 api_classify_session_dump (vat_main_t * vam)
20896 {
20897   unformat_input_t *input = vam->input;
20898   vl_api_classify_session_dump_t *mp;
20899   vl_api_control_ping_t *mp_ping;
20900
20901   u32 table_id = ~0;
20902   int ret;
20903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20904     {
20905       if (unformat (input, "table_id %d", &table_id))
20906         ;
20907       else
20908         break;
20909     }
20910   if (table_id == ~0)
20911     {
20912       errmsg ("missing table id");
20913       return -99;
20914     }
20915
20916   /* Construct the API message */
20917   M (CLASSIFY_SESSION_DUMP, mp);
20918   mp->context = 0;
20919   mp->table_id = ntohl (table_id);
20920   S (mp);
20921
20922   /* Use a control ping for synchronization */
20923   MPING (CONTROL_PING, mp_ping);
20924   S (mp_ping);
20925
20926   W (ret);
20927   return ret;
20928 }
20929
20930 static void
20931 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20932 {
20933   vat_main_t *vam = &vat_main;
20934
20935   print (vam->ofp, "collector_address %U, collector_port %d, "
20936          "src_address %U, vrf_id %d, path_mtu %u, "
20937          "template_interval %u, udp_checksum %d",
20938          format_ip4_address, mp->collector_address,
20939          ntohs (mp->collector_port),
20940          format_ip4_address, mp->src_address,
20941          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20942          ntohl (mp->template_interval), mp->udp_checksum);
20943
20944   vam->retval = 0;
20945   vam->result_ready = 1;
20946 }
20947
20948 static void
20949   vl_api_ipfix_exporter_details_t_handler_json
20950   (vl_api_ipfix_exporter_details_t * mp)
20951 {
20952   vat_main_t *vam = &vat_main;
20953   vat_json_node_t node;
20954   struct in_addr collector_address;
20955   struct in_addr src_address;
20956
20957   vat_json_init_object (&node);
20958   clib_memcpy (&collector_address, &mp->collector_address,
20959                sizeof (collector_address));
20960   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20961   vat_json_object_add_uint (&node, "collector_port",
20962                             ntohs (mp->collector_port));
20963   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20964   vat_json_object_add_ip4 (&node, "src_address", src_address);
20965   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20966   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20967   vat_json_object_add_uint (&node, "template_interval",
20968                             ntohl (mp->template_interval));
20969   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20970
20971   vat_json_print (vam->ofp, &node);
20972   vat_json_free (&node);
20973   vam->retval = 0;
20974   vam->result_ready = 1;
20975 }
20976
20977 int
20978 api_ipfix_exporter_dump (vat_main_t * vam)
20979 {
20980   vl_api_ipfix_exporter_dump_t *mp;
20981   int ret;
20982
20983   /* Construct the API message */
20984   M (IPFIX_EXPORTER_DUMP, mp);
20985   mp->context = 0;
20986
20987   S (mp);
20988   W (ret);
20989   return ret;
20990 }
20991
20992 static int
20993 api_ipfix_classify_stream_dump (vat_main_t * vam)
20994 {
20995   vl_api_ipfix_classify_stream_dump_t *mp;
20996   int ret;
20997
20998   /* Construct the API message */
20999   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21000   mp->context = 0;
21001
21002   S (mp);
21003   W (ret);
21004   return ret;
21005   /* NOTREACHED */
21006   return 0;
21007 }
21008
21009 static void
21010   vl_api_ipfix_classify_stream_details_t_handler
21011   (vl_api_ipfix_classify_stream_details_t * mp)
21012 {
21013   vat_main_t *vam = &vat_main;
21014   print (vam->ofp, "domain_id %d, src_port %d",
21015          ntohl (mp->domain_id), ntohs (mp->src_port));
21016   vam->retval = 0;
21017   vam->result_ready = 1;
21018 }
21019
21020 static void
21021   vl_api_ipfix_classify_stream_details_t_handler_json
21022   (vl_api_ipfix_classify_stream_details_t * mp)
21023 {
21024   vat_main_t *vam = &vat_main;
21025   vat_json_node_t node;
21026
21027   vat_json_init_object (&node);
21028   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21029   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21030
21031   vat_json_print (vam->ofp, &node);
21032   vat_json_free (&node);
21033   vam->retval = 0;
21034   vam->result_ready = 1;
21035 }
21036
21037 static int
21038 api_ipfix_classify_table_dump (vat_main_t * vam)
21039 {
21040   vl_api_ipfix_classify_table_dump_t *mp;
21041   vl_api_control_ping_t *mp_ping;
21042   int ret;
21043
21044   if (!vam->json_output)
21045     {
21046       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21047              "transport_protocol");
21048     }
21049
21050   /* Construct the API message */
21051   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21052
21053   /* send it... */
21054   S (mp);
21055
21056   /* Use a control ping for synchronization */
21057   MPING (CONTROL_PING, mp_ping);
21058   S (mp_ping);
21059
21060   W (ret);
21061   return ret;
21062 }
21063
21064 static void
21065   vl_api_ipfix_classify_table_details_t_handler
21066   (vl_api_ipfix_classify_table_details_t * mp)
21067 {
21068   vat_main_t *vam = &vat_main;
21069   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21070          mp->transport_protocol);
21071 }
21072
21073 static void
21074   vl_api_ipfix_classify_table_details_t_handler_json
21075   (vl_api_ipfix_classify_table_details_t * mp)
21076 {
21077   vat_json_node_t *node = NULL;
21078   vat_main_t *vam = &vat_main;
21079
21080   if (VAT_JSON_ARRAY != vam->json_tree.type)
21081     {
21082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21083       vat_json_init_array (&vam->json_tree);
21084     }
21085
21086   node = vat_json_array_add (&vam->json_tree);
21087   vat_json_init_object (node);
21088
21089   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21090   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21091   vat_json_object_add_uint (node, "transport_protocol",
21092                             mp->transport_protocol);
21093 }
21094
21095 static int
21096 api_sw_interface_span_enable_disable (vat_main_t * vam)
21097 {
21098   unformat_input_t *i = vam->input;
21099   vl_api_sw_interface_span_enable_disable_t *mp;
21100   u32 src_sw_if_index = ~0;
21101   u32 dst_sw_if_index = ~0;
21102   u8 state = 3;
21103   int ret;
21104   u8 is_l2 = 0;
21105
21106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21107     {
21108       if (unformat
21109           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21110         ;
21111       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21112         ;
21113       else
21114         if (unformat
21115             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21116         ;
21117       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21118         ;
21119       else if (unformat (i, "disable"))
21120         state = 0;
21121       else if (unformat (i, "rx"))
21122         state = 1;
21123       else if (unformat (i, "tx"))
21124         state = 2;
21125       else if (unformat (i, "both"))
21126         state = 3;
21127       else if (unformat (i, "l2"))
21128         is_l2 = 1;
21129       else
21130         break;
21131     }
21132
21133   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21134
21135   mp->sw_if_index_from = htonl (src_sw_if_index);
21136   mp->sw_if_index_to = htonl (dst_sw_if_index);
21137   mp->state = state;
21138   mp->is_l2 = is_l2;
21139
21140   S (mp);
21141   W (ret);
21142   return ret;
21143 }
21144
21145 static void
21146 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21147                                             * mp)
21148 {
21149   vat_main_t *vam = &vat_main;
21150   u8 *sw_if_from_name = 0;
21151   u8 *sw_if_to_name = 0;
21152   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21153   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21154   char *states[] = { "none", "rx", "tx", "both" };
21155   hash_pair_t *p;
21156
21157   /* *INDENT-OFF* */
21158   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21159   ({
21160     if ((u32) p->value[0] == sw_if_index_from)
21161       {
21162         sw_if_from_name = (u8 *)(p->key);
21163         if (sw_if_to_name)
21164           break;
21165       }
21166     if ((u32) p->value[0] == sw_if_index_to)
21167       {
21168         sw_if_to_name = (u8 *)(p->key);
21169         if (sw_if_from_name)
21170           break;
21171       }
21172   }));
21173   /* *INDENT-ON* */
21174   print (vam->ofp, "%20s => %20s (%s) %s",
21175          sw_if_from_name, sw_if_to_name, states[mp->state],
21176          mp->is_l2 ? "l2" : "device");
21177 }
21178
21179 static void
21180   vl_api_sw_interface_span_details_t_handler_json
21181   (vl_api_sw_interface_span_details_t * mp)
21182 {
21183   vat_main_t *vam = &vat_main;
21184   vat_json_node_t *node = NULL;
21185   u8 *sw_if_from_name = 0;
21186   u8 *sw_if_to_name = 0;
21187   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21188   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21189   hash_pair_t *p;
21190
21191   /* *INDENT-OFF* */
21192   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21193   ({
21194     if ((u32) p->value[0] == sw_if_index_from)
21195       {
21196         sw_if_from_name = (u8 *)(p->key);
21197         if (sw_if_to_name)
21198           break;
21199       }
21200     if ((u32) p->value[0] == sw_if_index_to)
21201       {
21202         sw_if_to_name = (u8 *)(p->key);
21203         if (sw_if_from_name)
21204           break;
21205       }
21206   }));
21207   /* *INDENT-ON* */
21208
21209   if (VAT_JSON_ARRAY != vam->json_tree.type)
21210     {
21211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21212       vat_json_init_array (&vam->json_tree);
21213     }
21214   node = vat_json_array_add (&vam->json_tree);
21215
21216   vat_json_init_object (node);
21217   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21218   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21219   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21220   if (0 != sw_if_to_name)
21221     {
21222       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21223     }
21224   vat_json_object_add_uint (node, "state", mp->state);
21225   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21226 }
21227
21228 static int
21229 api_sw_interface_span_dump (vat_main_t * vam)
21230 {
21231   unformat_input_t *input = vam->input;
21232   vl_api_sw_interface_span_dump_t *mp;
21233   vl_api_control_ping_t *mp_ping;
21234   u8 is_l2 = 0;
21235   int ret;
21236
21237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21238     {
21239       if (unformat (input, "l2"))
21240         is_l2 = 1;
21241       else
21242         break;
21243     }
21244
21245   M (SW_INTERFACE_SPAN_DUMP, mp);
21246   mp->is_l2 = is_l2;
21247   S (mp);
21248
21249   /* Use a control ping for synchronization */
21250   MPING (CONTROL_PING, mp_ping);
21251   S (mp_ping);
21252
21253   W (ret);
21254   return ret;
21255 }
21256
21257 int
21258 api_pg_create_interface (vat_main_t * vam)
21259 {
21260   unformat_input_t *input = vam->input;
21261   vl_api_pg_create_interface_t *mp;
21262
21263   u32 if_id = ~0;
21264   int ret;
21265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21266     {
21267       if (unformat (input, "if_id %d", &if_id))
21268         ;
21269       else
21270         break;
21271     }
21272   if (if_id == ~0)
21273     {
21274       errmsg ("missing pg interface index");
21275       return -99;
21276     }
21277
21278   /* Construct the API message */
21279   M (PG_CREATE_INTERFACE, mp);
21280   mp->context = 0;
21281   mp->interface_id = ntohl (if_id);
21282
21283   S (mp);
21284   W (ret);
21285   return ret;
21286 }
21287
21288 int
21289 api_pg_capture (vat_main_t * vam)
21290 {
21291   unformat_input_t *input = vam->input;
21292   vl_api_pg_capture_t *mp;
21293
21294   u32 if_id = ~0;
21295   u8 enable = 1;
21296   u32 count = 1;
21297   u8 pcap_file_set = 0;
21298   u8 *pcap_file = 0;
21299   int ret;
21300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21301     {
21302       if (unformat (input, "if_id %d", &if_id))
21303         ;
21304       else if (unformat (input, "pcap %s", &pcap_file))
21305         pcap_file_set = 1;
21306       else if (unformat (input, "count %d", &count))
21307         ;
21308       else if (unformat (input, "disable"))
21309         enable = 0;
21310       else
21311         break;
21312     }
21313   if (if_id == ~0)
21314     {
21315       errmsg ("missing pg interface index");
21316       return -99;
21317     }
21318   if (pcap_file_set > 0)
21319     {
21320       if (vec_len (pcap_file) > 255)
21321         {
21322           errmsg ("pcap file name is too long");
21323           return -99;
21324         }
21325     }
21326
21327   u32 name_len = vec_len (pcap_file);
21328   /* Construct the API message */
21329   M (PG_CAPTURE, mp);
21330   mp->context = 0;
21331   mp->interface_id = ntohl (if_id);
21332   mp->is_enabled = enable;
21333   mp->count = ntohl (count);
21334   mp->pcap_name_length = ntohl (name_len);
21335   if (pcap_file_set != 0)
21336     {
21337       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21338     }
21339   vec_free (pcap_file);
21340
21341   S (mp);
21342   W (ret);
21343   return ret;
21344 }
21345
21346 int
21347 api_pg_enable_disable (vat_main_t * vam)
21348 {
21349   unformat_input_t *input = vam->input;
21350   vl_api_pg_enable_disable_t *mp;
21351
21352   u8 enable = 1;
21353   u8 stream_name_set = 0;
21354   u8 *stream_name = 0;
21355   int ret;
21356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21357     {
21358       if (unformat (input, "stream %s", &stream_name))
21359         stream_name_set = 1;
21360       else if (unformat (input, "disable"))
21361         enable = 0;
21362       else
21363         break;
21364     }
21365
21366   if (stream_name_set > 0)
21367     {
21368       if (vec_len (stream_name) > 255)
21369         {
21370           errmsg ("stream name too long");
21371           return -99;
21372         }
21373     }
21374
21375   u32 name_len = vec_len (stream_name);
21376   /* Construct the API message */
21377   M (PG_ENABLE_DISABLE, mp);
21378   mp->context = 0;
21379   mp->is_enabled = enable;
21380   if (stream_name_set != 0)
21381     {
21382       mp->stream_name_length = ntohl (name_len);
21383       clib_memcpy (mp->stream_name, stream_name, name_len);
21384     }
21385   vec_free (stream_name);
21386
21387   S (mp);
21388   W (ret);
21389   return ret;
21390 }
21391
21392 int
21393 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21394 {
21395   unformat_input_t *input = vam->input;
21396   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21397
21398   u16 *low_ports = 0;
21399   u16 *high_ports = 0;
21400   u16 this_low;
21401   u16 this_hi;
21402   ip4_address_t ip4_addr;
21403   ip6_address_t ip6_addr;
21404   u32 length;
21405   u32 tmp, tmp2;
21406   u8 prefix_set = 0;
21407   u32 vrf_id = ~0;
21408   u8 is_add = 1;
21409   u8 is_ipv6 = 0;
21410   int ret;
21411
21412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21413     {
21414       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21415         {
21416           prefix_set = 1;
21417         }
21418       else
21419         if (unformat
21420             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21421         {
21422           prefix_set = 1;
21423           is_ipv6 = 1;
21424         }
21425       else if (unformat (input, "vrf %d", &vrf_id))
21426         ;
21427       else if (unformat (input, "del"))
21428         is_add = 0;
21429       else if (unformat (input, "port %d", &tmp))
21430         {
21431           if (tmp == 0 || tmp > 65535)
21432             {
21433               errmsg ("port %d out of range", tmp);
21434               return -99;
21435             }
21436           this_low = tmp;
21437           this_hi = this_low + 1;
21438           vec_add1 (low_ports, this_low);
21439           vec_add1 (high_ports, this_hi);
21440         }
21441       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21442         {
21443           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21444             {
21445               errmsg ("incorrect range parameters");
21446               return -99;
21447             }
21448           this_low = tmp;
21449           /* Note: in debug CLI +1 is added to high before
21450              passing to real fn that does "the work"
21451              (ip_source_and_port_range_check_add_del).
21452              This fn is a wrapper around the binary API fn a
21453              control plane will call, which expects this increment
21454              to have occurred. Hence letting the binary API control
21455              plane fn do the increment for consistency between VAT
21456              and other control planes.
21457            */
21458           this_hi = tmp2;
21459           vec_add1 (low_ports, this_low);
21460           vec_add1 (high_ports, this_hi);
21461         }
21462       else
21463         break;
21464     }
21465
21466   if (prefix_set == 0)
21467     {
21468       errmsg ("<address>/<mask> not specified");
21469       return -99;
21470     }
21471
21472   if (vrf_id == ~0)
21473     {
21474       errmsg ("VRF ID required, not specified");
21475       return -99;
21476     }
21477
21478   if (vrf_id == 0)
21479     {
21480       errmsg
21481         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21482       return -99;
21483     }
21484
21485   if (vec_len (low_ports) == 0)
21486     {
21487       errmsg ("At least one port or port range required");
21488       return -99;
21489     }
21490
21491   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21492
21493   mp->is_add = is_add;
21494
21495   if (is_ipv6)
21496     {
21497       mp->is_ipv6 = 1;
21498       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21499     }
21500   else
21501     {
21502       mp->is_ipv6 = 0;
21503       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21504     }
21505
21506   mp->mask_length = length;
21507   mp->number_of_ranges = vec_len (low_ports);
21508
21509   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21510   vec_free (low_ports);
21511
21512   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21513   vec_free (high_ports);
21514
21515   mp->vrf_id = ntohl (vrf_id);
21516
21517   S (mp);
21518   W (ret);
21519   return ret;
21520 }
21521
21522 int
21523 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21524 {
21525   unformat_input_t *input = vam->input;
21526   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21527   u32 sw_if_index = ~0;
21528   int vrf_set = 0;
21529   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21530   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21531   u8 is_add = 1;
21532   int ret;
21533
21534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21535     {
21536       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21537         ;
21538       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21539         ;
21540       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21541         vrf_set = 1;
21542       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21543         vrf_set = 1;
21544       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21545         vrf_set = 1;
21546       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21547         vrf_set = 1;
21548       else if (unformat (input, "del"))
21549         is_add = 0;
21550       else
21551         break;
21552     }
21553
21554   if (sw_if_index == ~0)
21555     {
21556       errmsg ("Interface required but not specified");
21557       return -99;
21558     }
21559
21560   if (vrf_set == 0)
21561     {
21562       errmsg ("VRF ID required but not specified");
21563       return -99;
21564     }
21565
21566   if (tcp_out_vrf_id == 0
21567       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21568     {
21569       errmsg
21570         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21571       return -99;
21572     }
21573
21574   /* Construct the API message */
21575   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21576
21577   mp->sw_if_index = ntohl (sw_if_index);
21578   mp->is_add = is_add;
21579   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21580   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21581   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21582   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21583
21584   /* send it... */
21585   S (mp);
21586
21587   /* Wait for a reply... */
21588   W (ret);
21589   return ret;
21590 }
21591
21592 static int
21593 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21594 {
21595   unformat_input_t *i = vam->input;
21596   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21597   u32 local_sa_id = 0;
21598   u32 remote_sa_id = 0;
21599   ip4_address_t src_address;
21600   ip4_address_t dst_address;
21601   u8 is_add = 1;
21602   int ret;
21603
21604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21605     {
21606       if (unformat (i, "local_sa %d", &local_sa_id))
21607         ;
21608       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21609         ;
21610       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21611         ;
21612       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21613         ;
21614       else if (unformat (i, "del"))
21615         is_add = 0;
21616       else
21617         {
21618           clib_warning ("parse error '%U'", format_unformat_error, i);
21619           return -99;
21620         }
21621     }
21622
21623   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21624
21625   mp->local_sa_id = ntohl (local_sa_id);
21626   mp->remote_sa_id = ntohl (remote_sa_id);
21627   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21628   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21629   mp->is_add = is_add;
21630
21631   S (mp);
21632   W (ret);
21633   return ret;
21634 }
21635
21636 static int
21637 api_punt (vat_main_t * vam)
21638 {
21639   unformat_input_t *i = vam->input;
21640   vl_api_punt_t *mp;
21641   u32 ipv = ~0;
21642   u32 protocol = ~0;
21643   u32 port = ~0;
21644   int is_add = 1;
21645   int ret;
21646
21647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21648     {
21649       if (unformat (i, "ip %d", &ipv))
21650         ;
21651       else if (unformat (i, "protocol %d", &protocol))
21652         ;
21653       else if (unformat (i, "port %d", &port))
21654         ;
21655       else if (unformat (i, "del"))
21656         is_add = 0;
21657       else
21658         {
21659           clib_warning ("parse error '%U'", format_unformat_error, i);
21660           return -99;
21661         }
21662     }
21663
21664   M (PUNT, mp);
21665
21666   mp->is_add = (u8) is_add;
21667   mp->ipv = (u8) ipv;
21668   mp->l4_protocol = (u8) protocol;
21669   mp->l4_port = htons ((u16) port);
21670
21671   S (mp);
21672   W (ret);
21673   return ret;
21674 }
21675
21676 static void vl_api_ipsec_gre_tunnel_details_t_handler
21677   (vl_api_ipsec_gre_tunnel_details_t * mp)
21678 {
21679   vat_main_t *vam = &vat_main;
21680
21681   print (vam->ofp, "%11d%15U%15U%14d%14d",
21682          ntohl (mp->sw_if_index),
21683          format_ip4_address, &mp->src_address,
21684          format_ip4_address, &mp->dst_address,
21685          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21686 }
21687
21688 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21689   (vl_api_ipsec_gre_tunnel_details_t * mp)
21690 {
21691   vat_main_t *vam = &vat_main;
21692   vat_json_node_t *node = NULL;
21693   struct in_addr ip4;
21694
21695   if (VAT_JSON_ARRAY != vam->json_tree.type)
21696     {
21697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21698       vat_json_init_array (&vam->json_tree);
21699     }
21700   node = vat_json_array_add (&vam->json_tree);
21701
21702   vat_json_init_object (node);
21703   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21704   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21705   vat_json_object_add_ip4 (node, "src_address", ip4);
21706   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21707   vat_json_object_add_ip4 (node, "dst_address", ip4);
21708   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21709   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21710 }
21711
21712 static int
21713 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21714 {
21715   unformat_input_t *i = vam->input;
21716   vl_api_ipsec_gre_tunnel_dump_t *mp;
21717   vl_api_control_ping_t *mp_ping;
21718   u32 sw_if_index;
21719   u8 sw_if_index_set = 0;
21720   int ret;
21721
21722   /* Parse args required to build the message */
21723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21724     {
21725       if (unformat (i, "sw_if_index %d", &sw_if_index))
21726         sw_if_index_set = 1;
21727       else
21728         break;
21729     }
21730
21731   if (sw_if_index_set == 0)
21732     {
21733       sw_if_index = ~0;
21734     }
21735
21736   if (!vam->json_output)
21737     {
21738       print (vam->ofp, "%11s%15s%15s%14s%14s",
21739              "sw_if_index", "src_address", "dst_address",
21740              "local_sa_id", "remote_sa_id");
21741     }
21742
21743   /* Get list of gre-tunnel interfaces */
21744   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21745
21746   mp->sw_if_index = htonl (sw_if_index);
21747
21748   S (mp);
21749
21750   /* Use a control ping for synchronization */
21751   MPING (CONTROL_PING, mp_ping);
21752   S (mp_ping);
21753
21754   W (ret);
21755   return ret;
21756 }
21757
21758 static int
21759 api_delete_subif (vat_main_t * vam)
21760 {
21761   unformat_input_t *i = vam->input;
21762   vl_api_delete_subif_t *mp;
21763   u32 sw_if_index = ~0;
21764   int ret;
21765
21766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21767     {
21768       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21769         ;
21770       if (unformat (i, "sw_if_index %d", &sw_if_index))
21771         ;
21772       else
21773         break;
21774     }
21775
21776   if (sw_if_index == ~0)
21777     {
21778       errmsg ("missing sw_if_index");
21779       return -99;
21780     }
21781
21782   /* Construct the API message */
21783   M (DELETE_SUBIF, mp);
21784   mp->sw_if_index = ntohl (sw_if_index);
21785
21786   S (mp);
21787   W (ret);
21788   return ret;
21789 }
21790
21791 #define foreach_pbb_vtr_op      \
21792 _("disable",  L2_VTR_DISABLED)  \
21793 _("pop",  L2_VTR_POP_2)         \
21794 _("push",  L2_VTR_PUSH_2)
21795
21796 static int
21797 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21798 {
21799   unformat_input_t *i = vam->input;
21800   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21801   u32 sw_if_index = ~0, vtr_op = ~0;
21802   u16 outer_tag = ~0;
21803   u8 dmac[6], smac[6];
21804   u8 dmac_set = 0, smac_set = 0;
21805   u16 vlanid = 0;
21806   u32 sid = ~0;
21807   u32 tmp;
21808   int ret;
21809
21810   /* Shut up coverity */
21811   memset (dmac, 0, sizeof (dmac));
21812   memset (smac, 0, sizeof (smac));
21813
21814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21815     {
21816       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21817         ;
21818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21819         ;
21820       else if (unformat (i, "vtr_op %d", &vtr_op))
21821         ;
21822 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21823       foreach_pbb_vtr_op
21824 #undef _
21825         else if (unformat (i, "translate_pbb_stag"))
21826         {
21827           if (unformat (i, "%d", &tmp))
21828             {
21829               vtr_op = L2_VTR_TRANSLATE_2_1;
21830               outer_tag = tmp;
21831             }
21832           else
21833             {
21834               errmsg
21835                 ("translate_pbb_stag operation requires outer tag definition");
21836               return -99;
21837             }
21838         }
21839       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21840         dmac_set++;
21841       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21842         smac_set++;
21843       else if (unformat (i, "sid %d", &sid))
21844         ;
21845       else if (unformat (i, "vlanid %d", &tmp))
21846         vlanid = tmp;
21847       else
21848         {
21849           clib_warning ("parse error '%U'", format_unformat_error, i);
21850           return -99;
21851         }
21852     }
21853
21854   if ((sw_if_index == ~0) || (vtr_op == ~0))
21855     {
21856       errmsg ("missing sw_if_index or vtr operation");
21857       return -99;
21858     }
21859   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21860       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21861     {
21862       errmsg
21863         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21864       return -99;
21865     }
21866
21867   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21868   mp->sw_if_index = ntohl (sw_if_index);
21869   mp->vtr_op = ntohl (vtr_op);
21870   mp->outer_tag = ntohs (outer_tag);
21871   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21872   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21873   mp->b_vlanid = ntohs (vlanid);
21874   mp->i_sid = ntohl (sid);
21875
21876   S (mp);
21877   W (ret);
21878   return ret;
21879 }
21880
21881 static int
21882 api_flow_classify_set_interface (vat_main_t * vam)
21883 {
21884   unformat_input_t *i = vam->input;
21885   vl_api_flow_classify_set_interface_t *mp;
21886   u32 sw_if_index;
21887   int sw_if_index_set;
21888   u32 ip4_table_index = ~0;
21889   u32 ip6_table_index = ~0;
21890   u8 is_add = 1;
21891   int ret;
21892
21893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21894     {
21895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21896         sw_if_index_set = 1;
21897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21898         sw_if_index_set = 1;
21899       else if (unformat (i, "del"))
21900         is_add = 0;
21901       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21902         ;
21903       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21904         ;
21905       else
21906         {
21907           clib_warning ("parse error '%U'", format_unformat_error, i);
21908           return -99;
21909         }
21910     }
21911
21912   if (sw_if_index_set == 0)
21913     {
21914       errmsg ("missing interface name or sw_if_index");
21915       return -99;
21916     }
21917
21918   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21919
21920   mp->sw_if_index = ntohl (sw_if_index);
21921   mp->ip4_table_index = ntohl (ip4_table_index);
21922   mp->ip6_table_index = ntohl (ip6_table_index);
21923   mp->is_add = is_add;
21924
21925   S (mp);
21926   W (ret);
21927   return ret;
21928 }
21929
21930 static int
21931 api_flow_classify_dump (vat_main_t * vam)
21932 {
21933   unformat_input_t *i = vam->input;
21934   vl_api_flow_classify_dump_t *mp;
21935   vl_api_control_ping_t *mp_ping;
21936   u8 type = FLOW_CLASSIFY_N_TABLES;
21937   int ret;
21938
21939   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21940     ;
21941   else
21942     {
21943       errmsg ("classify table type must be specified");
21944       return -99;
21945     }
21946
21947   if (!vam->json_output)
21948     {
21949       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21950     }
21951
21952   M (FLOW_CLASSIFY_DUMP, mp);
21953   mp->type = type;
21954   /* send it... */
21955   S (mp);
21956
21957   /* Use a control ping for synchronization */
21958   MPING (CONTROL_PING, mp_ping);
21959   S (mp_ping);
21960
21961   /* Wait for a reply... */
21962   W (ret);
21963   return ret;
21964 }
21965
21966 static int
21967 api_feature_enable_disable (vat_main_t * vam)
21968 {
21969   unformat_input_t *i = vam->input;
21970   vl_api_feature_enable_disable_t *mp;
21971   u8 *arc_name = 0;
21972   u8 *feature_name = 0;
21973   u32 sw_if_index = ~0;
21974   u8 enable = 1;
21975   int ret;
21976
21977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21978     {
21979       if (unformat (i, "arc_name %s", &arc_name))
21980         ;
21981       else if (unformat (i, "feature_name %s", &feature_name))
21982         ;
21983       else
21984         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21985         ;
21986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21987         ;
21988       else if (unformat (i, "disable"))
21989         enable = 0;
21990       else
21991         break;
21992     }
21993
21994   if (arc_name == 0)
21995     {
21996       errmsg ("missing arc name");
21997       return -99;
21998     }
21999   if (vec_len (arc_name) > 63)
22000     {
22001       errmsg ("arc name too long");
22002     }
22003
22004   if (feature_name == 0)
22005     {
22006       errmsg ("missing feature name");
22007       return -99;
22008     }
22009   if (vec_len (feature_name) > 63)
22010     {
22011       errmsg ("feature name too long");
22012     }
22013
22014   if (sw_if_index == ~0)
22015     {
22016       errmsg ("missing interface name or sw_if_index");
22017       return -99;
22018     }
22019
22020   /* Construct the API message */
22021   M (FEATURE_ENABLE_DISABLE, mp);
22022   mp->sw_if_index = ntohl (sw_if_index);
22023   mp->enable = enable;
22024   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22025   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22026   vec_free (arc_name);
22027   vec_free (feature_name);
22028
22029   S (mp);
22030   W (ret);
22031   return ret;
22032 }
22033
22034 static int
22035 api_sw_interface_tag_add_del (vat_main_t * vam)
22036 {
22037   unformat_input_t *i = vam->input;
22038   vl_api_sw_interface_tag_add_del_t *mp;
22039   u32 sw_if_index = ~0;
22040   u8 *tag = 0;
22041   u8 enable = 1;
22042   int ret;
22043
22044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22045     {
22046       if (unformat (i, "tag %s", &tag))
22047         ;
22048       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22049         ;
22050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22051         ;
22052       else if (unformat (i, "del"))
22053         enable = 0;
22054       else
22055         break;
22056     }
22057
22058   if (sw_if_index == ~0)
22059     {
22060       errmsg ("missing interface name or sw_if_index");
22061       return -99;
22062     }
22063
22064   if (enable && (tag == 0))
22065     {
22066       errmsg ("no tag specified");
22067       return -99;
22068     }
22069
22070   /* Construct the API message */
22071   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22072   mp->sw_if_index = ntohl (sw_if_index);
22073   mp->is_add = enable;
22074   if (enable)
22075     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22076   vec_free (tag);
22077
22078   S (mp);
22079   W (ret);
22080   return ret;
22081 }
22082
22083 static void vl_api_l2_xconnect_details_t_handler
22084   (vl_api_l2_xconnect_details_t * mp)
22085 {
22086   vat_main_t *vam = &vat_main;
22087
22088   print (vam->ofp, "%15d%15d",
22089          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22090 }
22091
22092 static void vl_api_l2_xconnect_details_t_handler_json
22093   (vl_api_l2_xconnect_details_t * mp)
22094 {
22095   vat_main_t *vam = &vat_main;
22096   vat_json_node_t *node = NULL;
22097
22098   if (VAT_JSON_ARRAY != vam->json_tree.type)
22099     {
22100       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22101       vat_json_init_array (&vam->json_tree);
22102     }
22103   node = vat_json_array_add (&vam->json_tree);
22104
22105   vat_json_init_object (node);
22106   vat_json_object_add_uint (node, "rx_sw_if_index",
22107                             ntohl (mp->rx_sw_if_index));
22108   vat_json_object_add_uint (node, "tx_sw_if_index",
22109                             ntohl (mp->tx_sw_if_index));
22110 }
22111
22112 static int
22113 api_l2_xconnect_dump (vat_main_t * vam)
22114 {
22115   vl_api_l2_xconnect_dump_t *mp;
22116   vl_api_control_ping_t *mp_ping;
22117   int ret;
22118
22119   if (!vam->json_output)
22120     {
22121       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22122     }
22123
22124   M (L2_XCONNECT_DUMP, mp);
22125
22126   S (mp);
22127
22128   /* Use a control ping for synchronization */
22129   MPING (CONTROL_PING, mp_ping);
22130   S (mp_ping);
22131
22132   W (ret);
22133   return ret;
22134 }
22135
22136 static int
22137 api_hw_interface_set_mtu (vat_main_t * vam)
22138 {
22139   unformat_input_t *i = vam->input;
22140   vl_api_hw_interface_set_mtu_t *mp;
22141   u32 sw_if_index = ~0;
22142   u32 mtu = 0;
22143   int ret;
22144
22145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22146     {
22147       if (unformat (i, "mtu %d", &mtu))
22148         ;
22149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22150         ;
22151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22152         ;
22153       else
22154         break;
22155     }
22156
22157   if (sw_if_index == ~0)
22158     {
22159       errmsg ("missing interface name or sw_if_index");
22160       return -99;
22161     }
22162
22163   if (mtu == 0)
22164     {
22165       errmsg ("no mtu specified");
22166       return -99;
22167     }
22168
22169   /* Construct the API message */
22170   M (HW_INTERFACE_SET_MTU, mp);
22171   mp->sw_if_index = ntohl (sw_if_index);
22172   mp->mtu = ntohs ((u16) mtu);
22173
22174   S (mp);
22175   W (ret);
22176   return ret;
22177 }
22178
22179 static int
22180 api_p2p_ethernet_add (vat_main_t * vam)
22181 {
22182   unformat_input_t *i = vam->input;
22183   vl_api_p2p_ethernet_add_t *mp;
22184   u32 parent_if_index = ~0;
22185   u32 sub_id = ~0;
22186   u8 remote_mac[6];
22187   u8 mac_set = 0;
22188   int ret;
22189
22190   memset (remote_mac, 0, sizeof (remote_mac));
22191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22192     {
22193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22194         ;
22195       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22196         ;
22197       else
22198         if (unformat
22199             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22200         mac_set++;
22201       else if (unformat (i, "sub_id %d", &sub_id))
22202         ;
22203       else
22204         {
22205           clib_warning ("parse error '%U'", format_unformat_error, i);
22206           return -99;
22207         }
22208     }
22209
22210   if (parent_if_index == ~0)
22211     {
22212       errmsg ("missing interface name or sw_if_index");
22213       return -99;
22214     }
22215   if (mac_set == 0)
22216     {
22217       errmsg ("missing remote mac address");
22218       return -99;
22219     }
22220   if (sub_id == ~0)
22221     {
22222       errmsg ("missing sub-interface id");
22223       return -99;
22224     }
22225
22226   M (P2P_ETHERNET_ADD, mp);
22227   mp->parent_if_index = ntohl (parent_if_index);
22228   mp->subif_id = ntohl (sub_id);
22229   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22230
22231   S (mp);
22232   W (ret);
22233   return ret;
22234 }
22235
22236 static int
22237 api_p2p_ethernet_del (vat_main_t * vam)
22238 {
22239   unformat_input_t *i = vam->input;
22240   vl_api_p2p_ethernet_del_t *mp;
22241   u32 parent_if_index = ~0;
22242   u8 remote_mac[6];
22243   u8 mac_set = 0;
22244   int ret;
22245
22246   memset (remote_mac, 0, sizeof (remote_mac));
22247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22248     {
22249       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22250         ;
22251       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22252         ;
22253       else
22254         if (unformat
22255             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22256         mac_set++;
22257       else
22258         {
22259           clib_warning ("parse error '%U'", format_unformat_error, i);
22260           return -99;
22261         }
22262     }
22263
22264   if (parent_if_index == ~0)
22265     {
22266       errmsg ("missing interface name or sw_if_index");
22267       return -99;
22268     }
22269   if (mac_set == 0)
22270     {
22271       errmsg ("missing remote mac address");
22272       return -99;
22273     }
22274
22275   M (P2P_ETHERNET_DEL, mp);
22276   mp->parent_if_index = ntohl (parent_if_index);
22277   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22278
22279   S (mp);
22280   W (ret);
22281   return ret;
22282 }
22283
22284 static int
22285 api_lldp_config (vat_main_t * vam)
22286 {
22287   unformat_input_t *i = vam->input;
22288   vl_api_lldp_config_t *mp;
22289   int tx_hold = 0;
22290   int tx_interval = 0;
22291   u8 *sys_name = NULL;
22292   int ret;
22293
22294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22295     {
22296       if (unformat (i, "system-name %s", &sys_name))
22297         ;
22298       else if (unformat (i, "tx-hold %d", &tx_hold))
22299         ;
22300       else if (unformat (i, "tx-interval %d", &tx_interval))
22301         ;
22302       else
22303         {
22304           clib_warning ("parse error '%U'", format_unformat_error, i);
22305           return -99;
22306         }
22307     }
22308
22309   vec_add1 (sys_name, 0);
22310
22311   M (LLDP_CONFIG, mp);
22312   mp->tx_hold = htonl (tx_hold);
22313   mp->tx_interval = htonl (tx_interval);
22314   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22315   vec_free (sys_name);
22316
22317   S (mp);
22318   W (ret);
22319   return ret;
22320 }
22321
22322 static int
22323 api_sw_interface_set_lldp (vat_main_t * vam)
22324 {
22325   unformat_input_t *i = vam->input;
22326   vl_api_sw_interface_set_lldp_t *mp;
22327   u32 sw_if_index = ~0;
22328   u32 enable = 1;
22329   u8 *port_desc = NULL, *mgmt_oid = NULL;
22330   ip4_address_t ip4_addr;
22331   ip6_address_t ip6_addr;
22332   int ret;
22333
22334   memset (&ip4_addr, 0, sizeof (ip4_addr));
22335   memset (&ip6_addr, 0, sizeof (ip6_addr));
22336
22337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22338     {
22339       if (unformat (i, "disable"))
22340         enable = 0;
22341       else
22342         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22343         ;
22344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22345         ;
22346       else if (unformat (i, "port-desc %s", &port_desc))
22347         ;
22348       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22349         ;
22350       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22351         ;
22352       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22353         ;
22354       else
22355         break;
22356     }
22357
22358   if (sw_if_index == ~0)
22359     {
22360       errmsg ("missing interface name or sw_if_index");
22361       return -99;
22362     }
22363
22364   /* Construct the API message */
22365   vec_add1 (port_desc, 0);
22366   vec_add1 (mgmt_oid, 0);
22367   M (SW_INTERFACE_SET_LLDP, mp);
22368   mp->sw_if_index = ntohl (sw_if_index);
22369   mp->enable = enable;
22370   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22371   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22372   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22373   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22374   vec_free (port_desc);
22375   vec_free (mgmt_oid);
22376
22377   S (mp);
22378   W (ret);
22379   return ret;
22380 }
22381
22382 static int
22383 api_tcp_configure_src_addresses (vat_main_t * vam)
22384 {
22385   vl_api_tcp_configure_src_addresses_t *mp;
22386   unformat_input_t *i = vam->input;
22387   ip4_address_t v4first, v4last;
22388   ip6_address_t v6first, v6last;
22389   u8 range_set = 0;
22390   u32 vrf_id = 0;
22391   int ret;
22392
22393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22394     {
22395       if (unformat (i, "%U - %U",
22396                     unformat_ip4_address, &v4first,
22397                     unformat_ip4_address, &v4last))
22398         {
22399           if (range_set)
22400             {
22401               errmsg ("one range per message (range already set)");
22402               return -99;
22403             }
22404           range_set = 1;
22405         }
22406       else if (unformat (i, "%U - %U",
22407                          unformat_ip6_address, &v6first,
22408                          unformat_ip6_address, &v6last))
22409         {
22410           if (range_set)
22411             {
22412               errmsg ("one range per message (range already set)");
22413               return -99;
22414             }
22415           range_set = 2;
22416         }
22417       else if (unformat (i, "vrf %d", &vrf_id))
22418         ;
22419       else
22420         break;
22421     }
22422
22423   if (range_set == 0)
22424     {
22425       errmsg ("address range not set");
22426       return -99;
22427     }
22428
22429   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22430   mp->vrf_id = ntohl (vrf_id);
22431   /* ipv6? */
22432   if (range_set == 2)
22433     {
22434       mp->is_ipv6 = 1;
22435       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22436       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22437     }
22438   else
22439     {
22440       mp->is_ipv6 = 0;
22441       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22442       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22443     }
22444   S (mp);
22445   W (ret);
22446   return ret;
22447 }
22448
22449 static void vl_api_app_namespace_add_del_reply_t_handler
22450   (vl_api_app_namespace_add_del_reply_t * mp)
22451 {
22452   vat_main_t *vam = &vat_main;
22453   i32 retval = ntohl (mp->retval);
22454   if (vam->async_mode)
22455     {
22456       vam->async_errors += (retval < 0);
22457     }
22458   else
22459     {
22460       vam->retval = retval;
22461       if (retval == 0)
22462         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22463       vam->result_ready = 1;
22464     }
22465 }
22466
22467 static void vl_api_app_namespace_add_del_reply_t_handler_json
22468   (vl_api_app_namespace_add_del_reply_t * mp)
22469 {
22470   vat_main_t *vam = &vat_main;
22471   vat_json_node_t node;
22472
22473   vat_json_init_object (&node);
22474   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22475   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22476
22477   vat_json_print (vam->ofp, &node);
22478   vat_json_free (&node);
22479
22480   vam->retval = ntohl (mp->retval);
22481   vam->result_ready = 1;
22482 }
22483
22484 static int
22485 api_app_namespace_add_del (vat_main_t * vam)
22486 {
22487   vl_api_app_namespace_add_del_t *mp;
22488   unformat_input_t *i = vam->input;
22489   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22490   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22491   u64 secret;
22492   int ret;
22493
22494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22495     {
22496       if (unformat (i, "id %_%v%_", &ns_id))
22497         ;
22498       else if (unformat (i, "secret %lu", &secret))
22499         secret_set = 1;
22500       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22501         sw_if_index_set = 1;
22502       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22503         ;
22504       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22505         ;
22506       else
22507         break;
22508     }
22509   if (!ns_id || !secret_set || !sw_if_index_set)
22510     {
22511       errmsg ("namespace id, secret and sw_if_index must be set");
22512       return -99;
22513     }
22514   if (vec_len (ns_id) > 64)
22515     {
22516       errmsg ("namespace id too long");
22517       return -99;
22518     }
22519   M (APP_NAMESPACE_ADD_DEL, mp);
22520
22521   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22522   mp->namespace_id_len = vec_len (ns_id);
22523   mp->secret = clib_host_to_net_u64 (secret);
22524   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22525   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22526   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22527   vec_free (ns_id);
22528   S (mp);
22529   W (ret);
22530   return ret;
22531 }
22532
22533 static void vl_api_map_stats_segment_reply_t_handler
22534   (vl_api_map_stats_segment_reply_t * mp)
22535 {
22536 #if VPP_API_TEST_BUILTIN == 0
22537   vat_main_t *vam = &vat_main;
22538   ssvm_private_t *ssvmp = &vam->stat_segment;
22539   ssvm_shared_header_t *shared_header;
22540   socket_client_main_t *scm = vam->socket_client_main;
22541   int rv = ntohl (mp->retval);
22542   int my_fd, retval;
22543   clib_error_t *error;
22544
22545   vam->retval = rv;
22546
22547   if (rv != 0)
22548     {
22549       vam->result_ready = 1;
22550       return;
22551     }
22552
22553   /*
22554    * Check the socket for the magic fd
22555    */
22556   error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 5);
22557   if (error)
22558     {
22559       clib_error_report (error);
22560       vam->retval = -99;
22561       vam->result_ready = 1;
22562       return;
22563     }
22564
22565   memset (ssvmp, 0, sizeof (*ssvmp));
22566   ssvmp->fd = my_fd;
22567
22568   /* Note: this closes memfd.fd */
22569   retval = ssvm_slave_init_memfd (ssvmp);
22570   if (retval)
22571     {
22572       clib_warning ("WARNING: segment map returned %d", retval);
22573       vam->retval = -99;
22574       vam->result_ready = 1;
22575       return;
22576     }
22577   else
22578     errmsg ("stat segment mapped OK...");
22579
22580   ASSERT (ssvmp && ssvmp->sh);
22581
22582   /* Pick up the segment lock from the shared memory header */
22583   shared_header = ssvmp->sh;
22584   vam->stat_segment_lockp = (clib_spinlock_t *) (shared_header->opaque[0]);
22585   vam->retval = 0;
22586   vam->result_ready = 1;
22587 #endif
22588 }
22589
22590 static void vl_api_map_stats_segment_reply_t_handler_json
22591   (vl_api_map_stats_segment_reply_t * mp)
22592 {
22593 #if VPP_API_TEST_BUILTIN == 0
22594   vat_main_t *vam = &vat_main;
22595   clib_warning ("not implemented");
22596   vam->retval = -99;
22597   vam->result_ready = 1;
22598 #endif
22599 }
22600
22601 static int
22602 api_map_stats_segment (vat_main_t * vam)
22603 {
22604 #if VPP_API_TEST_BUILTIN == 0
22605   vl_api_map_stats_segment_t *mp;
22606   int ret;
22607
22608   M (MAP_STATS_SEGMENT, mp);
22609   S (mp);
22610   W (ret);
22611
22612   return ret;
22613 #else
22614   errmsg ("api unavailable");
22615   return -99;
22616 #endif
22617 }
22618
22619 static int
22620 api_sock_init_shm (vat_main_t * vam)
22621 {
22622 #if VPP_API_TEST_BUILTIN == 0
22623   unformat_input_t *i = vam->input;
22624   vl_api_shm_elem_config_t *config = 0;
22625   u64 size = 64 << 20;
22626   int rv;
22627
22628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22629     {
22630       if (unformat (i, "size %U", unformat_memory_size, &size))
22631         ;
22632       else
22633         break;
22634     }
22635
22636   /*
22637    * Canned custom ring allocator config.
22638    * Should probably parse all of this
22639    */
22640   vec_validate (config, 6);
22641   config[0].type = VL_API_VLIB_RING;
22642   config[0].size = 256;
22643   config[0].count = 32;
22644
22645   config[1].type = VL_API_VLIB_RING;
22646   config[1].size = 1024;
22647   config[1].count = 16;
22648
22649   config[2].type = VL_API_VLIB_RING;
22650   config[2].size = 4096;
22651   config[2].count = 2;
22652
22653   config[3].type = VL_API_CLIENT_RING;
22654   config[3].size = 256;
22655   config[3].count = 32;
22656
22657   config[4].type = VL_API_CLIENT_RING;
22658   config[4].size = 1024;
22659   config[4].count = 16;
22660
22661   config[5].type = VL_API_CLIENT_RING;
22662   config[5].size = 4096;
22663   config[5].count = 2;
22664
22665   config[6].type = VL_API_QUEUE;
22666   config[6].count = 128;
22667   config[6].size = sizeof (uword);
22668
22669   rv = vl_socket_client_init_shm (config);
22670   if (!rv)
22671     vam->client_index_invalid = 1;
22672   return rv;
22673 #else
22674   return -99;
22675 #endif
22676 }
22677
22678 static int
22679 api_dns_enable_disable (vat_main_t * vam)
22680 {
22681   unformat_input_t *line_input = vam->input;
22682   vl_api_dns_enable_disable_t *mp;
22683   u8 enable_disable = 1;
22684   int ret;
22685
22686   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22687     {
22688       if (unformat (line_input, "disable"))
22689         enable_disable = 0;
22690       if (unformat (line_input, "enable"))
22691         enable_disable = 1;
22692       else
22693         break;
22694     }
22695
22696   /* Construct the API message */
22697   M (DNS_ENABLE_DISABLE, mp);
22698   mp->enable = enable_disable;
22699
22700   /* send it... */
22701   S (mp);
22702   /* Wait for the reply */
22703   W (ret);
22704   return ret;
22705 }
22706
22707 static int
22708 api_dns_resolve_name (vat_main_t * vam)
22709 {
22710   unformat_input_t *line_input = vam->input;
22711   vl_api_dns_resolve_name_t *mp;
22712   u8 *name = 0;
22713   int ret;
22714
22715   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22716     {
22717       if (unformat (line_input, "%s", &name))
22718         ;
22719       else
22720         break;
22721     }
22722
22723   if (vec_len (name) > 127)
22724     {
22725       errmsg ("name too long");
22726       return -99;
22727     }
22728
22729   /* Construct the API message */
22730   M (DNS_RESOLVE_NAME, mp);
22731   memcpy (mp->name, name, vec_len (name));
22732   vec_free (name);
22733
22734   /* send it... */
22735   S (mp);
22736   /* Wait for the reply */
22737   W (ret);
22738   return ret;
22739 }
22740
22741 static int
22742 api_dns_resolve_ip (vat_main_t * vam)
22743 {
22744   unformat_input_t *line_input = vam->input;
22745   vl_api_dns_resolve_ip_t *mp;
22746   int is_ip6 = -1;
22747   ip4_address_t addr4;
22748   ip6_address_t addr6;
22749   int ret;
22750
22751   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22752     {
22753       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22754         is_ip6 = 1;
22755       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22756         is_ip6 = 0;
22757       else
22758         break;
22759     }
22760
22761   if (is_ip6 == -1)
22762     {
22763       errmsg ("missing address");
22764       return -99;
22765     }
22766
22767   /* Construct the API message */
22768   M (DNS_RESOLVE_IP, mp);
22769   mp->is_ip6 = is_ip6;
22770   if (is_ip6)
22771     memcpy (mp->address, &addr6, sizeof (addr6));
22772   else
22773     memcpy (mp->address, &addr4, sizeof (addr4));
22774
22775   /* send it... */
22776   S (mp);
22777   /* Wait for the reply */
22778   W (ret);
22779   return ret;
22780 }
22781
22782 static int
22783 api_dns_name_server_add_del (vat_main_t * vam)
22784 {
22785   unformat_input_t *i = vam->input;
22786   vl_api_dns_name_server_add_del_t *mp;
22787   u8 is_add = 1;
22788   ip6_address_t ip6_server;
22789   ip4_address_t ip4_server;
22790   int ip6_set = 0;
22791   int ip4_set = 0;
22792   int ret = 0;
22793
22794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22795     {
22796       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22797         ip6_set = 1;
22798       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22799         ip4_set = 1;
22800       else if (unformat (i, "del"))
22801         is_add = 0;
22802       else
22803         {
22804           clib_warning ("parse error '%U'", format_unformat_error, i);
22805           return -99;
22806         }
22807     }
22808
22809   if (ip4_set && ip6_set)
22810     {
22811       errmsg ("Only one server address allowed per message");
22812       return -99;
22813     }
22814   if ((ip4_set + ip6_set) == 0)
22815     {
22816       errmsg ("Server address required");
22817       return -99;
22818     }
22819
22820   /* Construct the API message */
22821   M (DNS_NAME_SERVER_ADD_DEL, mp);
22822
22823   if (ip6_set)
22824     {
22825       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22826       mp->is_ip6 = 1;
22827     }
22828   else
22829     {
22830       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22831       mp->is_ip6 = 0;
22832     }
22833
22834   mp->is_add = is_add;
22835
22836   /* send it... */
22837   S (mp);
22838
22839   /* Wait for a reply, return good/bad news  */
22840   W (ret);
22841   return ret;
22842 }
22843
22844 static void
22845 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22846 {
22847   vat_main_t *vam = &vat_main;
22848
22849   if (mp->is_ip4)
22850     {
22851       print (vam->ofp,
22852              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22853              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22854              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22855              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22856              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22857              clib_net_to_host_u32 (mp->action_index), mp->tag);
22858     }
22859   else
22860     {
22861       print (vam->ofp,
22862              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22863              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22864              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22865              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22866              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22867              clib_net_to_host_u32 (mp->action_index), mp->tag);
22868     }
22869 }
22870
22871 static void
22872 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22873                                              mp)
22874 {
22875   vat_main_t *vam = &vat_main;
22876   vat_json_node_t *node = NULL;
22877   struct in6_addr ip6;
22878   struct in_addr ip4;
22879
22880   if (VAT_JSON_ARRAY != vam->json_tree.type)
22881     {
22882       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22883       vat_json_init_array (&vam->json_tree);
22884     }
22885   node = vat_json_array_add (&vam->json_tree);
22886   vat_json_init_object (node);
22887
22888   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22889   vat_json_object_add_uint (node, "appns_index",
22890                             clib_net_to_host_u32 (mp->appns_index));
22891   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22892   vat_json_object_add_uint (node, "scope", mp->scope);
22893   vat_json_object_add_uint (node, "action_index",
22894                             clib_net_to_host_u32 (mp->action_index));
22895   vat_json_object_add_uint (node, "lcl_port",
22896                             clib_net_to_host_u16 (mp->lcl_port));
22897   vat_json_object_add_uint (node, "rmt_port",
22898                             clib_net_to_host_u16 (mp->rmt_port));
22899   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22900   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22901   vat_json_object_add_string_copy (node, "tag", mp->tag);
22902   if (mp->is_ip4)
22903     {
22904       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22905       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22906       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22907       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22908     }
22909   else
22910     {
22911       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22912       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22913       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22914       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22915     }
22916 }
22917
22918 static int
22919 api_session_rule_add_del (vat_main_t * vam)
22920 {
22921   vl_api_session_rule_add_del_t *mp;
22922   unformat_input_t *i = vam->input;
22923   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22924   u32 appns_index = 0, scope = 0;
22925   ip4_address_t lcl_ip4, rmt_ip4;
22926   ip6_address_t lcl_ip6, rmt_ip6;
22927   u8 is_ip4 = 1, conn_set = 0;
22928   u8 is_add = 1, *tag = 0;
22929   int ret;
22930
22931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22932     {
22933       if (unformat (i, "del"))
22934         is_add = 0;
22935       else if (unformat (i, "add"))
22936         ;
22937       else if (unformat (i, "proto tcp"))
22938         proto = 0;
22939       else if (unformat (i, "proto udp"))
22940         proto = 1;
22941       else if (unformat (i, "appns %d", &appns_index))
22942         ;
22943       else if (unformat (i, "scope %d", &scope))
22944         ;
22945       else if (unformat (i, "tag %_%v%_", &tag))
22946         ;
22947       else
22948         if (unformat
22949             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22950              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22951              &rmt_port))
22952         {
22953           is_ip4 = 1;
22954           conn_set = 1;
22955         }
22956       else
22957         if (unformat
22958             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22959              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22960              &rmt_port))
22961         {
22962           is_ip4 = 0;
22963           conn_set = 1;
22964         }
22965       else if (unformat (i, "action %d", &action))
22966         ;
22967       else
22968         break;
22969     }
22970   if (proto == ~0 || !conn_set || action == ~0)
22971     {
22972       errmsg ("transport proto, connection and action must be set");
22973       return -99;
22974     }
22975
22976   if (scope > 3)
22977     {
22978       errmsg ("scope should be 0-3");
22979       return -99;
22980     }
22981
22982   M (SESSION_RULE_ADD_DEL, mp);
22983
22984   mp->is_ip4 = is_ip4;
22985   mp->transport_proto = proto;
22986   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22987   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22988   mp->lcl_plen = lcl_plen;
22989   mp->rmt_plen = rmt_plen;
22990   mp->action_index = clib_host_to_net_u32 (action);
22991   mp->appns_index = clib_host_to_net_u32 (appns_index);
22992   mp->scope = scope;
22993   mp->is_add = is_add;
22994   if (is_ip4)
22995     {
22996       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22997       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22998     }
22999   else
23000     {
23001       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23002       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23003     }
23004   if (tag)
23005     {
23006       clib_memcpy (mp->tag, tag, vec_len (tag));
23007       vec_free (tag);
23008     }
23009
23010   S (mp);
23011   W (ret);
23012   return ret;
23013 }
23014
23015 static int
23016 api_session_rules_dump (vat_main_t * vam)
23017 {
23018   vl_api_session_rules_dump_t *mp;
23019   vl_api_control_ping_t *mp_ping;
23020   int ret;
23021
23022   if (!vam->json_output)
23023     {
23024       print (vam->ofp, "%=20s", "Session Rules");
23025     }
23026
23027   M (SESSION_RULES_DUMP, mp);
23028   /* send it... */
23029   S (mp);
23030
23031   /* Use a control ping for synchronization */
23032   MPING (CONTROL_PING, mp_ping);
23033   S (mp_ping);
23034
23035   /* Wait for a reply... */
23036   W (ret);
23037   return ret;
23038 }
23039
23040 static int
23041 api_ip_container_proxy_add_del (vat_main_t * vam)
23042 {
23043   vl_api_ip_container_proxy_add_del_t *mp;
23044   unformat_input_t *i = vam->input;
23045   u32 plen = ~0, sw_if_index = ~0;
23046   ip4_address_t ip4;
23047   ip6_address_t ip6;
23048   u8 is_ip4 = 1;
23049   u8 is_add = 1;
23050   int ret;
23051
23052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23053     {
23054       if (unformat (i, "del"))
23055         is_add = 0;
23056       else if (unformat (i, "add"))
23057         ;
23058       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23059         {
23060           is_ip4 = 1;
23061           plen = 32;
23062         }
23063       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23064         {
23065           is_ip4 = 0;
23066           plen = 128;
23067         }
23068       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23069         ;
23070       else
23071         break;
23072     }
23073   if (sw_if_index == ~0 || plen == ~0)
23074     {
23075       errmsg ("address and sw_if_index must be set");
23076       return -99;
23077     }
23078
23079   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23080
23081   mp->is_ip4 = is_ip4;
23082   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23083   mp->plen = plen;
23084   mp->is_add = is_add;
23085   if (is_ip4)
23086     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23087   else
23088     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23089
23090   S (mp);
23091   W (ret);
23092   return ret;
23093 }
23094
23095 static int
23096 api_qos_record_enable_disable (vat_main_t * vam)
23097 {
23098   unformat_input_t *i = vam->input;
23099   vl_api_qos_record_enable_disable_t *mp;
23100   u32 sw_if_index, qs = 0xff;
23101   u8 sw_if_index_set = 0;
23102   u8 enable = 1;
23103   int ret;
23104
23105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23106     {
23107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23108         sw_if_index_set = 1;
23109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23110         sw_if_index_set = 1;
23111       else if (unformat (i, "%U", unformat_qos_source, &qs))
23112         ;
23113       else if (unformat (i, "disable"))
23114         enable = 0;
23115       else
23116         {
23117           clib_warning ("parse error '%U'", format_unformat_error, i);
23118           return -99;
23119         }
23120     }
23121
23122   if (sw_if_index_set == 0)
23123     {
23124       errmsg ("missing interface name or sw_if_index");
23125       return -99;
23126     }
23127   if (qs == 0xff)
23128     {
23129       errmsg ("input location must be specified");
23130       return -99;
23131     }
23132
23133   M (QOS_RECORD_ENABLE_DISABLE, mp);
23134
23135   mp->sw_if_index = ntohl (sw_if_index);
23136   mp->input_source = qs;
23137   mp->enable = enable;
23138
23139   S (mp);
23140   W (ret);
23141   return ret;
23142 }
23143
23144
23145 static int
23146 q_or_quit (vat_main_t * vam)
23147 {
23148 #if VPP_API_TEST_BUILTIN == 0
23149   longjmp (vam->jump_buf, 1);
23150 #endif
23151   return 0;                     /* not so much */
23152 }
23153
23154 static int
23155 q (vat_main_t * vam)
23156 {
23157   return q_or_quit (vam);
23158 }
23159
23160 static int
23161 quit (vat_main_t * vam)
23162 {
23163   return q_or_quit (vam);
23164 }
23165
23166 static int
23167 comment (vat_main_t * vam)
23168 {
23169   return 0;
23170 }
23171
23172 static int
23173 statseg (vat_main_t * vam)
23174 {
23175   ssvm_private_t *ssvmp = &vam->stat_segment;
23176   ssvm_shared_header_t *shared_header = ssvmp->sh;
23177   vlib_counter_t **counters;
23178   u64 thread0_index1_packets;
23179   u64 thread0_index1_bytes;
23180   f64 vector_rate, input_rate;
23181   uword *p;
23182
23183   uword *counter_vector_by_name;
23184   if (vam->stat_segment_lockp == 0)
23185     {
23186       errmsg ("Stat segment not mapped...");
23187       return -99;
23188     }
23189
23190   /* look up "/if/rx for sw_if_index 1 as a test */
23191
23192   clib_spinlock_lock (vam->stat_segment_lockp);
23193
23194   counter_vector_by_name = (uword *) shared_header->opaque[1];
23195
23196   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23197   if (p == 0)
23198     {
23199       clib_spinlock_unlock (vam->stat_segment_lockp);
23200       errmsg ("/if/tx not found?");
23201       return -99;
23202     }
23203
23204   /* Fish per-thread vector of combined counters from shared memory */
23205   counters = (vlib_counter_t **) p[0];
23206
23207   if (vec_len (counters[0]) < 2)
23208     {
23209       clib_spinlock_unlock (vam->stat_segment_lockp);
23210       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23211       return -99;
23212     }
23213
23214   /* Read thread 0 sw_if_index 1 counter */
23215   thread0_index1_packets = counters[0][1].packets;
23216   thread0_index1_bytes = counters[0][1].bytes;
23217
23218   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23219   if (p == 0)
23220     {
23221       clib_spinlock_unlock (vam->stat_segment_lockp);
23222       errmsg ("vector_rate not found?");
23223       return -99;
23224     }
23225
23226   vector_rate = *(f64 *) (p[0]);
23227   p = hash_get_mem (counter_vector_by_name, "input_rate");
23228   if (p == 0)
23229     {
23230       clib_spinlock_unlock (vam->stat_segment_lockp);
23231       errmsg ("input_rate not found?");
23232       return -99;
23233     }
23234   input_rate = *(f64 *) (p[0]);
23235
23236   clib_spinlock_unlock (vam->stat_segment_lockp);
23237
23238   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23239          vector_rate, input_rate);
23240   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23241          thread0_index1_packets, thread0_index1_bytes);
23242
23243   return 0;
23244 }
23245
23246 static int
23247 cmd_cmp (void *a1, void *a2)
23248 {
23249   u8 **c1 = a1;
23250   u8 **c2 = a2;
23251
23252   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23253 }
23254
23255 static int
23256 help (vat_main_t * vam)
23257 {
23258   u8 **cmds = 0;
23259   u8 *name = 0;
23260   hash_pair_t *p;
23261   unformat_input_t *i = vam->input;
23262   int j;
23263
23264   if (unformat (i, "%s", &name))
23265     {
23266       uword *hs;
23267
23268       vec_add1 (name, 0);
23269
23270       hs = hash_get_mem (vam->help_by_name, name);
23271       if (hs)
23272         print (vam->ofp, "usage: %s %s", name, hs[0]);
23273       else
23274         print (vam->ofp, "No such msg / command '%s'", name);
23275       vec_free (name);
23276       return 0;
23277     }
23278
23279   print (vam->ofp, "Help is available for the following:");
23280
23281     /* *INDENT-OFF* */
23282     hash_foreach_pair (p, vam->function_by_name,
23283     ({
23284       vec_add1 (cmds, (u8 *)(p->key));
23285     }));
23286     /* *INDENT-ON* */
23287
23288   vec_sort_with_function (cmds, cmd_cmp);
23289
23290   for (j = 0; j < vec_len (cmds); j++)
23291     print (vam->ofp, "%s", cmds[j]);
23292
23293   vec_free (cmds);
23294   return 0;
23295 }
23296
23297 static int
23298 set (vat_main_t * vam)
23299 {
23300   u8 *name = 0, *value = 0;
23301   unformat_input_t *i = vam->input;
23302
23303   if (unformat (i, "%s", &name))
23304     {
23305       /* The input buffer is a vector, not a string. */
23306       value = vec_dup (i->buffer);
23307       vec_delete (value, i->index, 0);
23308       /* Almost certainly has a trailing newline */
23309       if (value[vec_len (value) - 1] == '\n')
23310         value[vec_len (value) - 1] = 0;
23311       /* Make sure it's a proper string, one way or the other */
23312       vec_add1 (value, 0);
23313       (void) clib_macro_set_value (&vam->macro_main,
23314                                    (char *) name, (char *) value);
23315     }
23316   else
23317     errmsg ("usage: set <name> <value>");
23318
23319   vec_free (name);
23320   vec_free (value);
23321   return 0;
23322 }
23323
23324 static int
23325 unset (vat_main_t * vam)
23326 {
23327   u8 *name = 0;
23328
23329   if (unformat (vam->input, "%s", &name))
23330     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23331       errmsg ("unset: %s wasn't set", name);
23332   vec_free (name);
23333   return 0;
23334 }
23335
23336 typedef struct
23337 {
23338   u8 *name;
23339   u8 *value;
23340 } macro_sort_t;
23341
23342
23343 static int
23344 macro_sort_cmp (void *a1, void *a2)
23345 {
23346   macro_sort_t *s1 = a1;
23347   macro_sort_t *s2 = a2;
23348
23349   return strcmp ((char *) (s1->name), (char *) (s2->name));
23350 }
23351
23352 static int
23353 dump_macro_table (vat_main_t * vam)
23354 {
23355   macro_sort_t *sort_me = 0, *sm;
23356   int i;
23357   hash_pair_t *p;
23358
23359     /* *INDENT-OFF* */
23360     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23361     ({
23362       vec_add2 (sort_me, sm, 1);
23363       sm->name = (u8 *)(p->key);
23364       sm->value = (u8 *) (p->value[0]);
23365     }));
23366     /* *INDENT-ON* */
23367
23368   vec_sort_with_function (sort_me, macro_sort_cmp);
23369
23370   if (vec_len (sort_me))
23371     print (vam->ofp, "%-15s%s", "Name", "Value");
23372   else
23373     print (vam->ofp, "The macro table is empty...");
23374
23375   for (i = 0; i < vec_len (sort_me); i++)
23376     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23377   return 0;
23378 }
23379
23380 static int
23381 dump_node_table (vat_main_t * vam)
23382 {
23383   int i, j;
23384   vlib_node_t *node, *next_node;
23385
23386   if (vec_len (vam->graph_nodes) == 0)
23387     {
23388       print (vam->ofp, "Node table empty, issue get_node_graph...");
23389       return 0;
23390     }
23391
23392   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23393     {
23394       node = vam->graph_nodes[i];
23395       print (vam->ofp, "[%d] %s", i, node->name);
23396       for (j = 0; j < vec_len (node->next_nodes); j++)
23397         {
23398           if (node->next_nodes[j] != ~0)
23399             {
23400               next_node = vam->graph_nodes[node->next_nodes[j]];
23401               print (vam->ofp, "  [%d] %s", j, next_node->name);
23402             }
23403         }
23404     }
23405   return 0;
23406 }
23407
23408 static int
23409 value_sort_cmp (void *a1, void *a2)
23410 {
23411   name_sort_t *n1 = a1;
23412   name_sort_t *n2 = a2;
23413
23414   if (n1->value < n2->value)
23415     return -1;
23416   if (n1->value > n2->value)
23417     return 1;
23418   return 0;
23419 }
23420
23421
23422 static int
23423 dump_msg_api_table (vat_main_t * vam)
23424 {
23425   api_main_t *am = &api_main;
23426   name_sort_t *nses = 0, *ns;
23427   hash_pair_t *hp;
23428   int i;
23429
23430   /* *INDENT-OFF* */
23431   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23432   ({
23433     vec_add2 (nses, ns, 1);
23434     ns->name = (u8 *)(hp->key);
23435     ns->value = (u32) hp->value[0];
23436   }));
23437   /* *INDENT-ON* */
23438
23439   vec_sort_with_function (nses, value_sort_cmp);
23440
23441   for (i = 0; i < vec_len (nses); i++)
23442     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23443   vec_free (nses);
23444   return 0;
23445 }
23446
23447 static int
23448 get_msg_id (vat_main_t * vam)
23449 {
23450   u8 *name_and_crc;
23451   u32 message_index;
23452
23453   if (unformat (vam->input, "%s", &name_and_crc))
23454     {
23455       message_index = vl_msg_api_get_msg_index (name_and_crc);
23456       if (message_index == ~0)
23457         {
23458           print (vam->ofp, " '%s' not found", name_and_crc);
23459           return 0;
23460         }
23461       print (vam->ofp, " '%s' has message index %d",
23462              name_and_crc, message_index);
23463       return 0;
23464     }
23465   errmsg ("name_and_crc required...");
23466   return 0;
23467 }
23468
23469 static int
23470 search_node_table (vat_main_t * vam)
23471 {
23472   unformat_input_t *line_input = vam->input;
23473   u8 *node_to_find;
23474   int j;
23475   vlib_node_t *node, *next_node;
23476   uword *p;
23477
23478   if (vam->graph_node_index_by_name == 0)
23479     {
23480       print (vam->ofp, "Node table empty, issue get_node_graph...");
23481       return 0;
23482     }
23483
23484   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23485     {
23486       if (unformat (line_input, "%s", &node_to_find))
23487         {
23488           vec_add1 (node_to_find, 0);
23489           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23490           if (p == 0)
23491             {
23492               print (vam->ofp, "%s not found...", node_to_find);
23493               goto out;
23494             }
23495           node = vam->graph_nodes[p[0]];
23496           print (vam->ofp, "[%d] %s", p[0], node->name);
23497           for (j = 0; j < vec_len (node->next_nodes); j++)
23498             {
23499               if (node->next_nodes[j] != ~0)
23500                 {
23501                   next_node = vam->graph_nodes[node->next_nodes[j]];
23502                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23503                 }
23504             }
23505         }
23506
23507       else
23508         {
23509           clib_warning ("parse error '%U'", format_unformat_error,
23510                         line_input);
23511           return -99;
23512         }
23513
23514     out:
23515       vec_free (node_to_find);
23516
23517     }
23518
23519   return 0;
23520 }
23521
23522
23523 static int
23524 script (vat_main_t * vam)
23525 {
23526 #if (VPP_API_TEST_BUILTIN==0)
23527   u8 *s = 0;
23528   char *save_current_file;
23529   unformat_input_t save_input;
23530   jmp_buf save_jump_buf;
23531   u32 save_line_number;
23532
23533   FILE *new_fp, *save_ifp;
23534
23535   if (unformat (vam->input, "%s", &s))
23536     {
23537       new_fp = fopen ((char *) s, "r");
23538       if (new_fp == 0)
23539         {
23540           errmsg ("Couldn't open script file %s", s);
23541           vec_free (s);
23542           return -99;
23543         }
23544     }
23545   else
23546     {
23547       errmsg ("Missing script name");
23548       return -99;
23549     }
23550
23551   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23552   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23553   save_ifp = vam->ifp;
23554   save_line_number = vam->input_line_number;
23555   save_current_file = (char *) vam->current_file;
23556
23557   vam->input_line_number = 0;
23558   vam->ifp = new_fp;
23559   vam->current_file = s;
23560   do_one_file (vam);
23561
23562   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23563   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23564   vam->ifp = save_ifp;
23565   vam->input_line_number = save_line_number;
23566   vam->current_file = (u8 *) save_current_file;
23567   vec_free (s);
23568
23569   return 0;
23570 #else
23571   clib_warning ("use the exec command...");
23572   return -99;
23573 #endif
23574 }
23575
23576 static int
23577 echo (vat_main_t * vam)
23578 {
23579   print (vam->ofp, "%v", vam->input->buffer);
23580   return 0;
23581 }
23582
23583 /* List of API message constructors, CLI names map to api_xxx */
23584 #define foreach_vpe_api_msg                                             \
23585 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23586 _(sw_interface_dump,"")                                                 \
23587 _(sw_interface_set_flags,                                               \
23588   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23589 _(sw_interface_add_del_address,                                         \
23590   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23591 _(sw_interface_set_rx_mode,                                             \
23592   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23593 _(sw_interface_set_table,                                               \
23594   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23595 _(sw_interface_set_mpls_enable,                                         \
23596   "<intfc> | sw_if_index [disable | dis]")                              \
23597 _(sw_interface_set_vpath,                                               \
23598   "<intfc> | sw_if_index <id> enable | disable")                        \
23599 _(sw_interface_set_vxlan_bypass,                                        \
23600   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23601 _(sw_interface_set_geneve_bypass,                                       \
23602   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23603 _(sw_interface_set_l2_xconnect,                                         \
23604   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23605   "enable | disable")                                                   \
23606 _(sw_interface_set_l2_bridge,                                           \
23607   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23608   "[shg <split-horizon-group>] [bvi]\n"                                 \
23609   "enable | disable")                                                   \
23610 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23611 _(bridge_domain_add_del,                                                \
23612   "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") \
23613 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23614 _(l2fib_add_del,                                                        \
23615   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23616 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23617 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23618 _(l2_flags,                                                             \
23619   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23620 _(bridge_flags,                                                         \
23621   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23622 _(tap_connect,                                                          \
23623   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23624 _(tap_modify,                                                           \
23625   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23626 _(tap_delete,                                                           \
23627   "<vpp-if-name> | sw_if_index <id>")                                   \
23628 _(sw_interface_tap_dump, "")                                            \
23629 _(tap_create_v2,                                                        \
23630   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23631 _(tap_delete_v2,                                                        \
23632   "<vpp-if-name> | sw_if_index <id>")                                   \
23633 _(sw_interface_tap_v2_dump, "")                                         \
23634 _(bond_create,                                                          \
23635   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23636   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23637 _(bond_delete,                                                          \
23638   "<vpp-if-name> | sw_if_index <id>")                                   \
23639 _(bond_enslave,                                                         \
23640   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23641 _(bond_detach_slave,                                                    \
23642   "sw_if_index <n>")                                                    \
23643 _(sw_interface_bond_dump, "")                                           \
23644 _(sw_interface_slave_dump,                                              \
23645   "<vpp-if-name> | sw_if_index <id>")                                   \
23646 _(ip_table_add_del,                                                     \
23647   "table-id <n> [ipv6]\n")                                              \
23648 _(ip_add_del_route,                                                     \
23649   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23650   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23651   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23652   "[multipath] [count <n>]")                                            \
23653 _(ip_mroute_add_del,                                                    \
23654   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23655   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23656 _(mpls_table_add_del,                                                   \
23657   "table-id <n>\n")                                                     \
23658 _(mpls_route_add_del,                                                   \
23659   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23660   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23661   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23662   "[multipath] [count <n>]")                                            \
23663 _(mpls_ip_bind_unbind,                                                  \
23664   "<label> <addr/len>")                                                 \
23665 _(mpls_tunnel_add_del,                                                  \
23666   " via <addr> [table-id <n>]\n"                                        \
23667   "sw_if_index <id>] [l2]  [del]")                                      \
23668 _(bier_table_add_del,                                                   \
23669   "<label> <sub-domain> <set> <bsl> [del]")                             \
23670 _(bier_route_add_del,                                                   \
23671   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23672   "[<intfc> | sw_if_index <id>]"                                        \
23673   "[weight <n>] [del] [multipath]")                                     \
23674 _(proxy_arp_add_del,                                                    \
23675   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23676 _(proxy_arp_intfc_enable_disable,                                       \
23677   "<intfc> | sw_if_index <id> enable | disable")                        \
23678 _(sw_interface_set_unnumbered,                                          \
23679   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23680 _(ip_neighbor_add_del,                                                  \
23681   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23682   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23683 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23684 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23685   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23686   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23687   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23688 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23689 _(reset_fib, "vrf <n> [ipv6]")                                          \
23690 _(dhcp_proxy_config,                                                    \
23691   "svr <v46-address> src <v46-address>\n"                               \
23692    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23693 _(dhcp_proxy_set_vss,                                                   \
23694   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23695 _(dhcp_proxy_dump, "ip6")                                               \
23696 _(dhcp_client_config,                                                   \
23697   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23698 _(set_ip_flow_hash,                                                     \
23699   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23700 _(sw_interface_ip6_enable_disable,                                      \
23701   "<intfc> | sw_if_index <id> enable | disable")                        \
23702 _(sw_interface_ip6_set_link_local_address,                              \
23703   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23704 _(ip6nd_proxy_add_del,                                                  \
23705   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23706 _(ip6nd_proxy_dump, "")                                                 \
23707 _(sw_interface_ip6nd_ra_prefix,                                         \
23708   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23709   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23710   "[nolink] [isno]")                                                    \
23711 _(sw_interface_ip6nd_ra_config,                                         \
23712   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23713   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23714   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23715 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23716 _(l2_patch_add_del,                                                     \
23717   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23718   "enable | disable")                                                   \
23719 _(sr_localsid_add_del,                                                  \
23720   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23721   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23722 _(classify_add_del_table,                                               \
23723   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23724   " [del] [del-chain] mask <mask-value>\n"                              \
23725   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23726   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23727 _(classify_add_del_session,                                             \
23728   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23729   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23730   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23731   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23732 _(classify_set_interface_ip_table,                                      \
23733   "<intfc> | sw_if_index <nn> table <nn>")                              \
23734 _(classify_set_interface_l2_tables,                                     \
23735   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23736   "  [other-table <nn>]")                                               \
23737 _(get_node_index, "node <node-name")                                    \
23738 _(add_node_next, "node <node-name> next <next-node-name>")              \
23739 _(l2tpv3_create_tunnel,                                                 \
23740   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23741   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23742   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23743 _(l2tpv3_set_tunnel_cookies,                                            \
23744   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23745   "[new_remote_cookie <nn>]\n")                                         \
23746 _(l2tpv3_interface_enable_disable,                                      \
23747   "<intfc> | sw_if_index <nn> enable | disable")                        \
23748 _(l2tpv3_set_lookup_key,                                                \
23749   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23750 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23751 _(vxlan_offload_rx,                                                     \
23752   "hw { <interface name> | hw_if_index <nn>} "                          \
23753   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23754 _(vxlan_add_del_tunnel,                                                 \
23755   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23756   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23757   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23758 _(geneve_add_del_tunnel,                                                \
23759   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23760   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23761   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23762 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23763 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23764 _(gre_add_del_tunnel,                                                   \
23765   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23766   "[teb | erspan <session-id>] [del]")                                  \
23767 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23768 _(l2_fib_clear_table, "")                                               \
23769 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23770 _(l2_interface_vlan_tag_rewrite,                                        \
23771   "<intfc> | sw_if_index <nn> \n"                                       \
23772   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23773   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23774 _(create_vhost_user_if,                                                 \
23775         "socket <filename> [server] [renumber <dev_instance>] "         \
23776         "[mac <mac_address>]")                                          \
23777 _(modify_vhost_user_if,                                                 \
23778         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23779         "[server] [renumber <dev_instance>]")                           \
23780 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23781 _(sw_interface_vhost_user_dump, "")                                     \
23782 _(show_version, "")                                                     \
23783 _(vxlan_gpe_add_del_tunnel,                                             \
23784   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23785   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23786   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23787   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23788 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23789 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23790 _(interface_name_renumber,                                              \
23791   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23792 _(input_acl_set_interface,                                              \
23793   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23794   "  [l2-table <nn>] [del]")                                            \
23795 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23796 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23797   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23798 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23799 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23800 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23801 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23802 _(ip_dump, "ipv4 | ipv6")                                               \
23803 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23804 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23805   "  spid_id <n> ")                                                     \
23806 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23807   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23808   "  integ_alg <alg> integ_key <hex>")                                  \
23809 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23810   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23811   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23812   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23813 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23814 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23815   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23816   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23817   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23818   "  [instance <n>]")     \
23819 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23820 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23821   "  <alg> <hex>\n")                                                    \
23822 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23823 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23824 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23825   "(auth_data 0x<data> | auth_data <data>)")                            \
23826 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23827   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23828 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23829   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23830   "(local|remote)")                                                     \
23831 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23832 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23833 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23834 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23835 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23836 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23837 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23838 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23839 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23840 _(delete_loopback,"sw_if_index <nn>")                                   \
23841 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23842 _(map_add_domain,                                                       \
23843   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23844   "ip6-src <ip6addr> "                                                  \
23845   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23846 _(map_del_domain, "index <n>")                                          \
23847 _(map_add_del_rule,                                                     \
23848   "index <n> psid <n> dst <ip6addr> [del]")                             \
23849 _(map_domain_dump, "")                                                  \
23850 _(map_rule_dump, "index <map-domain>")                                  \
23851 _(want_interface_events,  "enable|disable")                             \
23852 _(want_stats,"enable|disable")                                          \
23853 _(get_first_msg_id, "client <name>")                                    \
23854 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23855 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23856   "fib-id <nn> [ip4][ip6][default]")                                    \
23857 _(get_node_graph, " ")                                                  \
23858 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23859 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23860 _(ioam_disable, "")                                                     \
23861 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23862                             " sw_if_index <sw_if_index> p <priority> "  \
23863                             "w <weight>] [del]")                        \
23864 _(one_add_del_locator, "locator-set <locator_name> "                    \
23865                         "iface <intf> | sw_if_index <sw_if_index> "     \
23866                         "p <priority> w <weight> [del]")                \
23867 _(one_add_del_local_eid,"vni <vni> eid "                                \
23868                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23869                          "locator-set <locator_name> [del]"             \
23870                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23871 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23872 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23873 _(one_enable_disable, "enable|disable")                                 \
23874 _(one_map_register_enable_disable, "enable|disable")                    \
23875 _(one_map_register_fallback_threshold, "<value>")                       \
23876 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23877 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23878                                "[seid <seid>] "                         \
23879                                "rloc <locator> p <prio> "               \
23880                                "w <weight> [rloc <loc> ... ] "          \
23881                                "action <action> [del-all]")             \
23882 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23883                           "<local-eid>")                                \
23884 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23885 _(one_use_petr, "ip-address> | disable")                                \
23886 _(one_map_request_mode, "src-dst|dst-only")                             \
23887 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23888 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23889 _(one_locator_set_dump, "[local | remote]")                             \
23890 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23891 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23892                        "[local] | [remote]")                            \
23893 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23894 _(one_ndp_bd_get, "")                                                   \
23895 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23896 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23897 _(one_l2_arp_bd_get, "")                                                \
23898 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23899 _(one_stats_enable_disable, "enable|disalbe")                           \
23900 _(show_one_stats_enable_disable, "")                                    \
23901 _(one_eid_table_vni_dump, "")                                           \
23902 _(one_eid_table_map_dump, "l2|l3")                                      \
23903 _(one_map_resolver_dump, "")                                            \
23904 _(one_map_server_dump, "")                                              \
23905 _(one_adjacencies_get, "vni <vni>")                                     \
23906 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23907 _(show_one_rloc_probe_state, "")                                        \
23908 _(show_one_map_register_state, "")                                      \
23909 _(show_one_status, "")                                                  \
23910 _(one_stats_dump, "")                                                   \
23911 _(one_stats_flush, "")                                                  \
23912 _(one_get_map_request_itr_rlocs, "")                                    \
23913 _(one_map_register_set_ttl, "<ttl>")                                    \
23914 _(one_set_transport_protocol, "udp|api")                                \
23915 _(one_get_transport_protocol, "")                                       \
23916 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23917 _(one_show_xtr_mode, "")                                                \
23918 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23919 _(one_show_pitr_mode, "")                                               \
23920 _(one_enable_disable_petr_mode, "enable|disable")                       \
23921 _(one_show_petr_mode, "")                                               \
23922 _(show_one_nsh_mapping, "")                                             \
23923 _(show_one_pitr, "")                                                    \
23924 _(show_one_use_petr, "")                                                \
23925 _(show_one_map_request_mode, "")                                        \
23926 _(show_one_map_register_ttl, "")                                        \
23927 _(show_one_map_register_fallback_threshold, "")                         \
23928 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23929                             " sw_if_index <sw_if_index> p <priority> "  \
23930                             "w <weight>] [del]")                        \
23931 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23932                         "iface <intf> | sw_if_index <sw_if_index> "     \
23933                         "p <priority> w <weight> [del]")                \
23934 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23935                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23936                          "locator-set <locator_name> [del]"             \
23937                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23938 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23939 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23940 _(lisp_enable_disable, "enable|disable")                                \
23941 _(lisp_map_register_enable_disable, "enable|disable")                   \
23942 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23943 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23944                                "[seid <seid>] "                         \
23945                                "rloc <locator> p <prio> "               \
23946                                "w <weight> [rloc <loc> ... ] "          \
23947                                "action <action> [del-all]")             \
23948 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23949                           "<local-eid>")                                \
23950 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23951 _(lisp_use_petr, "<ip-address> | disable")                              \
23952 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23953 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23954 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23955 _(lisp_locator_set_dump, "[local | remote]")                            \
23956 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23957 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23958                        "[local] | [remote]")                            \
23959 _(lisp_eid_table_vni_dump, "")                                          \
23960 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23961 _(lisp_map_resolver_dump, "")                                           \
23962 _(lisp_map_server_dump, "")                                             \
23963 _(lisp_adjacencies_get, "vni <vni>")                                    \
23964 _(gpe_fwd_entry_vnis_get, "")                                           \
23965 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23966 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23967                                 "[table <table-id>]")                   \
23968 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23969 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23970 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23971 _(gpe_get_encap_mode, "")                                               \
23972 _(lisp_gpe_add_del_iface, "up|down")                                    \
23973 _(lisp_gpe_enable_disable, "enable|disable")                            \
23974 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23975   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23976 _(show_lisp_rloc_probe_state, "")                                       \
23977 _(show_lisp_map_register_state, "")                                     \
23978 _(show_lisp_status, "")                                                 \
23979 _(lisp_get_map_request_itr_rlocs, "")                                   \
23980 _(show_lisp_pitr, "")                                                   \
23981 _(show_lisp_use_petr, "")                                               \
23982 _(show_lisp_map_request_mode, "")                                       \
23983 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23984 _(af_packet_delete, "name <host interface name>")                       \
23985 _(af_packet_dump, "")                                                   \
23986 _(policer_add_del, "name <policer name> <params> [del]")                \
23987 _(policer_dump, "[name <policer name>]")                                \
23988 _(policer_classify_set_interface,                                       \
23989   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23990   "  [l2-table <nn>] [del]")                                            \
23991 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23992 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23993     "[master|slave]")                                                   \
23994 _(netmap_delete, "name <interface name>")                               \
23995 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23996 _(mpls_fib_dump, "")                                                    \
23997 _(classify_table_ids, "")                                               \
23998 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23999 _(classify_table_info, "table_id <nn>")                                 \
24000 _(classify_session_dump, "table_id <nn>")                               \
24001 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24002     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24003     "[template_interval <nn>] [udp_checksum]")                          \
24004 _(ipfix_exporter_dump, "")                                              \
24005 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24006 _(ipfix_classify_stream_dump, "")                                       \
24007 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24008 _(ipfix_classify_table_dump, "")                                        \
24009 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24010 _(sw_interface_span_dump, "[l2]")                                           \
24011 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24012 _(pg_create_interface, "if_id <nn>")                                    \
24013 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24014 _(pg_enable_disable, "[stream <id>] disable")                           \
24015 _(ip_source_and_port_range_check_add_del,                               \
24016   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24017 _(ip_source_and_port_range_check_interface_add_del,                     \
24018   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24019   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24020 _(ipsec_gre_add_del_tunnel,                                             \
24021   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24022 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24023 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24024 _(l2_interface_pbb_tag_rewrite,                                         \
24025   "<intfc> | sw_if_index <nn> \n"                                       \
24026   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24027   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24028 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24029 _(flow_classify_set_interface,                                          \
24030   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24031 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24032 _(ip_fib_dump, "")                                                      \
24033 _(ip_mfib_dump, "")                                                     \
24034 _(ip6_fib_dump, "")                                                     \
24035 _(ip6_mfib_dump, "")                                                    \
24036 _(feature_enable_disable, "arc_name <arc_name> "                        \
24037   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24038 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24039 "[disable]")                                                            \
24040 _(l2_xconnect_dump, "")                                                 \
24041 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24042 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24043 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24044 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24045 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24046 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24047 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24048   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24049 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24050 _(sock_init_shm, "size <nnn>")                                          \
24051 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24052 _(dns_enable_disable, "[enable][disable]")                              \
24053 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24054 _(dns_resolve_name, "<hostname>")                                       \
24055 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24056 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24057 _(dns_resolve_name, "<hostname>")                                       \
24058 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24059   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24060 _(session_rules_dump, "")                                               \
24061 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24062 _(output_acl_set_interface,                                             \
24063   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24064   "  [l2-table <nn>] [del]")                                            \
24065 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]") \
24066 _(map_stats_segment, "<no-args>")
24067
24068 /* List of command functions, CLI names map directly to functions */
24069 #define foreach_cli_function                                    \
24070 _(comment, "usage: comment <ignore-rest-of-line>")              \
24071 _(dump_interface_table, "usage: dump_interface_table")          \
24072 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24073 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24074 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24075 _(dump_stats_table, "usage: dump_stats_table")                  \
24076 _(dump_macro_table, "usage: dump_macro_table ")                 \
24077 _(dump_node_table, "usage: dump_node_table")                    \
24078 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24079 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24080 _(echo, "usage: echo <message>")                                \
24081 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24082 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24083 _(help, "usage: help")                                          \
24084 _(q, "usage: quit")                                             \
24085 _(quit, "usage: quit")                                          \
24086 _(search_node_table, "usage: search_node_table <name>...")      \
24087 _(set, "usage: set <variable-name> <value>")                    \
24088 _(script, "usage: script <file-name>")                          \
24089 _(statseg, "usage: statseg");                                   \
24090 _(unset, "usage: unset <variable-name>")
24091
24092 #define _(N,n)                                  \
24093     static void vl_api_##n##_t_handler_uni      \
24094     (vl_api_##n##_t * mp)                       \
24095     {                                           \
24096         vat_main_t * vam = &vat_main;           \
24097         if (vam->json_output) {                 \
24098             vl_api_##n##_t_handler_json(mp);    \
24099         } else {                                \
24100             vl_api_##n##_t_handler(mp);         \
24101         }                                       \
24102     }
24103 foreach_vpe_api_reply_msg;
24104 #if VPP_API_TEST_BUILTIN == 0
24105 foreach_standalone_reply_msg;
24106 #endif
24107 #undef _
24108
24109 void
24110 vat_api_hookup (vat_main_t * vam)
24111 {
24112 #define _(N,n)                                                  \
24113     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24114                            vl_api_##n##_t_handler_uni,          \
24115                            vl_noop_handler,                     \
24116                            vl_api_##n##_t_endian,               \
24117                            vl_api_##n##_t_print,                \
24118                            sizeof(vl_api_##n##_t), 1);
24119   foreach_vpe_api_reply_msg;
24120 #if VPP_API_TEST_BUILTIN == 0
24121   foreach_standalone_reply_msg;
24122 #endif
24123 #undef _
24124
24125 #if (VPP_API_TEST_BUILTIN==0)
24126   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24127
24128   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24129
24130   vam->function_by_name = hash_create_string (0, sizeof (uword));
24131
24132   vam->help_by_name = hash_create_string (0, sizeof (uword));
24133 #endif
24134
24135   /* API messages we can send */
24136 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24137   foreach_vpe_api_msg;
24138 #undef _
24139
24140   /* Help strings */
24141 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24142   foreach_vpe_api_msg;
24143 #undef _
24144
24145   /* CLI functions */
24146 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24147   foreach_cli_function;
24148 #undef _
24149
24150   /* Help strings */
24151 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24152   foreach_cli_function;
24153 #undef _
24154 }
24155
24156 #if VPP_API_TEST_BUILTIN
24157 static clib_error_t *
24158 vat_api_hookup_shim (vlib_main_t * vm)
24159 {
24160   vat_api_hookup (&vat_main);
24161   return 0;
24162 }
24163
24164 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24165 #endif
24166
24167 /*
24168  * fd.io coding-style-patch-verification: ON
24169  *
24170  * Local Variables:
24171  * eval: (c-set-style "gnu")
24172  * End:
24173  */