[aarch64] Fixes CLI crashes on dpaa2 platform.
[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 <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52
53 #include "vat/json_format.h"
54
55 #include <inttypes.h>
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp/api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp/api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp/api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 #define __plugin_msg_base 0
75 #include <vlibapi/vat_helper_macros.h>
76
77 #if VPP_API_TEST_BUILTIN == 0
78 #include <netdb.h>
79
80 u32
81 vl (void *p)
82 {
83   return vec_len (p);
84 }
85
86 int
87 vat_socket_connect (vat_main_t * vam)
88 {
89   return vl_socket_client_connect
90     (&vam->socket_client_main, (char *) vam->socket_name,
91      "vpp_api_test(s)", 0 /* default socket rx, tx buffer */ );
92 }
93 #else /* vpp built-in case, we don't do sockets... */
94 int
95 vat_socket_connect (vat_main_t * vam)
96 {
97   return 0;
98 }
99
100 void
101 vl_socket_client_read_reply (socket_client_main_t * scm)
102 {
103 };
104 #endif
105
106
107 f64
108 vat_time_now (vat_main_t * vam)
109 {
110 #if VPP_API_TEST_BUILTIN
111   return vlib_time_now (vam->vlib_main);
112 #else
113   return clib_time_now (&vam->clib_time);
114 #endif
115 }
116
117 void
118 errmsg (char *fmt, ...)
119 {
120   vat_main_t *vam = &vat_main;
121   va_list va;
122   u8 *s;
123
124   va_start (va, fmt);
125   s = va_format (0, fmt, &va);
126   va_end (va);
127
128   vec_add1 (s, 0);
129
130 #if VPP_API_TEST_BUILTIN
131   vlib_cli_output (vam->vlib_main, (char *) s);
132 #else
133   {
134     if (vam->ifp != stdin)
135       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
136                vam->input_line_number);
137     fformat (vam->ofp, (char *) s);
138     fflush (vam->ofp);
139   }
140 #endif
141
142   vec_free (s);
143 }
144
145 #if VPP_API_TEST_BUILTIN == 0
146 static uword
147 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
148 {
149   vat_main_t *vam = va_arg (*args, vat_main_t *);
150   u32 *result = va_arg (*args, u32 *);
151   u8 *if_name;
152   uword *p;
153
154   if (!unformat (input, "%s", &if_name))
155     return 0;
156
157   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
158   if (p == 0)
159     return 0;
160   *result = p[0];
161   return 1;
162 }
163
164 /* Parse an IP4 address %d.%d.%d.%d. */
165 uword
166 unformat_ip4_address (unformat_input_t * input, va_list * args)
167 {
168   u8 *result = va_arg (*args, u8 *);
169   unsigned a[4];
170
171   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
172     return 0;
173
174   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
175     return 0;
176
177   result[0] = a[0];
178   result[1] = a[1];
179   result[2] = a[2];
180   result[3] = a[3];
181
182   return 1;
183 }
184
185 uword
186 unformat_ethernet_address (unformat_input_t * input, va_list * args)
187 {
188   u8 *result = va_arg (*args, u8 *);
189   u32 i, a[6];
190
191   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
192                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
193     return 0;
194
195   /* Check range. */
196   for (i = 0; i < 6; i++)
197     if (a[i] >= (1 << 8))
198       return 0;
199
200   for (i = 0; i < 6; i++)
201     result[i] = a[i];
202
203   return 1;
204 }
205
206 /* Returns ethernet type as an int in host byte order. */
207 uword
208 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
209                                         va_list * args)
210 {
211   u16 *result = va_arg (*args, u16 *);
212   int type;
213
214   /* Numeric type. */
215   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
216     {
217       if (type >= (1 << 16))
218         return 0;
219       *result = type;
220       return 1;
221     }
222   return 0;
223 }
224
225 /* Parse an IP6 address. */
226 uword
227 unformat_ip6_address (unformat_input_t * input, va_list * args)
228 {
229   ip6_address_t *result = va_arg (*args, ip6_address_t *);
230   u16 hex_quads[8];
231   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
232   uword c, n_colon, double_colon_index;
233
234   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
235   double_colon_index = ARRAY_LEN (hex_quads);
236   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
237     {
238       hex_digit = 16;
239       if (c >= '0' && c <= '9')
240         hex_digit = c - '0';
241       else if (c >= 'a' && c <= 'f')
242         hex_digit = c + 10 - 'a';
243       else if (c >= 'A' && c <= 'F')
244         hex_digit = c + 10 - 'A';
245       else if (c == ':' && n_colon < 2)
246         n_colon++;
247       else
248         {
249           unformat_put_input (input);
250           break;
251         }
252
253       /* Too many hex quads. */
254       if (n_hex_quads >= ARRAY_LEN (hex_quads))
255         return 0;
256
257       if (hex_digit < 16)
258         {
259           hex_quad = (hex_quad << 4) | hex_digit;
260
261           /* Hex quad must fit in 16 bits. */
262           if (n_hex_digits >= 4)
263             return 0;
264
265           n_colon = 0;
266           n_hex_digits++;
267         }
268
269       /* Save position of :: */
270       if (n_colon == 2)
271         {
272           /* More than one :: ? */
273           if (double_colon_index < ARRAY_LEN (hex_quads))
274             return 0;
275           double_colon_index = n_hex_quads;
276         }
277
278       if (n_colon > 0 && n_hex_digits > 0)
279         {
280           hex_quads[n_hex_quads++] = hex_quad;
281           hex_quad = 0;
282           n_hex_digits = 0;
283         }
284     }
285
286   if (n_hex_digits > 0)
287     hex_quads[n_hex_quads++] = hex_quad;
288
289   {
290     word i;
291
292     /* Expand :: to appropriate number of zero hex quads. */
293     if (double_colon_index < ARRAY_LEN (hex_quads))
294       {
295         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
296
297         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
298           hex_quads[n_zero + i] = hex_quads[i];
299
300         for (i = 0; i < n_zero; i++)
301           hex_quads[double_colon_index + i] = 0;
302
303         n_hex_quads = ARRAY_LEN (hex_quads);
304       }
305
306     /* Too few hex quads given. */
307     if (n_hex_quads < ARRAY_LEN (hex_quads))
308       return 0;
309
310     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
311       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
312
313     return 1;
314   }
315 }
316
317 uword
318 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
319 {
320   u32 *r = va_arg (*args, u32 *);
321
322   if (0);
323 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
324   foreach_ipsec_policy_action
325 #undef _
326     else
327     return 0;
328   return 1;
329 }
330
331 uword
332 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
338   foreach_ipsec_crypto_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_crypto_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_crypto_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
369   foreach_ipsec_integ_alg
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 u8 *
377 format_ipsec_integ_alg (u8 * s, va_list * args)
378 {
379   u32 i = va_arg (*args, u32);
380   u8 *t = 0;
381
382   switch (i)
383     {
384 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
385       foreach_ipsec_integ_alg
386 #undef _
387     default:
388       return format (s, "unknown");
389     }
390   return format (s, "%s", t);
391 }
392
393 uword
394 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
395 {
396   u32 *r = va_arg (*args, u32 *);
397
398   if (0);
399 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
400   foreach_ikev2_auth_method
401 #undef _
402     else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
409 {
410   u32 *r = va_arg (*args, u32 *);
411
412   if (0);
413 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
414   foreach_ikev2_id_type
415 #undef _
416     else
417     return 0;
418   return 1;
419 }
420 #else /* VPP_API_TEST_BUILTIN == 1 */
421 static uword
422 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
423 {
424   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
425   vnet_main_t *vnm = vnet_get_main ();
426   u32 *result = va_arg (*args, u32 *);
427   u32 sw_if_index;
428
429   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
430     return 0;
431
432   *result = sw_if_index;
433   return 1;
434 }
435 #endif /* VPP_API_TEST_BUILTIN */
436
437 static uword
438 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
439 {
440   u8 *r = va_arg (*args, u8 *);
441
442   if (unformat (input, "kbps"))
443     *r = SSE2_QOS_RATE_KBPS;
444   else if (unformat (input, "pps"))
445     *r = SSE2_QOS_RATE_PPS;
446   else
447     return 0;
448   return 1;
449 }
450
451 static uword
452 unformat_policer_round_type (unformat_input_t * input, va_list * args)
453 {
454   u8 *r = va_arg (*args, u8 *);
455
456   if (unformat (input, "closest"))
457     *r = SSE2_QOS_ROUND_TO_CLOSEST;
458   else if (unformat (input, "up"))
459     *r = SSE2_QOS_ROUND_TO_UP;
460   else if (unformat (input, "down"))
461     *r = SSE2_QOS_ROUND_TO_DOWN;
462   else
463     return 0;
464   return 1;
465 }
466
467 static uword
468 unformat_policer_type (unformat_input_t * input, va_list * args)
469 {
470   u8 *r = va_arg (*args, u8 *);
471
472   if (unformat (input, "1r2c"))
473     *r = SSE2_QOS_POLICER_TYPE_1R2C;
474   else if (unformat (input, "1r3c"))
475     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
476   else if (unformat (input, "2r3c-2698"))
477     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
478   else if (unformat (input, "2r3c-4115"))
479     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
480   else if (unformat (input, "2r3c-mef5cf1"))
481     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_dscp (unformat_input_t * input, va_list * va)
489 {
490   u8 *r = va_arg (*va, u8 *);
491
492   if (0);
493 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
494   foreach_vnet_dscp
495 #undef _
496     else
497     return 0;
498   return 1;
499 }
500
501 static uword
502 unformat_policer_action_type (unformat_input_t * input, va_list * va)
503 {
504   sse2_qos_pol_action_params_st *a
505     = va_arg (*va, sse2_qos_pol_action_params_st *);
506
507   if (unformat (input, "drop"))
508     a->action_type = SSE2_QOS_ACTION_DROP;
509   else if (unformat (input, "transmit"))
510     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
511   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
512     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
513   else
514     return 0;
515   return 1;
516 }
517
518 static uword
519 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
520 {
521   u32 *r = va_arg (*va, u32 *);
522   u32 tid;
523
524   if (unformat (input, "ip4"))
525     tid = POLICER_CLASSIFY_TABLE_IP4;
526   else if (unformat (input, "ip6"))
527     tid = POLICER_CLASSIFY_TABLE_IP6;
528   else if (unformat (input, "l2"))
529     tid = POLICER_CLASSIFY_TABLE_L2;
530   else
531     return 0;
532
533   *r = tid;
534   return 1;
535 }
536
537 static uword
538 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
539 {
540   u32 *r = va_arg (*va, u32 *);
541   u32 tid;
542
543   if (unformat (input, "ip4"))
544     tid = FLOW_CLASSIFY_TABLE_IP4;
545   else if (unformat (input, "ip6"))
546     tid = FLOW_CLASSIFY_TABLE_IP6;
547   else
548     return 0;
549
550   *r = tid;
551   return 1;
552 }
553
554 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
555 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
556 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
557 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
558
559 #if (VPP_API_TEST_BUILTIN==0)
560 uword
561 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
562 {
563   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
564   mfib_itf_attribute_t attr;
565
566   old = *iflags;
567   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
568   {
569     if (unformat (input, mfib_itf_flag_long_names[attr]))
570       *iflags |= (1 << attr);
571   }
572   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
573   {
574     if (unformat (input, mfib_itf_flag_names[attr]))
575       *iflags |= (1 << attr);
576   }
577
578   return (old == *iflags ? 0 : 1);
579 }
580
581 uword
582 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
583 {
584   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
585   mfib_entry_attribute_t attr;
586
587   old = *eflags;
588   FOR_EACH_MFIB_ATTRIBUTE (attr)
589   {
590     if (unformat (input, mfib_flag_long_names[attr]))
591       *eflags |= (1 << attr);
592   }
593   FOR_EACH_MFIB_ATTRIBUTE (attr)
594   {
595     if (unformat (input, mfib_flag_names[attr]))
596       *eflags |= (1 << attr);
597   }
598
599   return (old == *eflags ? 0 : 1);
600 }
601
602 u8 *
603 format_ip4_address (u8 * s, va_list * args)
604 {
605   u8 *a = va_arg (*args, u8 *);
606   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
607 }
608
609 u8 *
610 format_ip6_address (u8 * s, va_list * args)
611 {
612   ip6_address_t *a = va_arg (*args, ip6_address_t *);
613   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
614
615   i_max_n_zero = ARRAY_LEN (a->as_u16);
616   max_n_zeros = 0;
617   i_first_zero = i_max_n_zero;
618   n_zeros = 0;
619   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
620     {
621       u32 is_zero = a->as_u16[i] == 0;
622       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
623         {
624           i_first_zero = i;
625           n_zeros = 0;
626         }
627       n_zeros += is_zero;
628       if ((!is_zero && n_zeros > max_n_zeros)
629           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
630         {
631           i_max_n_zero = i_first_zero;
632           max_n_zeros = n_zeros;
633           i_first_zero = ARRAY_LEN (a->as_u16);
634           n_zeros = 0;
635         }
636     }
637
638   last_double_colon = 0;
639   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
640     {
641       if (i == i_max_n_zero && max_n_zeros > 1)
642         {
643           s = format (s, "::");
644           i += max_n_zeros - 1;
645           last_double_colon = 1;
646         }
647       else
648         {
649           s = format (s, "%s%x",
650                       (last_double_colon || i == 0) ? "" : ":",
651                       clib_net_to_host_u16 (a->as_u16[i]));
652           last_double_colon = 0;
653         }
654     }
655
656   return s;
657 }
658
659 /* Format an IP46 address. */
660 u8 *
661 format_ip46_address (u8 * s, va_list * args)
662 {
663   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
664   ip46_type_t type = va_arg (*args, ip46_type_t);
665   int is_ip4 = 1;
666
667   switch (type)
668     {
669     case IP46_TYPE_ANY:
670       is_ip4 = ip46_address_is_ip4 (ip46);
671       break;
672     case IP46_TYPE_IP4:
673       is_ip4 = 1;
674       break;
675     case IP46_TYPE_IP6:
676       is_ip4 = 0;
677       break;
678     }
679
680   return is_ip4 ?
681     format (s, "%U", format_ip4_address, &ip46->ip4) :
682     format (s, "%U", format_ip6_address, &ip46->ip6);
683 }
684
685 u8 *
686 format_ethernet_address (u8 * s, va_list * args)
687 {
688   u8 *a = va_arg (*args, u8 *);
689
690   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
691                  a[0], a[1], a[2], a[3], a[4], a[5]);
692 }
693 #endif
694
695 static void
696 increment_v4_address (ip4_address_t * a)
697 {
698   u32 v;
699
700   v = ntohl (a->as_u32) + 1;
701   a->as_u32 = ntohl (v);
702 }
703
704 static void
705 increment_v6_address (ip6_address_t * a)
706 {
707   u64 v0, v1;
708
709   v0 = clib_net_to_host_u64 (a->as_u64[0]);
710   v1 = clib_net_to_host_u64 (a->as_u64[1]);
711
712   v1 += 1;
713   if (v1 == 0)
714     v0 += 1;
715   a->as_u64[0] = clib_net_to_host_u64 (v0);
716   a->as_u64[1] = clib_net_to_host_u64 (v1);
717 }
718
719 static void
720 increment_mac_address (u64 * mac)
721 {
722   u64 tmp = *mac;
723
724   tmp = clib_net_to_host_u64 (tmp);
725   tmp += 1 << 16;               /* skip unused (least significant) octets */
726   tmp = clib_host_to_net_u64 (tmp);
727   *mac = tmp;
728 }
729
730 static void vl_api_create_loopback_reply_t_handler
731   (vl_api_create_loopback_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   i32 retval = ntohl (mp->retval);
735
736   vam->retval = retval;
737   vam->regenerate_interface_table = 1;
738   vam->sw_if_index = ntohl (mp->sw_if_index);
739   vam->result_ready = 1;
740 }
741
742 static void vl_api_create_loopback_reply_t_handler_json
743   (vl_api_create_loopback_reply_t * mp)
744 {
745   vat_main_t *vam = &vat_main;
746   vat_json_node_t node;
747
748   vat_json_init_object (&node);
749   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
750   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
751
752   vat_json_print (vam->ofp, &node);
753   vat_json_free (&node);
754   vam->retval = ntohl (mp->retval);
755   vam->result_ready = 1;
756 }
757
758 static void vl_api_create_loopback_instance_reply_t_handler
759   (vl_api_create_loopback_instance_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_instance_reply_t_handler_json
771   (vl_api_create_loopback_instance_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_af_packet_create_reply_t_handler
787   (vl_api_af_packet_create_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_af_packet_create_reply_t_handler_json
799   (vl_api_af_packet_create_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
811   vam->retval = ntohl (mp->retval);
812   vam->result_ready = 1;
813 }
814
815 static void vl_api_create_vlan_subif_reply_t_handler
816   (vl_api_create_vlan_subif_reply_t * mp)
817 {
818   vat_main_t *vam = &vat_main;
819   i32 retval = ntohl (mp->retval);
820
821   vam->retval = retval;
822   vam->regenerate_interface_table = 1;
823   vam->sw_if_index = ntohl (mp->sw_if_index);
824   vam->result_ready = 1;
825 }
826
827 static void vl_api_create_vlan_subif_reply_t_handler_json
828   (vl_api_create_vlan_subif_reply_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   vat_json_node_t node;
832
833   vat_json_init_object (&node);
834   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
835   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
836
837   vat_json_print (vam->ofp, &node);
838   vat_json_free (&node);
839
840   vam->retval = ntohl (mp->retval);
841   vam->result_ready = 1;
842 }
843
844 static void vl_api_create_subif_reply_t_handler
845   (vl_api_create_subif_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->regenerate_interface_table = 1;
852   vam->sw_if_index = ntohl (mp->sw_if_index);
853   vam->result_ready = 1;
854 }
855
856 static void vl_api_create_subif_reply_t_handler_json
857   (vl_api_create_subif_reply_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   vat_json_node_t node;
861
862   vat_json_init_object (&node);
863   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
864   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
865
866   vat_json_print (vam->ofp, &node);
867   vat_json_free (&node);
868
869   vam->retval = ntohl (mp->retval);
870   vam->result_ready = 1;
871 }
872
873 static void vl_api_interface_name_renumber_reply_t_handler
874   (vl_api_interface_name_renumber_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   i32 retval = ntohl (mp->retval);
878
879   vam->retval = retval;
880   vam->regenerate_interface_table = 1;
881   vam->result_ready = 1;
882 }
883
884 static void vl_api_interface_name_renumber_reply_t_handler_json
885   (vl_api_interface_name_renumber_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
893   vat_json_print (vam->ofp, &node);
894   vat_json_free (&node);
895
896   vam->retval = ntohl (mp->retval);
897   vam->result_ready = 1;
898 }
899
900 /*
901  * Special-case: build the interface table, maintain
902  * the next loopback sw_if_index vbl.
903  */
904 static void vl_api_sw_interface_details_t_handler
905   (vl_api_sw_interface_details_t * mp)
906 {
907   vat_main_t *vam = &vat_main;
908   u8 *s = format (0, "%s%c", mp->interface_name, 0);
909
910   hash_set_mem (vam->sw_if_index_by_interface_name, s,
911                 ntohl (mp->sw_if_index));
912
913   /* In sub interface case, fill the sub interface table entry */
914   if (mp->sw_if_index != mp->sup_sw_if_index)
915     {
916       sw_interface_subif_t *sub = NULL;
917
918       vec_add2 (vam->sw_if_subif_table, sub, 1);
919
920       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
921       strncpy ((char *) sub->interface_name, (char *) s,
922                vec_len (sub->interface_name));
923       sub->sw_if_index = ntohl (mp->sw_if_index);
924       sub->sub_id = ntohl (mp->sub_id);
925
926       sub->sub_dot1ad = mp->sub_dot1ad;
927       sub->sub_number_of_tags = mp->sub_number_of_tags;
928       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
929       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
930       sub->sub_exact_match = mp->sub_exact_match;
931       sub->sub_default = mp->sub_default;
932       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
933       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
934
935       /* vlan tag rewrite */
936       sub->vtr_op = ntohl (mp->vtr_op);
937       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
938       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
939       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
940     }
941 }
942
943 static void vl_api_sw_interface_details_t_handler_json
944   (vl_api_sw_interface_details_t * mp)
945 {
946   vat_main_t *vam = &vat_main;
947   vat_json_node_t *node = NULL;
948
949   if (VAT_JSON_ARRAY != vam->json_tree.type)
950     {
951       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
952       vat_json_init_array (&vam->json_tree);
953     }
954   node = vat_json_array_add (&vam->json_tree);
955
956   vat_json_init_object (node);
957   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
958   vat_json_object_add_uint (node, "sup_sw_if_index",
959                             ntohl (mp->sup_sw_if_index));
960   vat_json_object_add_uint (node, "l2_address_length",
961                             ntohl (mp->l2_address_length));
962   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
963                              sizeof (mp->l2_address));
964   vat_json_object_add_string_copy (node, "interface_name",
965                                    mp->interface_name);
966   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
967   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
968   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
969   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
970   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
971   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
972   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
973   vat_json_object_add_uint (node, "sub_number_of_tags",
974                             mp->sub_number_of_tags);
975   vat_json_object_add_uint (node, "sub_outer_vlan_id",
976                             ntohs (mp->sub_outer_vlan_id));
977   vat_json_object_add_uint (node, "sub_inner_vlan_id",
978                             ntohs (mp->sub_inner_vlan_id));
979   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
980   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
981   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
982                             mp->sub_outer_vlan_id_any);
983   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
984                             mp->sub_inner_vlan_id_any);
985   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
986   vat_json_object_add_uint (node, "vtr_push_dot1q",
987                             ntohl (mp->vtr_push_dot1q));
988   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
989   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
990   if (mp->sub_dot1ah)
991     {
992       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
993                                        format (0, "%U",
994                                                format_ethernet_address,
995                                                &mp->b_dmac));
996       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
997                                        format (0, "%U",
998                                                format_ethernet_address,
999                                                &mp->b_smac));
1000       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1001       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1002     }
1003 }
1004
1005 #if VPP_API_TEST_BUILTIN == 0
1006 static void vl_api_sw_interface_event_t_handler
1007   (vl_api_sw_interface_event_t * mp)
1008 {
1009   vat_main_t *vam = &vat_main;
1010   if (vam->interface_event_display)
1011     errmsg ("interface flags: sw_if_index %d %s %s",
1012             ntohl (mp->sw_if_index),
1013             mp->admin_up_down ? "admin-up" : "admin-down",
1014             mp->link_up_down ? "link-up" : "link-down");
1015 }
1016 #endif
1017
1018 static void vl_api_sw_interface_event_t_handler_json
1019   (vl_api_sw_interface_event_t * mp)
1020 {
1021   /* JSON output not supported */
1022 }
1023
1024 static void
1025 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1026 {
1027   vat_main_t *vam = &vat_main;
1028   i32 retval = ntohl (mp->retval);
1029
1030   vam->retval = retval;
1031   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1032   vam->result_ready = 1;
1033 }
1034
1035 static void
1036 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1037 {
1038   vat_main_t *vam = &vat_main;
1039   vat_json_node_t node;
1040   api_main_t *am = &api_main;
1041   void *oldheap;
1042   u8 *reply;
1043
1044   vat_json_init_object (&node);
1045   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1046   vat_json_object_add_uint (&node, "reply_in_shmem",
1047                             ntohl (mp->reply_in_shmem));
1048   /* Toss the shared-memory original... */
1049   pthread_mutex_lock (&am->vlib_rp->mutex);
1050   oldheap = svm_push_data_heap (am->vlib_rp);
1051
1052   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1053   vec_free (reply);
1054
1055   svm_pop_heap (oldheap);
1056   pthread_mutex_unlock (&am->vlib_rp->mutex);
1057
1058   vat_json_print (vam->ofp, &node);
1059   vat_json_free (&node);
1060
1061   vam->retval = ntohl (mp->retval);
1062   vam->result_ready = 1;
1063 }
1064
1065 static void
1066 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   i32 retval = ntohl (mp->retval);
1070   u32 length = ntohl (mp->length);
1071
1072   vec_reset_length (vam->cmd_reply);
1073
1074   vam->retval = retval;
1075   if (retval == 0)
1076     {
1077       vec_validate (vam->cmd_reply, length);
1078       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1079       vam->cmd_reply[length] = 0;
1080     }
1081   vam->result_ready = 1;
1082 }
1083
1084 static void
1085 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vec_reset_length (vam->cmd_reply);
1091
1092   vat_json_init_object (&node);
1093   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1094   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1095
1096   vat_json_print (vam->ofp, &node);
1097   vat_json_free (&node);
1098
1099   vam->retval = ntohl (mp->retval);
1100   vam->result_ready = 1;
1101 }
1102
1103 static void vl_api_classify_add_del_table_reply_t_handler
1104   (vl_api_classify_add_del_table_reply_t * mp)
1105 {
1106   vat_main_t *vam = &vat_main;
1107   i32 retval = ntohl (mp->retval);
1108   if (vam->async_mode)
1109     {
1110       vam->async_errors += (retval < 0);
1111     }
1112   else
1113     {
1114       vam->retval = retval;
1115       if (retval == 0 &&
1116           ((mp->new_table_index != 0xFFFFFFFF) ||
1117            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1118            (mp->match_n_vectors != 0xFFFFFFFF)))
1119         /*
1120          * Note: this is just barely thread-safe, depends on
1121          * the main thread spinning waiting for an answer...
1122          */
1123         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1124                 ntohl (mp->new_table_index),
1125                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1126       vam->result_ready = 1;
1127     }
1128 }
1129
1130 static void vl_api_classify_add_del_table_reply_t_handler_json
1131   (vl_api_classify_add_del_table_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   vat_json_node_t node;
1135
1136   vat_json_init_object (&node);
1137   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1138   vat_json_object_add_uint (&node, "new_table_index",
1139                             ntohl (mp->new_table_index));
1140   vat_json_object_add_uint (&node, "skip_n_vectors",
1141                             ntohl (mp->skip_n_vectors));
1142   vat_json_object_add_uint (&node, "match_n_vectors",
1143                             ntohl (mp->match_n_vectors));
1144
1145   vat_json_print (vam->ofp, &node);
1146   vat_json_free (&node);
1147
1148   vam->retval = ntohl (mp->retval);
1149   vam->result_ready = 1;
1150 }
1151
1152 static void vl_api_get_node_index_reply_t_handler
1153   (vl_api_get_node_index_reply_t * mp)
1154 {
1155   vat_main_t *vam = &vat_main;
1156   i32 retval = ntohl (mp->retval);
1157   if (vam->async_mode)
1158     {
1159       vam->async_errors += (retval < 0);
1160     }
1161   else
1162     {
1163       vam->retval = retval;
1164       if (retval == 0)
1165         errmsg ("node index %d", ntohl (mp->node_index));
1166       vam->result_ready = 1;
1167     }
1168 }
1169
1170 static void vl_api_get_node_index_reply_t_handler_json
1171   (vl_api_get_node_index_reply_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   vat_json_node_t node;
1175
1176   vat_json_init_object (&node);
1177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1178   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1179
1180   vat_json_print (vam->ofp, &node);
1181   vat_json_free (&node);
1182
1183   vam->retval = ntohl (mp->retval);
1184   vam->result_ready = 1;
1185 }
1186
1187 static void vl_api_get_next_index_reply_t_handler
1188   (vl_api_get_next_index_reply_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   i32 retval = ntohl (mp->retval);
1192   if (vam->async_mode)
1193     {
1194       vam->async_errors += (retval < 0);
1195     }
1196   else
1197     {
1198       vam->retval = retval;
1199       if (retval == 0)
1200         errmsg ("next node index %d", ntohl (mp->next_index));
1201       vam->result_ready = 1;
1202     }
1203 }
1204
1205 static void vl_api_get_next_index_reply_t_handler_json
1206   (vl_api_get_next_index_reply_t * mp)
1207 {
1208   vat_main_t *vam = &vat_main;
1209   vat_json_node_t node;
1210
1211   vat_json_init_object (&node);
1212   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1213   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1214
1215   vat_json_print (vam->ofp, &node);
1216   vat_json_free (&node);
1217
1218   vam->retval = ntohl (mp->retval);
1219   vam->result_ready = 1;
1220 }
1221
1222 static void vl_api_add_node_next_reply_t_handler
1223   (vl_api_add_node_next_reply_t * mp)
1224 {
1225   vat_main_t *vam = &vat_main;
1226   i32 retval = ntohl (mp->retval);
1227   if (vam->async_mode)
1228     {
1229       vam->async_errors += (retval < 0);
1230     }
1231   else
1232     {
1233       vam->retval = retval;
1234       if (retval == 0)
1235         errmsg ("next index %d", ntohl (mp->next_index));
1236       vam->result_ready = 1;
1237     }
1238 }
1239
1240 static void vl_api_add_node_next_reply_t_handler_json
1241   (vl_api_add_node_next_reply_t * mp)
1242 {
1243   vat_main_t *vam = &vat_main;
1244   vat_json_node_t node;
1245
1246   vat_json_init_object (&node);
1247   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1248   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1249
1250   vat_json_print (vam->ofp, &node);
1251   vat_json_free (&node);
1252
1253   vam->retval = ntohl (mp->retval);
1254   vam->result_ready = 1;
1255 }
1256
1257 static void vl_api_show_version_reply_t_handler
1258   (vl_api_show_version_reply_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   i32 retval = ntohl (mp->retval);
1262
1263   if (retval >= 0)
1264     {
1265       errmsg ("        program: %s", mp->program);
1266       errmsg ("        version: %s", mp->version);
1267       errmsg ("     build date: %s", mp->build_date);
1268       errmsg ("build directory: %s", mp->build_directory);
1269     }
1270   vam->retval = retval;
1271   vam->result_ready = 1;
1272 }
1273
1274 static void vl_api_show_version_reply_t_handler_json
1275   (vl_api_show_version_reply_t * mp)
1276 {
1277   vat_main_t *vam = &vat_main;
1278   vat_json_node_t node;
1279
1280   vat_json_init_object (&node);
1281   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1282   vat_json_object_add_string_copy (&node, "program", mp->program);
1283   vat_json_object_add_string_copy (&node, "version", mp->version);
1284   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1285   vat_json_object_add_string_copy (&node, "build_directory",
1286                                    mp->build_directory);
1287
1288   vat_json_print (vam->ofp, &node);
1289   vat_json_free (&node);
1290
1291   vam->retval = ntohl (mp->retval);
1292   vam->result_ready = 1;
1293 }
1294
1295 static void
1296 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1297 {
1298   u32 sw_if_index = ntohl (mp->sw_if_index);
1299   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1300           mp->mac_ip ? "mac/ip binding" : "address resolution",
1301           ntohl (mp->pid), format_ip4_address, &mp->address,
1302           format_ethernet_address, mp->new_mac, sw_if_index);
1303 }
1304
1305 static void
1306 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1307 {
1308   /* JSON output not supported */
1309 }
1310
1311 static void
1312 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1313 {
1314   u32 sw_if_index = ntohl (mp->sw_if_index);
1315   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1316           mp->mac_ip ? "mac/ip binding" : "address resolution",
1317           ntohl (mp->pid), format_ip6_address, mp->address,
1318           format_ethernet_address, mp->new_mac, sw_if_index);
1319 }
1320
1321 static void
1322 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1323 {
1324   /* JSON output not supported */
1325 }
1326
1327 static void
1328 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1329 {
1330   u32 n_macs = ntohl (mp->n_macs);
1331   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1332           ntohl (mp->pid), mp->client_index, n_macs);
1333   int i;
1334   for (i = 0; i < n_macs; i++)
1335     {
1336       vl_api_mac_entry_t *mac = &mp->mac[i];
1337       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1338               i + 1, ntohl (mac->sw_if_index),
1339               format_ethernet_address, mac->mac_addr, mac->is_del);
1340       if (i == 1000)
1341         break;
1342     }
1343 }
1344
1345 static void
1346 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1347 {
1348   /* JSON output not supported */
1349 }
1350
1351 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1352 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1353
1354 /*
1355  * Special-case: build the bridge domain table, maintain
1356  * the next bd id vbl.
1357  */
1358 static void vl_api_bridge_domain_details_t_handler
1359   (vl_api_bridge_domain_details_t * mp)
1360 {
1361   vat_main_t *vam = &vat_main;
1362   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1363   int i;
1364
1365   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1366          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1367
1368   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1369          ntohl (mp->bd_id), mp->learn, mp->forward,
1370          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1371
1372   if (n_sw_ifs)
1373     {
1374       vl_api_bridge_domain_sw_if_t *sw_ifs;
1375       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1376              "Interface Name");
1377
1378       sw_ifs = mp->sw_if_details;
1379       for (i = 0; i < n_sw_ifs; i++)
1380         {
1381           u8 *sw_if_name = 0;
1382           u32 sw_if_index;
1383           hash_pair_t *p;
1384
1385           sw_if_index = ntohl (sw_ifs->sw_if_index);
1386
1387           /* *INDENT-OFF* */
1388           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1389                              ({
1390                                if ((u32) p->value[0] == sw_if_index)
1391                                  {
1392                                    sw_if_name = (u8 *)(p->key);
1393                                    break;
1394                                  }
1395                              }));
1396           /* *INDENT-ON* */
1397           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1398                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1399                  "sw_if_index not found!");
1400
1401           sw_ifs++;
1402         }
1403     }
1404 }
1405
1406 static void vl_api_bridge_domain_details_t_handler_json
1407   (vl_api_bridge_domain_details_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t *node, *array = NULL;
1411   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1412
1413   if (VAT_JSON_ARRAY != vam->json_tree.type)
1414     {
1415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1416       vat_json_init_array (&vam->json_tree);
1417     }
1418   node = vat_json_array_add (&vam->json_tree);
1419
1420   vat_json_init_object (node);
1421   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1422   vat_json_object_add_uint (node, "flood", mp->flood);
1423   vat_json_object_add_uint (node, "forward", mp->forward);
1424   vat_json_object_add_uint (node, "learn", mp->learn);
1425   vat_json_object_add_uint (node, "bvi_sw_if_index",
1426                             ntohl (mp->bvi_sw_if_index));
1427   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1428   array = vat_json_object_add (node, "sw_if");
1429   vat_json_init_array (array);
1430
1431
1432
1433   if (n_sw_ifs)
1434     {
1435       vl_api_bridge_domain_sw_if_t *sw_ifs;
1436       int i;
1437
1438       sw_ifs = mp->sw_if_details;
1439       for (i = 0; i < n_sw_ifs; i++)
1440         {
1441           node = vat_json_array_add (array);
1442           vat_json_init_object (node);
1443           vat_json_object_add_uint (node, "sw_if_index",
1444                                     ntohl (sw_ifs->sw_if_index));
1445           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1446           sw_ifs++;
1447         }
1448     }
1449 }
1450
1451 static void vl_api_control_ping_reply_t_handler
1452   (vl_api_control_ping_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   i32 retval = ntohl (mp->retval);
1456   if (vam->async_mode)
1457     {
1458       vam->async_errors += (retval < 0);
1459     }
1460   else
1461     {
1462       vam->retval = retval;
1463       vam->result_ready = 1;
1464     }
1465   vam->socket_client_main.control_pings_outstanding--;
1466 }
1467
1468 static void vl_api_control_ping_reply_t_handler_json
1469   (vl_api_control_ping_reply_t * mp)
1470 {
1471   vat_main_t *vam = &vat_main;
1472   i32 retval = ntohl (mp->retval);
1473
1474   if (VAT_JSON_NONE != vam->json_tree.type)
1475     {
1476       vat_json_print (vam->ofp, &vam->json_tree);
1477       vat_json_free (&vam->json_tree);
1478       vam->json_tree.type = VAT_JSON_NONE;
1479     }
1480   else
1481     {
1482       /* just print [] */
1483       vat_json_init_array (&vam->json_tree);
1484       vat_json_print (vam->ofp, &vam->json_tree);
1485       vam->json_tree.type = VAT_JSON_NONE;
1486     }
1487
1488   vam->retval = retval;
1489   vam->result_ready = 1;
1490 }
1491
1492 static void
1493   vl_api_bridge_domain_set_mac_age_reply_t_handler
1494   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   i32 retval = ntohl (mp->retval);
1498   if (vam->async_mode)
1499     {
1500       vam->async_errors += (retval < 0);
1501     }
1502   else
1503     {
1504       vam->retval = retval;
1505       vam->result_ready = 1;
1506     }
1507 }
1508
1509 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1510   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   vat_json_node_t node;
1514
1515   vat_json_init_object (&node);
1516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517
1518   vat_json_print (vam->ofp, &node);
1519   vat_json_free (&node);
1520
1521   vam->retval = ntohl (mp->retval);
1522   vam->result_ready = 1;
1523 }
1524
1525 static void
1526 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   i32 retval = ntohl (mp->retval);
1530   if (vam->async_mode)
1531     {
1532       vam->async_errors += (retval < 0);
1533     }
1534   else
1535     {
1536       vam->retval = retval;
1537       vam->result_ready = 1;
1538     }
1539 }
1540
1541 static void vl_api_l2_flags_reply_t_handler_json
1542   (vl_api_l2_flags_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   vat_json_node_t node;
1546
1547   vat_json_init_object (&node);
1548   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1549   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1550                             ntohl (mp->resulting_feature_bitmap));
1551
1552   vat_json_print (vam->ofp, &node);
1553   vat_json_free (&node);
1554
1555   vam->retval = ntohl (mp->retval);
1556   vam->result_ready = 1;
1557 }
1558
1559 static void vl_api_bridge_flags_reply_t_handler
1560   (vl_api_bridge_flags_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_bridge_flags_reply_t_handler_json
1576   (vl_api_bridge_flags_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1584                             ntohl (mp->resulting_feature_bitmap));
1585
1586   vat_json_print (vam->ofp, &node);
1587   vat_json_free (&node);
1588
1589   vam->retval = ntohl (mp->retval);
1590   vam->result_ready = 1;
1591 }
1592
1593 static void vl_api_tap_connect_reply_t_handler
1594   (vl_api_tap_connect_reply_t * mp)
1595 {
1596   vat_main_t *vam = &vat_main;
1597   i32 retval = ntohl (mp->retval);
1598   if (vam->async_mode)
1599     {
1600       vam->async_errors += (retval < 0);
1601     }
1602   else
1603     {
1604       vam->retval = retval;
1605       vam->sw_if_index = ntohl (mp->sw_if_index);
1606       vam->result_ready = 1;
1607     }
1608
1609 }
1610
1611 static void vl_api_tap_connect_reply_t_handler_json
1612   (vl_api_tap_connect_reply_t * mp)
1613 {
1614   vat_main_t *vam = &vat_main;
1615   vat_json_node_t node;
1616
1617   vat_json_init_object (&node);
1618   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1619   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1620
1621   vat_json_print (vam->ofp, &node);
1622   vat_json_free (&node);
1623
1624   vam->retval = ntohl (mp->retval);
1625   vam->result_ready = 1;
1626
1627 }
1628
1629 static void
1630 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->sw_if_index = ntohl (mp->sw_if_index);
1642       vam->result_ready = 1;
1643     }
1644 }
1645
1646 static void vl_api_tap_modify_reply_t_handler_json
1647   (vl_api_tap_modify_reply_t * mp)
1648 {
1649   vat_main_t *vam = &vat_main;
1650   vat_json_node_t node;
1651
1652   vat_json_init_object (&node);
1653   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1654   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void
1664 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->result_ready = 1;
1676     }
1677 }
1678
1679 static void vl_api_tap_delete_reply_t_handler_json
1680   (vl_api_tap_delete_reply_t * mp)
1681 {
1682   vat_main_t *vam = &vat_main;
1683   vat_json_node_t node;
1684
1685   vat_json_init_object (&node);
1686   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1687
1688   vat_json_print (vam->ofp, &node);
1689   vat_json_free (&node);
1690
1691   vam->retval = ntohl (mp->retval);
1692   vam->result_ready = 1;
1693 }
1694
1695 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1696   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1697 {
1698   vat_main_t *vam = &vat_main;
1699   i32 retval = ntohl (mp->retval);
1700   if (vam->async_mode)
1701     {
1702       vam->async_errors += (retval < 0);
1703     }
1704   else
1705     {
1706       vam->retval = retval;
1707       vam->result_ready = 1;
1708     }
1709 }
1710
1711 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1712   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1713 {
1714   vat_main_t *vam = &vat_main;
1715   vat_json_node_t node;
1716
1717   vat_json_init_object (&node);
1718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1719   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1720                             ntohl (mp->sw_if_index));
1721
1722   vat_json_print (vam->ofp, &node);
1723   vat_json_free (&node);
1724
1725   vam->retval = ntohl (mp->retval);
1726   vam->result_ready = 1;
1727 }
1728
1729 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1730   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1731 {
1732   vat_main_t *vam = &vat_main;
1733   i32 retval = ntohl (mp->retval);
1734   if (vam->async_mode)
1735     {
1736       vam->async_errors += (retval < 0);
1737     }
1738   else
1739     {
1740       vam->retval = retval;
1741       vam->sw_if_index = ntohl (mp->sw_if_index);
1742       vam->result_ready = 1;
1743     }
1744 }
1745
1746 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1747   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   vat_json_node_t node;
1751
1752   vat_json_init_object (&node);
1753   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1754   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1755
1756   vat_json_print (vam->ofp, &node);
1757   vat_json_free (&node);
1758
1759   vam->retval = ntohl (mp->retval);
1760   vam->result_ready = 1;
1761 }
1762
1763 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1764   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1765 {
1766   vat_main_t *vam = &vat_main;
1767   i32 retval = ntohl (mp->retval);
1768   if (vam->async_mode)
1769     {
1770       vam->async_errors += (retval < 0);
1771     }
1772   else
1773     {
1774       vam->retval = retval;
1775       vam->result_ready = 1;
1776     }
1777 }
1778
1779 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1780   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1781 {
1782   vat_main_t *vam = &vat_main;
1783   vat_json_node_t node;
1784
1785   vat_json_init_object (&node);
1786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1787   vat_json_object_add_uint (&node, "fwd_entry_index",
1788                             clib_net_to_host_u32 (mp->fwd_entry_index));
1789
1790   vat_json_print (vam->ofp, &node);
1791   vat_json_free (&node);
1792
1793   vam->retval = ntohl (mp->retval);
1794   vam->result_ready = 1;
1795 }
1796
1797 u8 *
1798 format_lisp_transport_protocol (u8 * s, va_list * args)
1799 {
1800   u32 proto = va_arg (*args, u32);
1801
1802   switch (proto)
1803     {
1804     case 1:
1805       return format (s, "udp");
1806     case 2:
1807       return format (s, "api");
1808     default:
1809       return 0;
1810     }
1811   return 0;
1812 }
1813
1814 static void vl_api_one_get_transport_protocol_reply_t_handler
1815   (vl_api_one_get_transport_protocol_reply_t * mp)
1816 {
1817   vat_main_t *vam = &vat_main;
1818   i32 retval = ntohl (mp->retval);
1819   if (vam->async_mode)
1820     {
1821       vam->async_errors += (retval < 0);
1822     }
1823   else
1824     {
1825       u32 proto = mp->protocol;
1826       print (vam->ofp, "Transport protocol: %U",
1827              format_lisp_transport_protocol, proto);
1828       vam->retval = retval;
1829       vam->result_ready = 1;
1830     }
1831 }
1832
1833 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1834   (vl_api_one_get_transport_protocol_reply_t * mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   vat_json_node_t node;
1838   u8 *s;
1839
1840   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1841   vec_add1 (s, 0);
1842
1843   vat_json_init_object (&node);
1844   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1845   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1846
1847   vec_free (s);
1848   vat_json_print (vam->ofp, &node);
1849   vat_json_free (&node);
1850
1851   vam->retval = ntohl (mp->retval);
1852   vam->result_ready = 1;
1853 }
1854
1855 static void vl_api_one_add_del_locator_set_reply_t_handler
1856   (vl_api_one_add_del_locator_set_reply_t * mp)
1857 {
1858   vat_main_t *vam = &vat_main;
1859   i32 retval = ntohl (mp->retval);
1860   if (vam->async_mode)
1861     {
1862       vam->async_errors += (retval < 0);
1863     }
1864   else
1865     {
1866       vam->retval = retval;
1867       vam->result_ready = 1;
1868     }
1869 }
1870
1871 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1872   (vl_api_one_add_del_locator_set_reply_t * mp)
1873 {
1874   vat_main_t *vam = &vat_main;
1875   vat_json_node_t node;
1876
1877   vat_json_init_object (&node);
1878   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1879   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1880
1881   vat_json_print (vam->ofp, &node);
1882   vat_json_free (&node);
1883
1884   vam->retval = ntohl (mp->retval);
1885   vam->result_ready = 1;
1886 }
1887
1888 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1889   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1890 {
1891   vat_main_t *vam = &vat_main;
1892   i32 retval = ntohl (mp->retval);
1893   if (vam->async_mode)
1894     {
1895       vam->async_errors += (retval < 0);
1896     }
1897   else
1898     {
1899       vam->retval = retval;
1900       vam->sw_if_index = ntohl (mp->sw_if_index);
1901       vam->result_ready = 1;
1902     }
1903 }
1904
1905 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1906   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1907 {
1908   vat_main_t *vam = &vat_main;
1909   vat_json_node_t node;
1910
1911   vat_json_init_object (&node);
1912   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1913   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1914
1915   vat_json_print (vam->ofp, &node);
1916   vat_json_free (&node);
1917
1918   vam->retval = ntohl (mp->retval);
1919   vam->result_ready = 1;
1920 }
1921
1922 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1923   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1924 {
1925   vat_main_t *vam = &vat_main;
1926   i32 retval = ntohl (mp->retval);
1927   if (vam->async_mode)
1928     {
1929       vam->async_errors += (retval < 0);
1930     }
1931   else
1932     {
1933       vam->retval = retval;
1934       vam->sw_if_index = ntohl (mp->sw_if_index);
1935       vam->result_ready = 1;
1936     }
1937 }
1938
1939 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1940   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1941 {
1942   vat_main_t *vam = &vat_main;
1943   vat_json_node_t node;
1944
1945   vat_json_init_object (&node);
1946   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1947   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1948
1949   vat_json_print (vam->ofp, &node);
1950   vat_json_free (&node);
1951
1952   vam->retval = ntohl (mp->retval);
1953   vam->result_ready = 1;
1954 }
1955
1956 static void vl_api_gre_add_del_tunnel_reply_t_handler
1957   (vl_api_gre_add_del_tunnel_reply_t * mp)
1958 {
1959   vat_main_t *vam = &vat_main;
1960   i32 retval = ntohl (mp->retval);
1961   if (vam->async_mode)
1962     {
1963       vam->async_errors += (retval < 0);
1964     }
1965   else
1966     {
1967       vam->retval = retval;
1968       vam->sw_if_index = ntohl (mp->sw_if_index);
1969       vam->result_ready = 1;
1970     }
1971 }
1972
1973 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1974   (vl_api_gre_add_del_tunnel_reply_t * mp)
1975 {
1976   vat_main_t *vam = &vat_main;
1977   vat_json_node_t node;
1978
1979   vat_json_init_object (&node);
1980   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1981   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1982
1983   vat_json_print (vam->ofp, &node);
1984   vat_json_free (&node);
1985
1986   vam->retval = ntohl (mp->retval);
1987   vam->result_ready = 1;
1988 }
1989
1990 static void vl_api_create_vhost_user_if_reply_t_handler
1991   (vl_api_create_vhost_user_if_reply_t * mp)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   i32 retval = ntohl (mp->retval);
1995   if (vam->async_mode)
1996     {
1997       vam->async_errors += (retval < 0);
1998     }
1999   else
2000     {
2001       vam->retval = retval;
2002       vam->sw_if_index = ntohl (mp->sw_if_index);
2003       vam->result_ready = 1;
2004     }
2005 }
2006
2007 static void vl_api_create_vhost_user_if_reply_t_handler_json
2008   (vl_api_create_vhost_user_if_reply_t * mp)
2009 {
2010   vat_main_t *vam = &vat_main;
2011   vat_json_node_t node;
2012
2013   vat_json_init_object (&node);
2014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2015   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2016
2017   vat_json_print (vam->ofp, &node);
2018   vat_json_free (&node);
2019
2020   vam->retval = ntohl (mp->retval);
2021   vam->result_ready = 1;
2022 }
2023
2024 static clib_error_t *
2025 receive_fd_msg (int socket_fd, int *my_fd)
2026 {
2027   char msgbuf[16];
2028   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2029   struct msghdr mh = { 0 };
2030   struct iovec iov[1];
2031   ssize_t size;
2032   struct ucred *cr = 0;
2033   struct cmsghdr *cmsg;
2034   pid_t pid __attribute__ ((unused));
2035   uid_t uid __attribute__ ((unused));
2036   gid_t gid __attribute__ ((unused));
2037
2038   iov[0].iov_base = msgbuf;
2039   iov[0].iov_len = 5;
2040   mh.msg_iov = iov;
2041   mh.msg_iovlen = 1;
2042   mh.msg_control = ctl;
2043   mh.msg_controllen = sizeof (ctl);
2044
2045   memset (ctl, 0, sizeof (ctl));
2046
2047   /* receive the incoming message */
2048   size = recvmsg (socket_fd, &mh, 0);
2049   if (size != 5)
2050     {
2051       return (size == 0) ? clib_error_return (0, "disconnected") :
2052         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2053                                 socket_fd);
2054     }
2055
2056   cmsg = CMSG_FIRSTHDR (&mh);
2057   while (cmsg)
2058     {
2059       if (cmsg->cmsg_level == SOL_SOCKET)
2060         {
2061           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2062             {
2063               cr = (struct ucred *) CMSG_DATA (cmsg);
2064               uid = cr->uid;
2065               gid = cr->gid;
2066               pid = cr->pid;
2067             }
2068           else if (cmsg->cmsg_type == SCM_RIGHTS)
2069             {
2070               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2071             }
2072         }
2073       cmsg = CMSG_NXTHDR (&mh, cmsg);
2074     }
2075   return 0;
2076 }
2077
2078 static void vl_api_memfd_segment_create_reply_t_handler
2079   (vl_api_memfd_segment_create_reply_t * mp)
2080 {
2081   /* Dont bother in the builtin version */
2082 #if VPP_API_TEST_BUILTIN == 0
2083   vat_main_t *vam = &vat_main;
2084   api_main_t *am = &api_main;
2085   socket_client_main_t *scm = &vam->socket_client_main;
2086   int my_fd = -1;
2087   clib_error_t *error;
2088   memfd_private_t memfd;
2089   i32 retval = ntohl (mp->retval);
2090
2091   if (retval == 0)
2092     {
2093       error = receive_fd_msg (scm->socket_fd, &my_fd);
2094       if (error)
2095         {
2096           retval = -99;
2097           goto out;
2098         }
2099
2100       memset (&memfd, 0, sizeof (memfd));
2101       memfd.fd = my_fd;
2102
2103       vam->client_index_invalid = 1;
2104
2105       retval = memfd_slave_init (&memfd);
2106       if (retval)
2107         clib_warning ("WARNING: segment map returned %d", retval);
2108
2109       /* Pivot to the memory client segment that vpp just created */
2110
2111       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2112
2113       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2114
2115       vl_client_install_client_message_handlers ();
2116
2117       vl_client_connect_to_vlib_no_map ("pvt",
2118                                         "vpp_api_test(p)",
2119                                         32 /* input_queue_length */ );
2120       if (close (my_fd) < 0)
2121         clib_unix_warning ("close memfd fd pivot");
2122       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2123
2124       vl_socket_client_enable_disable (&vam->socket_client_main,
2125                                        0 /* disable socket */ );
2126     }
2127
2128 out:
2129   if (vam->async_mode)
2130     {
2131       vam->async_errors += (retval < 0);
2132     }
2133   else
2134     {
2135       vam->retval = retval;
2136       vam->result_ready = 1;
2137     }
2138 #endif
2139 }
2140
2141 static void vl_api_memfd_segment_create_reply_t_handler_json
2142   (vl_api_memfd_segment_create_reply_t * mp)
2143 {
2144   clib_warning ("no");
2145 }
2146
2147
2148 static void vl_api_ip_address_details_t_handler
2149   (vl_api_ip_address_details_t * mp)
2150 {
2151   vat_main_t *vam = &vat_main;
2152   static ip_address_details_t empty_ip_address_details = { {0} };
2153   ip_address_details_t *address = NULL;
2154   ip_details_t *current_ip_details = NULL;
2155   ip_details_t *details = NULL;
2156
2157   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2158
2159   if (!details || vam->current_sw_if_index >= vec_len (details)
2160       || !details[vam->current_sw_if_index].present)
2161     {
2162       errmsg ("ip address details arrived but not stored");
2163       errmsg ("ip_dump should be called first");
2164       return;
2165     }
2166
2167   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2168
2169 #define addresses (current_ip_details->addr)
2170
2171   vec_validate_init_empty (addresses, vec_len (addresses),
2172                            empty_ip_address_details);
2173
2174   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2175
2176   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2177   address->prefix_length = mp->prefix_length;
2178 #undef addresses
2179 }
2180
2181 static void vl_api_ip_address_details_t_handler_json
2182   (vl_api_ip_address_details_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   vat_json_node_t *node = NULL;
2186   struct in6_addr ip6;
2187   struct in_addr ip4;
2188
2189   if (VAT_JSON_ARRAY != vam->json_tree.type)
2190     {
2191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2192       vat_json_init_array (&vam->json_tree);
2193     }
2194   node = vat_json_array_add (&vam->json_tree);
2195
2196   vat_json_init_object (node);
2197   if (vam->is_ipv6)
2198     {
2199       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2200       vat_json_object_add_ip6 (node, "ip", ip6);
2201     }
2202   else
2203     {
2204       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2205       vat_json_object_add_ip4 (node, "ip", ip4);
2206     }
2207   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2208 }
2209
2210 static void
2211 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2212 {
2213   vat_main_t *vam = &vat_main;
2214   static ip_details_t empty_ip_details = { 0 };
2215   ip_details_t *ip = NULL;
2216   u32 sw_if_index = ~0;
2217
2218   sw_if_index = ntohl (mp->sw_if_index);
2219
2220   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2221                            sw_if_index, empty_ip_details);
2222
2223   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2224                          sw_if_index);
2225
2226   ip->present = 1;
2227 }
2228
2229 static void
2230 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2231 {
2232   vat_main_t *vam = &vat_main;
2233
2234   if (VAT_JSON_ARRAY != vam->json_tree.type)
2235     {
2236       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2237       vat_json_init_array (&vam->json_tree);
2238     }
2239   vat_json_array_add_uint (&vam->json_tree,
2240                            clib_net_to_host_u32 (mp->sw_if_index));
2241 }
2242
2243 static void vl_api_map_domain_details_t_handler_json
2244   (vl_api_map_domain_details_t * mp)
2245 {
2246   vat_json_node_t *node = NULL;
2247   vat_main_t *vam = &vat_main;
2248   struct in6_addr ip6;
2249   struct in_addr ip4;
2250
2251   if (VAT_JSON_ARRAY != vam->json_tree.type)
2252     {
2253       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2254       vat_json_init_array (&vam->json_tree);
2255     }
2256
2257   node = vat_json_array_add (&vam->json_tree);
2258   vat_json_init_object (node);
2259
2260   vat_json_object_add_uint (node, "domain_index",
2261                             clib_net_to_host_u32 (mp->domain_index));
2262   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2263   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2264   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2265   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2266   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2267   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2268   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2269   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2270   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2271   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2272   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2273   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2274   vat_json_object_add_uint (node, "flags", mp->flags);
2275   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2276   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2277 }
2278
2279 static void vl_api_map_domain_details_t_handler
2280   (vl_api_map_domain_details_t * mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283
2284   if (mp->is_translation)
2285     {
2286       print (vam->ofp,
2287              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2288              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2289              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2290              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2291              clib_net_to_host_u32 (mp->domain_index));
2292     }
2293   else
2294     {
2295       print (vam->ofp,
2296              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2297              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2298              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2299              format_ip6_address, mp->ip6_src,
2300              clib_net_to_host_u32 (mp->domain_index));
2301     }
2302   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2303          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2304          mp->is_translation ? "map-t" : "");
2305 }
2306
2307 static void vl_api_map_rule_details_t_handler_json
2308   (vl_api_map_rule_details_t * mp)
2309 {
2310   struct in6_addr ip6;
2311   vat_json_node_t *node = NULL;
2312   vat_main_t *vam = &vat_main;
2313
2314   if (VAT_JSON_ARRAY != vam->json_tree.type)
2315     {
2316       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2317       vat_json_init_array (&vam->json_tree);
2318     }
2319
2320   node = vat_json_array_add (&vam->json_tree);
2321   vat_json_init_object (node);
2322
2323   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2324   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2325   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2326 }
2327
2328 static void
2329 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2330 {
2331   vat_main_t *vam = &vat_main;
2332   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2333          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2334 }
2335
2336 static void
2337 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2338 {
2339   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2340           "router_addr %U host_mac %U",
2341           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2342           format_ip4_address, &mp->host_address,
2343           format_ip4_address, &mp->router_address,
2344           format_ethernet_address, mp->host_mac);
2345 }
2346
2347 static void vl_api_dhcp_compl_event_t_handler_json
2348   (vl_api_dhcp_compl_event_t * mp)
2349 {
2350   /* JSON output not supported */
2351 }
2352
2353 static void
2354 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2355                               u32 counter)
2356 {
2357   vat_main_t *vam = &vat_main;
2358   static u64 default_counter = 0;
2359
2360   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2361                            NULL);
2362   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2363                            sw_if_index, default_counter);
2364   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2365 }
2366
2367 static void
2368 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2369                                 interface_counter_t counter)
2370 {
2371   vat_main_t *vam = &vat_main;
2372   static interface_counter_t default_counter = { 0, };
2373
2374   vec_validate_init_empty (vam->combined_interface_counters,
2375                            vnet_counter_type, NULL);
2376   vec_validate_init_empty (vam->combined_interface_counters
2377                            [vnet_counter_type], sw_if_index, default_counter);
2378   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2379 }
2380
2381 static void vl_api_vnet_interface_simple_counters_t_handler
2382   (vl_api_vnet_interface_simple_counters_t * mp)
2383 {
2384   /* not supported */
2385 }
2386
2387 static void vl_api_vnet_interface_combined_counters_t_handler
2388   (vl_api_vnet_interface_combined_counters_t * mp)
2389 {
2390   /* not supported */
2391 }
2392
2393 static void vl_api_vnet_interface_simple_counters_t_handler_json
2394   (vl_api_vnet_interface_simple_counters_t * mp)
2395 {
2396   u64 *v_packets;
2397   u64 packets;
2398   u32 count;
2399   u32 first_sw_if_index;
2400   int i;
2401
2402   count = ntohl (mp->count);
2403   first_sw_if_index = ntohl (mp->first_sw_if_index);
2404
2405   v_packets = (u64 *) & mp->data;
2406   for (i = 0; i < count; i++)
2407     {
2408       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2409       set_simple_interface_counter (mp->vnet_counter_type,
2410                                     first_sw_if_index + i, packets);
2411       v_packets++;
2412     }
2413 }
2414
2415 static void vl_api_vnet_interface_combined_counters_t_handler_json
2416   (vl_api_vnet_interface_combined_counters_t * mp)
2417 {
2418   interface_counter_t counter;
2419   vlib_counter_t *v;
2420   u32 first_sw_if_index;
2421   int i;
2422   u32 count;
2423
2424   count = ntohl (mp->count);
2425   first_sw_if_index = ntohl (mp->first_sw_if_index);
2426
2427   v = (vlib_counter_t *) & mp->data;
2428   for (i = 0; i < count; i++)
2429     {
2430       counter.packets =
2431         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2432       counter.bytes =
2433         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2434       set_combined_interface_counter (mp->vnet_counter_type,
2435                                       first_sw_if_index + i, counter);
2436       v++;
2437     }
2438 }
2439
2440 static u32
2441 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2442 {
2443   vat_main_t *vam = &vat_main;
2444   u32 i;
2445
2446   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2447     {
2448       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2449         {
2450           return i;
2451         }
2452     }
2453   return ~0;
2454 }
2455
2456 static u32
2457 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   u32 i;
2461
2462   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2463     {
2464       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2465         {
2466           return i;
2467         }
2468     }
2469   return ~0;
2470 }
2471
2472 static void vl_api_vnet_ip4_fib_counters_t_handler
2473   (vl_api_vnet_ip4_fib_counters_t * mp)
2474 {
2475   /* not supported */
2476 }
2477
2478 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2479   (vl_api_vnet_ip4_fib_counters_t * mp)
2480 {
2481   vat_main_t *vam = &vat_main;
2482   vl_api_ip4_fib_counter_t *v;
2483   ip4_fib_counter_t *counter;
2484   struct in_addr ip4;
2485   u32 vrf_id;
2486   u32 vrf_index;
2487   u32 count;
2488   int i;
2489
2490   vrf_id = ntohl (mp->vrf_id);
2491   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2492   if (~0 == vrf_index)
2493     {
2494       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2495       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2496       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2497       vec_validate (vam->ip4_fib_counters, vrf_index);
2498       vam->ip4_fib_counters[vrf_index] = NULL;
2499     }
2500
2501   vec_free (vam->ip4_fib_counters[vrf_index]);
2502   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2503   count = ntohl (mp->count);
2504   for (i = 0; i < count; i++)
2505     {
2506       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2507       counter = &vam->ip4_fib_counters[vrf_index][i];
2508       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2509       counter->address = ip4;
2510       counter->address_length = v->address_length;
2511       counter->packets = clib_net_to_host_u64 (v->packets);
2512       counter->bytes = clib_net_to_host_u64 (v->bytes);
2513       v++;
2514     }
2515 }
2516
2517 static void vl_api_vnet_ip4_nbr_counters_t_handler
2518   (vl_api_vnet_ip4_nbr_counters_t * mp)
2519 {
2520   /* not supported */
2521 }
2522
2523 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2524   (vl_api_vnet_ip4_nbr_counters_t * mp)
2525 {
2526   vat_main_t *vam = &vat_main;
2527   vl_api_ip4_nbr_counter_t *v;
2528   ip4_nbr_counter_t *counter;
2529   u32 sw_if_index;
2530   u32 count;
2531   int i;
2532
2533   sw_if_index = ntohl (mp->sw_if_index);
2534   count = ntohl (mp->count);
2535   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2536
2537   if (mp->begin)
2538     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2539
2540   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2541   for (i = 0; i < count; i++)
2542     {
2543       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2544       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2545       counter->address.s_addr = v->address;
2546       counter->packets = clib_net_to_host_u64 (v->packets);
2547       counter->bytes = clib_net_to_host_u64 (v->bytes);
2548       counter->linkt = v->link_type;
2549       v++;
2550     }
2551 }
2552
2553 static void vl_api_vnet_ip6_fib_counters_t_handler
2554   (vl_api_vnet_ip6_fib_counters_t * mp)
2555 {
2556   /* not supported */
2557 }
2558
2559 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2560   (vl_api_vnet_ip6_fib_counters_t * mp)
2561 {
2562   vat_main_t *vam = &vat_main;
2563   vl_api_ip6_fib_counter_t *v;
2564   ip6_fib_counter_t *counter;
2565   struct in6_addr ip6;
2566   u32 vrf_id;
2567   u32 vrf_index;
2568   u32 count;
2569   int i;
2570
2571   vrf_id = ntohl (mp->vrf_id);
2572   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2573   if (~0 == vrf_index)
2574     {
2575       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2576       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2577       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2578       vec_validate (vam->ip6_fib_counters, vrf_index);
2579       vam->ip6_fib_counters[vrf_index] = NULL;
2580     }
2581
2582   vec_free (vam->ip6_fib_counters[vrf_index]);
2583   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2584   count = ntohl (mp->count);
2585   for (i = 0; i < count; i++)
2586     {
2587       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2588       counter = &vam->ip6_fib_counters[vrf_index][i];
2589       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2590       counter->address = ip6;
2591       counter->address_length = v->address_length;
2592       counter->packets = clib_net_to_host_u64 (v->packets);
2593       counter->bytes = clib_net_to_host_u64 (v->bytes);
2594       v++;
2595     }
2596 }
2597
2598 static void vl_api_vnet_ip6_nbr_counters_t_handler
2599   (vl_api_vnet_ip6_nbr_counters_t * mp)
2600 {
2601   /* not supported */
2602 }
2603
2604 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2605   (vl_api_vnet_ip6_nbr_counters_t * mp)
2606 {
2607   vat_main_t *vam = &vat_main;
2608   vl_api_ip6_nbr_counter_t *v;
2609   ip6_nbr_counter_t *counter;
2610   struct in6_addr ip6;
2611   u32 sw_if_index;
2612   u32 count;
2613   int i;
2614
2615   sw_if_index = ntohl (mp->sw_if_index);
2616   count = ntohl (mp->count);
2617   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2618
2619   if (mp->begin)
2620     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2621
2622   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2623   for (i = 0; i < count; i++)
2624     {
2625       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2626       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2627       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2628       counter->address = ip6;
2629       counter->packets = clib_net_to_host_u64 (v->packets);
2630       counter->bytes = clib_net_to_host_u64 (v->bytes);
2631       v++;
2632     }
2633 }
2634
2635 static void vl_api_get_first_msg_id_reply_t_handler
2636   (vl_api_get_first_msg_id_reply_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   i32 retval = ntohl (mp->retval);
2640
2641   if (vam->async_mode)
2642     {
2643       vam->async_errors += (retval < 0);
2644     }
2645   else
2646     {
2647       vam->retval = retval;
2648       vam->result_ready = 1;
2649     }
2650   if (retval >= 0)
2651     {
2652       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2653     }
2654 }
2655
2656 static void vl_api_get_first_msg_id_reply_t_handler_json
2657   (vl_api_get_first_msg_id_reply_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t node;
2661
2662   vat_json_init_object (&node);
2663   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2664   vat_json_object_add_uint (&node, "first_msg_id",
2665                             (uint) ntohs (mp->first_msg_id));
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void vl_api_get_node_graph_reply_t_handler
2675   (vl_api_get_node_graph_reply_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   api_main_t *am = &api_main;
2679   i32 retval = ntohl (mp->retval);
2680   u8 *pvt_copy, *reply;
2681   void *oldheap;
2682   vlib_node_t *node;
2683   int i;
2684
2685   if (vam->async_mode)
2686     {
2687       vam->async_errors += (retval < 0);
2688     }
2689   else
2690     {
2691       vam->retval = retval;
2692       vam->result_ready = 1;
2693     }
2694
2695   /* "Should never happen..." */
2696   if (retval != 0)
2697     return;
2698
2699   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2700   pvt_copy = vec_dup (reply);
2701
2702   /* Toss the shared-memory original... */
2703   pthread_mutex_lock (&am->vlib_rp->mutex);
2704   oldheap = svm_push_data_heap (am->vlib_rp);
2705
2706   vec_free (reply);
2707
2708   svm_pop_heap (oldheap);
2709   pthread_mutex_unlock (&am->vlib_rp->mutex);
2710
2711   if (vam->graph_nodes)
2712     {
2713       hash_free (vam->graph_node_index_by_name);
2714
2715       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2716         {
2717           node = vam->graph_nodes[i];
2718           vec_free (node->name);
2719           vec_free (node->next_nodes);
2720           vec_free (node);
2721         }
2722       vec_free (vam->graph_nodes);
2723     }
2724
2725   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2726   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2727   vec_free (pvt_copy);
2728
2729   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2730     {
2731       node = vam->graph_nodes[i];
2732       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2733     }
2734 }
2735
2736 static void vl_api_get_node_graph_reply_t_handler_json
2737   (vl_api_get_node_graph_reply_t * mp)
2738 {
2739   vat_main_t *vam = &vat_main;
2740   api_main_t *am = &api_main;
2741   void *oldheap;
2742   vat_json_node_t node;
2743   u8 *reply;
2744
2745   /* $$$$ make this real? */
2746   vat_json_init_object (&node);
2747   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2748   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2749
2750   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2751
2752   /* Toss the shared-memory original... */
2753   pthread_mutex_lock (&am->vlib_rp->mutex);
2754   oldheap = svm_push_data_heap (am->vlib_rp);
2755
2756   vec_free (reply);
2757
2758   svm_pop_heap (oldheap);
2759   pthread_mutex_unlock (&am->vlib_rp->mutex);
2760
2761   vat_json_print (vam->ofp, &node);
2762   vat_json_free (&node);
2763
2764   vam->retval = ntohl (mp->retval);
2765   vam->result_ready = 1;
2766 }
2767
2768 static void
2769 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2770 {
2771   vat_main_t *vam = &vat_main;
2772   u8 *s = 0;
2773
2774   if (mp->local)
2775     {
2776       s = format (s, "%=16d%=16d%=16d",
2777                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2778     }
2779   else
2780     {
2781       s = format (s, "%=16U%=16d%=16d",
2782                   mp->is_ipv6 ? format_ip6_address :
2783                   format_ip4_address,
2784                   mp->ip_address, mp->priority, mp->weight);
2785     }
2786
2787   print (vam->ofp, "%v", s);
2788   vec_free (s);
2789 }
2790
2791 static void
2792 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2793 {
2794   vat_main_t *vam = &vat_main;
2795   vat_json_node_t *node = NULL;
2796   struct in6_addr ip6;
2797   struct in_addr ip4;
2798
2799   if (VAT_JSON_ARRAY != vam->json_tree.type)
2800     {
2801       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2802       vat_json_init_array (&vam->json_tree);
2803     }
2804   node = vat_json_array_add (&vam->json_tree);
2805   vat_json_init_object (node);
2806
2807   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2808   vat_json_object_add_uint (node, "priority", mp->priority);
2809   vat_json_object_add_uint (node, "weight", mp->weight);
2810
2811   if (mp->local)
2812     vat_json_object_add_uint (node, "sw_if_index",
2813                               clib_net_to_host_u32 (mp->sw_if_index));
2814   else
2815     {
2816       if (mp->is_ipv6)
2817         {
2818           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2819           vat_json_object_add_ip6 (node, "address", ip6);
2820         }
2821       else
2822         {
2823           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2824           vat_json_object_add_ip4 (node, "address", ip4);
2825         }
2826     }
2827 }
2828
2829 static void
2830 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2831                                           mp)
2832 {
2833   vat_main_t *vam = &vat_main;
2834   u8 *ls_name = 0;
2835
2836   ls_name = format (0, "%s", mp->ls_name);
2837
2838   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2839          ls_name);
2840   vec_free (ls_name);
2841 }
2842
2843 static void
2844   vl_api_one_locator_set_details_t_handler_json
2845   (vl_api_one_locator_set_details_t * mp)
2846 {
2847   vat_main_t *vam = &vat_main;
2848   vat_json_node_t *node = 0;
2849   u8 *ls_name = 0;
2850
2851   ls_name = format (0, "%s", mp->ls_name);
2852   vec_add1 (ls_name, 0);
2853
2854   if (VAT_JSON_ARRAY != vam->json_tree.type)
2855     {
2856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2857       vat_json_init_array (&vam->json_tree);
2858     }
2859   node = vat_json_array_add (&vam->json_tree);
2860
2861   vat_json_init_object (node);
2862   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2863   vat_json_object_add_uint (node, "ls_index",
2864                             clib_net_to_host_u32 (mp->ls_index));
2865   vec_free (ls_name);
2866 }
2867
2868 typedef struct
2869 {
2870   u32 spi;
2871   u8 si;
2872 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2873
2874 uword
2875 unformat_nsh_address (unformat_input_t * input, va_list * args)
2876 {
2877   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2878   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2879 }
2880
2881 u8 *
2882 format_nsh_address_vat (u8 * s, va_list * args)
2883 {
2884   nsh_t *a = va_arg (*args, nsh_t *);
2885   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2886 }
2887
2888 static u8 *
2889 format_lisp_flat_eid (u8 * s, va_list * args)
2890 {
2891   u32 type = va_arg (*args, u32);
2892   u8 *eid = va_arg (*args, u8 *);
2893   u32 eid_len = va_arg (*args, u32);
2894
2895   switch (type)
2896     {
2897     case 0:
2898       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2899     case 1:
2900       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2901     case 2:
2902       return format (s, "%U", format_ethernet_address, eid);
2903     case 3:
2904       return format (s, "%U", format_nsh_address_vat, eid);
2905     }
2906   return 0;
2907 }
2908
2909 static u8 *
2910 format_lisp_eid_vat (u8 * s, va_list * args)
2911 {
2912   u32 type = va_arg (*args, u32);
2913   u8 *eid = va_arg (*args, u8 *);
2914   u32 eid_len = va_arg (*args, u32);
2915   u8 *seid = va_arg (*args, u8 *);
2916   u32 seid_len = va_arg (*args, u32);
2917   u32 is_src_dst = va_arg (*args, u32);
2918
2919   if (is_src_dst)
2920     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2921
2922   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2923
2924   return s;
2925 }
2926
2927 static void
2928 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2929 {
2930   vat_main_t *vam = &vat_main;
2931   u8 *s = 0, *eid = 0;
2932
2933   if (~0 == mp->locator_set_index)
2934     s = format (0, "action: %d", mp->action);
2935   else
2936     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2937
2938   eid = format (0, "%U", format_lisp_eid_vat,
2939                 mp->eid_type,
2940                 mp->eid,
2941                 mp->eid_prefix_len,
2942                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2943   vec_add1 (eid, 0);
2944
2945   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2946          clib_net_to_host_u32 (mp->vni),
2947          eid,
2948          mp->is_local ? "local" : "remote",
2949          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2950          clib_net_to_host_u16 (mp->key_id), mp->key);
2951
2952   vec_free (s);
2953   vec_free (eid);
2954 }
2955
2956 static void
2957 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2958                                              * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   vat_json_node_t *node = 0;
2962   u8 *eid = 0;
2963
2964   if (VAT_JSON_ARRAY != vam->json_tree.type)
2965     {
2966       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2967       vat_json_init_array (&vam->json_tree);
2968     }
2969   node = vat_json_array_add (&vam->json_tree);
2970
2971   vat_json_init_object (node);
2972   if (~0 == mp->locator_set_index)
2973     vat_json_object_add_uint (node, "action", mp->action);
2974   else
2975     vat_json_object_add_uint (node, "locator_set_index",
2976                               clib_net_to_host_u32 (mp->locator_set_index));
2977
2978   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2979   if (mp->eid_type == 3)
2980     {
2981       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2982       vat_json_init_object (nsh_json);
2983       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2984       vat_json_object_add_uint (nsh_json, "spi",
2985                                 clib_net_to_host_u32 (nsh->spi));
2986       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2987     }
2988   else
2989     {
2990       eid = format (0, "%U", format_lisp_eid_vat,
2991                     mp->eid_type,
2992                     mp->eid,
2993                     mp->eid_prefix_len,
2994                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2995       vec_add1 (eid, 0);
2996       vat_json_object_add_string_copy (node, "eid", eid);
2997       vec_free (eid);
2998     }
2999   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3000   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3001   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3002
3003   if (mp->key_id)
3004     {
3005       vat_json_object_add_uint (node, "key_id",
3006                                 clib_net_to_host_u16 (mp->key_id));
3007       vat_json_object_add_string_copy (node, "key", mp->key);
3008     }
3009 }
3010
3011 static void
3012 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   u8 *seid = 0, *deid = 0;
3016   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3017
3018   deid = format (0, "%U", format_lisp_eid_vat,
3019                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3020
3021   seid = format (0, "%U", format_lisp_eid_vat,
3022                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3023
3024   vec_add1 (deid, 0);
3025   vec_add1 (seid, 0);
3026
3027   if (mp->is_ip4)
3028     format_ip_address_fcn = format_ip4_address;
3029   else
3030     format_ip_address_fcn = format_ip6_address;
3031
3032
3033   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3034          clib_net_to_host_u32 (mp->vni),
3035          seid, deid,
3036          format_ip_address_fcn, mp->lloc,
3037          format_ip_address_fcn, mp->rloc,
3038          clib_net_to_host_u32 (mp->pkt_count),
3039          clib_net_to_host_u32 (mp->bytes));
3040
3041   vec_free (deid);
3042   vec_free (seid);
3043 }
3044
3045 static void
3046 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3047 {
3048   struct in6_addr ip6;
3049   struct in_addr ip4;
3050   vat_main_t *vam = &vat_main;
3051   vat_json_node_t *node = 0;
3052   u8 *deid = 0, *seid = 0;
3053
3054   if (VAT_JSON_ARRAY != vam->json_tree.type)
3055     {
3056       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3057       vat_json_init_array (&vam->json_tree);
3058     }
3059   node = vat_json_array_add (&vam->json_tree);
3060
3061   vat_json_init_object (node);
3062   deid = format (0, "%U", format_lisp_eid_vat,
3063                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3064
3065   seid = format (0, "%U", format_lisp_eid_vat,
3066                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3067
3068   vec_add1 (deid, 0);
3069   vec_add1 (seid, 0);
3070
3071   vat_json_object_add_string_copy (node, "seid", seid);
3072   vat_json_object_add_string_copy (node, "deid", deid);
3073   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3074
3075   if (mp->is_ip4)
3076     {
3077       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3078       vat_json_object_add_ip4 (node, "lloc", ip4);
3079       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3080       vat_json_object_add_ip4 (node, "rloc", ip4);
3081     }
3082   else
3083     {
3084       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3085       vat_json_object_add_ip6 (node, "lloc", ip6);
3086       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3087       vat_json_object_add_ip6 (node, "rloc", ip6);
3088     }
3089   vat_json_object_add_uint (node, "pkt_count",
3090                             clib_net_to_host_u32 (mp->pkt_count));
3091   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3092
3093   vec_free (deid);
3094   vec_free (seid);
3095 }
3096
3097 static void
3098   vl_api_one_eid_table_map_details_t_handler
3099   (vl_api_one_eid_table_map_details_t * mp)
3100 {
3101   vat_main_t *vam = &vat_main;
3102
3103   u8 *line = format (0, "%=10d%=10d",
3104                      clib_net_to_host_u32 (mp->vni),
3105                      clib_net_to_host_u32 (mp->dp_table));
3106   print (vam->ofp, "%v", line);
3107   vec_free (line);
3108 }
3109
3110 static void
3111   vl_api_one_eid_table_map_details_t_handler_json
3112   (vl_api_one_eid_table_map_details_t * mp)
3113 {
3114   vat_main_t *vam = &vat_main;
3115   vat_json_node_t *node = NULL;
3116
3117   if (VAT_JSON_ARRAY != vam->json_tree.type)
3118     {
3119       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3120       vat_json_init_array (&vam->json_tree);
3121     }
3122   node = vat_json_array_add (&vam->json_tree);
3123   vat_json_init_object (node);
3124   vat_json_object_add_uint (node, "dp_table",
3125                             clib_net_to_host_u32 (mp->dp_table));
3126   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3127 }
3128
3129 static void
3130   vl_api_one_eid_table_vni_details_t_handler
3131   (vl_api_one_eid_table_vni_details_t * mp)
3132 {
3133   vat_main_t *vam = &vat_main;
3134
3135   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3136   print (vam->ofp, "%v", line);
3137   vec_free (line);
3138 }
3139
3140 static void
3141   vl_api_one_eid_table_vni_details_t_handler_json
3142   (vl_api_one_eid_table_vni_details_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   vat_json_node_t *node = NULL;
3146
3147   if (VAT_JSON_ARRAY != vam->json_tree.type)
3148     {
3149       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3150       vat_json_init_array (&vam->json_tree);
3151     }
3152   node = vat_json_array_add (&vam->json_tree);
3153   vat_json_init_object (node);
3154   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3155 }
3156
3157 static void
3158   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3159   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3160 {
3161   vat_main_t *vam = &vat_main;
3162   int retval = clib_net_to_host_u32 (mp->retval);
3163
3164   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3165   print (vam->ofp, "fallback threshold value: %d", mp->value);
3166
3167   vam->retval = retval;
3168   vam->result_ready = 1;
3169 }
3170
3171 static void
3172   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3173   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3174 {
3175   vat_main_t *vam = &vat_main;
3176   vat_json_node_t _node, *node = &_node;
3177   int retval = clib_net_to_host_u32 (mp->retval);
3178
3179   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3180   vat_json_init_object (node);
3181   vat_json_object_add_uint (node, "value", mp->value);
3182
3183   vat_json_print (vam->ofp, node);
3184   vat_json_free (node);
3185
3186   vam->retval = retval;
3187   vam->result_ready = 1;
3188 }
3189
3190 static void
3191   vl_api_show_one_map_register_state_reply_t_handler
3192   (vl_api_show_one_map_register_state_reply_t * mp)
3193 {
3194   vat_main_t *vam = &vat_main;
3195   int retval = clib_net_to_host_u32 (mp->retval);
3196
3197   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3198
3199   vam->retval = retval;
3200   vam->result_ready = 1;
3201 }
3202
3203 static void
3204   vl_api_show_one_map_register_state_reply_t_handler_json
3205   (vl_api_show_one_map_register_state_reply_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t _node, *node = &_node;
3209   int retval = clib_net_to_host_u32 (mp->retval);
3210
3211   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3212
3213   vat_json_init_object (node);
3214   vat_json_object_add_string_copy (node, "state", s);
3215
3216   vat_json_print (vam->ofp, node);
3217   vat_json_free (node);
3218
3219   vam->retval = retval;
3220   vam->result_ready = 1;
3221   vec_free (s);
3222 }
3223
3224 static void
3225   vl_api_show_one_rloc_probe_state_reply_t_handler
3226   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229   int retval = clib_net_to_host_u32 (mp->retval);
3230
3231   if (retval)
3232     goto end;
3233
3234   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3235 end:
3236   vam->retval = retval;
3237   vam->result_ready = 1;
3238 }
3239
3240 static void
3241   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3242   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3243 {
3244   vat_main_t *vam = &vat_main;
3245   vat_json_node_t _node, *node = &_node;
3246   int retval = clib_net_to_host_u32 (mp->retval);
3247
3248   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3249   vat_json_init_object (node);
3250   vat_json_object_add_string_copy (node, "state", s);
3251
3252   vat_json_print (vam->ofp, node);
3253   vat_json_free (node);
3254
3255   vam->retval = retval;
3256   vam->result_ready = 1;
3257   vec_free (s);
3258 }
3259
3260 static void
3261   vl_api_show_one_stats_enable_disable_reply_t_handler
3262   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3263 {
3264   vat_main_t *vam = &vat_main;
3265   int retval = clib_net_to_host_u32 (mp->retval);
3266
3267   if (retval)
3268     goto end;
3269
3270   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3271 end:
3272   vam->retval = retval;
3273   vam->result_ready = 1;
3274 }
3275
3276 static void
3277   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3278   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t _node, *node = &_node;
3282   int retval = clib_net_to_host_u32 (mp->retval);
3283
3284   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3285   vat_json_init_object (node);
3286   vat_json_object_add_string_copy (node, "state", s);
3287
3288   vat_json_print (vam->ofp, node);
3289   vat_json_free (node);
3290
3291   vam->retval = retval;
3292   vam->result_ready = 1;
3293   vec_free (s);
3294 }
3295
3296 static void
3297 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3298 {
3299   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3300   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3301   e->vni = clib_net_to_host_u32 (e->vni);
3302 }
3303
3304 static void
3305   gpe_fwd_entries_get_reply_t_net_to_host
3306   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3307 {
3308   u32 i;
3309
3310   mp->count = clib_net_to_host_u32 (mp->count);
3311   for (i = 0; i < mp->count; i++)
3312     {
3313       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3314     }
3315 }
3316
3317 static u8 *
3318 format_gpe_encap_mode (u8 * s, va_list * args)
3319 {
3320   u32 mode = va_arg (*args, u32);
3321
3322   switch (mode)
3323     {
3324     case 0:
3325       return format (s, "lisp");
3326     case 1:
3327       return format (s, "vxlan");
3328     }
3329   return 0;
3330 }
3331
3332 static void
3333   vl_api_gpe_get_encap_mode_reply_t_handler
3334   (vl_api_gpe_get_encap_mode_reply_t * mp)
3335 {
3336   vat_main_t *vam = &vat_main;
3337
3338   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3339   vam->retval = ntohl (mp->retval);
3340   vam->result_ready = 1;
3341 }
3342
3343 static void
3344   vl_api_gpe_get_encap_mode_reply_t_handler_json
3345   (vl_api_gpe_get_encap_mode_reply_t * mp)
3346 {
3347   vat_main_t *vam = &vat_main;
3348   vat_json_node_t node;
3349
3350   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3351   vec_add1 (encap_mode, 0);
3352
3353   vat_json_init_object (&node);
3354   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3355
3356   vec_free (encap_mode);
3357   vat_json_print (vam->ofp, &node);
3358   vat_json_free (&node);
3359
3360   vam->retval = ntohl (mp->retval);
3361   vam->result_ready = 1;
3362 }
3363
3364 static void
3365   vl_api_gpe_fwd_entry_path_details_t_handler
3366   (vl_api_gpe_fwd_entry_path_details_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3370
3371   if (mp->lcl_loc.is_ip4)
3372     format_ip_address_fcn = format_ip4_address;
3373   else
3374     format_ip_address_fcn = format_ip6_address;
3375
3376   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3377          format_ip_address_fcn, &mp->lcl_loc,
3378          format_ip_address_fcn, &mp->rmt_loc);
3379 }
3380
3381 static void
3382 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3383 {
3384   struct in6_addr ip6;
3385   struct in_addr ip4;
3386
3387   if (loc->is_ip4)
3388     {
3389       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3390       vat_json_object_add_ip4 (n, "address", ip4);
3391     }
3392   else
3393     {
3394       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3395       vat_json_object_add_ip6 (n, "address", ip6);
3396     }
3397   vat_json_object_add_uint (n, "weight", loc->weight);
3398 }
3399
3400 static void
3401   vl_api_gpe_fwd_entry_path_details_t_handler_json
3402   (vl_api_gpe_fwd_entry_path_details_t * mp)
3403 {
3404   vat_main_t *vam = &vat_main;
3405   vat_json_node_t *node = NULL;
3406   vat_json_node_t *loc_node;
3407
3408   if (VAT_JSON_ARRAY != vam->json_tree.type)
3409     {
3410       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3411       vat_json_init_array (&vam->json_tree);
3412     }
3413   node = vat_json_array_add (&vam->json_tree);
3414   vat_json_init_object (node);
3415
3416   loc_node = vat_json_object_add (node, "local_locator");
3417   vat_json_init_object (loc_node);
3418   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3419
3420   loc_node = vat_json_object_add (node, "remote_locator");
3421   vat_json_init_object (loc_node);
3422   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3423 }
3424
3425 static void
3426   vl_api_gpe_fwd_entries_get_reply_t_handler
3427   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3428 {
3429   vat_main_t *vam = &vat_main;
3430   u32 i;
3431   int retval = clib_net_to_host_u32 (mp->retval);
3432   vl_api_gpe_fwd_entry_t *e;
3433
3434   if (retval)
3435     goto end;
3436
3437   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3438
3439   for (i = 0; i < mp->count; i++)
3440     {
3441       e = &mp->entries[i];
3442       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3443              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3444              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3445     }
3446
3447 end:
3448   vam->retval = retval;
3449   vam->result_ready = 1;
3450 }
3451
3452 static void
3453   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3454   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3455 {
3456   u8 *s = 0;
3457   vat_main_t *vam = &vat_main;
3458   vat_json_node_t *e = 0, root;
3459   u32 i;
3460   int retval = clib_net_to_host_u32 (mp->retval);
3461   vl_api_gpe_fwd_entry_t *fwd;
3462
3463   if (retval)
3464     goto end;
3465
3466   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3467   vat_json_init_array (&root);
3468
3469   for (i = 0; i < mp->count; i++)
3470     {
3471       e = vat_json_array_add (&root);
3472       fwd = &mp->entries[i];
3473
3474       vat_json_init_object (e);
3475       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3476       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3477       vat_json_object_add_int (e, "vni", fwd->vni);
3478       vat_json_object_add_int (e, "action", fwd->action);
3479
3480       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3481                   fwd->leid_prefix_len);
3482       vec_add1 (s, 0);
3483       vat_json_object_add_string_copy (e, "leid", s);
3484       vec_free (s);
3485
3486       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3487                   fwd->reid_prefix_len);
3488       vec_add1 (s, 0);
3489       vat_json_object_add_string_copy (e, "reid", s);
3490       vec_free (s);
3491     }
3492
3493   vat_json_print (vam->ofp, &root);
3494   vat_json_free (&root);
3495
3496 end:
3497   vam->retval = retval;
3498   vam->result_ready = 1;
3499 }
3500
3501 static void
3502   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3503   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3504 {
3505   vat_main_t *vam = &vat_main;
3506   u32 i, n;
3507   int retval = clib_net_to_host_u32 (mp->retval);
3508   vl_api_gpe_native_fwd_rpath_t *r;
3509
3510   if (retval)
3511     goto end;
3512
3513   n = clib_net_to_host_u32 (mp->count);
3514
3515   for (i = 0; i < n; i++)
3516     {
3517       r = &mp->entries[i];
3518       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3519              clib_net_to_host_u32 (r->fib_index),
3520              clib_net_to_host_u32 (r->nh_sw_if_index),
3521              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3522     }
3523
3524 end:
3525   vam->retval = retval;
3526   vam->result_ready = 1;
3527 }
3528
3529 static void
3530   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3531   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3532 {
3533   vat_main_t *vam = &vat_main;
3534   vat_json_node_t root, *e;
3535   u32 i, n;
3536   int retval = clib_net_to_host_u32 (mp->retval);
3537   vl_api_gpe_native_fwd_rpath_t *r;
3538   u8 *s;
3539
3540   if (retval)
3541     goto end;
3542
3543   n = clib_net_to_host_u32 (mp->count);
3544   vat_json_init_array (&root);
3545
3546   for (i = 0; i < n; i++)
3547     {
3548       e = vat_json_array_add (&root);
3549       vat_json_init_object (e);
3550       r = &mp->entries[i];
3551       s =
3552         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3553                 r->nh_addr);
3554       vec_add1 (s, 0);
3555       vat_json_object_add_string_copy (e, "ip4", s);
3556       vec_free (s);
3557
3558       vat_json_object_add_uint (e, "fib_index",
3559                                 clib_net_to_host_u32 (r->fib_index));
3560       vat_json_object_add_uint (e, "nh_sw_if_index",
3561                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3562     }
3563
3564   vat_json_print (vam->ofp, &root);
3565   vat_json_free (&root);
3566
3567 end:
3568   vam->retval = retval;
3569   vam->result_ready = 1;
3570 }
3571
3572 static void
3573   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3574   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3575 {
3576   vat_main_t *vam = &vat_main;
3577   u32 i, n;
3578   int retval = clib_net_to_host_u32 (mp->retval);
3579
3580   if (retval)
3581     goto end;
3582
3583   n = clib_net_to_host_u32 (mp->count);
3584
3585   for (i = 0; i < n; i++)
3586     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3587
3588 end:
3589   vam->retval = retval;
3590   vam->result_ready = 1;
3591 }
3592
3593 static void
3594   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3595   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3596 {
3597   vat_main_t *vam = &vat_main;
3598   vat_json_node_t root;
3599   u32 i, n;
3600   int retval = clib_net_to_host_u32 (mp->retval);
3601
3602   if (retval)
3603     goto end;
3604
3605   n = clib_net_to_host_u32 (mp->count);
3606   vat_json_init_array (&root);
3607
3608   for (i = 0; i < n; i++)
3609     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3610
3611   vat_json_print (vam->ofp, &root);
3612   vat_json_free (&root);
3613
3614 end:
3615   vam->retval = retval;
3616   vam->result_ready = 1;
3617 }
3618
3619 static void
3620   vl_api_one_ndp_entries_get_reply_t_handler
3621   (vl_api_one_ndp_entries_get_reply_t * mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624   u32 i, n;
3625   int retval = clib_net_to_host_u32 (mp->retval);
3626
3627   if (retval)
3628     goto end;
3629
3630   n = clib_net_to_host_u32 (mp->count);
3631
3632   for (i = 0; i < n; i++)
3633     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3634            format_ethernet_address, mp->entries[i].mac);
3635
3636 end:
3637   vam->retval = retval;
3638   vam->result_ready = 1;
3639 }
3640
3641 static void
3642   vl_api_one_ndp_entries_get_reply_t_handler_json
3643   (vl_api_one_ndp_entries_get_reply_t * mp)
3644 {
3645   u8 *s = 0;
3646   vat_main_t *vam = &vat_main;
3647   vat_json_node_t *e = 0, root;
3648   u32 i, n;
3649   int retval = clib_net_to_host_u32 (mp->retval);
3650   vl_api_one_ndp_entry_t *arp_entry;
3651
3652   if (retval)
3653     goto end;
3654
3655   n = clib_net_to_host_u32 (mp->count);
3656   vat_json_init_array (&root);
3657
3658   for (i = 0; i < n; i++)
3659     {
3660       e = vat_json_array_add (&root);
3661       arp_entry = &mp->entries[i];
3662
3663       vat_json_init_object (e);
3664       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3665       vec_add1 (s, 0);
3666
3667       vat_json_object_add_string_copy (e, "mac", s);
3668       vec_free (s);
3669
3670       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3671       vec_add1 (s, 0);
3672       vat_json_object_add_string_copy (e, "ip6", s);
3673       vec_free (s);
3674     }
3675
3676   vat_json_print (vam->ofp, &root);
3677   vat_json_free (&root);
3678
3679 end:
3680   vam->retval = retval;
3681   vam->result_ready = 1;
3682 }
3683
3684 static void
3685   vl_api_one_l2_arp_entries_get_reply_t_handler
3686   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3687 {
3688   vat_main_t *vam = &vat_main;
3689   u32 i, n;
3690   int retval = clib_net_to_host_u32 (mp->retval);
3691
3692   if (retval)
3693     goto end;
3694
3695   n = clib_net_to_host_u32 (mp->count);
3696
3697   for (i = 0; i < n; i++)
3698     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3699            format_ethernet_address, mp->entries[i].mac);
3700
3701 end:
3702   vam->retval = retval;
3703   vam->result_ready = 1;
3704 }
3705
3706 static void
3707   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3708   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3709 {
3710   u8 *s = 0;
3711   vat_main_t *vam = &vat_main;
3712   vat_json_node_t *e = 0, root;
3713   u32 i, n;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715   vl_api_one_l2_arp_entry_t *arp_entry;
3716
3717   if (retval)
3718     goto end;
3719
3720   n = clib_net_to_host_u32 (mp->count);
3721   vat_json_init_array (&root);
3722
3723   for (i = 0; i < n; i++)
3724     {
3725       e = vat_json_array_add (&root);
3726       arp_entry = &mp->entries[i];
3727
3728       vat_json_init_object (e);
3729       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3730       vec_add1 (s, 0);
3731
3732       vat_json_object_add_string_copy (e, "mac", s);
3733       vec_free (s);
3734
3735       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3736       vec_add1 (s, 0);
3737       vat_json_object_add_string_copy (e, "ip4", s);
3738       vec_free (s);
3739     }
3740
3741   vat_json_print (vam->ofp, &root);
3742   vat_json_free (&root);
3743
3744 end:
3745   vam->retval = retval;
3746   vam->result_ready = 1;
3747 }
3748
3749 static void
3750 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3751 {
3752   vat_main_t *vam = &vat_main;
3753   u32 i, n;
3754   int retval = clib_net_to_host_u32 (mp->retval);
3755
3756   if (retval)
3757     goto end;
3758
3759   n = clib_net_to_host_u32 (mp->count);
3760
3761   for (i = 0; i < n; i++)
3762     {
3763       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3764     }
3765
3766 end:
3767   vam->retval = retval;
3768   vam->result_ready = 1;
3769 }
3770
3771 static void
3772   vl_api_one_ndp_bd_get_reply_t_handler_json
3773   (vl_api_one_ndp_bd_get_reply_t * mp)
3774 {
3775   vat_main_t *vam = &vat_main;
3776   vat_json_node_t root;
3777   u32 i, n;
3778   int retval = clib_net_to_host_u32 (mp->retval);
3779
3780   if (retval)
3781     goto end;
3782
3783   n = clib_net_to_host_u32 (mp->count);
3784   vat_json_init_array (&root);
3785
3786   for (i = 0; i < n; i++)
3787     {
3788       vat_json_array_add_uint (&root,
3789                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3790     }
3791
3792   vat_json_print (vam->ofp, &root);
3793   vat_json_free (&root);
3794
3795 end:
3796   vam->retval = retval;
3797   vam->result_ready = 1;
3798 }
3799
3800 static void
3801   vl_api_one_l2_arp_bd_get_reply_t_handler
3802   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 i, n;
3806   int retval = clib_net_to_host_u32 (mp->retval);
3807
3808   if (retval)
3809     goto end;
3810
3811   n = clib_net_to_host_u32 (mp->count);
3812
3813   for (i = 0; i < n; i++)
3814     {
3815       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3816     }
3817
3818 end:
3819   vam->retval = retval;
3820   vam->result_ready = 1;
3821 }
3822
3823 static void
3824   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3825   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3826 {
3827   vat_main_t *vam = &vat_main;
3828   vat_json_node_t root;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831
3832   if (retval)
3833     goto end;
3834
3835   n = clib_net_to_host_u32 (mp->count);
3836   vat_json_init_array (&root);
3837
3838   for (i = 0; i < n; i++)
3839     {
3840       vat_json_array_add_uint (&root,
3841                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3842     }
3843
3844   vat_json_print (vam->ofp, &root);
3845   vat_json_free (&root);
3846
3847 end:
3848   vam->retval = retval;
3849   vam->result_ready = 1;
3850 }
3851
3852 static void
3853   vl_api_one_adjacencies_get_reply_t_handler
3854   (vl_api_one_adjacencies_get_reply_t * mp)
3855 {
3856   vat_main_t *vam = &vat_main;
3857   u32 i, n;
3858   int retval = clib_net_to_host_u32 (mp->retval);
3859   vl_api_one_adjacency_t *a;
3860
3861   if (retval)
3862     goto end;
3863
3864   n = clib_net_to_host_u32 (mp->count);
3865
3866   for (i = 0; i < n; i++)
3867     {
3868       a = &mp->adjacencies[i];
3869       print (vam->ofp, "%U %40U",
3870              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3871              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3872     }
3873
3874 end:
3875   vam->retval = retval;
3876   vam->result_ready = 1;
3877 }
3878
3879 static void
3880   vl_api_one_adjacencies_get_reply_t_handler_json
3881   (vl_api_one_adjacencies_get_reply_t * mp)
3882 {
3883   u8 *s = 0;
3884   vat_main_t *vam = &vat_main;
3885   vat_json_node_t *e = 0, root;
3886   u32 i, n;
3887   int retval = clib_net_to_host_u32 (mp->retval);
3888   vl_api_one_adjacency_t *a;
3889
3890   if (retval)
3891     goto end;
3892
3893   n = clib_net_to_host_u32 (mp->count);
3894   vat_json_init_array (&root);
3895
3896   for (i = 0; i < n; i++)
3897     {
3898       e = vat_json_array_add (&root);
3899       a = &mp->adjacencies[i];
3900
3901       vat_json_init_object (e);
3902       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3903                   a->leid_prefix_len);
3904       vec_add1 (s, 0);
3905       vat_json_object_add_string_copy (e, "leid", s);
3906       vec_free (s);
3907
3908       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3909                   a->reid_prefix_len);
3910       vec_add1 (s, 0);
3911       vat_json_object_add_string_copy (e, "reid", s);
3912       vec_free (s);
3913     }
3914
3915   vat_json_print (vam->ofp, &root);
3916   vat_json_free (&root);
3917
3918 end:
3919   vam->retval = retval;
3920   vam->result_ready = 1;
3921 }
3922
3923 static void
3924 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3925 {
3926   vat_main_t *vam = &vat_main;
3927
3928   print (vam->ofp, "%=20U",
3929          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3930          mp->ip_address);
3931 }
3932
3933 static void
3934   vl_api_one_map_server_details_t_handler_json
3935   (vl_api_one_map_server_details_t * mp)
3936 {
3937   vat_main_t *vam = &vat_main;
3938   vat_json_node_t *node = NULL;
3939   struct in6_addr ip6;
3940   struct in_addr ip4;
3941
3942   if (VAT_JSON_ARRAY != vam->json_tree.type)
3943     {
3944       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3945       vat_json_init_array (&vam->json_tree);
3946     }
3947   node = vat_json_array_add (&vam->json_tree);
3948
3949   vat_json_init_object (node);
3950   if (mp->is_ipv6)
3951     {
3952       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3953       vat_json_object_add_ip6 (node, "map-server", ip6);
3954     }
3955   else
3956     {
3957       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3958       vat_json_object_add_ip4 (node, "map-server", ip4);
3959     }
3960 }
3961
3962 static void
3963 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3964                                            * mp)
3965 {
3966   vat_main_t *vam = &vat_main;
3967
3968   print (vam->ofp, "%=20U",
3969          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3970          mp->ip_address);
3971 }
3972
3973 static void
3974   vl_api_one_map_resolver_details_t_handler_json
3975   (vl_api_one_map_resolver_details_t * mp)
3976 {
3977   vat_main_t *vam = &vat_main;
3978   vat_json_node_t *node = NULL;
3979   struct in6_addr ip6;
3980   struct in_addr ip4;
3981
3982   if (VAT_JSON_ARRAY != vam->json_tree.type)
3983     {
3984       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3985       vat_json_init_array (&vam->json_tree);
3986     }
3987   node = vat_json_array_add (&vam->json_tree);
3988
3989   vat_json_init_object (node);
3990   if (mp->is_ipv6)
3991     {
3992       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3993       vat_json_object_add_ip6 (node, "map resolver", ip6);
3994     }
3995   else
3996     {
3997       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3998       vat_json_object_add_ip4 (node, "map resolver", ip4);
3999     }
4000 }
4001
4002 static void
4003 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4004 {
4005   vat_main_t *vam = &vat_main;
4006   i32 retval = ntohl (mp->retval);
4007
4008   if (0 <= retval)
4009     {
4010       print (vam->ofp, "feature: %s\ngpe: %s",
4011              mp->feature_status ? "enabled" : "disabled",
4012              mp->gpe_status ? "enabled" : "disabled");
4013     }
4014
4015   vam->retval = retval;
4016   vam->result_ready = 1;
4017 }
4018
4019 static void
4020   vl_api_show_one_status_reply_t_handler_json
4021   (vl_api_show_one_status_reply_t * mp)
4022 {
4023   vat_main_t *vam = &vat_main;
4024   vat_json_node_t node;
4025   u8 *gpe_status = NULL;
4026   u8 *feature_status = NULL;
4027
4028   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4029   feature_status = format (0, "%s",
4030                            mp->feature_status ? "enabled" : "disabled");
4031   vec_add1 (gpe_status, 0);
4032   vec_add1 (feature_status, 0);
4033
4034   vat_json_init_object (&node);
4035   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4036   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4037
4038   vec_free (gpe_status);
4039   vec_free (feature_status);
4040
4041   vat_json_print (vam->ofp, &node);
4042   vat_json_free (&node);
4043
4044   vam->retval = ntohl (mp->retval);
4045   vam->result_ready = 1;
4046 }
4047
4048 static void
4049   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4050   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4051 {
4052   vat_main_t *vam = &vat_main;
4053   i32 retval = ntohl (mp->retval);
4054
4055   if (retval >= 0)
4056     {
4057       print (vam->ofp, "%=20s", mp->locator_set_name);
4058     }
4059
4060   vam->retval = retval;
4061   vam->result_ready = 1;
4062 }
4063
4064 static void
4065   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4066   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4067 {
4068   vat_main_t *vam = &vat_main;
4069   vat_json_node_t *node = NULL;
4070
4071   if (VAT_JSON_ARRAY != vam->json_tree.type)
4072     {
4073       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4074       vat_json_init_array (&vam->json_tree);
4075     }
4076   node = vat_json_array_add (&vam->json_tree);
4077
4078   vat_json_init_object (node);
4079   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4080
4081   vat_json_print (vam->ofp, node);
4082   vat_json_free (node);
4083
4084   vam->retval = ntohl (mp->retval);
4085   vam->result_ready = 1;
4086 }
4087
4088 static u8 *
4089 format_lisp_map_request_mode (u8 * s, va_list * args)
4090 {
4091   u32 mode = va_arg (*args, u32);
4092
4093   switch (mode)
4094     {
4095     case 0:
4096       return format (0, "dst-only");
4097     case 1:
4098       return format (0, "src-dst");
4099     }
4100   return 0;
4101 }
4102
4103 static void
4104   vl_api_show_one_map_request_mode_reply_t_handler
4105   (vl_api_show_one_map_request_mode_reply_t * mp)
4106 {
4107   vat_main_t *vam = &vat_main;
4108   i32 retval = ntohl (mp->retval);
4109
4110   if (0 <= retval)
4111     {
4112       u32 mode = mp->mode;
4113       print (vam->ofp, "map_request_mode: %U",
4114              format_lisp_map_request_mode, mode);
4115     }
4116
4117   vam->retval = retval;
4118   vam->result_ready = 1;
4119 }
4120
4121 static void
4122   vl_api_show_one_map_request_mode_reply_t_handler_json
4123   (vl_api_show_one_map_request_mode_reply_t * mp)
4124 {
4125   vat_main_t *vam = &vat_main;
4126   vat_json_node_t node;
4127   u8 *s = 0;
4128   u32 mode;
4129
4130   mode = mp->mode;
4131   s = format (0, "%U", format_lisp_map_request_mode, mode);
4132   vec_add1 (s, 0);
4133
4134   vat_json_init_object (&node);
4135   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4136   vat_json_print (vam->ofp, &node);
4137   vat_json_free (&node);
4138
4139   vec_free (s);
4140   vam->retval = ntohl (mp->retval);
4141   vam->result_ready = 1;
4142 }
4143
4144 static void
4145   vl_api_show_one_use_petr_reply_t_handler
4146   (vl_api_show_one_use_petr_reply_t * mp)
4147 {
4148   vat_main_t *vam = &vat_main;
4149   i32 retval = ntohl (mp->retval);
4150
4151   if (0 <= retval)
4152     {
4153       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4154       if (mp->status)
4155         {
4156           print (vam->ofp, "Proxy-ETR address; %U",
4157                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4158                  mp->address);
4159         }
4160     }
4161
4162   vam->retval = retval;
4163   vam->result_ready = 1;
4164 }
4165
4166 static void
4167   vl_api_show_one_use_petr_reply_t_handler_json
4168   (vl_api_show_one_use_petr_reply_t * mp)
4169 {
4170   vat_main_t *vam = &vat_main;
4171   vat_json_node_t node;
4172   u8 *status = 0;
4173   struct in_addr ip4;
4174   struct in6_addr ip6;
4175
4176   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4177   vec_add1 (status, 0);
4178
4179   vat_json_init_object (&node);
4180   vat_json_object_add_string_copy (&node, "status", status);
4181   if (mp->status)
4182     {
4183       if (mp->is_ip4)
4184         {
4185           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4186           vat_json_object_add_ip6 (&node, "address", ip6);
4187         }
4188       else
4189         {
4190           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4191           vat_json_object_add_ip4 (&node, "address", ip4);
4192         }
4193     }
4194
4195   vec_free (status);
4196
4197   vat_json_print (vam->ofp, &node);
4198   vat_json_free (&node);
4199
4200   vam->retval = ntohl (mp->retval);
4201   vam->result_ready = 1;
4202 }
4203
4204 static void
4205   vl_api_show_one_nsh_mapping_reply_t_handler
4206   (vl_api_show_one_nsh_mapping_reply_t * mp)
4207 {
4208   vat_main_t *vam = &vat_main;
4209   i32 retval = ntohl (mp->retval);
4210
4211   if (0 <= retval)
4212     {
4213       print (vam->ofp, "%-20s%-16s",
4214              mp->is_set ? "set" : "not-set",
4215              mp->is_set ? (char *) mp->locator_set_name : "");
4216     }
4217
4218   vam->retval = retval;
4219   vam->result_ready = 1;
4220 }
4221
4222 static void
4223   vl_api_show_one_nsh_mapping_reply_t_handler_json
4224   (vl_api_show_one_nsh_mapping_reply_t * mp)
4225 {
4226   vat_main_t *vam = &vat_main;
4227   vat_json_node_t node;
4228   u8 *status = 0;
4229
4230   status = format (0, "%s", mp->is_set ? "yes" : "no");
4231   vec_add1 (status, 0);
4232
4233   vat_json_init_object (&node);
4234   vat_json_object_add_string_copy (&node, "is_set", status);
4235   if (mp->is_set)
4236     {
4237       vat_json_object_add_string_copy (&node, "locator_set",
4238                                        mp->locator_set_name);
4239     }
4240
4241   vec_free (status);
4242
4243   vat_json_print (vam->ofp, &node);
4244   vat_json_free (&node);
4245
4246   vam->retval = ntohl (mp->retval);
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_show_one_map_register_ttl_reply_t_handler
4252   (vl_api_show_one_map_register_ttl_reply_t * mp)
4253 {
4254   vat_main_t *vam = &vat_main;
4255   i32 retval = ntohl (mp->retval);
4256
4257   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4258
4259   if (0 <= retval)
4260     {
4261       print (vam->ofp, "ttl: %u", mp->ttl);
4262     }
4263
4264   vam->retval = retval;
4265   vam->result_ready = 1;
4266 }
4267
4268 static void
4269   vl_api_show_one_map_register_ttl_reply_t_handler_json
4270   (vl_api_show_one_map_register_ttl_reply_t * mp)
4271 {
4272   vat_main_t *vam = &vat_main;
4273   vat_json_node_t node;
4274
4275   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4276   vat_json_init_object (&node);
4277   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4278
4279   vat_json_print (vam->ofp, &node);
4280   vat_json_free (&node);
4281
4282   vam->retval = ntohl (mp->retval);
4283   vam->result_ready = 1;
4284 }
4285
4286 static void
4287 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   if (0 <= retval)
4293     {
4294       print (vam->ofp, "%-20s%-16s",
4295              mp->status ? "enabled" : "disabled",
4296              mp->status ? (char *) mp->locator_set_name : "");
4297     }
4298
4299   vam->retval = retval;
4300   vam->result_ready = 1;
4301 }
4302
4303 static void
4304 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *status = 0;
4309
4310   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4311   vec_add1 (status, 0);
4312
4313   vat_json_init_object (&node);
4314   vat_json_object_add_string_copy (&node, "status", status);
4315   if (mp->status)
4316     {
4317       vat_json_object_add_string_copy (&node, "locator_set",
4318                                        mp->locator_set_name);
4319     }
4320
4321   vec_free (status);
4322
4323   vat_json_print (vam->ofp, &node);
4324   vat_json_free (&node);
4325
4326   vam->retval = ntohl (mp->retval);
4327   vam->result_ready = 1;
4328 }
4329
4330 static u8 *
4331 format_policer_type (u8 * s, va_list * va)
4332 {
4333   u32 i = va_arg (*va, u32);
4334
4335   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4336     s = format (s, "1r2c");
4337   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4338     s = format (s, "1r3c");
4339   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4340     s = format (s, "2r3c-2698");
4341   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4342     s = format (s, "2r3c-4115");
4343   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4344     s = format (s, "2r3c-mef5cf1");
4345   else
4346     s = format (s, "ILLEGAL");
4347   return s;
4348 }
4349
4350 static u8 *
4351 format_policer_rate_type (u8 * s, va_list * va)
4352 {
4353   u32 i = va_arg (*va, u32);
4354
4355   if (i == SSE2_QOS_RATE_KBPS)
4356     s = format (s, "kbps");
4357   else if (i == SSE2_QOS_RATE_PPS)
4358     s = format (s, "pps");
4359   else
4360     s = format (s, "ILLEGAL");
4361   return s;
4362 }
4363
4364 static u8 *
4365 format_policer_round_type (u8 * s, va_list * va)
4366 {
4367   u32 i = va_arg (*va, u32);
4368
4369   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4370     s = format (s, "closest");
4371   else if (i == SSE2_QOS_ROUND_TO_UP)
4372     s = format (s, "up");
4373   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4374     s = format (s, "down");
4375   else
4376     s = format (s, "ILLEGAL");
4377   return s;
4378 }
4379
4380 static u8 *
4381 format_policer_action_type (u8 * s, va_list * va)
4382 {
4383   u32 i = va_arg (*va, u32);
4384
4385   if (i == SSE2_QOS_ACTION_DROP)
4386     s = format (s, "drop");
4387   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4388     s = format (s, "transmit");
4389   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4390     s = format (s, "mark-and-transmit");
4391   else
4392     s = format (s, "ILLEGAL");
4393   return s;
4394 }
4395
4396 static u8 *
4397 format_dscp (u8 * s, va_list * va)
4398 {
4399   u32 i = va_arg (*va, u32);
4400   char *t = 0;
4401
4402   switch (i)
4403     {
4404 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4405       foreach_vnet_dscp
4406 #undef _
4407     default:
4408       return format (s, "ILLEGAL");
4409     }
4410   s = format (s, "%s", t);
4411   return s;
4412 }
4413
4414 static void
4415 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4416 {
4417   vat_main_t *vam = &vat_main;
4418   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4419
4420   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4421     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4422   else
4423     conform_dscp_str = format (0, "");
4424
4425   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4426     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4427   else
4428     exceed_dscp_str = format (0, "");
4429
4430   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4431     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4432   else
4433     violate_dscp_str = format (0, "");
4434
4435   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4436          "rate type %U, round type %U, %s rate, %s color-aware, "
4437          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4438          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4439          "conform action %U%s, exceed action %U%s, violate action %U%s",
4440          mp->name,
4441          format_policer_type, mp->type,
4442          ntohl (mp->cir),
4443          ntohl (mp->eir),
4444          clib_net_to_host_u64 (mp->cb),
4445          clib_net_to_host_u64 (mp->eb),
4446          format_policer_rate_type, mp->rate_type,
4447          format_policer_round_type, mp->round_type,
4448          mp->single_rate ? "single" : "dual",
4449          mp->color_aware ? "is" : "not",
4450          ntohl (mp->cir_tokens_per_period),
4451          ntohl (mp->pir_tokens_per_period),
4452          ntohl (mp->scale),
4453          ntohl (mp->current_limit),
4454          ntohl (mp->current_bucket),
4455          ntohl (mp->extended_limit),
4456          ntohl (mp->extended_bucket),
4457          clib_net_to_host_u64 (mp->last_update_time),
4458          format_policer_action_type, mp->conform_action_type,
4459          conform_dscp_str,
4460          format_policer_action_type, mp->exceed_action_type,
4461          exceed_dscp_str,
4462          format_policer_action_type, mp->violate_action_type,
4463          violate_dscp_str);
4464
4465   vec_free (conform_dscp_str);
4466   vec_free (exceed_dscp_str);
4467   vec_free (violate_dscp_str);
4468 }
4469
4470 static void vl_api_policer_details_t_handler_json
4471   (vl_api_policer_details_t * mp)
4472 {
4473   vat_main_t *vam = &vat_main;
4474   vat_json_node_t *node;
4475   u8 *rate_type_str, *round_type_str, *type_str;
4476   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4477
4478   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4479   round_type_str =
4480     format (0, "%U", format_policer_round_type, mp->round_type);
4481   type_str = format (0, "%U", format_policer_type, mp->type);
4482   conform_action_str = format (0, "%U", format_policer_action_type,
4483                                mp->conform_action_type);
4484   exceed_action_str = format (0, "%U", format_policer_action_type,
4485                               mp->exceed_action_type);
4486   violate_action_str = format (0, "%U", format_policer_action_type,
4487                                mp->violate_action_type);
4488
4489   if (VAT_JSON_ARRAY != vam->json_tree.type)
4490     {
4491       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4492       vat_json_init_array (&vam->json_tree);
4493     }
4494   node = vat_json_array_add (&vam->json_tree);
4495
4496   vat_json_init_object (node);
4497   vat_json_object_add_string_copy (node, "name", mp->name);
4498   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4499   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4500   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4501   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4502   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4503   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4504   vat_json_object_add_string_copy (node, "type", type_str);
4505   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4506   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4507   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4508   vat_json_object_add_uint (node, "cir_tokens_per_period",
4509                             ntohl (mp->cir_tokens_per_period));
4510   vat_json_object_add_uint (node, "eir_tokens_per_period",
4511                             ntohl (mp->pir_tokens_per_period));
4512   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4513   vat_json_object_add_uint (node, "current_bucket",
4514                             ntohl (mp->current_bucket));
4515   vat_json_object_add_uint (node, "extended_limit",
4516                             ntohl (mp->extended_limit));
4517   vat_json_object_add_uint (node, "extended_bucket",
4518                             ntohl (mp->extended_bucket));
4519   vat_json_object_add_uint (node, "last_update_time",
4520                             ntohl (mp->last_update_time));
4521   vat_json_object_add_string_copy (node, "conform_action",
4522                                    conform_action_str);
4523   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4524     {
4525       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4526       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4527       vec_free (dscp_str);
4528     }
4529   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4530   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4531     {
4532       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4533       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4534       vec_free (dscp_str);
4535     }
4536   vat_json_object_add_string_copy (node, "violate_action",
4537                                    violate_action_str);
4538   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4539     {
4540       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4541       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4542       vec_free (dscp_str);
4543     }
4544
4545   vec_free (rate_type_str);
4546   vec_free (round_type_str);
4547   vec_free (type_str);
4548   vec_free (conform_action_str);
4549   vec_free (exceed_action_str);
4550   vec_free (violate_action_str);
4551 }
4552
4553 static void
4554 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4555                                            mp)
4556 {
4557   vat_main_t *vam = &vat_main;
4558   int i, count = ntohl (mp->count);
4559
4560   if (count > 0)
4561     print (vam->ofp, "classify table ids (%d) : ", count);
4562   for (i = 0; i < count; i++)
4563     {
4564       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4565       print (vam->ofp, (i < count - 1) ? "," : "");
4566     }
4567   vam->retval = ntohl (mp->retval);
4568   vam->result_ready = 1;
4569 }
4570
4571 static void
4572   vl_api_classify_table_ids_reply_t_handler_json
4573   (vl_api_classify_table_ids_reply_t * mp)
4574 {
4575   vat_main_t *vam = &vat_main;
4576   int i, count = ntohl (mp->count);
4577
4578   if (count > 0)
4579     {
4580       vat_json_node_t node;
4581
4582       vat_json_init_object (&node);
4583       for (i = 0; i < count; i++)
4584         {
4585           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4586         }
4587       vat_json_print (vam->ofp, &node);
4588       vat_json_free (&node);
4589     }
4590   vam->retval = ntohl (mp->retval);
4591   vam->result_ready = 1;
4592 }
4593
4594 static void
4595   vl_api_classify_table_by_interface_reply_t_handler
4596   (vl_api_classify_table_by_interface_reply_t * mp)
4597 {
4598   vat_main_t *vam = &vat_main;
4599   u32 table_id;
4600
4601   table_id = ntohl (mp->l2_table_id);
4602   if (table_id != ~0)
4603     print (vam->ofp, "l2 table id : %d", table_id);
4604   else
4605     print (vam->ofp, "l2 table id : No input ACL tables configured");
4606   table_id = ntohl (mp->ip4_table_id);
4607   if (table_id != ~0)
4608     print (vam->ofp, "ip4 table id : %d", table_id);
4609   else
4610     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4611   table_id = ntohl (mp->ip6_table_id);
4612   if (table_id != ~0)
4613     print (vam->ofp, "ip6 table id : %d", table_id);
4614   else
4615     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4616   vam->retval = ntohl (mp->retval);
4617   vam->result_ready = 1;
4618 }
4619
4620 static void
4621   vl_api_classify_table_by_interface_reply_t_handler_json
4622   (vl_api_classify_table_by_interface_reply_t * mp)
4623 {
4624   vat_main_t *vam = &vat_main;
4625   vat_json_node_t node;
4626
4627   vat_json_init_object (&node);
4628
4629   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4630   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4631   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4632
4633   vat_json_print (vam->ofp, &node);
4634   vat_json_free (&node);
4635
4636   vam->retval = ntohl (mp->retval);
4637   vam->result_ready = 1;
4638 }
4639
4640 static void vl_api_policer_add_del_reply_t_handler
4641   (vl_api_policer_add_del_reply_t * mp)
4642 {
4643   vat_main_t *vam = &vat_main;
4644   i32 retval = ntohl (mp->retval);
4645   if (vam->async_mode)
4646     {
4647       vam->async_errors += (retval < 0);
4648     }
4649   else
4650     {
4651       vam->retval = retval;
4652       vam->result_ready = 1;
4653       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4654         /*
4655          * Note: this is just barely thread-safe, depends on
4656          * the main thread spinning waiting for an answer...
4657          */
4658         errmsg ("policer index %d", ntohl (mp->policer_index));
4659     }
4660 }
4661
4662 static void vl_api_policer_add_del_reply_t_handler_json
4663   (vl_api_policer_add_del_reply_t * mp)
4664 {
4665   vat_main_t *vam = &vat_main;
4666   vat_json_node_t node;
4667
4668   vat_json_init_object (&node);
4669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4670   vat_json_object_add_uint (&node, "policer_index",
4671                             ntohl (mp->policer_index));
4672
4673   vat_json_print (vam->ofp, &node);
4674   vat_json_free (&node);
4675
4676   vam->retval = ntohl (mp->retval);
4677   vam->result_ready = 1;
4678 }
4679
4680 /* Format hex dump. */
4681 u8 *
4682 format_hex_bytes (u8 * s, va_list * va)
4683 {
4684   u8 *bytes = va_arg (*va, u8 *);
4685   int n_bytes = va_arg (*va, int);
4686   uword i;
4687
4688   /* Print short or long form depending on byte count. */
4689   uword short_form = n_bytes <= 32;
4690   u32 indent = format_get_indent (s);
4691
4692   if (n_bytes == 0)
4693     return s;
4694
4695   for (i = 0; i < n_bytes; i++)
4696     {
4697       if (!short_form && (i % 32) == 0)
4698         s = format (s, "%08x: ", i);
4699       s = format (s, "%02x", bytes[i]);
4700       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4701         s = format (s, "\n%U", format_white_space, indent);
4702     }
4703
4704   return s;
4705 }
4706
4707 static void
4708 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4709                                             * mp)
4710 {
4711   vat_main_t *vam = &vat_main;
4712   i32 retval = ntohl (mp->retval);
4713   if (retval == 0)
4714     {
4715       print (vam->ofp, "classify table info :");
4716       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4717              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4718              ntohl (mp->miss_next_index));
4719       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4720              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4721              ntohl (mp->match_n_vectors));
4722       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4723              ntohl (mp->mask_length));
4724     }
4725   vam->retval = retval;
4726   vam->result_ready = 1;
4727 }
4728
4729 static void
4730   vl_api_classify_table_info_reply_t_handler_json
4731   (vl_api_classify_table_info_reply_t * mp)
4732 {
4733   vat_main_t *vam = &vat_main;
4734   vat_json_node_t node;
4735
4736   i32 retval = ntohl (mp->retval);
4737   if (retval == 0)
4738     {
4739       vat_json_init_object (&node);
4740
4741       vat_json_object_add_int (&node, "sessions",
4742                                ntohl (mp->active_sessions));
4743       vat_json_object_add_int (&node, "nexttbl",
4744                                ntohl (mp->next_table_index));
4745       vat_json_object_add_int (&node, "nextnode",
4746                                ntohl (mp->miss_next_index));
4747       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4748       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4749       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4750       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4751                       ntohl (mp->mask_length), 0);
4752       vat_json_object_add_string_copy (&node, "mask", s);
4753
4754       vat_json_print (vam->ofp, &node);
4755       vat_json_free (&node);
4756     }
4757   vam->retval = ntohl (mp->retval);
4758   vam->result_ready = 1;
4759 }
4760
4761 static void
4762 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4763                                            mp)
4764 {
4765   vat_main_t *vam = &vat_main;
4766
4767   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4768          ntohl (mp->hit_next_index), ntohl (mp->advance),
4769          ntohl (mp->opaque_index));
4770   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4771          ntohl (mp->match_length));
4772 }
4773
4774 static void
4775   vl_api_classify_session_details_t_handler_json
4776   (vl_api_classify_session_details_t * mp)
4777 {
4778   vat_main_t *vam = &vat_main;
4779   vat_json_node_t *node = NULL;
4780
4781   if (VAT_JSON_ARRAY != vam->json_tree.type)
4782     {
4783       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4784       vat_json_init_array (&vam->json_tree);
4785     }
4786   node = vat_json_array_add (&vam->json_tree);
4787
4788   vat_json_init_object (node);
4789   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4790   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4791   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4792   u8 *s =
4793     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4794             0);
4795   vat_json_object_add_string_copy (node, "match", s);
4796 }
4797
4798 static void vl_api_pg_create_interface_reply_t_handler
4799   (vl_api_pg_create_interface_reply_t * mp)
4800 {
4801   vat_main_t *vam = &vat_main;
4802
4803   vam->retval = ntohl (mp->retval);
4804   vam->result_ready = 1;
4805 }
4806
4807 static void vl_api_pg_create_interface_reply_t_handler_json
4808   (vl_api_pg_create_interface_reply_t * mp)
4809 {
4810   vat_main_t *vam = &vat_main;
4811   vat_json_node_t node;
4812
4813   i32 retval = ntohl (mp->retval);
4814   if (retval == 0)
4815     {
4816       vat_json_init_object (&node);
4817
4818       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4819
4820       vat_json_print (vam->ofp, &node);
4821       vat_json_free (&node);
4822     }
4823   vam->retval = ntohl (mp->retval);
4824   vam->result_ready = 1;
4825 }
4826
4827 static void vl_api_policer_classify_details_t_handler
4828   (vl_api_policer_classify_details_t * mp)
4829 {
4830   vat_main_t *vam = &vat_main;
4831
4832   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4833          ntohl (mp->table_index));
4834 }
4835
4836 static void vl_api_policer_classify_details_t_handler_json
4837   (vl_api_policer_classify_details_t * mp)
4838 {
4839   vat_main_t *vam = &vat_main;
4840   vat_json_node_t *node;
4841
4842   if (VAT_JSON_ARRAY != vam->json_tree.type)
4843     {
4844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4845       vat_json_init_array (&vam->json_tree);
4846     }
4847   node = vat_json_array_add (&vam->json_tree);
4848
4849   vat_json_init_object (node);
4850   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4851   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4852 }
4853
4854 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4855   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4856 {
4857   vat_main_t *vam = &vat_main;
4858   i32 retval = ntohl (mp->retval);
4859   if (vam->async_mode)
4860     {
4861       vam->async_errors += (retval < 0);
4862     }
4863   else
4864     {
4865       vam->retval = retval;
4866       vam->sw_if_index = ntohl (mp->sw_if_index);
4867       vam->result_ready = 1;
4868     }
4869 }
4870
4871 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4872   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   vat_json_node_t node;
4876
4877   vat_json_init_object (&node);
4878   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4879   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4880
4881   vat_json_print (vam->ofp, &node);
4882   vat_json_free (&node);
4883
4884   vam->retval = ntohl (mp->retval);
4885   vam->result_ready = 1;
4886 }
4887
4888 static void vl_api_flow_classify_details_t_handler
4889   (vl_api_flow_classify_details_t * mp)
4890 {
4891   vat_main_t *vam = &vat_main;
4892
4893   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4894          ntohl (mp->table_index));
4895 }
4896
4897 static void vl_api_flow_classify_details_t_handler_json
4898   (vl_api_flow_classify_details_t * mp)
4899 {
4900   vat_main_t *vam = &vat_main;
4901   vat_json_node_t *node;
4902
4903   if (VAT_JSON_ARRAY != vam->json_tree.type)
4904     {
4905       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4906       vat_json_init_array (&vam->json_tree);
4907     }
4908   node = vat_json_array_add (&vam->json_tree);
4909
4910   vat_json_init_object (node);
4911   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4912   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4913 }
4914
4915 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4916 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4917 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4918 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4919 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4920 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4921 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4922 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4923 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4924 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4925 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4926 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4927 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4928 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4929 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4930 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4931 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4932 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4933 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
4934 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
4935 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
4936 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
4937
4938 /*
4939  * Generate boilerplate reply handlers, which
4940  * dig the return value out of the xxx_reply_t API message,
4941  * stick it into vam->retval, and set vam->result_ready
4942  *
4943  * Could also do this by pointing N message decode slots at
4944  * a single function, but that could break in subtle ways.
4945  */
4946
4947 #define foreach_standard_reply_retval_handler           \
4948 _(sw_interface_set_flags_reply)                         \
4949 _(sw_interface_add_del_address_reply)                   \
4950 _(sw_interface_set_table_reply)                         \
4951 _(sw_interface_set_mpls_enable_reply)                   \
4952 _(sw_interface_set_vpath_reply)                         \
4953 _(sw_interface_set_vxlan_bypass_reply)                  \
4954 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4955 _(sw_interface_set_l2_bridge_reply)                     \
4956 _(bridge_domain_add_del_reply)                          \
4957 _(sw_interface_set_l2_xconnect_reply)                   \
4958 _(l2fib_add_del_reply)                                  \
4959 _(l2fib_flush_int_reply)                                \
4960 _(l2fib_flush_bd_reply)                                 \
4961 _(ip_add_del_route_reply)                               \
4962 _(ip_table_add_del_reply)                               \
4963 _(ip_mroute_add_del_reply)                              \
4964 _(mpls_route_add_del_reply)                             \
4965 _(mpls_table_add_del_reply)                             \
4966 _(mpls_ip_bind_unbind_reply)                            \
4967 _(proxy_arp_add_del_reply)                              \
4968 _(proxy_arp_intfc_enable_disable_reply)                 \
4969 _(sw_interface_set_unnumbered_reply)                    \
4970 _(ip_neighbor_add_del_reply)                            \
4971 _(reset_vrf_reply)                                      \
4972 _(oam_add_del_reply)                                    \
4973 _(reset_fib_reply)                                      \
4974 _(dhcp_proxy_config_reply)                              \
4975 _(dhcp_proxy_set_vss_reply)                             \
4976 _(dhcp_client_config_reply)                             \
4977 _(set_ip_flow_hash_reply)                               \
4978 _(sw_interface_ip6_enable_disable_reply)                \
4979 _(sw_interface_ip6_set_link_local_address_reply)        \
4980 _(ip6nd_proxy_add_del_reply)                            \
4981 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4982 _(sw_interface_ip6nd_ra_config_reply)                   \
4983 _(set_arp_neighbor_limit_reply)                         \
4984 _(l2_patch_add_del_reply)                               \
4985 _(sr_policy_add_reply)                                  \
4986 _(sr_policy_mod_reply)                                  \
4987 _(sr_policy_del_reply)                                  \
4988 _(sr_localsid_add_del_reply)                            \
4989 _(sr_steering_add_del_reply)                            \
4990 _(classify_add_del_session_reply)                       \
4991 _(classify_set_interface_ip_table_reply)                \
4992 _(classify_set_interface_l2_tables_reply)               \
4993 _(l2tpv3_set_tunnel_cookies_reply)                      \
4994 _(l2tpv3_interface_enable_disable_reply)                \
4995 _(l2tpv3_set_lookup_key_reply)                          \
4996 _(l2_fib_clear_table_reply)                             \
4997 _(l2_interface_efp_filter_reply)                        \
4998 _(l2_interface_vlan_tag_rewrite_reply)                  \
4999 _(modify_vhost_user_if_reply)                           \
5000 _(delete_vhost_user_if_reply)                           \
5001 _(want_ip4_arp_events_reply)                            \
5002 _(want_ip6_nd_events_reply)                             \
5003 _(want_l2_macs_events_reply)                            \
5004 _(input_acl_set_interface_reply)                        \
5005 _(ipsec_spd_add_del_reply)                              \
5006 _(ipsec_interface_add_del_spd_reply)                    \
5007 _(ipsec_spd_add_del_entry_reply)                        \
5008 _(ipsec_sad_add_del_entry_reply)                        \
5009 _(ipsec_sa_set_key_reply)                               \
5010 _(ipsec_tunnel_if_add_del_reply)                        \
5011 _(ikev2_profile_add_del_reply)                          \
5012 _(ikev2_profile_set_auth_reply)                         \
5013 _(ikev2_profile_set_id_reply)                           \
5014 _(ikev2_profile_set_ts_reply)                           \
5015 _(ikev2_set_local_key_reply)                            \
5016 _(ikev2_set_responder_reply)                            \
5017 _(ikev2_set_ike_transforms_reply)                       \
5018 _(ikev2_set_esp_transforms_reply)                       \
5019 _(ikev2_set_sa_lifetime_reply)                          \
5020 _(ikev2_initiate_sa_init_reply)                         \
5021 _(ikev2_initiate_del_ike_sa_reply)                      \
5022 _(ikev2_initiate_del_child_sa_reply)                    \
5023 _(ikev2_initiate_rekey_child_sa_reply)                  \
5024 _(delete_loopback_reply)                                \
5025 _(bd_ip_mac_add_del_reply)                              \
5026 _(map_del_domain_reply)                                 \
5027 _(map_add_del_rule_reply)                               \
5028 _(want_interface_events_reply)                          \
5029 _(want_stats_reply)                                     \
5030 _(cop_interface_enable_disable_reply)                   \
5031 _(cop_whitelist_enable_disable_reply)                   \
5032 _(sw_interface_clear_stats_reply)                       \
5033 _(ioam_enable_reply)                              \
5034 _(ioam_disable_reply)                              \
5035 _(one_add_del_locator_reply)                            \
5036 _(one_add_del_local_eid_reply)                          \
5037 _(one_add_del_remote_mapping_reply)                     \
5038 _(one_add_del_adjacency_reply)                          \
5039 _(one_add_del_map_resolver_reply)                       \
5040 _(one_add_del_map_server_reply)                         \
5041 _(one_enable_disable_reply)                             \
5042 _(one_rloc_probe_enable_disable_reply)                  \
5043 _(one_map_register_enable_disable_reply)                \
5044 _(one_map_register_set_ttl_reply)                       \
5045 _(one_set_transport_protocol_reply)                     \
5046 _(one_map_register_fallback_threshold_reply)            \
5047 _(one_pitr_set_locator_set_reply)                       \
5048 _(one_map_request_mode_reply)                           \
5049 _(one_add_del_map_request_itr_rlocs_reply)              \
5050 _(one_eid_table_add_del_map_reply)                      \
5051 _(one_use_petr_reply)                                   \
5052 _(one_stats_enable_disable_reply)                       \
5053 _(one_add_del_l2_arp_entry_reply)                       \
5054 _(one_add_del_ndp_entry_reply)                          \
5055 _(one_stats_flush_reply)                                \
5056 _(gpe_enable_disable_reply)                             \
5057 _(gpe_set_encap_mode_reply)                             \
5058 _(gpe_add_del_iface_reply)                              \
5059 _(gpe_add_del_native_fwd_rpath_reply)                   \
5060 _(af_packet_delete_reply)                               \
5061 _(policer_classify_set_interface_reply)                 \
5062 _(netmap_create_reply)                                  \
5063 _(netmap_delete_reply)                                  \
5064 _(set_ipfix_exporter_reply)                             \
5065 _(set_ipfix_classify_stream_reply)                      \
5066 _(ipfix_classify_table_add_del_reply)                   \
5067 _(flow_classify_set_interface_reply)                    \
5068 _(sw_interface_span_enable_disable_reply)               \
5069 _(pg_capture_reply)                                     \
5070 _(pg_enable_disable_reply)                              \
5071 _(ip_source_and_port_range_check_add_del_reply)         \
5072 _(ip_source_and_port_range_check_interface_add_del_reply)\
5073 _(delete_subif_reply)                                   \
5074 _(l2_interface_pbb_tag_rewrite_reply)                   \
5075 _(punt_reply)                                           \
5076 _(feature_enable_disable_reply)                         \
5077 _(sw_interface_tag_add_del_reply)                       \
5078 _(sw_interface_set_mtu_reply)                           \
5079 _(p2p_ethernet_add_reply)                               \
5080 _(p2p_ethernet_del_reply)                               \
5081 _(lldp_config_reply)                                    \
5082 _(sw_interface_set_lldp_reply)                          \
5083 _(tcp_configure_src_addresses_reply)
5084
5085 #define _(n)                                    \
5086     static void vl_api_##n##_t_handler          \
5087     (vl_api_##n##_t * mp)                       \
5088     {                                           \
5089         vat_main_t * vam = &vat_main;           \
5090         i32 retval = ntohl(mp->retval);         \
5091         if (vam->async_mode) {                  \
5092             vam->async_errors += (retval < 0);  \
5093         } else {                                \
5094             vam->retval = retval;               \
5095             vam->result_ready = 1;              \
5096         }                                       \
5097     }
5098 foreach_standard_reply_retval_handler;
5099 #undef _
5100
5101 #define _(n)                                    \
5102     static void vl_api_##n##_t_handler_json     \
5103     (vl_api_##n##_t * mp)                       \
5104     {                                           \
5105         vat_main_t * vam = &vat_main;           \
5106         vat_json_node_t node;                   \
5107         vat_json_init_object(&node);            \
5108         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5109         vat_json_print(vam->ofp, &node);        \
5110         vam->retval = ntohl(mp->retval);        \
5111         vam->result_ready = 1;                  \
5112     }
5113 foreach_standard_reply_retval_handler;
5114 #undef _
5115
5116 /*
5117  * Table of message reply handlers, must include boilerplate handlers
5118  * we just generated
5119  */
5120
5121 #define foreach_vpe_api_reply_msg                                       \
5122 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5123 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5124 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5125 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5126 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5127 _(CLI_REPLY, cli_reply)                                                 \
5128 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5129 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5130   sw_interface_add_del_address_reply)                                   \
5131 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5132 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5133 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5134 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5135 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5136 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5137   sw_interface_set_l2_xconnect_reply)                                   \
5138 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5139   sw_interface_set_l2_bridge_reply)                                     \
5140 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5141 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5142 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5143 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5144 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5145 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5146 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5147 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5148 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5149 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5150 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5151 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5152 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5153 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5154 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5155 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5156 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5157 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5158 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5159 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5160   proxy_arp_intfc_enable_disable_reply)                                 \
5161 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5162 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5163   sw_interface_set_unnumbered_reply)                                    \
5164 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5165 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5166 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5167 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5168 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5169 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5170 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5171 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5172 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5173 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5174 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5175 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5176   sw_interface_ip6_enable_disable_reply)                                \
5177 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5178   sw_interface_ip6_set_link_local_address_reply)                        \
5179 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5180 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5181 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5182   sw_interface_ip6nd_ra_prefix_reply)                                   \
5183 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5184   sw_interface_ip6nd_ra_config_reply)                                   \
5185 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5186 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5187 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5188 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5189 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5190 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5191 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5192 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5193 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5194 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5195 classify_set_interface_ip_table_reply)                                  \
5196 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5197   classify_set_interface_l2_tables_reply)                               \
5198 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5199 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5200 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5201 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5202 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5203   l2tpv3_interface_enable_disable_reply)                                \
5204 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5205 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5206 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5207 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5208 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5209 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5210 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5211 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5212 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5213 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5214 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5215 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5216 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5217 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5218 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5219 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5220 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5221 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5222 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5223 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5224 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5225 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5226 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5227 _(L2_MACS_EVENT, l2_macs_event)                                         \
5228 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5229 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5230 _(IP_DETAILS, ip_details)                                               \
5231 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5232 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5233 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5234 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5235 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5236 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5237 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5238 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5239 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5240 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5241 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5242 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5243 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5244 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5245 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5246 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5247 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5248 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5249 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5250 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5251 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5252 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5253 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5254 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5255 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5256 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5257 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5258 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5259 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5260 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5261 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5262 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5263 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5264 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5265 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5266 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5267 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5268 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5269 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5270 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5271 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5272 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5273 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5274 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5275 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5276 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5277   one_map_register_enable_disable_reply)                                \
5278 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5279 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5280 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5281 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5282   one_map_register_fallback_threshold_reply)                            \
5283 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5284   one_rloc_probe_enable_disable_reply)                                  \
5285 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5286 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5287 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5288 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5289 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5290 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5291 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5292 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5293 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5294 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5295 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5296 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5297 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5298 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5299 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5300 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5301   show_one_stats_enable_disable_reply)                                  \
5302 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5303 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5304 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5305 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5306 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5307 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5308 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5309 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5310 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5311 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5312 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5313 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5314 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5315 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5316 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5317   gpe_add_del_native_fwd_rpath_reply)                                   \
5318 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5319   gpe_fwd_entry_path_details)                                           \
5320 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5321 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5322   one_add_del_map_request_itr_rlocs_reply)                              \
5323 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5324   one_get_map_request_itr_rlocs_reply)                                  \
5325 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5326 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5327 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5328 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5329 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5330 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5331   show_one_map_register_state_reply)                                    \
5332 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5333 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5334   show_one_map_register_fallback_threshold_reply)                       \
5335 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5336 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5337 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5338 _(POLICER_DETAILS, policer_details)                                     \
5339 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5340 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5341 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5342 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5343 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5344 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5345 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5346 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5347 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5348 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5349 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5350 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5351 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5352 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5353 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5354 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5355 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5356 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5357 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5358 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5359 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5360 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5361 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5362 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5363 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5364  ip_source_and_port_range_check_add_del_reply)                          \
5365 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5366  ip_source_and_port_range_check_interface_add_del_reply)                \
5367 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5368 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5369 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5370 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5371 _(PUNT_REPLY, punt_reply)                                               \
5372 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5373 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5374 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5375 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5376 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5377 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5378 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5379 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5380 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5381 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5382 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5383 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5384 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply)
5385
5386 #define foreach_standalone_reply_msg                                    \
5387 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5388 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5389 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5390 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5391 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5392 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5393 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5394 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)
5395
5396 typedef struct
5397 {
5398   u8 *name;
5399   u32 value;
5400 } name_sort_t;
5401
5402
5403 #define STR_VTR_OP_CASE(op)     \
5404     case L2_VTR_ ## op:         \
5405         return "" # op;
5406
5407 static const char *
5408 str_vtr_op (u32 vtr_op)
5409 {
5410   switch (vtr_op)
5411     {
5412       STR_VTR_OP_CASE (DISABLED);
5413       STR_VTR_OP_CASE (PUSH_1);
5414       STR_VTR_OP_CASE (PUSH_2);
5415       STR_VTR_OP_CASE (POP_1);
5416       STR_VTR_OP_CASE (POP_2);
5417       STR_VTR_OP_CASE (TRANSLATE_1_1);
5418       STR_VTR_OP_CASE (TRANSLATE_1_2);
5419       STR_VTR_OP_CASE (TRANSLATE_2_1);
5420       STR_VTR_OP_CASE (TRANSLATE_2_2);
5421     }
5422
5423   return "UNKNOWN";
5424 }
5425
5426 static int
5427 dump_sub_interface_table (vat_main_t * vam)
5428 {
5429   const sw_interface_subif_t *sub = NULL;
5430
5431   if (vam->json_output)
5432     {
5433       clib_warning
5434         ("JSON output supported only for VPE API calls and dump_stats_table");
5435       return -99;
5436     }
5437
5438   print (vam->ofp,
5439          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5440          "Interface", "sw_if_index",
5441          "sub id", "dot1ad", "tags", "outer id",
5442          "inner id", "exact", "default", "outer any", "inner any");
5443
5444   vec_foreach (sub, vam->sw_if_subif_table)
5445   {
5446     print (vam->ofp,
5447            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5448            sub->interface_name,
5449            sub->sw_if_index,
5450            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5451            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5452            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5453            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5454     if (sub->vtr_op != L2_VTR_DISABLED)
5455       {
5456         print (vam->ofp,
5457                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5458                "tag1: %d tag2: %d ]",
5459                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5460                sub->vtr_tag1, sub->vtr_tag2);
5461       }
5462   }
5463
5464   return 0;
5465 }
5466
5467 static int
5468 name_sort_cmp (void *a1, void *a2)
5469 {
5470   name_sort_t *n1 = a1;
5471   name_sort_t *n2 = a2;
5472
5473   return strcmp ((char *) n1->name, (char *) n2->name);
5474 }
5475
5476 static int
5477 dump_interface_table (vat_main_t * vam)
5478 {
5479   hash_pair_t *p;
5480   name_sort_t *nses = 0, *ns;
5481
5482   if (vam->json_output)
5483     {
5484       clib_warning
5485         ("JSON output supported only for VPE API calls and dump_stats_table");
5486       return -99;
5487     }
5488
5489   /* *INDENT-OFF* */
5490   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5491   ({
5492     vec_add2 (nses, ns, 1);
5493     ns->name = (u8 *)(p->key);
5494     ns->value = (u32) p->value[0];
5495   }));
5496   /* *INDENT-ON* */
5497
5498   vec_sort_with_function (nses, name_sort_cmp);
5499
5500   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5501   vec_foreach (ns, nses)
5502   {
5503     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5504   }
5505   vec_free (nses);
5506   return 0;
5507 }
5508
5509 static int
5510 dump_ip_table (vat_main_t * vam, int is_ipv6)
5511 {
5512   const ip_details_t *det = NULL;
5513   const ip_address_details_t *address = NULL;
5514   u32 i = ~0;
5515
5516   print (vam->ofp, "%-12s", "sw_if_index");
5517
5518   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5519   {
5520     i++;
5521     if (!det->present)
5522       {
5523         continue;
5524       }
5525     print (vam->ofp, "%-12d", i);
5526     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5527     if (!det->addr)
5528       {
5529         continue;
5530       }
5531     vec_foreach (address, det->addr)
5532     {
5533       print (vam->ofp,
5534              "            %-30U%-13d",
5535              is_ipv6 ? format_ip6_address : format_ip4_address,
5536              address->ip, address->prefix_length);
5537     }
5538   }
5539
5540   return 0;
5541 }
5542
5543 static int
5544 dump_ipv4_table (vat_main_t * vam)
5545 {
5546   if (vam->json_output)
5547     {
5548       clib_warning
5549         ("JSON output supported only for VPE API calls and dump_stats_table");
5550       return -99;
5551     }
5552
5553   return dump_ip_table (vam, 0);
5554 }
5555
5556 static int
5557 dump_ipv6_table (vat_main_t * vam)
5558 {
5559   if (vam->json_output)
5560     {
5561       clib_warning
5562         ("JSON output supported only for VPE API calls and dump_stats_table");
5563       return -99;
5564     }
5565
5566   return dump_ip_table (vam, 1);
5567 }
5568
5569 static char *
5570 counter_type_to_str (u8 counter_type, u8 is_combined)
5571 {
5572   if (!is_combined)
5573     {
5574       switch (counter_type)
5575         {
5576         case VNET_INTERFACE_COUNTER_DROP:
5577           return "drop";
5578         case VNET_INTERFACE_COUNTER_PUNT:
5579           return "punt";
5580         case VNET_INTERFACE_COUNTER_IP4:
5581           return "ip4";
5582         case VNET_INTERFACE_COUNTER_IP6:
5583           return "ip6";
5584         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5585           return "rx-no-buf";
5586         case VNET_INTERFACE_COUNTER_RX_MISS:
5587           return "rx-miss";
5588         case VNET_INTERFACE_COUNTER_RX_ERROR:
5589           return "rx-error";
5590         case VNET_INTERFACE_COUNTER_TX_ERROR:
5591           return "tx-error";
5592         default:
5593           return "INVALID-COUNTER-TYPE";
5594         }
5595     }
5596   else
5597     {
5598       switch (counter_type)
5599         {
5600         case VNET_INTERFACE_COUNTER_RX:
5601           return "rx";
5602         case VNET_INTERFACE_COUNTER_TX:
5603           return "tx";
5604         default:
5605           return "INVALID-COUNTER-TYPE";
5606         }
5607     }
5608 }
5609
5610 static int
5611 dump_stats_table (vat_main_t * vam)
5612 {
5613   vat_json_node_t node;
5614   vat_json_node_t *msg_array;
5615   vat_json_node_t *msg;
5616   vat_json_node_t *counter_array;
5617   vat_json_node_t *counter;
5618   interface_counter_t c;
5619   u64 packets;
5620   ip4_fib_counter_t *c4;
5621   ip6_fib_counter_t *c6;
5622   ip4_nbr_counter_t *n4;
5623   ip6_nbr_counter_t *n6;
5624   int i, j;
5625
5626   if (!vam->json_output)
5627     {
5628       clib_warning ("dump_stats_table supported only in JSON format");
5629       return -99;
5630     }
5631
5632   vat_json_init_object (&node);
5633
5634   /* interface counters */
5635   msg_array = vat_json_object_add (&node, "interface_counters");
5636   vat_json_init_array (msg_array);
5637   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5638     {
5639       msg = vat_json_array_add (msg_array);
5640       vat_json_init_object (msg);
5641       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5642                                        (u8 *) counter_type_to_str (i, 0));
5643       vat_json_object_add_int (msg, "is_combined", 0);
5644       counter_array = vat_json_object_add (msg, "data");
5645       vat_json_init_array (counter_array);
5646       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5647         {
5648           packets = vam->simple_interface_counters[i][j];
5649           vat_json_array_add_uint (counter_array, packets);
5650         }
5651     }
5652   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5653     {
5654       msg = vat_json_array_add (msg_array);
5655       vat_json_init_object (msg);
5656       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5657                                        (u8 *) counter_type_to_str (i, 1));
5658       vat_json_object_add_int (msg, "is_combined", 1);
5659       counter_array = vat_json_object_add (msg, "data");
5660       vat_json_init_array (counter_array);
5661       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5662         {
5663           c = vam->combined_interface_counters[i][j];
5664           counter = vat_json_array_add (counter_array);
5665           vat_json_init_object (counter);
5666           vat_json_object_add_uint (counter, "packets", c.packets);
5667           vat_json_object_add_uint (counter, "bytes", c.bytes);
5668         }
5669     }
5670
5671   /* ip4 fib counters */
5672   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5673   vat_json_init_array (msg_array);
5674   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5675     {
5676       msg = vat_json_array_add (msg_array);
5677       vat_json_init_object (msg);
5678       vat_json_object_add_uint (msg, "vrf_id",
5679                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5680       counter_array = vat_json_object_add (msg, "c");
5681       vat_json_init_array (counter_array);
5682       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5683         {
5684           counter = vat_json_array_add (counter_array);
5685           vat_json_init_object (counter);
5686           c4 = &vam->ip4_fib_counters[i][j];
5687           vat_json_object_add_ip4 (counter, "address", c4->address);
5688           vat_json_object_add_uint (counter, "address_length",
5689                                     c4->address_length);
5690           vat_json_object_add_uint (counter, "packets", c4->packets);
5691           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5692         }
5693     }
5694
5695   /* ip6 fib counters */
5696   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5697   vat_json_init_array (msg_array);
5698   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5699     {
5700       msg = vat_json_array_add (msg_array);
5701       vat_json_init_object (msg);
5702       vat_json_object_add_uint (msg, "vrf_id",
5703                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5704       counter_array = vat_json_object_add (msg, "c");
5705       vat_json_init_array (counter_array);
5706       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5707         {
5708           counter = vat_json_array_add (counter_array);
5709           vat_json_init_object (counter);
5710           c6 = &vam->ip6_fib_counters[i][j];
5711           vat_json_object_add_ip6 (counter, "address", c6->address);
5712           vat_json_object_add_uint (counter, "address_length",
5713                                     c6->address_length);
5714           vat_json_object_add_uint (counter, "packets", c6->packets);
5715           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5716         }
5717     }
5718
5719   /* ip4 nbr counters */
5720   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5721   vat_json_init_array (msg_array);
5722   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5723     {
5724       msg = vat_json_array_add (msg_array);
5725       vat_json_init_object (msg);
5726       vat_json_object_add_uint (msg, "sw_if_index", i);
5727       counter_array = vat_json_object_add (msg, "c");
5728       vat_json_init_array (counter_array);
5729       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5730         {
5731           counter = vat_json_array_add (counter_array);
5732           vat_json_init_object (counter);
5733           n4 = &vam->ip4_nbr_counters[i][j];
5734           vat_json_object_add_ip4 (counter, "address", n4->address);
5735           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5736           vat_json_object_add_uint (counter, "packets", n4->packets);
5737           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5738         }
5739     }
5740
5741   /* ip6 nbr counters */
5742   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5743   vat_json_init_array (msg_array);
5744   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5745     {
5746       msg = vat_json_array_add (msg_array);
5747       vat_json_init_object (msg);
5748       vat_json_object_add_uint (msg, "sw_if_index", i);
5749       counter_array = vat_json_object_add (msg, "c");
5750       vat_json_init_array (counter_array);
5751       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5752         {
5753           counter = vat_json_array_add (counter_array);
5754           vat_json_init_object (counter);
5755           n6 = &vam->ip6_nbr_counters[i][j];
5756           vat_json_object_add_ip6 (counter, "address", n6->address);
5757           vat_json_object_add_uint (counter, "packets", n6->packets);
5758           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5759         }
5760     }
5761
5762   vat_json_print (vam->ofp, &node);
5763   vat_json_free (&node);
5764
5765   return 0;
5766 }
5767
5768 /*
5769  * Pass CLI buffers directly in the CLI_INBAND API message,
5770  * instead of an additional shared memory area.
5771  */
5772 static int
5773 exec_inband (vat_main_t * vam)
5774 {
5775   vl_api_cli_inband_t *mp;
5776   unformat_input_t *i = vam->input;
5777   int ret;
5778
5779   if (vec_len (i->buffer) == 0)
5780     return -1;
5781
5782   if (vam->exec_mode == 0 && unformat (i, "mode"))
5783     {
5784       vam->exec_mode = 1;
5785       return 0;
5786     }
5787   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5788     {
5789       vam->exec_mode = 0;
5790       return 0;
5791     }
5792
5793   /*
5794    * In order for the CLI command to work, it
5795    * must be a vector ending in \n, not a C-string ending
5796    * in \n\0.
5797    */
5798   u32 len = vec_len (vam->input->buffer);
5799   M2 (CLI_INBAND, mp, len);
5800   clib_memcpy (mp->cmd, vam->input->buffer, len);
5801   mp->length = htonl (len);
5802
5803   S (mp);
5804   W (ret);
5805   /* json responses may or may not include a useful reply... */
5806   if (vec_len (vam->cmd_reply))
5807     print (vam->ofp, (char *) (vam->cmd_reply));
5808   return ret;
5809 }
5810
5811 int
5812 exec (vat_main_t * vam)
5813 {
5814   return exec_inband (vam);
5815 }
5816
5817 static int
5818 api_create_loopback (vat_main_t * vam)
5819 {
5820   unformat_input_t *i = vam->input;
5821   vl_api_create_loopback_t *mp;
5822   vl_api_create_loopback_instance_t *mp_lbi;
5823   u8 mac_address[6];
5824   u8 mac_set = 0;
5825   u8 is_specified = 0;
5826   u32 user_instance = 0;
5827   int ret;
5828
5829   memset (mac_address, 0, sizeof (mac_address));
5830
5831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5832     {
5833       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5834         mac_set = 1;
5835       if (unformat (i, "instance %d", &user_instance))
5836         is_specified = 1;
5837       else
5838         break;
5839     }
5840
5841   if (is_specified)
5842     {
5843       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5844       mp_lbi->is_specified = is_specified;
5845       if (is_specified)
5846         mp_lbi->user_instance = htonl (user_instance);
5847       if (mac_set)
5848         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5849       S (mp_lbi);
5850     }
5851   else
5852     {
5853       /* Construct the API message */
5854       M (CREATE_LOOPBACK, mp);
5855       if (mac_set)
5856         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5857       S (mp);
5858     }
5859
5860   W (ret);
5861   return ret;
5862 }
5863
5864 static int
5865 api_delete_loopback (vat_main_t * vam)
5866 {
5867   unformat_input_t *i = vam->input;
5868   vl_api_delete_loopback_t *mp;
5869   u32 sw_if_index = ~0;
5870   int ret;
5871
5872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5873     {
5874       if (unformat (i, "sw_if_index %d", &sw_if_index))
5875         ;
5876       else
5877         break;
5878     }
5879
5880   if (sw_if_index == ~0)
5881     {
5882       errmsg ("missing sw_if_index");
5883       return -99;
5884     }
5885
5886   /* Construct the API message */
5887   M (DELETE_LOOPBACK, mp);
5888   mp->sw_if_index = ntohl (sw_if_index);
5889
5890   S (mp);
5891   W (ret);
5892   return ret;
5893 }
5894
5895 static int
5896 api_want_stats (vat_main_t * vam)
5897 {
5898   unformat_input_t *i = vam->input;
5899   vl_api_want_stats_t *mp;
5900   int enable = -1;
5901   int ret;
5902
5903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5904     {
5905       if (unformat (i, "enable"))
5906         enable = 1;
5907       else if (unformat (i, "disable"))
5908         enable = 0;
5909       else
5910         break;
5911     }
5912
5913   if (enable == -1)
5914     {
5915       errmsg ("missing enable|disable");
5916       return -99;
5917     }
5918
5919   M (WANT_STATS, mp);
5920   mp->enable_disable = enable;
5921
5922   S (mp);
5923   W (ret);
5924   return ret;
5925 }
5926
5927 static int
5928 api_want_interface_events (vat_main_t * vam)
5929 {
5930   unformat_input_t *i = vam->input;
5931   vl_api_want_interface_events_t *mp;
5932   int enable = -1;
5933   int ret;
5934
5935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5936     {
5937       if (unformat (i, "enable"))
5938         enable = 1;
5939       else if (unformat (i, "disable"))
5940         enable = 0;
5941       else
5942         break;
5943     }
5944
5945   if (enable == -1)
5946     {
5947       errmsg ("missing enable|disable");
5948       return -99;
5949     }
5950
5951   M (WANT_INTERFACE_EVENTS, mp);
5952   mp->enable_disable = enable;
5953
5954   vam->interface_event_display = enable;
5955
5956   S (mp);
5957   W (ret);
5958   return ret;
5959 }
5960
5961
5962 /* Note: non-static, called once to set up the initial intfc table */
5963 int
5964 api_sw_interface_dump (vat_main_t * vam)
5965 {
5966   vl_api_sw_interface_dump_t *mp;
5967   vl_api_control_ping_t *mp_ping;
5968   hash_pair_t *p;
5969   name_sort_t *nses = 0, *ns;
5970   sw_interface_subif_t *sub = NULL;
5971   int ret;
5972
5973   /* Toss the old name table */
5974   /* *INDENT-OFF* */
5975   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5976   ({
5977     vec_add2 (nses, ns, 1);
5978     ns->name = (u8 *)(p->key);
5979     ns->value = (u32) p->value[0];
5980   }));
5981   /* *INDENT-ON* */
5982
5983   hash_free (vam->sw_if_index_by_interface_name);
5984
5985   vec_foreach (ns, nses) vec_free (ns->name);
5986
5987   vec_free (nses);
5988
5989   vec_foreach (sub, vam->sw_if_subif_table)
5990   {
5991     vec_free (sub->interface_name);
5992   }
5993   vec_free (vam->sw_if_subif_table);
5994
5995   /* recreate the interface name hash table */
5996   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5997
5998   /* Get list of ethernets */
5999   M (SW_INTERFACE_DUMP, mp);
6000   mp->name_filter_valid = 1;
6001   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6002   S (mp);
6003
6004   /* and local / loopback interfaces */
6005   M (SW_INTERFACE_DUMP, mp);
6006   mp->name_filter_valid = 1;
6007   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6008   S (mp);
6009
6010   /* and packet-generator interfaces */
6011   M (SW_INTERFACE_DUMP, mp);
6012   mp->name_filter_valid = 1;
6013   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6014   S (mp);
6015
6016   /* and vxlan-gpe tunnel interfaces */
6017   M (SW_INTERFACE_DUMP, mp);
6018   mp->name_filter_valid = 1;
6019   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6020            sizeof (mp->name_filter) - 1);
6021   S (mp);
6022
6023   /* and vxlan tunnel interfaces */
6024   M (SW_INTERFACE_DUMP, mp);
6025   mp->name_filter_valid = 1;
6026   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6027   S (mp);
6028
6029   /* and host (af_packet) interfaces */
6030   M (SW_INTERFACE_DUMP, mp);
6031   mp->name_filter_valid = 1;
6032   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6033   S (mp);
6034
6035   /* and l2tpv3 tunnel interfaces */
6036   M (SW_INTERFACE_DUMP, mp);
6037   mp->name_filter_valid = 1;
6038   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6039            sizeof (mp->name_filter) - 1);
6040   S (mp);
6041
6042   /* and GRE tunnel interfaces */
6043   M (SW_INTERFACE_DUMP, mp);
6044   mp->name_filter_valid = 1;
6045   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6046   S (mp);
6047
6048   /* and LISP-GPE interfaces */
6049   M (SW_INTERFACE_DUMP, mp);
6050   mp->name_filter_valid = 1;
6051   strncpy ((char *) mp->name_filter, "lisp_gpe",
6052            sizeof (mp->name_filter) - 1);
6053   S (mp);
6054
6055   /* and IPSEC tunnel interfaces */
6056   M (SW_INTERFACE_DUMP, mp);
6057   mp->name_filter_valid = 1;
6058   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6059   S (mp);
6060
6061   /* Use a control ping for synchronization */
6062   MPING (CONTROL_PING, mp_ping);
6063   S (mp_ping);
6064
6065   W (ret);
6066   return ret;
6067 }
6068
6069 static int
6070 api_sw_interface_set_flags (vat_main_t * vam)
6071 {
6072   unformat_input_t *i = vam->input;
6073   vl_api_sw_interface_set_flags_t *mp;
6074   u32 sw_if_index;
6075   u8 sw_if_index_set = 0;
6076   u8 admin_up = 0;
6077   int ret;
6078
6079   /* Parse args required to build the message */
6080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6081     {
6082       if (unformat (i, "admin-up"))
6083         admin_up = 1;
6084       else if (unformat (i, "admin-down"))
6085         admin_up = 0;
6086       else
6087         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6088         sw_if_index_set = 1;
6089       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6090         sw_if_index_set = 1;
6091       else
6092         break;
6093     }
6094
6095   if (sw_if_index_set == 0)
6096     {
6097       errmsg ("missing interface name or sw_if_index");
6098       return -99;
6099     }
6100
6101   /* Construct the API message */
6102   M (SW_INTERFACE_SET_FLAGS, mp);
6103   mp->sw_if_index = ntohl (sw_if_index);
6104   mp->admin_up_down = admin_up;
6105
6106   /* send it... */
6107   S (mp);
6108
6109   /* Wait for a reply, return the good/bad news... */
6110   W (ret);
6111   return ret;
6112 }
6113
6114 static int
6115 api_sw_interface_clear_stats (vat_main_t * vam)
6116 {
6117   unformat_input_t *i = vam->input;
6118   vl_api_sw_interface_clear_stats_t *mp;
6119   u32 sw_if_index;
6120   u8 sw_if_index_set = 0;
6121   int ret;
6122
6123   /* Parse args required to build the message */
6124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6125     {
6126       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6127         sw_if_index_set = 1;
6128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6129         sw_if_index_set = 1;
6130       else
6131         break;
6132     }
6133
6134   /* Construct the API message */
6135   M (SW_INTERFACE_CLEAR_STATS, mp);
6136
6137   if (sw_if_index_set == 1)
6138     mp->sw_if_index = ntohl (sw_if_index);
6139   else
6140     mp->sw_if_index = ~0;
6141
6142   /* send it... */
6143   S (mp);
6144
6145   /* Wait for a reply, return the good/bad news... */
6146   W (ret);
6147   return ret;
6148 }
6149
6150 static int
6151 api_sw_interface_add_del_address (vat_main_t * vam)
6152 {
6153   unformat_input_t *i = vam->input;
6154   vl_api_sw_interface_add_del_address_t *mp;
6155   u32 sw_if_index;
6156   u8 sw_if_index_set = 0;
6157   u8 is_add = 1, del_all = 0;
6158   u32 address_length = 0;
6159   u8 v4_address_set = 0;
6160   u8 v6_address_set = 0;
6161   ip4_address_t v4address;
6162   ip6_address_t v6address;
6163   int ret;
6164
6165   /* Parse args required to build the message */
6166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6167     {
6168       if (unformat (i, "del-all"))
6169         del_all = 1;
6170       else if (unformat (i, "del"))
6171         is_add = 0;
6172       else
6173         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6174         sw_if_index_set = 1;
6175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6176         sw_if_index_set = 1;
6177       else if (unformat (i, "%U/%d",
6178                          unformat_ip4_address, &v4address, &address_length))
6179         v4_address_set = 1;
6180       else if (unformat (i, "%U/%d",
6181                          unformat_ip6_address, &v6address, &address_length))
6182         v6_address_set = 1;
6183       else
6184         break;
6185     }
6186
6187   if (sw_if_index_set == 0)
6188     {
6189       errmsg ("missing interface name or sw_if_index");
6190       return -99;
6191     }
6192   if (v4_address_set && v6_address_set)
6193     {
6194       errmsg ("both v4 and v6 addresses set");
6195       return -99;
6196     }
6197   if (!v4_address_set && !v6_address_set && !del_all)
6198     {
6199       errmsg ("no addresses set");
6200       return -99;
6201     }
6202
6203   /* Construct the API message */
6204   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6205
6206   mp->sw_if_index = ntohl (sw_if_index);
6207   mp->is_add = is_add;
6208   mp->del_all = del_all;
6209   if (v6_address_set)
6210     {
6211       mp->is_ipv6 = 1;
6212       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6213     }
6214   else
6215     {
6216       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6217     }
6218   mp->address_length = address_length;
6219
6220   /* send it... */
6221   S (mp);
6222
6223   /* Wait for a reply, return good/bad news  */
6224   W (ret);
6225   return ret;
6226 }
6227
6228 static int
6229 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6230 {
6231   unformat_input_t *i = vam->input;
6232   vl_api_sw_interface_set_mpls_enable_t *mp;
6233   u32 sw_if_index;
6234   u8 sw_if_index_set = 0;
6235   u8 enable = 1;
6236   int ret;
6237
6238   /* Parse args required to build the message */
6239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6240     {
6241       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6242         sw_if_index_set = 1;
6243       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6244         sw_if_index_set = 1;
6245       else if (unformat (i, "disable"))
6246         enable = 0;
6247       else if (unformat (i, "dis"))
6248         enable = 0;
6249       else
6250         break;
6251     }
6252
6253   if (sw_if_index_set == 0)
6254     {
6255       errmsg ("missing interface name or sw_if_index");
6256       return -99;
6257     }
6258
6259   /* Construct the API message */
6260   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6261
6262   mp->sw_if_index = ntohl (sw_if_index);
6263   mp->enable = enable;
6264
6265   /* send it... */
6266   S (mp);
6267
6268   /* Wait for a reply... */
6269   W (ret);
6270   return ret;
6271 }
6272
6273 static int
6274 api_sw_interface_set_table (vat_main_t * vam)
6275 {
6276   unformat_input_t *i = vam->input;
6277   vl_api_sw_interface_set_table_t *mp;
6278   u32 sw_if_index, vrf_id = 0;
6279   u8 sw_if_index_set = 0;
6280   u8 is_ipv6 = 0;
6281   int ret;
6282
6283   /* Parse args required to build the message */
6284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6285     {
6286       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6287         sw_if_index_set = 1;
6288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6289         sw_if_index_set = 1;
6290       else if (unformat (i, "vrf %d", &vrf_id))
6291         ;
6292       else if (unformat (i, "ipv6"))
6293         is_ipv6 = 1;
6294       else
6295         break;
6296     }
6297
6298   if (sw_if_index_set == 0)
6299     {
6300       errmsg ("missing interface name or sw_if_index");
6301       return -99;
6302     }
6303
6304   /* Construct the API message */
6305   M (SW_INTERFACE_SET_TABLE, mp);
6306
6307   mp->sw_if_index = ntohl (sw_if_index);
6308   mp->is_ipv6 = is_ipv6;
6309   mp->vrf_id = ntohl (vrf_id);
6310
6311   /* send it... */
6312   S (mp);
6313
6314   /* Wait for a reply... */
6315   W (ret);
6316   return ret;
6317 }
6318
6319 static void vl_api_sw_interface_get_table_reply_t_handler
6320   (vl_api_sw_interface_get_table_reply_t * mp)
6321 {
6322   vat_main_t *vam = &vat_main;
6323
6324   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6325
6326   vam->retval = ntohl (mp->retval);
6327   vam->result_ready = 1;
6328
6329 }
6330
6331 static void vl_api_sw_interface_get_table_reply_t_handler_json
6332   (vl_api_sw_interface_get_table_reply_t * mp)
6333 {
6334   vat_main_t *vam = &vat_main;
6335   vat_json_node_t node;
6336
6337   vat_json_init_object (&node);
6338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6339   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6340
6341   vat_json_print (vam->ofp, &node);
6342   vat_json_free (&node);
6343
6344   vam->retval = ntohl (mp->retval);
6345   vam->result_ready = 1;
6346 }
6347
6348 static int
6349 api_sw_interface_get_table (vat_main_t * vam)
6350 {
6351   unformat_input_t *i = vam->input;
6352   vl_api_sw_interface_get_table_t *mp;
6353   u32 sw_if_index;
6354   u8 sw_if_index_set = 0;
6355   u8 is_ipv6 = 0;
6356   int ret;
6357
6358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6359     {
6360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6361         sw_if_index_set = 1;
6362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6363         sw_if_index_set = 1;
6364       else if (unformat (i, "ipv6"))
6365         is_ipv6 = 1;
6366       else
6367         break;
6368     }
6369
6370   if (sw_if_index_set == 0)
6371     {
6372       errmsg ("missing interface name or sw_if_index");
6373       return -99;
6374     }
6375
6376   M (SW_INTERFACE_GET_TABLE, mp);
6377   mp->sw_if_index = htonl (sw_if_index);
6378   mp->is_ipv6 = is_ipv6;
6379
6380   S (mp);
6381   W (ret);
6382   return ret;
6383 }
6384
6385 static int
6386 api_sw_interface_set_vpath (vat_main_t * vam)
6387 {
6388   unformat_input_t *i = vam->input;
6389   vl_api_sw_interface_set_vpath_t *mp;
6390   u32 sw_if_index = 0;
6391   u8 sw_if_index_set = 0;
6392   u8 is_enable = 0;
6393   int ret;
6394
6395   /* Parse args required to build the message */
6396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6397     {
6398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6399         sw_if_index_set = 1;
6400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6401         sw_if_index_set = 1;
6402       else if (unformat (i, "enable"))
6403         is_enable = 1;
6404       else if (unformat (i, "disable"))
6405         is_enable = 0;
6406       else
6407         break;
6408     }
6409
6410   if (sw_if_index_set == 0)
6411     {
6412       errmsg ("missing interface name or sw_if_index");
6413       return -99;
6414     }
6415
6416   /* Construct the API message */
6417   M (SW_INTERFACE_SET_VPATH, mp);
6418
6419   mp->sw_if_index = ntohl (sw_if_index);
6420   mp->enable = is_enable;
6421
6422   /* send it... */
6423   S (mp);
6424
6425   /* Wait for a reply... */
6426   W (ret);
6427   return ret;
6428 }
6429
6430 static int
6431 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6432 {
6433   unformat_input_t *i = vam->input;
6434   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6435   u32 sw_if_index = 0;
6436   u8 sw_if_index_set = 0;
6437   u8 is_enable = 1;
6438   u8 is_ipv6 = 0;
6439   int ret;
6440
6441   /* Parse args required to build the message */
6442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6443     {
6444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6445         sw_if_index_set = 1;
6446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6447         sw_if_index_set = 1;
6448       else if (unformat (i, "enable"))
6449         is_enable = 1;
6450       else if (unformat (i, "disable"))
6451         is_enable = 0;
6452       else if (unformat (i, "ip4"))
6453         is_ipv6 = 0;
6454       else if (unformat (i, "ip6"))
6455         is_ipv6 = 1;
6456       else
6457         break;
6458     }
6459
6460   if (sw_if_index_set == 0)
6461     {
6462       errmsg ("missing interface name or sw_if_index");
6463       return -99;
6464     }
6465
6466   /* Construct the API message */
6467   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6468
6469   mp->sw_if_index = ntohl (sw_if_index);
6470   mp->enable = is_enable;
6471   mp->is_ipv6 = is_ipv6;
6472
6473   /* send it... */
6474   S (mp);
6475
6476   /* Wait for a reply... */
6477   W (ret);
6478   return ret;
6479 }
6480
6481
6482 static int
6483 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6484 {
6485   unformat_input_t *i = vam->input;
6486   vl_api_sw_interface_set_l2_xconnect_t *mp;
6487   u32 rx_sw_if_index;
6488   u8 rx_sw_if_index_set = 0;
6489   u32 tx_sw_if_index;
6490   u8 tx_sw_if_index_set = 0;
6491   u8 enable = 1;
6492   int ret;
6493
6494   /* Parse args required to build the message */
6495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6496     {
6497       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6498         rx_sw_if_index_set = 1;
6499       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6500         tx_sw_if_index_set = 1;
6501       else if (unformat (i, "rx"))
6502         {
6503           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6504             {
6505               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6506                             &rx_sw_if_index))
6507                 rx_sw_if_index_set = 1;
6508             }
6509           else
6510             break;
6511         }
6512       else if (unformat (i, "tx"))
6513         {
6514           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6515             {
6516               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6517                             &tx_sw_if_index))
6518                 tx_sw_if_index_set = 1;
6519             }
6520           else
6521             break;
6522         }
6523       else if (unformat (i, "enable"))
6524         enable = 1;
6525       else if (unformat (i, "disable"))
6526         enable = 0;
6527       else
6528         break;
6529     }
6530
6531   if (rx_sw_if_index_set == 0)
6532     {
6533       errmsg ("missing rx interface name or rx_sw_if_index");
6534       return -99;
6535     }
6536
6537   if (enable && (tx_sw_if_index_set == 0))
6538     {
6539       errmsg ("missing tx interface name or tx_sw_if_index");
6540       return -99;
6541     }
6542
6543   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6544
6545   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6546   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6547   mp->enable = enable;
6548
6549   S (mp);
6550   W (ret);
6551   return ret;
6552 }
6553
6554 static int
6555 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6556 {
6557   unformat_input_t *i = vam->input;
6558   vl_api_sw_interface_set_l2_bridge_t *mp;
6559   u32 rx_sw_if_index;
6560   u8 rx_sw_if_index_set = 0;
6561   u32 bd_id;
6562   u8 bd_id_set = 0;
6563   u8 bvi = 0;
6564   u32 shg = 0;
6565   u8 enable = 1;
6566   int ret;
6567
6568   /* Parse args required to build the message */
6569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6570     {
6571       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6572         rx_sw_if_index_set = 1;
6573       else if (unformat (i, "bd_id %d", &bd_id))
6574         bd_id_set = 1;
6575       else
6576         if (unformat
6577             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6578         rx_sw_if_index_set = 1;
6579       else if (unformat (i, "shg %d", &shg))
6580         ;
6581       else if (unformat (i, "bvi"))
6582         bvi = 1;
6583       else if (unformat (i, "enable"))
6584         enable = 1;
6585       else if (unformat (i, "disable"))
6586         enable = 0;
6587       else
6588         break;
6589     }
6590
6591   if (rx_sw_if_index_set == 0)
6592     {
6593       errmsg ("missing rx interface name or sw_if_index");
6594       return -99;
6595     }
6596
6597   if (enable && (bd_id_set == 0))
6598     {
6599       errmsg ("missing bridge domain");
6600       return -99;
6601     }
6602
6603   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6604
6605   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6606   mp->bd_id = ntohl (bd_id);
6607   mp->shg = (u8) shg;
6608   mp->bvi = bvi;
6609   mp->enable = enable;
6610
6611   S (mp);
6612   W (ret);
6613   return ret;
6614 }
6615
6616 static int
6617 api_bridge_domain_dump (vat_main_t * vam)
6618 {
6619   unformat_input_t *i = vam->input;
6620   vl_api_bridge_domain_dump_t *mp;
6621   vl_api_control_ping_t *mp_ping;
6622   u32 bd_id = ~0;
6623   int ret;
6624
6625   /* Parse args required to build the message */
6626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6627     {
6628       if (unformat (i, "bd_id %d", &bd_id))
6629         ;
6630       else
6631         break;
6632     }
6633
6634   M (BRIDGE_DOMAIN_DUMP, mp);
6635   mp->bd_id = ntohl (bd_id);
6636   S (mp);
6637
6638   /* Use a control ping for synchronization */
6639   MPING (CONTROL_PING, mp_ping);
6640   S (mp_ping);
6641
6642   W (ret);
6643   return ret;
6644 }
6645
6646 static int
6647 api_bridge_domain_add_del (vat_main_t * vam)
6648 {
6649   unformat_input_t *i = vam->input;
6650   vl_api_bridge_domain_add_del_t *mp;
6651   u32 bd_id = ~0;
6652   u8 is_add = 1;
6653   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6654   u8 *bd_tag = NULL;
6655   u32 mac_age = 0;
6656   int ret;
6657
6658   /* Parse args required to build the message */
6659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6660     {
6661       if (unformat (i, "bd_id %d", &bd_id))
6662         ;
6663       else if (unformat (i, "flood %d", &flood))
6664         ;
6665       else if (unformat (i, "uu-flood %d", &uu_flood))
6666         ;
6667       else if (unformat (i, "forward %d", &forward))
6668         ;
6669       else if (unformat (i, "learn %d", &learn))
6670         ;
6671       else if (unformat (i, "arp-term %d", &arp_term))
6672         ;
6673       else if (unformat (i, "mac-age %d", &mac_age))
6674         ;
6675       else if (unformat (i, "bd-tag %s", &bd_tag))
6676         ;
6677       else if (unformat (i, "del"))
6678         {
6679           is_add = 0;
6680           flood = uu_flood = forward = learn = 0;
6681         }
6682       else
6683         break;
6684     }
6685
6686   if (bd_id == ~0)
6687     {
6688       errmsg ("missing bridge domain");
6689       ret = -99;
6690       goto done;
6691     }
6692
6693   if (mac_age > 255)
6694     {
6695       errmsg ("mac age must be less than 256 ");
6696       ret = -99;
6697       goto done;
6698     }
6699
6700   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6701     {
6702       errmsg ("bd-tag cannot be longer than 63");
6703       ret = -99;
6704       goto done;
6705     }
6706
6707   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6708
6709   mp->bd_id = ntohl (bd_id);
6710   mp->flood = flood;
6711   mp->uu_flood = uu_flood;
6712   mp->forward = forward;
6713   mp->learn = learn;
6714   mp->arp_term = arp_term;
6715   mp->is_add = is_add;
6716   mp->mac_age = (u8) mac_age;
6717   if (bd_tag)
6718     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6719
6720   S (mp);
6721   W (ret);
6722
6723 done:
6724   vec_free (bd_tag);
6725   return ret;
6726 }
6727
6728 static int
6729 api_l2fib_flush_bd (vat_main_t * vam)
6730 {
6731   unformat_input_t *i = vam->input;
6732   vl_api_l2fib_flush_bd_t *mp;
6733   u32 bd_id = ~0;
6734   int ret;
6735
6736   /* Parse args required to build the message */
6737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6738     {
6739       if (unformat (i, "bd_id %d", &bd_id));
6740       else
6741         break;
6742     }
6743
6744   if (bd_id == ~0)
6745     {
6746       errmsg ("missing bridge domain");
6747       return -99;
6748     }
6749
6750   M (L2FIB_FLUSH_BD, mp);
6751
6752   mp->bd_id = htonl (bd_id);
6753
6754   S (mp);
6755   W (ret);
6756   return ret;
6757 }
6758
6759 static int
6760 api_l2fib_flush_int (vat_main_t * vam)
6761 {
6762   unformat_input_t *i = vam->input;
6763   vl_api_l2fib_flush_int_t *mp;
6764   u32 sw_if_index = ~0;
6765   int ret;
6766
6767   /* Parse args required to build the message */
6768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6769     {
6770       if (unformat (i, "sw_if_index %d", &sw_if_index));
6771       else
6772         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6773       else
6774         break;
6775     }
6776
6777   if (sw_if_index == ~0)
6778     {
6779       errmsg ("missing interface name or sw_if_index");
6780       return -99;
6781     }
6782
6783   M (L2FIB_FLUSH_INT, mp);
6784
6785   mp->sw_if_index = ntohl (sw_if_index);
6786
6787   S (mp);
6788   W (ret);
6789   return ret;
6790 }
6791
6792 static int
6793 api_l2fib_add_del (vat_main_t * vam)
6794 {
6795   unformat_input_t *i = vam->input;
6796   vl_api_l2fib_add_del_t *mp;
6797   f64 timeout;
6798   u64 mac = 0;
6799   u8 mac_set = 0;
6800   u32 bd_id;
6801   u8 bd_id_set = 0;
6802   u32 sw_if_index = ~0;
6803   u8 sw_if_index_set = 0;
6804   u8 is_add = 1;
6805   u8 static_mac = 0;
6806   u8 filter_mac = 0;
6807   u8 bvi_mac = 0;
6808   int count = 1;
6809   f64 before = 0;
6810   int j;
6811
6812   /* Parse args required to build the message */
6813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6814     {
6815       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6816         mac_set = 1;
6817       else if (unformat (i, "bd_id %d", &bd_id))
6818         bd_id_set = 1;
6819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6820         sw_if_index_set = 1;
6821       else if (unformat (i, "sw_if"))
6822         {
6823           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6824             {
6825               if (unformat
6826                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6827                 sw_if_index_set = 1;
6828             }
6829           else
6830             break;
6831         }
6832       else if (unformat (i, "static"))
6833         static_mac = 1;
6834       else if (unformat (i, "filter"))
6835         {
6836           filter_mac = 1;
6837           static_mac = 1;
6838         }
6839       else if (unformat (i, "bvi"))
6840         {
6841           bvi_mac = 1;
6842           static_mac = 1;
6843         }
6844       else if (unformat (i, "del"))
6845         is_add = 0;
6846       else if (unformat (i, "count %d", &count))
6847         ;
6848       else
6849         break;
6850     }
6851
6852   if (mac_set == 0)
6853     {
6854       errmsg ("missing mac address");
6855       return -99;
6856     }
6857
6858   if (bd_id_set == 0)
6859     {
6860       errmsg ("missing bridge domain");
6861       return -99;
6862     }
6863
6864   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6865     {
6866       errmsg ("missing interface name or sw_if_index");
6867       return -99;
6868     }
6869
6870   if (count > 1)
6871     {
6872       /* Turn on async mode */
6873       vam->async_mode = 1;
6874       vam->async_errors = 0;
6875       before = vat_time_now (vam);
6876     }
6877
6878   for (j = 0; j < count; j++)
6879     {
6880       M (L2FIB_ADD_DEL, mp);
6881
6882       mp->mac = mac;
6883       mp->bd_id = ntohl (bd_id);
6884       mp->is_add = is_add;
6885
6886       if (is_add)
6887         {
6888           mp->sw_if_index = ntohl (sw_if_index);
6889           mp->static_mac = static_mac;
6890           mp->filter_mac = filter_mac;
6891           mp->bvi_mac = bvi_mac;
6892         }
6893       increment_mac_address (&mac);
6894       /* send it... */
6895       S (mp);
6896     }
6897
6898   if (count > 1)
6899     {
6900       vl_api_control_ping_t *mp_ping;
6901       f64 after;
6902
6903       /* Shut off async mode */
6904       vam->async_mode = 0;
6905
6906       MPING (CONTROL_PING, mp_ping);
6907       S (mp_ping);
6908
6909       timeout = vat_time_now (vam) + 1.0;
6910       while (vat_time_now (vam) < timeout)
6911         if (vam->result_ready == 1)
6912           goto out;
6913       vam->retval = -99;
6914
6915     out:
6916       if (vam->retval == -99)
6917         errmsg ("timeout");
6918
6919       if (vam->async_errors > 0)
6920         {
6921           errmsg ("%d asynchronous errors", vam->async_errors);
6922           vam->retval = -98;
6923         }
6924       vam->async_errors = 0;
6925       after = vat_time_now (vam);
6926
6927       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6928              count, after - before, count / (after - before));
6929     }
6930   else
6931     {
6932       int ret;
6933
6934       /* Wait for a reply... */
6935       W (ret);
6936       return ret;
6937     }
6938   /* Return the good/bad news */
6939   return (vam->retval);
6940 }
6941
6942 static int
6943 api_bridge_domain_set_mac_age (vat_main_t * vam)
6944 {
6945   unformat_input_t *i = vam->input;
6946   vl_api_bridge_domain_set_mac_age_t *mp;
6947   u32 bd_id = ~0;
6948   u32 mac_age = 0;
6949   int ret;
6950
6951   /* Parse args required to build the message */
6952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6953     {
6954       if (unformat (i, "bd_id %d", &bd_id));
6955       else if (unformat (i, "mac-age %d", &mac_age));
6956       else
6957         break;
6958     }
6959
6960   if (bd_id == ~0)
6961     {
6962       errmsg ("missing bridge domain");
6963       return -99;
6964     }
6965
6966   if (mac_age > 255)
6967     {
6968       errmsg ("mac age must be less than 256 ");
6969       return -99;
6970     }
6971
6972   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6973
6974   mp->bd_id = htonl (bd_id);
6975   mp->mac_age = (u8) mac_age;
6976
6977   S (mp);
6978   W (ret);
6979   return ret;
6980 }
6981
6982 static int
6983 api_l2_flags (vat_main_t * vam)
6984 {
6985   unformat_input_t *i = vam->input;
6986   vl_api_l2_flags_t *mp;
6987   u32 sw_if_index;
6988   u32 flags = 0;
6989   u8 sw_if_index_set = 0;
6990   u8 is_set = 0;
6991   int ret;
6992
6993   /* Parse args required to build the message */
6994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6995     {
6996       if (unformat (i, "sw_if_index %d", &sw_if_index))
6997         sw_if_index_set = 1;
6998       else if (unformat (i, "sw_if"))
6999         {
7000           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7001             {
7002               if (unformat
7003                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7004                 sw_if_index_set = 1;
7005             }
7006           else
7007             break;
7008         }
7009       else if (unformat (i, "learn"))
7010         flags |= L2_LEARN;
7011       else if (unformat (i, "forward"))
7012         flags |= L2_FWD;
7013       else if (unformat (i, "flood"))
7014         flags |= L2_FLOOD;
7015       else if (unformat (i, "uu-flood"))
7016         flags |= L2_UU_FLOOD;
7017       else if (unformat (i, "arp-term"))
7018         flags |= L2_ARP_TERM;
7019       else if (unformat (i, "off"))
7020         is_set = 0;
7021       else if (unformat (i, "disable"))
7022         is_set = 0;
7023       else
7024         break;
7025     }
7026
7027   if (sw_if_index_set == 0)
7028     {
7029       errmsg ("missing interface name or sw_if_index");
7030       return -99;
7031     }
7032
7033   M (L2_FLAGS, mp);
7034
7035   mp->sw_if_index = ntohl (sw_if_index);
7036   mp->feature_bitmap = ntohl (flags);
7037   mp->is_set = is_set;
7038
7039   S (mp);
7040   W (ret);
7041   return ret;
7042 }
7043
7044 static int
7045 api_bridge_flags (vat_main_t * vam)
7046 {
7047   unformat_input_t *i = vam->input;
7048   vl_api_bridge_flags_t *mp;
7049   u32 bd_id;
7050   u8 bd_id_set = 0;
7051   u8 is_set = 1;
7052   u32 flags = 0;
7053   int ret;
7054
7055   /* Parse args required to build the message */
7056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7057     {
7058       if (unformat (i, "bd_id %d", &bd_id))
7059         bd_id_set = 1;
7060       else if (unformat (i, "learn"))
7061         flags |= L2_LEARN;
7062       else if (unformat (i, "forward"))
7063         flags |= L2_FWD;
7064       else if (unformat (i, "flood"))
7065         flags |= L2_FLOOD;
7066       else if (unformat (i, "uu-flood"))
7067         flags |= L2_UU_FLOOD;
7068       else if (unformat (i, "arp-term"))
7069         flags |= L2_ARP_TERM;
7070       else if (unformat (i, "off"))
7071         is_set = 0;
7072       else if (unformat (i, "disable"))
7073         is_set = 0;
7074       else
7075         break;
7076     }
7077
7078   if (bd_id_set == 0)
7079     {
7080       errmsg ("missing bridge domain");
7081       return -99;
7082     }
7083
7084   M (BRIDGE_FLAGS, mp);
7085
7086   mp->bd_id = ntohl (bd_id);
7087   mp->feature_bitmap = ntohl (flags);
7088   mp->is_set = is_set;
7089
7090   S (mp);
7091   W (ret);
7092   return ret;
7093 }
7094
7095 static int
7096 api_bd_ip_mac_add_del (vat_main_t * vam)
7097 {
7098   unformat_input_t *i = vam->input;
7099   vl_api_bd_ip_mac_add_del_t *mp;
7100   u32 bd_id;
7101   u8 is_ipv6 = 0;
7102   u8 is_add = 1;
7103   u8 bd_id_set = 0;
7104   u8 ip_set = 0;
7105   u8 mac_set = 0;
7106   ip4_address_t v4addr;
7107   ip6_address_t v6addr;
7108   u8 macaddr[6];
7109   int ret;
7110
7111
7112   /* Parse args required to build the message */
7113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7114     {
7115       if (unformat (i, "bd_id %d", &bd_id))
7116         {
7117           bd_id_set++;
7118         }
7119       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7120         {
7121           ip_set++;
7122         }
7123       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7124         {
7125           ip_set++;
7126           is_ipv6++;
7127         }
7128       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7129         {
7130           mac_set++;
7131         }
7132       else if (unformat (i, "del"))
7133         is_add = 0;
7134       else
7135         break;
7136     }
7137
7138   if (bd_id_set == 0)
7139     {
7140       errmsg ("missing bridge domain");
7141       return -99;
7142     }
7143   else if (ip_set == 0)
7144     {
7145       errmsg ("missing IP address");
7146       return -99;
7147     }
7148   else if (mac_set == 0)
7149     {
7150       errmsg ("missing MAC address");
7151       return -99;
7152     }
7153
7154   M (BD_IP_MAC_ADD_DEL, mp);
7155
7156   mp->bd_id = ntohl (bd_id);
7157   mp->is_ipv6 = is_ipv6;
7158   mp->is_add = is_add;
7159   if (is_ipv6)
7160     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7161   else
7162     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7163   clib_memcpy (mp->mac_address, macaddr, 6);
7164   S (mp);
7165   W (ret);
7166   return ret;
7167 }
7168
7169 static int
7170 api_tap_connect (vat_main_t * vam)
7171 {
7172   unformat_input_t *i = vam->input;
7173   vl_api_tap_connect_t *mp;
7174   u8 mac_address[6];
7175   u8 random_mac = 1;
7176   u8 name_set = 0;
7177   u8 *tap_name;
7178   u8 *tag = 0;
7179   ip4_address_t ip4_address;
7180   u32 ip4_mask_width;
7181   int ip4_address_set = 0;
7182   ip6_address_t ip6_address;
7183   u32 ip6_mask_width;
7184   int ip6_address_set = 0;
7185   int ret;
7186
7187   memset (mac_address, 0, sizeof (mac_address));
7188
7189   /* Parse args required to build the message */
7190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7191     {
7192       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7193         {
7194           random_mac = 0;
7195         }
7196       else if (unformat (i, "random-mac"))
7197         random_mac = 1;
7198       else if (unformat (i, "tapname %s", &tap_name))
7199         name_set = 1;
7200       else if (unformat (i, "tag %s", &tag))
7201         ;
7202       else if (unformat (i, "address %U/%d",
7203                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7204         ip4_address_set = 1;
7205       else if (unformat (i, "address %U/%d",
7206                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7207         ip6_address_set = 1;
7208       else
7209         break;
7210     }
7211
7212   if (name_set == 0)
7213     {
7214       errmsg ("missing tap name");
7215       return -99;
7216     }
7217   if (vec_len (tap_name) > 63)
7218     {
7219       errmsg ("tap name too long");
7220       return -99;
7221     }
7222   vec_add1 (tap_name, 0);
7223
7224   if (vec_len (tag) > 63)
7225     {
7226       errmsg ("tag too long");
7227       return -99;
7228     }
7229
7230   /* Construct the API message */
7231   M (TAP_CONNECT, mp);
7232
7233   mp->use_random_mac = random_mac;
7234   clib_memcpy (mp->mac_address, mac_address, 6);
7235   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7236   if (tag)
7237     clib_memcpy (mp->tag, tag, vec_len (tag));
7238
7239   if (ip4_address_set)
7240     {
7241       mp->ip4_address_set = 1;
7242       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7243       mp->ip4_mask_width = ip4_mask_width;
7244     }
7245   if (ip6_address_set)
7246     {
7247       mp->ip6_address_set = 1;
7248       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7249       mp->ip6_mask_width = ip6_mask_width;
7250     }
7251
7252   vec_free (tap_name);
7253   vec_free (tag);
7254
7255   /* send it... */
7256   S (mp);
7257
7258   /* Wait for a reply... */
7259   W (ret);
7260   return ret;
7261 }
7262
7263 static int
7264 api_tap_modify (vat_main_t * vam)
7265 {
7266   unformat_input_t *i = vam->input;
7267   vl_api_tap_modify_t *mp;
7268   u8 mac_address[6];
7269   u8 random_mac = 1;
7270   u8 name_set = 0;
7271   u8 *tap_name;
7272   u32 sw_if_index = ~0;
7273   u8 sw_if_index_set = 0;
7274   int ret;
7275
7276   memset (mac_address, 0, sizeof (mac_address));
7277
7278   /* Parse args required to build the message */
7279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7280     {
7281       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7282         sw_if_index_set = 1;
7283       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7284         sw_if_index_set = 1;
7285       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7286         {
7287           random_mac = 0;
7288         }
7289       else if (unformat (i, "random-mac"))
7290         random_mac = 1;
7291       else if (unformat (i, "tapname %s", &tap_name))
7292         name_set = 1;
7293       else
7294         break;
7295     }
7296
7297   if (sw_if_index_set == 0)
7298     {
7299       errmsg ("missing vpp interface name");
7300       return -99;
7301     }
7302   if (name_set == 0)
7303     {
7304       errmsg ("missing tap name");
7305       return -99;
7306     }
7307   if (vec_len (tap_name) > 63)
7308     {
7309       errmsg ("tap name too long");
7310     }
7311   vec_add1 (tap_name, 0);
7312
7313   /* Construct the API message */
7314   M (TAP_MODIFY, mp);
7315
7316   mp->use_random_mac = random_mac;
7317   mp->sw_if_index = ntohl (sw_if_index);
7318   clib_memcpy (mp->mac_address, mac_address, 6);
7319   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7320   vec_free (tap_name);
7321
7322   /* send it... */
7323   S (mp);
7324
7325   /* Wait for a reply... */
7326   W (ret);
7327   return ret;
7328 }
7329
7330 static int
7331 api_tap_delete (vat_main_t * vam)
7332 {
7333   unformat_input_t *i = vam->input;
7334   vl_api_tap_delete_t *mp;
7335   u32 sw_if_index = ~0;
7336   u8 sw_if_index_set = 0;
7337   int ret;
7338
7339   /* Parse args required to build the message */
7340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7341     {
7342       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7343         sw_if_index_set = 1;
7344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7345         sw_if_index_set = 1;
7346       else
7347         break;
7348     }
7349
7350   if (sw_if_index_set == 0)
7351     {
7352       errmsg ("missing vpp interface name");
7353       return -99;
7354     }
7355
7356   /* Construct the API message */
7357   M (TAP_DELETE, mp);
7358
7359   mp->sw_if_index = ntohl (sw_if_index);
7360
7361   /* send it... */
7362   S (mp);
7363
7364   /* Wait for a reply... */
7365   W (ret);
7366   return ret;
7367 }
7368
7369 static int
7370 api_ip_table_add_del (vat_main_t * vam)
7371 {
7372   unformat_input_t *i = vam->input;
7373   vl_api_ip_table_add_del_t *mp;
7374   u32 table_id = ~0;
7375   u8 is_ipv6 = 0;
7376   u8 is_add = 1;
7377   int ret = 0;
7378
7379   /* Parse args required to build the message */
7380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7381     {
7382       if (unformat (i, "ipv6"))
7383         is_ipv6 = 1;
7384       else if (unformat (i, "del"))
7385         is_add = 0;
7386       else if (unformat (i, "add"))
7387         is_add = 1;
7388       else if (unformat (i, "table %d", &table_id))
7389         ;
7390       else
7391         {
7392           clib_warning ("parse error '%U'", format_unformat_error, i);
7393           return -99;
7394         }
7395     }
7396
7397   if (~0 == table_id)
7398     {
7399       errmsg ("missing table-ID");
7400       return -99;
7401     }
7402
7403   /* Construct the API message */
7404   M (IP_TABLE_ADD_DEL, mp);
7405
7406   mp->table_id = ntohl (table_id);
7407   mp->is_ipv6 = is_ipv6;
7408   mp->is_add = is_add;
7409
7410   /* send it... */
7411   S (mp);
7412
7413   /* Wait for a reply... */
7414   W (ret);
7415
7416   return ret;
7417 }
7418
7419 static int
7420 api_ip_add_del_route (vat_main_t * vam)
7421 {
7422   unformat_input_t *i = vam->input;
7423   vl_api_ip_add_del_route_t *mp;
7424   u32 sw_if_index = ~0, vrf_id = 0;
7425   u8 is_ipv6 = 0;
7426   u8 is_local = 0, is_drop = 0;
7427   u8 is_unreach = 0, is_prohibit = 0;
7428   u8 create_vrf_if_needed = 0;
7429   u8 is_add = 1;
7430   u32 next_hop_weight = 1;
7431   u8 not_last = 0;
7432   u8 is_multipath = 0;
7433   u8 address_set = 0;
7434   u8 address_length_set = 0;
7435   u32 next_hop_table_id = 0;
7436   u32 resolve_attempts = 0;
7437   u32 dst_address_length = 0;
7438   u8 next_hop_set = 0;
7439   ip4_address_t v4_dst_address, v4_next_hop_address;
7440   ip6_address_t v6_dst_address, v6_next_hop_address;
7441   int count = 1;
7442   int j;
7443   f64 before = 0;
7444   u32 random_add_del = 0;
7445   u32 *random_vector = 0;
7446   uword *random_hash;
7447   u32 random_seed = 0xdeaddabe;
7448   u32 classify_table_index = ~0;
7449   u8 is_classify = 0;
7450   u8 resolve_host = 0, resolve_attached = 0;
7451   mpls_label_t *next_hop_out_label_stack = NULL;
7452   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7453   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7454
7455   /* Parse args required to build the message */
7456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7457     {
7458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7459         ;
7460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7461         ;
7462       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7463         {
7464           address_set = 1;
7465           is_ipv6 = 0;
7466         }
7467       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7468         {
7469           address_set = 1;
7470           is_ipv6 = 1;
7471         }
7472       else if (unformat (i, "/%d", &dst_address_length))
7473         {
7474           address_length_set = 1;
7475         }
7476
7477       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7478                                          &v4_next_hop_address))
7479         {
7480           next_hop_set = 1;
7481         }
7482       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7483                                          &v6_next_hop_address))
7484         {
7485           next_hop_set = 1;
7486         }
7487       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7488         ;
7489       else if (unformat (i, "weight %d", &next_hop_weight))
7490         ;
7491       else if (unformat (i, "drop"))
7492         {
7493           is_drop = 1;
7494         }
7495       else if (unformat (i, "null-send-unreach"))
7496         {
7497           is_unreach = 1;
7498         }
7499       else if (unformat (i, "null-send-prohibit"))
7500         {
7501           is_prohibit = 1;
7502         }
7503       else if (unformat (i, "local"))
7504         {
7505           is_local = 1;
7506         }
7507       else if (unformat (i, "classify %d", &classify_table_index))
7508         {
7509           is_classify = 1;
7510         }
7511       else if (unformat (i, "del"))
7512         is_add = 0;
7513       else if (unformat (i, "add"))
7514         is_add = 1;
7515       else if (unformat (i, "not-last"))
7516         not_last = 1;
7517       else if (unformat (i, "resolve-via-host"))
7518         resolve_host = 1;
7519       else if (unformat (i, "resolve-via-attached"))
7520         resolve_attached = 1;
7521       else if (unformat (i, "multipath"))
7522         is_multipath = 1;
7523       else if (unformat (i, "vrf %d", &vrf_id))
7524         ;
7525       else if (unformat (i, "create-vrf"))
7526         create_vrf_if_needed = 1;
7527       else if (unformat (i, "count %d", &count))
7528         ;
7529       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7530         ;
7531       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7532         ;
7533       else if (unformat (i, "out-label %d", &next_hop_out_label))
7534         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7535       else if (unformat (i, "via-label %d", &next_hop_via_label))
7536         ;
7537       else if (unformat (i, "random"))
7538         random_add_del = 1;
7539       else if (unformat (i, "seed %d", &random_seed))
7540         ;
7541       else
7542         {
7543           clib_warning ("parse error '%U'", format_unformat_error, i);
7544           return -99;
7545         }
7546     }
7547
7548   if (!next_hop_set && !is_drop && !is_local &&
7549       !is_classify && !is_unreach && !is_prohibit &&
7550       MPLS_LABEL_INVALID == next_hop_via_label)
7551     {
7552       errmsg
7553         ("next hop / local / drop / unreach / prohibit / classify not set");
7554       return -99;
7555     }
7556
7557   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7558     {
7559       errmsg ("next hop and next-hop via label set");
7560       return -99;
7561     }
7562   if (address_set == 0)
7563     {
7564       errmsg ("missing addresses");
7565       return -99;
7566     }
7567
7568   if (address_length_set == 0)
7569     {
7570       errmsg ("missing address length");
7571       return -99;
7572     }
7573
7574   /* Generate a pile of unique, random routes */
7575   if (random_add_del)
7576     {
7577       u32 this_random_address;
7578       random_hash = hash_create (count, sizeof (uword));
7579
7580       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7581       for (j = 0; j <= count; j++)
7582         {
7583           do
7584             {
7585               this_random_address = random_u32 (&random_seed);
7586               this_random_address =
7587                 clib_host_to_net_u32 (this_random_address);
7588             }
7589           while (hash_get (random_hash, this_random_address));
7590           vec_add1 (random_vector, this_random_address);
7591           hash_set (random_hash, this_random_address, 1);
7592         }
7593       hash_free (random_hash);
7594       v4_dst_address.as_u32 = random_vector[0];
7595     }
7596
7597   if (count > 1)
7598     {
7599       /* Turn on async mode */
7600       vam->async_mode = 1;
7601       vam->async_errors = 0;
7602       before = vat_time_now (vam);
7603     }
7604
7605   for (j = 0; j < count; j++)
7606     {
7607       /* Construct the API message */
7608       M2 (IP_ADD_DEL_ROUTE, mp,
7609           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7610
7611       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7612       mp->table_id = ntohl (vrf_id);
7613       mp->create_vrf_if_needed = create_vrf_if_needed;
7614
7615       mp->is_add = is_add;
7616       mp->is_drop = is_drop;
7617       mp->is_unreach = is_unreach;
7618       mp->is_prohibit = is_prohibit;
7619       mp->is_ipv6 = is_ipv6;
7620       mp->is_local = is_local;
7621       mp->is_classify = is_classify;
7622       mp->is_multipath = is_multipath;
7623       mp->is_resolve_host = resolve_host;
7624       mp->is_resolve_attached = resolve_attached;
7625       mp->not_last = not_last;
7626       mp->next_hop_weight = next_hop_weight;
7627       mp->dst_address_length = dst_address_length;
7628       mp->next_hop_table_id = ntohl (next_hop_table_id);
7629       mp->classify_table_index = ntohl (classify_table_index);
7630       mp->next_hop_via_label = ntohl (next_hop_via_label);
7631       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7632       if (0 != mp->next_hop_n_out_labels)
7633         {
7634           memcpy (mp->next_hop_out_label_stack,
7635                   next_hop_out_label_stack,
7636                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7637           vec_free (next_hop_out_label_stack);
7638         }
7639
7640       if (is_ipv6)
7641         {
7642           clib_memcpy (mp->dst_address, &v6_dst_address,
7643                        sizeof (v6_dst_address));
7644           if (next_hop_set)
7645             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7646                          sizeof (v6_next_hop_address));
7647           increment_v6_address (&v6_dst_address);
7648         }
7649       else
7650         {
7651           clib_memcpy (mp->dst_address, &v4_dst_address,
7652                        sizeof (v4_dst_address));
7653           if (next_hop_set)
7654             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7655                          sizeof (v4_next_hop_address));
7656           if (random_add_del)
7657             v4_dst_address.as_u32 = random_vector[j + 1];
7658           else
7659             increment_v4_address (&v4_dst_address);
7660         }
7661       /* send it... */
7662       S (mp);
7663       /* If we receive SIGTERM, stop now... */
7664       if (vam->do_exit)
7665         break;
7666     }
7667
7668   /* When testing multiple add/del ops, use a control-ping to sync */
7669   if (count > 1)
7670     {
7671       vl_api_control_ping_t *mp_ping;
7672       f64 after;
7673       f64 timeout;
7674
7675       /* Shut off async mode */
7676       vam->async_mode = 0;
7677
7678       MPING (CONTROL_PING, mp_ping);
7679       S (mp_ping);
7680
7681       timeout = vat_time_now (vam) + 1.0;
7682       while (vat_time_now (vam) < timeout)
7683         if (vam->result_ready == 1)
7684           goto out;
7685       vam->retval = -99;
7686
7687     out:
7688       if (vam->retval == -99)
7689         errmsg ("timeout");
7690
7691       if (vam->async_errors > 0)
7692         {
7693           errmsg ("%d asynchronous errors", vam->async_errors);
7694           vam->retval = -98;
7695         }
7696       vam->async_errors = 0;
7697       after = vat_time_now (vam);
7698
7699       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7700       if (j > 0)
7701         count = j;
7702
7703       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7704              count, after - before, count / (after - before));
7705     }
7706   else
7707     {
7708       int ret;
7709
7710       /* Wait for a reply... */
7711       W (ret);
7712       return ret;
7713     }
7714
7715   /* Return the good/bad news */
7716   return (vam->retval);
7717 }
7718
7719 static int
7720 api_ip_mroute_add_del (vat_main_t * vam)
7721 {
7722   unformat_input_t *i = vam->input;
7723   vl_api_ip_mroute_add_del_t *mp;
7724   u32 sw_if_index = ~0, vrf_id = 0;
7725   u8 is_ipv6 = 0;
7726   u8 is_local = 0;
7727   u8 create_vrf_if_needed = 0;
7728   u8 is_add = 1;
7729   u8 address_set = 0;
7730   u32 grp_address_length = 0;
7731   ip4_address_t v4_grp_address, v4_src_address;
7732   ip6_address_t v6_grp_address, v6_src_address;
7733   mfib_itf_flags_t iflags = 0;
7734   mfib_entry_flags_t eflags = 0;
7735   int ret;
7736
7737   /* Parse args required to build the message */
7738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7739     {
7740       if (unformat (i, "sw_if_index %d", &sw_if_index))
7741         ;
7742       else if (unformat (i, "%U %U",
7743                          unformat_ip4_address, &v4_src_address,
7744                          unformat_ip4_address, &v4_grp_address))
7745         {
7746           grp_address_length = 64;
7747           address_set = 1;
7748           is_ipv6 = 0;
7749         }
7750       else if (unformat (i, "%U %U",
7751                          unformat_ip6_address, &v6_src_address,
7752                          unformat_ip6_address, &v6_grp_address))
7753         {
7754           grp_address_length = 256;
7755           address_set = 1;
7756           is_ipv6 = 1;
7757         }
7758       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7759         {
7760           memset (&v4_src_address, 0, sizeof (v4_src_address));
7761           grp_address_length = 32;
7762           address_set = 1;
7763           is_ipv6 = 0;
7764         }
7765       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7766         {
7767           memset (&v6_src_address, 0, sizeof (v6_src_address));
7768           grp_address_length = 128;
7769           address_set = 1;
7770           is_ipv6 = 1;
7771         }
7772       else if (unformat (i, "/%d", &grp_address_length))
7773         ;
7774       else if (unformat (i, "local"))
7775         {
7776           is_local = 1;
7777         }
7778       else if (unformat (i, "del"))
7779         is_add = 0;
7780       else if (unformat (i, "add"))
7781         is_add = 1;
7782       else if (unformat (i, "vrf %d", &vrf_id))
7783         ;
7784       else if (unformat (i, "create-vrf"))
7785         create_vrf_if_needed = 1;
7786       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7787         ;
7788       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7789         ;
7790       else
7791         {
7792           clib_warning ("parse error '%U'", format_unformat_error, i);
7793           return -99;
7794         }
7795     }
7796
7797   if (address_set == 0)
7798     {
7799       errmsg ("missing addresses\n");
7800       return -99;
7801     }
7802
7803   /* Construct the API message */
7804   M (IP_MROUTE_ADD_DEL, mp);
7805
7806   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7807   mp->table_id = ntohl (vrf_id);
7808   mp->create_vrf_if_needed = create_vrf_if_needed;
7809
7810   mp->is_add = is_add;
7811   mp->is_ipv6 = is_ipv6;
7812   mp->is_local = is_local;
7813   mp->itf_flags = ntohl (iflags);
7814   mp->entry_flags = ntohl (eflags);
7815   mp->grp_address_length = grp_address_length;
7816   mp->grp_address_length = ntohs (mp->grp_address_length);
7817
7818   if (is_ipv6)
7819     {
7820       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7821       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7822     }
7823   else
7824     {
7825       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7826       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7827
7828     }
7829
7830   /* send it... */
7831   S (mp);
7832   /* Wait for a reply... */
7833   W (ret);
7834   return ret;
7835 }
7836
7837 static int
7838 api_mpls_table_add_del (vat_main_t * vam)
7839 {
7840   unformat_input_t *i = vam->input;
7841   vl_api_mpls_table_add_del_t *mp;
7842   u32 table_id = ~0;
7843   u8 is_add = 1;
7844   int ret = 0;
7845
7846   /* Parse args required to build the message */
7847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7848     {
7849       if (unformat (i, "table %d", &table_id))
7850         ;
7851       else if (unformat (i, "del"))
7852         is_add = 0;
7853       else if (unformat (i, "add"))
7854         is_add = 1;
7855       else
7856         {
7857           clib_warning ("parse error '%U'", format_unformat_error, i);
7858           return -99;
7859         }
7860     }
7861
7862   if (~0 == table_id)
7863     {
7864       errmsg ("missing table-ID");
7865       return -99;
7866     }
7867
7868   /* Construct the API message */
7869   M (MPLS_TABLE_ADD_DEL, mp);
7870
7871   mp->mt_table_id = ntohl (table_id);
7872   mp->mt_is_add = is_add;
7873
7874   /* send it... */
7875   S (mp);
7876
7877   /* Wait for a reply... */
7878   W (ret);
7879
7880   return ret;
7881 }
7882
7883 static int
7884 api_mpls_route_add_del (vat_main_t * vam)
7885 {
7886   unformat_input_t *i = vam->input;
7887   vl_api_mpls_route_add_del_t *mp;
7888   u32 sw_if_index = ~0, table_id = 0;
7889   u8 create_table_if_needed = 0;
7890   u8 is_add = 1;
7891   u32 next_hop_weight = 1;
7892   u8 is_multipath = 0;
7893   u32 next_hop_table_id = 0;
7894   u8 next_hop_set = 0;
7895   ip4_address_t v4_next_hop_address = {
7896     .as_u32 = 0,
7897   };
7898   ip6_address_t v6_next_hop_address = { {0} };
7899   int count = 1;
7900   int j;
7901   f64 before = 0;
7902   u32 classify_table_index = ~0;
7903   u8 is_classify = 0;
7904   u8 resolve_host = 0, resolve_attached = 0;
7905   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7906   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7907   mpls_label_t *next_hop_out_label_stack = NULL;
7908   mpls_label_t local_label = MPLS_LABEL_INVALID;
7909   u8 is_eos = 0;
7910   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
7911
7912   /* Parse args required to build the message */
7913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7914     {
7915       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7916         ;
7917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7918         ;
7919       else if (unformat (i, "%d", &local_label))
7920         ;
7921       else if (unformat (i, "eos"))
7922         is_eos = 1;
7923       else if (unformat (i, "non-eos"))
7924         is_eos = 0;
7925       else if (unformat (i, "via %U", unformat_ip4_address,
7926                          &v4_next_hop_address))
7927         {
7928           next_hop_set = 1;
7929           next_hop_proto = DPO_PROTO_IP4;
7930         }
7931       else if (unformat (i, "via %U", unformat_ip6_address,
7932                          &v6_next_hop_address))
7933         {
7934           next_hop_set = 1;
7935           next_hop_proto = DPO_PROTO_IP6;
7936         }
7937       else if (unformat (i, "weight %d", &next_hop_weight))
7938         ;
7939       else if (unformat (i, "create-table"))
7940         create_table_if_needed = 1;
7941       else if (unformat (i, "classify %d", &classify_table_index))
7942         {
7943           is_classify = 1;
7944         }
7945       else if (unformat (i, "del"))
7946         is_add = 0;
7947       else if (unformat (i, "add"))
7948         is_add = 1;
7949       else if (unformat (i, "resolve-via-host"))
7950         resolve_host = 1;
7951       else if (unformat (i, "resolve-via-attached"))
7952         resolve_attached = 1;
7953       else if (unformat (i, "multipath"))
7954         is_multipath = 1;
7955       else if (unformat (i, "count %d", &count))
7956         ;
7957       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7958         {
7959           next_hop_set = 1;
7960           next_hop_proto = DPO_PROTO_IP4;
7961         }
7962       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7963         {
7964           next_hop_set = 1;
7965           next_hop_proto = DPO_PROTO_IP6;
7966         }
7967       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7968         ;
7969       else if (unformat (i, "via-label %d", &next_hop_via_label))
7970         ;
7971       else if (unformat (i, "out-label %d", &next_hop_out_label))
7972         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7973       else
7974         {
7975           clib_warning ("parse error '%U'", format_unformat_error, i);
7976           return -99;
7977         }
7978     }
7979
7980   if (!next_hop_set && !is_classify)
7981     {
7982       errmsg ("next hop / classify not set");
7983       return -99;
7984     }
7985
7986   if (MPLS_LABEL_INVALID == local_label)
7987     {
7988       errmsg ("missing label");
7989       return -99;
7990     }
7991
7992   if (count > 1)
7993     {
7994       /* Turn on async mode */
7995       vam->async_mode = 1;
7996       vam->async_errors = 0;
7997       before = vat_time_now (vam);
7998     }
7999
8000   for (j = 0; j < count; j++)
8001     {
8002       /* Construct the API message */
8003       M2 (MPLS_ROUTE_ADD_DEL, mp,
8004           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8005
8006       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8007       mp->mr_table_id = ntohl (table_id);
8008       mp->mr_create_table_if_needed = create_table_if_needed;
8009
8010       mp->mr_is_add = is_add;
8011       mp->mr_next_hop_proto = next_hop_proto;
8012       mp->mr_is_classify = is_classify;
8013       mp->mr_is_multipath = is_multipath;
8014       mp->mr_is_resolve_host = resolve_host;
8015       mp->mr_is_resolve_attached = resolve_attached;
8016       mp->mr_next_hop_weight = next_hop_weight;
8017       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8018       mp->mr_classify_table_index = ntohl (classify_table_index);
8019       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8020       mp->mr_label = ntohl (local_label);
8021       mp->mr_eos = is_eos;
8022
8023       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8024       if (0 != mp->mr_next_hop_n_out_labels)
8025         {
8026           memcpy (mp->mr_next_hop_out_label_stack,
8027                   next_hop_out_label_stack,
8028                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8029           vec_free (next_hop_out_label_stack);
8030         }
8031
8032       if (next_hop_set)
8033         {
8034           if (DPO_PROTO_IP4 == next_hop_proto)
8035             {
8036               clib_memcpy (mp->mr_next_hop,
8037                            &v4_next_hop_address,
8038                            sizeof (v4_next_hop_address));
8039             }
8040           else if (DPO_PROTO_IP6 == next_hop_proto)
8041
8042             {
8043               clib_memcpy (mp->mr_next_hop,
8044                            &v6_next_hop_address,
8045                            sizeof (v6_next_hop_address));
8046             }
8047         }
8048       local_label++;
8049
8050       /* send it... */
8051       S (mp);
8052       /* If we receive SIGTERM, stop now... */
8053       if (vam->do_exit)
8054         break;
8055     }
8056
8057   /* When testing multiple add/del ops, use a control-ping to sync */
8058   if (count > 1)
8059     {
8060       vl_api_control_ping_t *mp_ping;
8061       f64 after;
8062       f64 timeout;
8063
8064       /* Shut off async mode */
8065       vam->async_mode = 0;
8066
8067       MPING (CONTROL_PING, mp_ping);
8068       S (mp_ping);
8069
8070       timeout = vat_time_now (vam) + 1.0;
8071       while (vat_time_now (vam) < timeout)
8072         if (vam->result_ready == 1)
8073           goto out;
8074       vam->retval = -99;
8075
8076     out:
8077       if (vam->retval == -99)
8078         errmsg ("timeout");
8079
8080       if (vam->async_errors > 0)
8081         {
8082           errmsg ("%d asynchronous errors", vam->async_errors);
8083           vam->retval = -98;
8084         }
8085       vam->async_errors = 0;
8086       after = vat_time_now (vam);
8087
8088       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8089       if (j > 0)
8090         count = j;
8091
8092       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8093              count, after - before, count / (after - before));
8094     }
8095   else
8096     {
8097       int ret;
8098
8099       /* Wait for a reply... */
8100       W (ret);
8101       return ret;
8102     }
8103
8104   /* Return the good/bad news */
8105   return (vam->retval);
8106 }
8107
8108 static int
8109 api_mpls_ip_bind_unbind (vat_main_t * vam)
8110 {
8111   unformat_input_t *i = vam->input;
8112   vl_api_mpls_ip_bind_unbind_t *mp;
8113   u32 ip_table_id = 0;
8114   u8 create_table_if_needed = 0;
8115   u8 is_bind = 1;
8116   u8 is_ip4 = 1;
8117   ip4_address_t v4_address;
8118   ip6_address_t v6_address;
8119   u32 address_length;
8120   u8 address_set = 0;
8121   mpls_label_t local_label = MPLS_LABEL_INVALID;
8122   int ret;
8123
8124   /* Parse args required to build the message */
8125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8126     {
8127       if (unformat (i, "%U/%d", unformat_ip4_address,
8128                     &v4_address, &address_length))
8129         {
8130           is_ip4 = 1;
8131           address_set = 1;
8132         }
8133       else if (unformat (i, "%U/%d", unformat_ip6_address,
8134                          &v6_address, &address_length))
8135         {
8136           is_ip4 = 0;
8137           address_set = 1;
8138         }
8139       else if (unformat (i, "%d", &local_label))
8140         ;
8141       else if (unformat (i, "create-table"))
8142         create_table_if_needed = 1;
8143       else if (unformat (i, "table-id %d", &ip_table_id))
8144         ;
8145       else if (unformat (i, "unbind"))
8146         is_bind = 0;
8147       else if (unformat (i, "bind"))
8148         is_bind = 1;
8149       else
8150         {
8151           clib_warning ("parse error '%U'", format_unformat_error, i);
8152           return -99;
8153         }
8154     }
8155
8156   if (!address_set)
8157     {
8158       errmsg ("IP addres not set");
8159       return -99;
8160     }
8161
8162   if (MPLS_LABEL_INVALID == local_label)
8163     {
8164       errmsg ("missing label");
8165       return -99;
8166     }
8167
8168   /* Construct the API message */
8169   M (MPLS_IP_BIND_UNBIND, mp);
8170
8171   mp->mb_create_table_if_needed = create_table_if_needed;
8172   mp->mb_is_bind = is_bind;
8173   mp->mb_is_ip4 = is_ip4;
8174   mp->mb_ip_table_id = ntohl (ip_table_id);
8175   mp->mb_mpls_table_id = 0;
8176   mp->mb_label = ntohl (local_label);
8177   mp->mb_address_length = address_length;
8178
8179   if (is_ip4)
8180     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8181   else
8182     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8183
8184   /* send it... */
8185   S (mp);
8186
8187   /* Wait for a reply... */
8188   W (ret);
8189   return ret;
8190 }
8191
8192 static int
8193 api_proxy_arp_add_del (vat_main_t * vam)
8194 {
8195   unformat_input_t *i = vam->input;
8196   vl_api_proxy_arp_add_del_t *mp;
8197   u32 vrf_id = 0;
8198   u8 is_add = 1;
8199   ip4_address_t lo, hi;
8200   u8 range_set = 0;
8201   int ret;
8202
8203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8204     {
8205       if (unformat (i, "vrf %d", &vrf_id))
8206         ;
8207       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8208                          unformat_ip4_address, &hi))
8209         range_set = 1;
8210       else if (unformat (i, "del"))
8211         is_add = 0;
8212       else
8213         {
8214           clib_warning ("parse error '%U'", format_unformat_error, i);
8215           return -99;
8216         }
8217     }
8218
8219   if (range_set == 0)
8220     {
8221       errmsg ("address range not set");
8222       return -99;
8223     }
8224
8225   M (PROXY_ARP_ADD_DEL, mp);
8226
8227   mp->vrf_id = ntohl (vrf_id);
8228   mp->is_add = is_add;
8229   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8230   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8231
8232   S (mp);
8233   W (ret);
8234   return ret;
8235 }
8236
8237 static int
8238 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8239 {
8240   unformat_input_t *i = vam->input;
8241   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8242   u32 sw_if_index;
8243   u8 enable = 1;
8244   u8 sw_if_index_set = 0;
8245   int ret;
8246
8247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8248     {
8249       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8250         sw_if_index_set = 1;
8251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8252         sw_if_index_set = 1;
8253       else if (unformat (i, "enable"))
8254         enable = 1;
8255       else if (unformat (i, "disable"))
8256         enable = 0;
8257       else
8258         {
8259           clib_warning ("parse error '%U'", format_unformat_error, i);
8260           return -99;
8261         }
8262     }
8263
8264   if (sw_if_index_set == 0)
8265     {
8266       errmsg ("missing interface name or sw_if_index");
8267       return -99;
8268     }
8269
8270   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8271
8272   mp->sw_if_index = ntohl (sw_if_index);
8273   mp->enable_disable = enable;
8274
8275   S (mp);
8276   W (ret);
8277   return ret;
8278 }
8279
8280 static int
8281 api_mpls_tunnel_add_del (vat_main_t * vam)
8282 {
8283   unformat_input_t *i = vam->input;
8284   vl_api_mpls_tunnel_add_del_t *mp;
8285
8286   u8 is_add = 1;
8287   u8 l2_only = 0;
8288   u32 sw_if_index = ~0;
8289   u32 next_hop_sw_if_index = ~0;
8290   u32 next_hop_proto_is_ip4 = 1;
8291
8292   u32 next_hop_table_id = 0;
8293   ip4_address_t v4_next_hop_address = {
8294     .as_u32 = 0,
8295   };
8296   ip6_address_t v6_next_hop_address = { {0} };
8297   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8298   int ret;
8299
8300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8301     {
8302       if (unformat (i, "add"))
8303         is_add = 1;
8304       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8305         is_add = 0;
8306       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8307         ;
8308       else if (unformat (i, "via %U",
8309                          unformat_ip4_address, &v4_next_hop_address))
8310         {
8311           next_hop_proto_is_ip4 = 1;
8312         }
8313       else if (unformat (i, "via %U",
8314                          unformat_ip6_address, &v6_next_hop_address))
8315         {
8316           next_hop_proto_is_ip4 = 0;
8317         }
8318       else if (unformat (i, "l2-only"))
8319         l2_only = 1;
8320       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8321         ;
8322       else if (unformat (i, "out-label %d", &next_hop_out_label))
8323         vec_add1 (labels, ntohl (next_hop_out_label));
8324       else
8325         {
8326           clib_warning ("parse error '%U'", format_unformat_error, i);
8327           return -99;
8328         }
8329     }
8330
8331   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8332
8333   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8334   mp->mt_sw_if_index = ntohl (sw_if_index);
8335   mp->mt_is_add = is_add;
8336   mp->mt_l2_only = l2_only;
8337   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8338   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8339
8340   mp->mt_next_hop_n_out_labels = vec_len (labels);
8341
8342   if (0 != mp->mt_next_hop_n_out_labels)
8343     {
8344       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8345                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8346       vec_free (labels);
8347     }
8348
8349   if (next_hop_proto_is_ip4)
8350     {
8351       clib_memcpy (mp->mt_next_hop,
8352                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8353     }
8354   else
8355     {
8356       clib_memcpy (mp->mt_next_hop,
8357                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8358     }
8359
8360   S (mp);
8361   W (ret);
8362   return ret;
8363 }
8364
8365 static int
8366 api_sw_interface_set_unnumbered (vat_main_t * vam)
8367 {
8368   unformat_input_t *i = vam->input;
8369   vl_api_sw_interface_set_unnumbered_t *mp;
8370   u32 sw_if_index;
8371   u32 unnum_sw_index = ~0;
8372   u8 is_add = 1;
8373   u8 sw_if_index_set = 0;
8374   int ret;
8375
8376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8377     {
8378       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8379         sw_if_index_set = 1;
8380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8381         sw_if_index_set = 1;
8382       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8383         ;
8384       else if (unformat (i, "del"))
8385         is_add = 0;
8386       else
8387         {
8388           clib_warning ("parse error '%U'", format_unformat_error, i);
8389           return -99;
8390         }
8391     }
8392
8393   if (sw_if_index_set == 0)
8394     {
8395       errmsg ("missing interface name or sw_if_index");
8396       return -99;
8397     }
8398
8399   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8400
8401   mp->sw_if_index = ntohl (sw_if_index);
8402   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8403   mp->is_add = is_add;
8404
8405   S (mp);
8406   W (ret);
8407   return ret;
8408 }
8409
8410 static int
8411 api_ip_neighbor_add_del (vat_main_t * vam)
8412 {
8413   unformat_input_t *i = vam->input;
8414   vl_api_ip_neighbor_add_del_t *mp;
8415   u32 sw_if_index;
8416   u8 sw_if_index_set = 0;
8417   u8 is_add = 1;
8418   u8 is_static = 0;
8419   u8 is_no_fib_entry = 0;
8420   u8 mac_address[6];
8421   u8 mac_set = 0;
8422   u8 v4_address_set = 0;
8423   u8 v6_address_set = 0;
8424   ip4_address_t v4address;
8425   ip6_address_t v6address;
8426   int ret;
8427
8428   memset (mac_address, 0, sizeof (mac_address));
8429
8430   /* Parse args required to build the message */
8431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8432     {
8433       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8434         {
8435           mac_set = 1;
8436         }
8437       else if (unformat (i, "del"))
8438         is_add = 0;
8439       else
8440         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8441         sw_if_index_set = 1;
8442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8443         sw_if_index_set = 1;
8444       else if (unformat (i, "is_static"))
8445         is_static = 1;
8446       else if (unformat (i, "no-fib-entry"))
8447         is_no_fib_entry = 1;
8448       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8449         v4_address_set = 1;
8450       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8451         v6_address_set = 1;
8452       else
8453         {
8454           clib_warning ("parse error '%U'", format_unformat_error, i);
8455           return -99;
8456         }
8457     }
8458
8459   if (sw_if_index_set == 0)
8460     {
8461       errmsg ("missing interface name or sw_if_index");
8462       return -99;
8463     }
8464   if (v4_address_set && v6_address_set)
8465     {
8466       errmsg ("both v4 and v6 addresses set");
8467       return -99;
8468     }
8469   if (!v4_address_set && !v6_address_set)
8470     {
8471       errmsg ("no address set");
8472       return -99;
8473     }
8474
8475   /* Construct the API message */
8476   M (IP_NEIGHBOR_ADD_DEL, mp);
8477
8478   mp->sw_if_index = ntohl (sw_if_index);
8479   mp->is_add = is_add;
8480   mp->is_static = is_static;
8481   mp->is_no_adj_fib = is_no_fib_entry;
8482   if (mac_set)
8483     clib_memcpy (mp->mac_address, mac_address, 6);
8484   if (v6_address_set)
8485     {
8486       mp->is_ipv6 = 1;
8487       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8488     }
8489   else
8490     {
8491       /* mp->is_ipv6 = 0; via memset in M macro above */
8492       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8493     }
8494
8495   /* send it... */
8496   S (mp);
8497
8498   /* Wait for a reply, return good/bad news  */
8499   W (ret);
8500   return ret;
8501 }
8502
8503 static int
8504 api_reset_vrf (vat_main_t * vam)
8505 {
8506   unformat_input_t *i = vam->input;
8507   vl_api_reset_vrf_t *mp;
8508   u32 vrf_id = 0;
8509   u8 is_ipv6 = 0;
8510   u8 vrf_id_set = 0;
8511   int ret;
8512
8513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8514     {
8515       if (unformat (i, "vrf %d", &vrf_id))
8516         vrf_id_set = 1;
8517       else if (unformat (i, "ipv6"))
8518         is_ipv6 = 1;
8519       else
8520         {
8521           clib_warning ("parse error '%U'", format_unformat_error, i);
8522           return -99;
8523         }
8524     }
8525
8526   if (vrf_id_set == 0)
8527     {
8528       errmsg ("missing vrf id");
8529       return -99;
8530     }
8531
8532   M (RESET_VRF, mp);
8533
8534   mp->vrf_id = ntohl (vrf_id);
8535   mp->is_ipv6 = is_ipv6;
8536
8537   S (mp);
8538   W (ret);
8539   return ret;
8540 }
8541
8542 static int
8543 api_create_vlan_subif (vat_main_t * vam)
8544 {
8545   unformat_input_t *i = vam->input;
8546   vl_api_create_vlan_subif_t *mp;
8547   u32 sw_if_index;
8548   u8 sw_if_index_set = 0;
8549   u32 vlan_id;
8550   u8 vlan_id_set = 0;
8551   int ret;
8552
8553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8554     {
8555       if (unformat (i, "sw_if_index %d", &sw_if_index))
8556         sw_if_index_set = 1;
8557       else
8558         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8559         sw_if_index_set = 1;
8560       else if (unformat (i, "vlan %d", &vlan_id))
8561         vlan_id_set = 1;
8562       else
8563         {
8564           clib_warning ("parse error '%U'", format_unformat_error, i);
8565           return -99;
8566         }
8567     }
8568
8569   if (sw_if_index_set == 0)
8570     {
8571       errmsg ("missing interface name or sw_if_index");
8572       return -99;
8573     }
8574
8575   if (vlan_id_set == 0)
8576     {
8577       errmsg ("missing vlan_id");
8578       return -99;
8579     }
8580   M (CREATE_VLAN_SUBIF, mp);
8581
8582   mp->sw_if_index = ntohl (sw_if_index);
8583   mp->vlan_id = ntohl (vlan_id);
8584
8585   S (mp);
8586   W (ret);
8587   return ret;
8588 }
8589
8590 #define foreach_create_subif_bit                \
8591 _(no_tags)                                      \
8592 _(one_tag)                                      \
8593 _(two_tags)                                     \
8594 _(dot1ad)                                       \
8595 _(exact_match)                                  \
8596 _(default_sub)                                  \
8597 _(outer_vlan_id_any)                            \
8598 _(inner_vlan_id_any)
8599
8600 static int
8601 api_create_subif (vat_main_t * vam)
8602 {
8603   unformat_input_t *i = vam->input;
8604   vl_api_create_subif_t *mp;
8605   u32 sw_if_index;
8606   u8 sw_if_index_set = 0;
8607   u32 sub_id;
8608   u8 sub_id_set = 0;
8609   u32 no_tags = 0;
8610   u32 one_tag = 0;
8611   u32 two_tags = 0;
8612   u32 dot1ad = 0;
8613   u32 exact_match = 0;
8614   u32 default_sub = 0;
8615   u32 outer_vlan_id_any = 0;
8616   u32 inner_vlan_id_any = 0;
8617   u32 tmp;
8618   u16 outer_vlan_id = 0;
8619   u16 inner_vlan_id = 0;
8620   int ret;
8621
8622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8623     {
8624       if (unformat (i, "sw_if_index %d", &sw_if_index))
8625         sw_if_index_set = 1;
8626       else
8627         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8628         sw_if_index_set = 1;
8629       else if (unformat (i, "sub_id %d", &sub_id))
8630         sub_id_set = 1;
8631       else if (unformat (i, "outer_vlan_id %d", &tmp))
8632         outer_vlan_id = tmp;
8633       else if (unformat (i, "inner_vlan_id %d", &tmp))
8634         inner_vlan_id = tmp;
8635
8636 #define _(a) else if (unformat (i, #a)) a = 1 ;
8637       foreach_create_subif_bit
8638 #undef _
8639         else
8640         {
8641           clib_warning ("parse error '%U'", format_unformat_error, i);
8642           return -99;
8643         }
8644     }
8645
8646   if (sw_if_index_set == 0)
8647     {
8648       errmsg ("missing interface name or sw_if_index");
8649       return -99;
8650     }
8651
8652   if (sub_id_set == 0)
8653     {
8654       errmsg ("missing sub_id");
8655       return -99;
8656     }
8657   M (CREATE_SUBIF, mp);
8658
8659   mp->sw_if_index = ntohl (sw_if_index);
8660   mp->sub_id = ntohl (sub_id);
8661
8662 #define _(a) mp->a = a;
8663   foreach_create_subif_bit;
8664 #undef _
8665
8666   mp->outer_vlan_id = ntohs (outer_vlan_id);
8667   mp->inner_vlan_id = ntohs (inner_vlan_id);
8668
8669   S (mp);
8670   W (ret);
8671   return ret;
8672 }
8673
8674 static int
8675 api_oam_add_del (vat_main_t * vam)
8676 {
8677   unformat_input_t *i = vam->input;
8678   vl_api_oam_add_del_t *mp;
8679   u32 vrf_id = 0;
8680   u8 is_add = 1;
8681   ip4_address_t src, dst;
8682   u8 src_set = 0;
8683   u8 dst_set = 0;
8684   int ret;
8685
8686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8687     {
8688       if (unformat (i, "vrf %d", &vrf_id))
8689         ;
8690       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8691         src_set = 1;
8692       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8693         dst_set = 1;
8694       else if (unformat (i, "del"))
8695         is_add = 0;
8696       else
8697         {
8698           clib_warning ("parse error '%U'", format_unformat_error, i);
8699           return -99;
8700         }
8701     }
8702
8703   if (src_set == 0)
8704     {
8705       errmsg ("missing src addr");
8706       return -99;
8707     }
8708
8709   if (dst_set == 0)
8710     {
8711       errmsg ("missing dst addr");
8712       return -99;
8713     }
8714
8715   M (OAM_ADD_DEL, mp);
8716
8717   mp->vrf_id = ntohl (vrf_id);
8718   mp->is_add = is_add;
8719   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8720   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8721
8722   S (mp);
8723   W (ret);
8724   return ret;
8725 }
8726
8727 static int
8728 api_reset_fib (vat_main_t * vam)
8729 {
8730   unformat_input_t *i = vam->input;
8731   vl_api_reset_fib_t *mp;
8732   u32 vrf_id = 0;
8733   u8 is_ipv6 = 0;
8734   u8 vrf_id_set = 0;
8735
8736   int ret;
8737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8738     {
8739       if (unformat (i, "vrf %d", &vrf_id))
8740         vrf_id_set = 1;
8741       else if (unformat (i, "ipv6"))
8742         is_ipv6 = 1;
8743       else
8744         {
8745           clib_warning ("parse error '%U'", format_unformat_error, i);
8746           return -99;
8747         }
8748     }
8749
8750   if (vrf_id_set == 0)
8751     {
8752       errmsg ("missing vrf id");
8753       return -99;
8754     }
8755
8756   M (RESET_FIB, mp);
8757
8758   mp->vrf_id = ntohl (vrf_id);
8759   mp->is_ipv6 = is_ipv6;
8760
8761   S (mp);
8762   W (ret);
8763   return ret;
8764 }
8765
8766 static int
8767 api_dhcp_proxy_config (vat_main_t * vam)
8768 {
8769   unformat_input_t *i = vam->input;
8770   vl_api_dhcp_proxy_config_t *mp;
8771   u32 rx_vrf_id = 0;
8772   u32 server_vrf_id = 0;
8773   u8 is_add = 1;
8774   u8 v4_address_set = 0;
8775   u8 v6_address_set = 0;
8776   ip4_address_t v4address;
8777   ip6_address_t v6address;
8778   u8 v4_src_address_set = 0;
8779   u8 v6_src_address_set = 0;
8780   ip4_address_t v4srcaddress;
8781   ip6_address_t v6srcaddress;
8782   int ret;
8783
8784   /* Parse args required to build the message */
8785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8786     {
8787       if (unformat (i, "del"))
8788         is_add = 0;
8789       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8790         ;
8791       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8792         ;
8793       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8794         v4_address_set = 1;
8795       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8796         v6_address_set = 1;
8797       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8798         v4_src_address_set = 1;
8799       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8800         v6_src_address_set = 1;
8801       else
8802         break;
8803     }
8804
8805   if (v4_address_set && v6_address_set)
8806     {
8807       errmsg ("both v4 and v6 server addresses set");
8808       return -99;
8809     }
8810   if (!v4_address_set && !v6_address_set)
8811     {
8812       errmsg ("no server addresses set");
8813       return -99;
8814     }
8815
8816   if (v4_src_address_set && v6_src_address_set)
8817     {
8818       errmsg ("both v4 and v6  src addresses set");
8819       return -99;
8820     }
8821   if (!v4_src_address_set && !v6_src_address_set)
8822     {
8823       errmsg ("no src addresses set");
8824       return -99;
8825     }
8826
8827   if (!(v4_src_address_set && v4_address_set) &&
8828       !(v6_src_address_set && v6_address_set))
8829     {
8830       errmsg ("no matching server and src addresses set");
8831       return -99;
8832     }
8833
8834   /* Construct the API message */
8835   M (DHCP_PROXY_CONFIG, mp);
8836
8837   mp->is_add = is_add;
8838   mp->rx_vrf_id = ntohl (rx_vrf_id);
8839   mp->server_vrf_id = ntohl (server_vrf_id);
8840   if (v6_address_set)
8841     {
8842       mp->is_ipv6 = 1;
8843       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8844       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8845     }
8846   else
8847     {
8848       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8849       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8850     }
8851
8852   /* send it... */
8853   S (mp);
8854
8855   /* Wait for a reply, return good/bad news  */
8856   W (ret);
8857   return ret;
8858 }
8859
8860 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8861 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8862
8863 static void
8864 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8865 {
8866   vat_main_t *vam = &vat_main;
8867   u32 i, count = mp->count;
8868   vl_api_dhcp_server_t *s;
8869
8870   if (mp->is_ipv6)
8871     print (vam->ofp,
8872            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8873            ntohl (mp->rx_vrf_id),
8874            format_ip6_address, mp->dhcp_src_address,
8875            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8876   else
8877     print (vam->ofp,
8878            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8879            ntohl (mp->rx_vrf_id),
8880            format_ip4_address, mp->dhcp_src_address,
8881            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8882
8883   for (i = 0; i < count; i++)
8884     {
8885       s = &mp->servers[i];
8886
8887       if (mp->is_ipv6)
8888         print (vam->ofp,
8889                " Server Table-ID %d, Server Address %U",
8890                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8891       else
8892         print (vam->ofp,
8893                " Server Table-ID %d, Server Address %U",
8894                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8895     }
8896 }
8897
8898 static void vl_api_dhcp_proxy_details_t_handler_json
8899   (vl_api_dhcp_proxy_details_t * mp)
8900 {
8901   vat_main_t *vam = &vat_main;
8902   vat_json_node_t *node = NULL;
8903   u32 i, count = mp->count;
8904   struct in_addr ip4;
8905   struct in6_addr ip6;
8906   vl_api_dhcp_server_t *s;
8907
8908   if (VAT_JSON_ARRAY != vam->json_tree.type)
8909     {
8910       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8911       vat_json_init_array (&vam->json_tree);
8912     }
8913   node = vat_json_array_add (&vam->json_tree);
8914
8915   vat_json_init_object (node);
8916   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8917   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8918   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8919
8920   if (mp->is_ipv6)
8921     {
8922       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8923       vat_json_object_add_ip6 (node, "src_address", ip6);
8924     }
8925   else
8926     {
8927       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8928       vat_json_object_add_ip4 (node, "src_address", ip4);
8929     }
8930
8931   for (i = 0; i < count; i++)
8932     {
8933       s = &mp->servers[i];
8934
8935       vat_json_object_add_uint (node, "server-table-id",
8936                                 ntohl (s->server_vrf_id));
8937
8938       if (mp->is_ipv6)
8939         {
8940           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8941           vat_json_object_add_ip4 (node, "src_address", ip4);
8942         }
8943       else
8944         {
8945           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8946           vat_json_object_add_ip6 (node, "server_address", ip6);
8947         }
8948     }
8949 }
8950
8951 static int
8952 api_dhcp_proxy_dump (vat_main_t * vam)
8953 {
8954   unformat_input_t *i = vam->input;
8955   vl_api_control_ping_t *mp_ping;
8956   vl_api_dhcp_proxy_dump_t *mp;
8957   u8 is_ipv6 = 0;
8958   int ret;
8959
8960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8961     {
8962       if (unformat (i, "ipv6"))
8963         is_ipv6 = 1;
8964       else
8965         {
8966           clib_warning ("parse error '%U'", format_unformat_error, i);
8967           return -99;
8968         }
8969     }
8970
8971   M (DHCP_PROXY_DUMP, mp);
8972
8973   mp->is_ip6 = is_ipv6;
8974   S (mp);
8975
8976   /* Use a control ping for synchronization */
8977   MPING (CONTROL_PING, mp_ping);
8978   S (mp_ping);
8979
8980   W (ret);
8981   return ret;
8982 }
8983
8984 static int
8985 api_dhcp_proxy_set_vss (vat_main_t * vam)
8986 {
8987   unformat_input_t *i = vam->input;
8988   vl_api_dhcp_proxy_set_vss_t *mp;
8989   u8 is_ipv6 = 0;
8990   u8 is_add = 1;
8991   u32 tbl_id;
8992   u8 tbl_id_set = 0;
8993   u32 oui;
8994   u8 oui_set = 0;
8995   u32 fib_id;
8996   u8 fib_id_set = 0;
8997   int ret;
8998
8999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9000     {
9001       if (unformat (i, "tbl_id %d", &tbl_id))
9002         tbl_id_set = 1;
9003       if (unformat (i, "fib_id %d", &fib_id))
9004         fib_id_set = 1;
9005       if (unformat (i, "oui %d", &oui))
9006         oui_set = 1;
9007       else if (unformat (i, "ipv6"))
9008         is_ipv6 = 1;
9009       else if (unformat (i, "del"))
9010         is_add = 0;
9011       else
9012         {
9013           clib_warning ("parse error '%U'", format_unformat_error, i);
9014           return -99;
9015         }
9016     }
9017
9018   if (tbl_id_set == 0)
9019     {
9020       errmsg ("missing tbl id");
9021       return -99;
9022     }
9023
9024   if (fib_id_set == 0)
9025     {
9026       errmsg ("missing fib id");
9027       return -99;
9028     }
9029   if (oui_set == 0)
9030     {
9031       errmsg ("missing oui");
9032       return -99;
9033     }
9034
9035   M (DHCP_PROXY_SET_VSS, mp);
9036   mp->tbl_id = ntohl (tbl_id);
9037   mp->fib_id = ntohl (fib_id);
9038   mp->oui = ntohl (oui);
9039   mp->is_ipv6 = is_ipv6;
9040   mp->is_add = is_add;
9041
9042   S (mp);
9043   W (ret);
9044   return ret;
9045 }
9046
9047 static int
9048 api_dhcp_client_config (vat_main_t * vam)
9049 {
9050   unformat_input_t *i = vam->input;
9051   vl_api_dhcp_client_config_t *mp;
9052   u32 sw_if_index;
9053   u8 sw_if_index_set = 0;
9054   u8 is_add = 1;
9055   u8 *hostname = 0;
9056   u8 disable_event = 0;
9057   int ret;
9058
9059   /* Parse args required to build the message */
9060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9061     {
9062       if (unformat (i, "del"))
9063         is_add = 0;
9064       else
9065         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9066         sw_if_index_set = 1;
9067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9068         sw_if_index_set = 1;
9069       else if (unformat (i, "hostname %s", &hostname))
9070         ;
9071       else if (unformat (i, "disable_event"))
9072         disable_event = 1;
9073       else
9074         break;
9075     }
9076
9077   if (sw_if_index_set == 0)
9078     {
9079       errmsg ("missing interface name or sw_if_index");
9080       return -99;
9081     }
9082
9083   if (vec_len (hostname) > 63)
9084     {
9085       errmsg ("hostname too long");
9086     }
9087   vec_add1 (hostname, 0);
9088
9089   /* Construct the API message */
9090   M (DHCP_CLIENT_CONFIG, mp);
9091
9092   mp->sw_if_index = htonl (sw_if_index);
9093   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9094   vec_free (hostname);
9095   mp->is_add = is_add;
9096   mp->want_dhcp_event = disable_event ? 0 : 1;
9097   mp->pid = htonl (getpid ());
9098
9099   /* send it... */
9100   S (mp);
9101
9102   /* Wait for a reply, return good/bad news  */
9103   W (ret);
9104   return ret;
9105 }
9106
9107 static int
9108 api_set_ip_flow_hash (vat_main_t * vam)
9109 {
9110   unformat_input_t *i = vam->input;
9111   vl_api_set_ip_flow_hash_t *mp;
9112   u32 vrf_id = 0;
9113   u8 is_ipv6 = 0;
9114   u8 vrf_id_set = 0;
9115   u8 src = 0;
9116   u8 dst = 0;
9117   u8 sport = 0;
9118   u8 dport = 0;
9119   u8 proto = 0;
9120   u8 reverse = 0;
9121   int ret;
9122
9123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9124     {
9125       if (unformat (i, "vrf %d", &vrf_id))
9126         vrf_id_set = 1;
9127       else if (unformat (i, "ipv6"))
9128         is_ipv6 = 1;
9129       else if (unformat (i, "src"))
9130         src = 1;
9131       else if (unformat (i, "dst"))
9132         dst = 1;
9133       else if (unformat (i, "sport"))
9134         sport = 1;
9135       else if (unformat (i, "dport"))
9136         dport = 1;
9137       else if (unformat (i, "proto"))
9138         proto = 1;
9139       else if (unformat (i, "reverse"))
9140         reverse = 1;
9141
9142       else
9143         {
9144           clib_warning ("parse error '%U'", format_unformat_error, i);
9145           return -99;
9146         }
9147     }
9148
9149   if (vrf_id_set == 0)
9150     {
9151       errmsg ("missing vrf id");
9152       return -99;
9153     }
9154
9155   M (SET_IP_FLOW_HASH, mp);
9156   mp->src = src;
9157   mp->dst = dst;
9158   mp->sport = sport;
9159   mp->dport = dport;
9160   mp->proto = proto;
9161   mp->reverse = reverse;
9162   mp->vrf_id = ntohl (vrf_id);
9163   mp->is_ipv6 = is_ipv6;
9164
9165   S (mp);
9166   W (ret);
9167   return ret;
9168 }
9169
9170 static int
9171 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9172 {
9173   unformat_input_t *i = vam->input;
9174   vl_api_sw_interface_ip6_enable_disable_t *mp;
9175   u32 sw_if_index;
9176   u8 sw_if_index_set = 0;
9177   u8 enable = 0;
9178   int ret;
9179
9180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9181     {
9182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9183         sw_if_index_set = 1;
9184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9185         sw_if_index_set = 1;
9186       else if (unformat (i, "enable"))
9187         enable = 1;
9188       else if (unformat (i, "disable"))
9189         enable = 0;
9190       else
9191         {
9192           clib_warning ("parse error '%U'", format_unformat_error, i);
9193           return -99;
9194         }
9195     }
9196
9197   if (sw_if_index_set == 0)
9198     {
9199       errmsg ("missing interface name or sw_if_index");
9200       return -99;
9201     }
9202
9203   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9204
9205   mp->sw_if_index = ntohl (sw_if_index);
9206   mp->enable = enable;
9207
9208   S (mp);
9209   W (ret);
9210   return ret;
9211 }
9212
9213 static int
9214 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9215 {
9216   unformat_input_t *i = vam->input;
9217   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9218   u32 sw_if_index;
9219   u8 sw_if_index_set = 0;
9220   u8 v6_address_set = 0;
9221   ip6_address_t v6address;
9222   int ret;
9223
9224   /* Parse args required to build the message */
9225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9226     {
9227       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9228         sw_if_index_set = 1;
9229       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9230         sw_if_index_set = 1;
9231       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9232         v6_address_set = 1;
9233       else
9234         break;
9235     }
9236
9237   if (sw_if_index_set == 0)
9238     {
9239       errmsg ("missing interface name or sw_if_index");
9240       return -99;
9241     }
9242   if (!v6_address_set)
9243     {
9244       errmsg ("no address set");
9245       return -99;
9246     }
9247
9248   /* Construct the API message */
9249   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9250
9251   mp->sw_if_index = ntohl (sw_if_index);
9252   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9253
9254   /* send it... */
9255   S (mp);
9256
9257   /* Wait for a reply, return good/bad news  */
9258   W (ret);
9259   return ret;
9260 }
9261
9262 static int
9263 api_ip6nd_proxy_add_del (vat_main_t * vam)
9264 {
9265   unformat_input_t *i = vam->input;
9266   vl_api_ip6nd_proxy_add_del_t *mp;
9267   u32 sw_if_index = ~0;
9268   u8 v6_address_set = 0;
9269   ip6_address_t v6address;
9270   u8 is_del = 0;
9271   int ret;
9272
9273   /* Parse args required to build the message */
9274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9275     {
9276       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9277         ;
9278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9279         ;
9280       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9281         v6_address_set = 1;
9282       if (unformat (i, "del"))
9283         is_del = 1;
9284       else
9285         {
9286           clib_warning ("parse error '%U'", format_unformat_error, i);
9287           return -99;
9288         }
9289     }
9290
9291   if (sw_if_index == ~0)
9292     {
9293       errmsg ("missing interface name or sw_if_index");
9294       return -99;
9295     }
9296   if (!v6_address_set)
9297     {
9298       errmsg ("no address set");
9299       return -99;
9300     }
9301
9302   /* Construct the API message */
9303   M (IP6ND_PROXY_ADD_DEL, mp);
9304
9305   mp->is_del = is_del;
9306   mp->sw_if_index = ntohl (sw_if_index);
9307   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9308
9309   /* send it... */
9310   S (mp);
9311
9312   /* Wait for a reply, return good/bad news  */
9313   W (ret);
9314   return ret;
9315 }
9316
9317 static int
9318 api_ip6nd_proxy_dump (vat_main_t * vam)
9319 {
9320   vl_api_ip6nd_proxy_dump_t *mp;
9321   vl_api_control_ping_t *mp_ping;
9322   int ret;
9323
9324   M (IP6ND_PROXY_DUMP, mp);
9325
9326   S (mp);
9327
9328   /* Use a control ping for synchronization */
9329   MPING (CONTROL_PING, mp_ping);
9330   S (mp_ping);
9331
9332   W (ret);
9333   return ret;
9334 }
9335
9336 static void vl_api_ip6nd_proxy_details_t_handler
9337   (vl_api_ip6nd_proxy_details_t * mp)
9338 {
9339   vat_main_t *vam = &vat_main;
9340
9341   print (vam->ofp, "host %U sw_if_index %d",
9342          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9343 }
9344
9345 static void vl_api_ip6nd_proxy_details_t_handler_json
9346   (vl_api_ip6nd_proxy_details_t * mp)
9347 {
9348   vat_main_t *vam = &vat_main;
9349   struct in6_addr ip6;
9350   vat_json_node_t *node = NULL;
9351
9352   if (VAT_JSON_ARRAY != vam->json_tree.type)
9353     {
9354       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9355       vat_json_init_array (&vam->json_tree);
9356     }
9357   node = vat_json_array_add (&vam->json_tree);
9358
9359   vat_json_init_object (node);
9360   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9361
9362   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9363   vat_json_object_add_ip6 (node, "host", ip6);
9364 }
9365
9366 static int
9367 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9368 {
9369   unformat_input_t *i = vam->input;
9370   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9371   u32 sw_if_index;
9372   u8 sw_if_index_set = 0;
9373   u32 address_length = 0;
9374   u8 v6_address_set = 0;
9375   ip6_address_t v6address;
9376   u8 use_default = 0;
9377   u8 no_advertise = 0;
9378   u8 off_link = 0;
9379   u8 no_autoconfig = 0;
9380   u8 no_onlink = 0;
9381   u8 is_no = 0;
9382   u32 val_lifetime = 0;
9383   u32 pref_lifetime = 0;
9384   int ret;
9385
9386   /* Parse args required to build the message */
9387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9388     {
9389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9390         sw_if_index_set = 1;
9391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9392         sw_if_index_set = 1;
9393       else if (unformat (i, "%U/%d",
9394                          unformat_ip6_address, &v6address, &address_length))
9395         v6_address_set = 1;
9396       else if (unformat (i, "val_life %d", &val_lifetime))
9397         ;
9398       else if (unformat (i, "pref_life %d", &pref_lifetime))
9399         ;
9400       else if (unformat (i, "def"))
9401         use_default = 1;
9402       else if (unformat (i, "noadv"))
9403         no_advertise = 1;
9404       else if (unformat (i, "offl"))
9405         off_link = 1;
9406       else if (unformat (i, "noauto"))
9407         no_autoconfig = 1;
9408       else if (unformat (i, "nolink"))
9409         no_onlink = 1;
9410       else if (unformat (i, "isno"))
9411         is_no = 1;
9412       else
9413         {
9414           clib_warning ("parse error '%U'", format_unformat_error, i);
9415           return -99;
9416         }
9417     }
9418
9419   if (sw_if_index_set == 0)
9420     {
9421       errmsg ("missing interface name or sw_if_index");
9422       return -99;
9423     }
9424   if (!v6_address_set)
9425     {
9426       errmsg ("no address set");
9427       return -99;
9428     }
9429
9430   /* Construct the API message */
9431   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9432
9433   mp->sw_if_index = ntohl (sw_if_index);
9434   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9435   mp->address_length = address_length;
9436   mp->use_default = use_default;
9437   mp->no_advertise = no_advertise;
9438   mp->off_link = off_link;
9439   mp->no_autoconfig = no_autoconfig;
9440   mp->no_onlink = no_onlink;
9441   mp->is_no = is_no;
9442   mp->val_lifetime = ntohl (val_lifetime);
9443   mp->pref_lifetime = ntohl (pref_lifetime);
9444
9445   /* send it... */
9446   S (mp);
9447
9448   /* Wait for a reply, return good/bad news  */
9449   W (ret);
9450   return ret;
9451 }
9452
9453 static int
9454 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9455 {
9456   unformat_input_t *i = vam->input;
9457   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9458   u32 sw_if_index;
9459   u8 sw_if_index_set = 0;
9460   u8 suppress = 0;
9461   u8 managed = 0;
9462   u8 other = 0;
9463   u8 ll_option = 0;
9464   u8 send_unicast = 0;
9465   u8 cease = 0;
9466   u8 is_no = 0;
9467   u8 default_router = 0;
9468   u32 max_interval = 0;
9469   u32 min_interval = 0;
9470   u32 lifetime = 0;
9471   u32 initial_count = 0;
9472   u32 initial_interval = 0;
9473   int ret;
9474
9475
9476   /* Parse args required to build the message */
9477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9478     {
9479       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9480         sw_if_index_set = 1;
9481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9482         sw_if_index_set = 1;
9483       else if (unformat (i, "maxint %d", &max_interval))
9484         ;
9485       else if (unformat (i, "minint %d", &min_interval))
9486         ;
9487       else if (unformat (i, "life %d", &lifetime))
9488         ;
9489       else if (unformat (i, "count %d", &initial_count))
9490         ;
9491       else if (unformat (i, "interval %d", &initial_interval))
9492         ;
9493       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9494         suppress = 1;
9495       else if (unformat (i, "managed"))
9496         managed = 1;
9497       else if (unformat (i, "other"))
9498         other = 1;
9499       else if (unformat (i, "ll"))
9500         ll_option = 1;
9501       else if (unformat (i, "send"))
9502         send_unicast = 1;
9503       else if (unformat (i, "cease"))
9504         cease = 1;
9505       else if (unformat (i, "isno"))
9506         is_no = 1;
9507       else if (unformat (i, "def"))
9508         default_router = 1;
9509       else
9510         {
9511           clib_warning ("parse error '%U'", format_unformat_error, i);
9512           return -99;
9513         }
9514     }
9515
9516   if (sw_if_index_set == 0)
9517     {
9518       errmsg ("missing interface name or sw_if_index");
9519       return -99;
9520     }
9521
9522   /* Construct the API message */
9523   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9524
9525   mp->sw_if_index = ntohl (sw_if_index);
9526   mp->max_interval = ntohl (max_interval);
9527   mp->min_interval = ntohl (min_interval);
9528   mp->lifetime = ntohl (lifetime);
9529   mp->initial_count = ntohl (initial_count);
9530   mp->initial_interval = ntohl (initial_interval);
9531   mp->suppress = suppress;
9532   mp->managed = managed;
9533   mp->other = other;
9534   mp->ll_option = ll_option;
9535   mp->send_unicast = send_unicast;
9536   mp->cease = cease;
9537   mp->is_no = is_no;
9538   mp->default_router = default_router;
9539
9540   /* send it... */
9541   S (mp);
9542
9543   /* Wait for a reply, return good/bad news  */
9544   W (ret);
9545   return ret;
9546 }
9547
9548 static int
9549 api_set_arp_neighbor_limit (vat_main_t * vam)
9550 {
9551   unformat_input_t *i = vam->input;
9552   vl_api_set_arp_neighbor_limit_t *mp;
9553   u32 arp_nbr_limit;
9554   u8 limit_set = 0;
9555   u8 is_ipv6 = 0;
9556   int ret;
9557
9558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9559     {
9560       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9561         limit_set = 1;
9562       else if (unformat (i, "ipv6"))
9563         is_ipv6 = 1;
9564       else
9565         {
9566           clib_warning ("parse error '%U'", format_unformat_error, i);
9567           return -99;
9568         }
9569     }
9570
9571   if (limit_set == 0)
9572     {
9573       errmsg ("missing limit value");
9574       return -99;
9575     }
9576
9577   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9578
9579   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9580   mp->is_ipv6 = is_ipv6;
9581
9582   S (mp);
9583   W (ret);
9584   return ret;
9585 }
9586
9587 static int
9588 api_l2_patch_add_del (vat_main_t * vam)
9589 {
9590   unformat_input_t *i = vam->input;
9591   vl_api_l2_patch_add_del_t *mp;
9592   u32 rx_sw_if_index;
9593   u8 rx_sw_if_index_set = 0;
9594   u32 tx_sw_if_index;
9595   u8 tx_sw_if_index_set = 0;
9596   u8 is_add = 1;
9597   int ret;
9598
9599   /* Parse args required to build the message */
9600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9601     {
9602       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9603         rx_sw_if_index_set = 1;
9604       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9605         tx_sw_if_index_set = 1;
9606       else if (unformat (i, "rx"))
9607         {
9608           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9609             {
9610               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9611                             &rx_sw_if_index))
9612                 rx_sw_if_index_set = 1;
9613             }
9614           else
9615             break;
9616         }
9617       else if (unformat (i, "tx"))
9618         {
9619           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9620             {
9621               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9622                             &tx_sw_if_index))
9623                 tx_sw_if_index_set = 1;
9624             }
9625           else
9626             break;
9627         }
9628       else if (unformat (i, "del"))
9629         is_add = 0;
9630       else
9631         break;
9632     }
9633
9634   if (rx_sw_if_index_set == 0)
9635     {
9636       errmsg ("missing rx interface name or rx_sw_if_index");
9637       return -99;
9638     }
9639
9640   if (tx_sw_if_index_set == 0)
9641     {
9642       errmsg ("missing tx interface name or tx_sw_if_index");
9643       return -99;
9644     }
9645
9646   M (L2_PATCH_ADD_DEL, mp);
9647
9648   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9649   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9650   mp->is_add = is_add;
9651
9652   S (mp);
9653   W (ret);
9654   return ret;
9655 }
9656
9657 u8 is_del;
9658 u8 localsid_addr[16];
9659 u8 end_psp;
9660 u8 behavior;
9661 u32 sw_if_index;
9662 u32 vlan_index;
9663 u32 fib_table;
9664 u8 nh_addr[16];
9665
9666 static int
9667 api_sr_localsid_add_del (vat_main_t * vam)
9668 {
9669   unformat_input_t *i = vam->input;
9670   vl_api_sr_localsid_add_del_t *mp;
9671
9672   u8 is_del;
9673   ip6_address_t localsid;
9674   u8 end_psp = 0;
9675   u8 behavior = ~0;
9676   u32 sw_if_index;
9677   u32 fib_table = ~(u32) 0;
9678   ip6_address_t next_hop;
9679
9680   bool nexthop_set = 0;
9681
9682   int ret;
9683
9684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9685     {
9686       if (unformat (i, "del"))
9687         is_del = 1;
9688       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9689       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9690         nexthop_set = 1;
9691       else if (unformat (i, "behavior %u", &behavior));
9692       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9693       else if (unformat (i, "fib-table %u", &fib_table));
9694       else if (unformat (i, "end.psp %u", &behavior));
9695       else
9696         break;
9697     }
9698
9699   M (SR_LOCALSID_ADD_DEL, mp);
9700
9701   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9702   if (nexthop_set)
9703     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9704   mp->behavior = behavior;
9705   mp->sw_if_index = ntohl (sw_if_index);
9706   mp->fib_table = ntohl (fib_table);
9707   mp->end_psp = end_psp;
9708   mp->is_del = is_del;
9709
9710   S (mp);
9711   W (ret);
9712   return ret;
9713 }
9714
9715 static int
9716 api_ioam_enable (vat_main_t * vam)
9717 {
9718   unformat_input_t *input = vam->input;
9719   vl_api_ioam_enable_t *mp;
9720   u32 id = 0;
9721   int has_trace_option = 0;
9722   int has_pot_option = 0;
9723   int has_seqno_option = 0;
9724   int has_analyse_option = 0;
9725   int ret;
9726
9727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9728     {
9729       if (unformat (input, "trace"))
9730         has_trace_option = 1;
9731       else if (unformat (input, "pot"))
9732         has_pot_option = 1;
9733       else if (unformat (input, "seqno"))
9734         has_seqno_option = 1;
9735       else if (unformat (input, "analyse"))
9736         has_analyse_option = 1;
9737       else
9738         break;
9739     }
9740   M (IOAM_ENABLE, mp);
9741   mp->id = htons (id);
9742   mp->seqno = has_seqno_option;
9743   mp->analyse = has_analyse_option;
9744   mp->pot_enable = has_pot_option;
9745   mp->trace_enable = has_trace_option;
9746
9747   S (mp);
9748   W (ret);
9749   return ret;
9750 }
9751
9752
9753 static int
9754 api_ioam_disable (vat_main_t * vam)
9755 {
9756   vl_api_ioam_disable_t *mp;
9757   int ret;
9758
9759   M (IOAM_DISABLE, mp);
9760   S (mp);
9761   W (ret);
9762   return ret;
9763 }
9764
9765 #define foreach_tcp_proto_field                 \
9766 _(src_port)                                     \
9767 _(dst_port)
9768
9769 #define foreach_udp_proto_field                 \
9770 _(src_port)                                     \
9771 _(dst_port)
9772
9773 #define foreach_ip4_proto_field                 \
9774 _(src_address)                                  \
9775 _(dst_address)                                  \
9776 _(tos)                                          \
9777 _(length)                                       \
9778 _(fragment_id)                                  \
9779 _(ttl)                                          \
9780 _(protocol)                                     \
9781 _(checksum)
9782
9783 typedef struct
9784 {
9785   u16 src_port, dst_port;
9786 } tcpudp_header_t;
9787
9788 #if VPP_API_TEST_BUILTIN == 0
9789 uword
9790 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9791 {
9792   u8 **maskp = va_arg (*args, u8 **);
9793   u8 *mask = 0;
9794   u8 found_something = 0;
9795   tcp_header_t *tcp;
9796
9797 #define _(a) u8 a=0;
9798   foreach_tcp_proto_field;
9799 #undef _
9800
9801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9802     {
9803       if (0);
9804 #define _(a) else if (unformat (input, #a)) a=1;
9805       foreach_tcp_proto_field
9806 #undef _
9807         else
9808         break;
9809     }
9810
9811 #define _(a) found_something += a;
9812   foreach_tcp_proto_field;
9813 #undef _
9814
9815   if (found_something == 0)
9816     return 0;
9817
9818   vec_validate (mask, sizeof (*tcp) - 1);
9819
9820   tcp = (tcp_header_t *) mask;
9821
9822 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9823   foreach_tcp_proto_field;
9824 #undef _
9825
9826   *maskp = mask;
9827   return 1;
9828 }
9829
9830 uword
9831 unformat_udp_mask (unformat_input_t * input, va_list * args)
9832 {
9833   u8 **maskp = va_arg (*args, u8 **);
9834   u8 *mask = 0;
9835   u8 found_something = 0;
9836   udp_header_t *udp;
9837
9838 #define _(a) u8 a=0;
9839   foreach_udp_proto_field;
9840 #undef _
9841
9842   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9843     {
9844       if (0);
9845 #define _(a) else if (unformat (input, #a)) a=1;
9846       foreach_udp_proto_field
9847 #undef _
9848         else
9849         break;
9850     }
9851
9852 #define _(a) found_something += a;
9853   foreach_udp_proto_field;
9854 #undef _
9855
9856   if (found_something == 0)
9857     return 0;
9858
9859   vec_validate (mask, sizeof (*udp) - 1);
9860
9861   udp = (udp_header_t *) mask;
9862
9863 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9864   foreach_udp_proto_field;
9865 #undef _
9866
9867   *maskp = mask;
9868   return 1;
9869 }
9870
9871 uword
9872 unformat_l4_mask (unformat_input_t * input, va_list * args)
9873 {
9874   u8 **maskp = va_arg (*args, u8 **);
9875   u16 src_port = 0, dst_port = 0;
9876   tcpudp_header_t *tcpudp;
9877
9878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9879     {
9880       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9881         return 1;
9882       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9883         return 1;
9884       else if (unformat (input, "src_port"))
9885         src_port = 0xFFFF;
9886       else if (unformat (input, "dst_port"))
9887         dst_port = 0xFFFF;
9888       else
9889         return 0;
9890     }
9891
9892   if (!src_port && !dst_port)
9893     return 0;
9894
9895   u8 *mask = 0;
9896   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9897
9898   tcpudp = (tcpudp_header_t *) mask;
9899   tcpudp->src_port = src_port;
9900   tcpudp->dst_port = dst_port;
9901
9902   *maskp = mask;
9903
9904   return 1;
9905 }
9906
9907 uword
9908 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9909 {
9910   u8 **maskp = va_arg (*args, u8 **);
9911   u8 *mask = 0;
9912   u8 found_something = 0;
9913   ip4_header_t *ip;
9914
9915 #define _(a) u8 a=0;
9916   foreach_ip4_proto_field;
9917 #undef _
9918   u8 version = 0;
9919   u8 hdr_length = 0;
9920
9921
9922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9923     {
9924       if (unformat (input, "version"))
9925         version = 1;
9926       else if (unformat (input, "hdr_length"))
9927         hdr_length = 1;
9928       else if (unformat (input, "src"))
9929         src_address = 1;
9930       else if (unformat (input, "dst"))
9931         dst_address = 1;
9932       else if (unformat (input, "proto"))
9933         protocol = 1;
9934
9935 #define _(a) else if (unformat (input, #a)) a=1;
9936       foreach_ip4_proto_field
9937 #undef _
9938         else
9939         break;
9940     }
9941
9942 #define _(a) found_something += a;
9943   foreach_ip4_proto_field;
9944 #undef _
9945
9946   if (found_something == 0)
9947     return 0;
9948
9949   vec_validate (mask, sizeof (*ip) - 1);
9950
9951   ip = (ip4_header_t *) mask;
9952
9953 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9954   foreach_ip4_proto_field;
9955 #undef _
9956
9957   ip->ip_version_and_header_length = 0;
9958
9959   if (version)
9960     ip->ip_version_and_header_length |= 0xF0;
9961
9962   if (hdr_length)
9963     ip->ip_version_and_header_length |= 0x0F;
9964
9965   *maskp = mask;
9966   return 1;
9967 }
9968
9969 #define foreach_ip6_proto_field                 \
9970 _(src_address)                                  \
9971 _(dst_address)                                  \
9972 _(payload_length)                               \
9973 _(hop_limit)                                    \
9974 _(protocol)
9975
9976 uword
9977 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9978 {
9979   u8 **maskp = va_arg (*args, u8 **);
9980   u8 *mask = 0;
9981   u8 found_something = 0;
9982   ip6_header_t *ip;
9983   u32 ip_version_traffic_class_and_flow_label;
9984
9985 #define _(a) u8 a=0;
9986   foreach_ip6_proto_field;
9987 #undef _
9988   u8 version = 0;
9989   u8 traffic_class = 0;
9990   u8 flow_label = 0;
9991
9992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9993     {
9994       if (unformat (input, "version"))
9995         version = 1;
9996       else if (unformat (input, "traffic-class"))
9997         traffic_class = 1;
9998       else if (unformat (input, "flow-label"))
9999         flow_label = 1;
10000       else if (unformat (input, "src"))
10001         src_address = 1;
10002       else if (unformat (input, "dst"))
10003         dst_address = 1;
10004       else if (unformat (input, "proto"))
10005         protocol = 1;
10006
10007 #define _(a) else if (unformat (input, #a)) a=1;
10008       foreach_ip6_proto_field
10009 #undef _
10010         else
10011         break;
10012     }
10013
10014 #define _(a) found_something += a;
10015   foreach_ip6_proto_field;
10016 #undef _
10017
10018   if (found_something == 0)
10019     return 0;
10020
10021   vec_validate (mask, sizeof (*ip) - 1);
10022
10023   ip = (ip6_header_t *) mask;
10024
10025 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10026   foreach_ip6_proto_field;
10027 #undef _
10028
10029   ip_version_traffic_class_and_flow_label = 0;
10030
10031   if (version)
10032     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10033
10034   if (traffic_class)
10035     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10036
10037   if (flow_label)
10038     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10039
10040   ip->ip_version_traffic_class_and_flow_label =
10041     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10042
10043   *maskp = mask;
10044   return 1;
10045 }
10046
10047 uword
10048 unformat_l3_mask (unformat_input_t * input, va_list * args)
10049 {
10050   u8 **maskp = va_arg (*args, u8 **);
10051
10052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10053     {
10054       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10055         return 1;
10056       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10057         return 1;
10058       else
10059         break;
10060     }
10061   return 0;
10062 }
10063
10064 uword
10065 unformat_l2_mask (unformat_input_t * input, va_list * args)
10066 {
10067   u8 **maskp = va_arg (*args, u8 **);
10068   u8 *mask = 0;
10069   u8 src = 0;
10070   u8 dst = 0;
10071   u8 proto = 0;
10072   u8 tag1 = 0;
10073   u8 tag2 = 0;
10074   u8 ignore_tag1 = 0;
10075   u8 ignore_tag2 = 0;
10076   u8 cos1 = 0;
10077   u8 cos2 = 0;
10078   u8 dot1q = 0;
10079   u8 dot1ad = 0;
10080   int len = 14;
10081
10082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10083     {
10084       if (unformat (input, "src"))
10085         src = 1;
10086       else if (unformat (input, "dst"))
10087         dst = 1;
10088       else if (unformat (input, "proto"))
10089         proto = 1;
10090       else if (unformat (input, "tag1"))
10091         tag1 = 1;
10092       else if (unformat (input, "tag2"))
10093         tag2 = 1;
10094       else if (unformat (input, "ignore-tag1"))
10095         ignore_tag1 = 1;
10096       else if (unformat (input, "ignore-tag2"))
10097         ignore_tag2 = 1;
10098       else if (unformat (input, "cos1"))
10099         cos1 = 1;
10100       else if (unformat (input, "cos2"))
10101         cos2 = 1;
10102       else if (unformat (input, "dot1q"))
10103         dot1q = 1;
10104       else if (unformat (input, "dot1ad"))
10105         dot1ad = 1;
10106       else
10107         break;
10108     }
10109   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10110        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10111     return 0;
10112
10113   if (tag1 || ignore_tag1 || cos1 || dot1q)
10114     len = 18;
10115   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10116     len = 22;
10117
10118   vec_validate (mask, len - 1);
10119
10120   if (dst)
10121     memset (mask, 0xff, 6);
10122
10123   if (src)
10124     memset (mask + 6, 0xff, 6);
10125
10126   if (tag2 || dot1ad)
10127     {
10128       /* inner vlan tag */
10129       if (tag2)
10130         {
10131           mask[19] = 0xff;
10132           mask[18] = 0x0f;
10133         }
10134       if (cos2)
10135         mask[18] |= 0xe0;
10136       if (proto)
10137         mask[21] = mask[20] = 0xff;
10138       if (tag1)
10139         {
10140           mask[15] = 0xff;
10141           mask[14] = 0x0f;
10142         }
10143       if (cos1)
10144         mask[14] |= 0xe0;
10145       *maskp = mask;
10146       return 1;
10147     }
10148   if (tag1 | dot1q)
10149     {
10150       if (tag1)
10151         {
10152           mask[15] = 0xff;
10153           mask[14] = 0x0f;
10154         }
10155       if (cos1)
10156         mask[14] |= 0xe0;
10157       if (proto)
10158         mask[16] = mask[17] = 0xff;
10159
10160       *maskp = mask;
10161       return 1;
10162     }
10163   if (cos2)
10164     mask[18] |= 0xe0;
10165   if (cos1)
10166     mask[14] |= 0xe0;
10167   if (proto)
10168     mask[12] = mask[13] = 0xff;
10169
10170   *maskp = mask;
10171   return 1;
10172 }
10173
10174 uword
10175 unformat_classify_mask (unformat_input_t * input, va_list * args)
10176 {
10177   u8 **maskp = va_arg (*args, u8 **);
10178   u32 *skipp = va_arg (*args, u32 *);
10179   u32 *matchp = va_arg (*args, u32 *);
10180   u32 match;
10181   u8 *mask = 0;
10182   u8 *l2 = 0;
10183   u8 *l3 = 0;
10184   u8 *l4 = 0;
10185   int i;
10186
10187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10188     {
10189       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10190         ;
10191       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10192         ;
10193       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10194         ;
10195       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10196         ;
10197       else
10198         break;
10199     }
10200
10201   if (l4 && !l3)
10202     {
10203       vec_free (mask);
10204       vec_free (l2);
10205       vec_free (l4);
10206       return 0;
10207     }
10208
10209   if (mask || l2 || l3 || l4)
10210     {
10211       if (l2 || l3 || l4)
10212         {
10213           /* "With a free Ethernet header in every package" */
10214           if (l2 == 0)
10215             vec_validate (l2, 13);
10216           mask = l2;
10217           if (vec_len (l3))
10218             {
10219               vec_append (mask, l3);
10220               vec_free (l3);
10221             }
10222           if (vec_len (l4))
10223             {
10224               vec_append (mask, l4);
10225               vec_free (l4);
10226             }
10227         }
10228
10229       /* Scan forward looking for the first significant mask octet */
10230       for (i = 0; i < vec_len (mask); i++)
10231         if (mask[i])
10232           break;
10233
10234       /* compute (skip, match) params */
10235       *skipp = i / sizeof (u32x4);
10236       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10237
10238       /* Pad mask to an even multiple of the vector size */
10239       while (vec_len (mask) % sizeof (u32x4))
10240         vec_add1 (mask, 0);
10241
10242       match = vec_len (mask) / sizeof (u32x4);
10243
10244       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10245         {
10246           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10247           if (*tmp || *(tmp + 1))
10248             break;
10249           match--;
10250         }
10251       if (match == 0)
10252         clib_warning ("BUG: match 0");
10253
10254       _vec_len (mask) = match * sizeof (u32x4);
10255
10256       *matchp = match;
10257       *maskp = mask;
10258
10259       return 1;
10260     }
10261
10262   return 0;
10263 }
10264 #endif /* VPP_API_TEST_BUILTIN */
10265
10266 #define foreach_l2_next                         \
10267 _(drop, DROP)                                   \
10268 _(ethernet, ETHERNET_INPUT)                     \
10269 _(ip4, IP4_INPUT)                               \
10270 _(ip6, IP6_INPUT)
10271
10272 uword
10273 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10274 {
10275   u32 *miss_next_indexp = va_arg (*args, u32 *);
10276   u32 next_index = 0;
10277   u32 tmp;
10278
10279 #define _(n,N) \
10280   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10281   foreach_l2_next;
10282 #undef _
10283
10284   if (unformat (input, "%d", &tmp))
10285     {
10286       next_index = tmp;
10287       goto out;
10288     }
10289
10290   return 0;
10291
10292 out:
10293   *miss_next_indexp = next_index;
10294   return 1;
10295 }
10296
10297 #define foreach_ip_next                         \
10298 _(drop, DROP)                                   \
10299 _(local, LOCAL)                                 \
10300 _(rewrite, REWRITE)
10301
10302 uword
10303 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10304 {
10305   u32 *miss_next_indexp = va_arg (*args, u32 *);
10306   u32 next_index = 0;
10307   u32 tmp;
10308
10309 #define _(n,N) \
10310   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10311   foreach_ip_next;
10312 #undef _
10313
10314   if (unformat (input, "%d", &tmp))
10315     {
10316       next_index = tmp;
10317       goto out;
10318     }
10319
10320   return 0;
10321
10322 out:
10323   *miss_next_indexp = next_index;
10324   return 1;
10325 }
10326
10327 #define foreach_acl_next                        \
10328 _(deny, DENY)
10329
10330 uword
10331 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10332 {
10333   u32 *miss_next_indexp = va_arg (*args, u32 *);
10334   u32 next_index = 0;
10335   u32 tmp;
10336
10337 #define _(n,N) \
10338   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10339   foreach_acl_next;
10340 #undef _
10341
10342   if (unformat (input, "permit"))
10343     {
10344       next_index = ~0;
10345       goto out;
10346     }
10347   else if (unformat (input, "%d", &tmp))
10348     {
10349       next_index = tmp;
10350       goto out;
10351     }
10352
10353   return 0;
10354
10355 out:
10356   *miss_next_indexp = next_index;
10357   return 1;
10358 }
10359
10360 uword
10361 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10362 {
10363   u32 *r = va_arg (*args, u32 *);
10364
10365   if (unformat (input, "conform-color"))
10366     *r = POLICE_CONFORM;
10367   else if (unformat (input, "exceed-color"))
10368     *r = POLICE_EXCEED;
10369   else
10370     return 0;
10371
10372   return 1;
10373 }
10374
10375 static int
10376 api_classify_add_del_table (vat_main_t * vam)
10377 {
10378   unformat_input_t *i = vam->input;
10379   vl_api_classify_add_del_table_t *mp;
10380
10381   u32 nbuckets = 2;
10382   u32 skip = ~0;
10383   u32 match = ~0;
10384   int is_add = 1;
10385   int del_chain = 0;
10386   u32 table_index = ~0;
10387   u32 next_table_index = ~0;
10388   u32 miss_next_index = ~0;
10389   u32 memory_size = 32 << 20;
10390   u8 *mask = 0;
10391   u32 current_data_flag = 0;
10392   int current_data_offset = 0;
10393   int ret;
10394
10395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10396     {
10397       if (unformat (i, "del"))
10398         is_add = 0;
10399       else if (unformat (i, "del-chain"))
10400         {
10401           is_add = 0;
10402           del_chain = 1;
10403         }
10404       else if (unformat (i, "buckets %d", &nbuckets))
10405         ;
10406       else if (unformat (i, "memory_size %d", &memory_size))
10407         ;
10408       else if (unformat (i, "skip %d", &skip))
10409         ;
10410       else if (unformat (i, "match %d", &match))
10411         ;
10412       else if (unformat (i, "table %d", &table_index))
10413         ;
10414       else if (unformat (i, "mask %U", unformat_classify_mask,
10415                          &mask, &skip, &match))
10416         ;
10417       else if (unformat (i, "next-table %d", &next_table_index))
10418         ;
10419       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10420                          &miss_next_index))
10421         ;
10422       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10423                          &miss_next_index))
10424         ;
10425       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10426                          &miss_next_index))
10427         ;
10428       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10429         ;
10430       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10431         ;
10432       else
10433         break;
10434     }
10435
10436   if (is_add && mask == 0)
10437     {
10438       errmsg ("Mask required");
10439       return -99;
10440     }
10441
10442   if (is_add && skip == ~0)
10443     {
10444       errmsg ("skip count required");
10445       return -99;
10446     }
10447
10448   if (is_add && match == ~0)
10449     {
10450       errmsg ("match count required");
10451       return -99;
10452     }
10453
10454   if (!is_add && table_index == ~0)
10455     {
10456       errmsg ("table index required for delete");
10457       return -99;
10458     }
10459
10460   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10461
10462   mp->is_add = is_add;
10463   mp->del_chain = del_chain;
10464   mp->table_index = ntohl (table_index);
10465   mp->nbuckets = ntohl (nbuckets);
10466   mp->memory_size = ntohl (memory_size);
10467   mp->skip_n_vectors = ntohl (skip);
10468   mp->match_n_vectors = ntohl (match);
10469   mp->next_table_index = ntohl (next_table_index);
10470   mp->miss_next_index = ntohl (miss_next_index);
10471   mp->current_data_flag = ntohl (current_data_flag);
10472   mp->current_data_offset = ntohl (current_data_offset);
10473   clib_memcpy (mp->mask, mask, vec_len (mask));
10474
10475   vec_free (mask);
10476
10477   S (mp);
10478   W (ret);
10479   return ret;
10480 }
10481
10482 #if VPP_API_TEST_BUILTIN == 0
10483 uword
10484 unformat_l4_match (unformat_input_t * input, va_list * args)
10485 {
10486   u8 **matchp = va_arg (*args, u8 **);
10487
10488   u8 *proto_header = 0;
10489   int src_port = 0;
10490   int dst_port = 0;
10491
10492   tcpudp_header_t h;
10493
10494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10495     {
10496       if (unformat (input, "src_port %d", &src_port))
10497         ;
10498       else if (unformat (input, "dst_port %d", &dst_port))
10499         ;
10500       else
10501         return 0;
10502     }
10503
10504   h.src_port = clib_host_to_net_u16 (src_port);
10505   h.dst_port = clib_host_to_net_u16 (dst_port);
10506   vec_validate (proto_header, sizeof (h) - 1);
10507   memcpy (proto_header, &h, sizeof (h));
10508
10509   *matchp = proto_header;
10510
10511   return 1;
10512 }
10513
10514 uword
10515 unformat_ip4_match (unformat_input_t * input, va_list * args)
10516 {
10517   u8 **matchp = va_arg (*args, u8 **);
10518   u8 *match = 0;
10519   ip4_header_t *ip;
10520   int version = 0;
10521   u32 version_val;
10522   int hdr_length = 0;
10523   u32 hdr_length_val;
10524   int src = 0, dst = 0;
10525   ip4_address_t src_val, dst_val;
10526   int proto = 0;
10527   u32 proto_val;
10528   int tos = 0;
10529   u32 tos_val;
10530   int length = 0;
10531   u32 length_val;
10532   int fragment_id = 0;
10533   u32 fragment_id_val;
10534   int ttl = 0;
10535   int ttl_val;
10536   int checksum = 0;
10537   u32 checksum_val;
10538
10539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10540     {
10541       if (unformat (input, "version %d", &version_val))
10542         version = 1;
10543       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10544         hdr_length = 1;
10545       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10546         src = 1;
10547       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10548         dst = 1;
10549       else if (unformat (input, "proto %d", &proto_val))
10550         proto = 1;
10551       else if (unformat (input, "tos %d", &tos_val))
10552         tos = 1;
10553       else if (unformat (input, "length %d", &length_val))
10554         length = 1;
10555       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10556         fragment_id = 1;
10557       else if (unformat (input, "ttl %d", &ttl_val))
10558         ttl = 1;
10559       else if (unformat (input, "checksum %d", &checksum_val))
10560         checksum = 1;
10561       else
10562         break;
10563     }
10564
10565   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10566       + ttl + checksum == 0)
10567     return 0;
10568
10569   /*
10570    * Aligned because we use the real comparison functions
10571    */
10572   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10573
10574   ip = (ip4_header_t *) match;
10575
10576   /* These are realistically matched in practice */
10577   if (src)
10578     ip->src_address.as_u32 = src_val.as_u32;
10579
10580   if (dst)
10581     ip->dst_address.as_u32 = dst_val.as_u32;
10582
10583   if (proto)
10584     ip->protocol = proto_val;
10585
10586
10587   /* These are not, but they're included for completeness */
10588   if (version)
10589     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10590
10591   if (hdr_length)
10592     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10593
10594   if (tos)
10595     ip->tos = tos_val;
10596
10597   if (length)
10598     ip->length = clib_host_to_net_u16 (length_val);
10599
10600   if (ttl)
10601     ip->ttl = ttl_val;
10602
10603   if (checksum)
10604     ip->checksum = clib_host_to_net_u16 (checksum_val);
10605
10606   *matchp = match;
10607   return 1;
10608 }
10609
10610 uword
10611 unformat_ip6_match (unformat_input_t * input, va_list * args)
10612 {
10613   u8 **matchp = va_arg (*args, u8 **);
10614   u8 *match = 0;
10615   ip6_header_t *ip;
10616   int version = 0;
10617   u32 version_val;
10618   u8 traffic_class = 0;
10619   u32 traffic_class_val = 0;
10620   u8 flow_label = 0;
10621   u8 flow_label_val;
10622   int src = 0, dst = 0;
10623   ip6_address_t src_val, dst_val;
10624   int proto = 0;
10625   u32 proto_val;
10626   int payload_length = 0;
10627   u32 payload_length_val;
10628   int hop_limit = 0;
10629   int hop_limit_val;
10630   u32 ip_version_traffic_class_and_flow_label;
10631
10632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10633     {
10634       if (unformat (input, "version %d", &version_val))
10635         version = 1;
10636       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10637         traffic_class = 1;
10638       else if (unformat (input, "flow_label %d", &flow_label_val))
10639         flow_label = 1;
10640       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10641         src = 1;
10642       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10643         dst = 1;
10644       else if (unformat (input, "proto %d", &proto_val))
10645         proto = 1;
10646       else if (unformat (input, "payload_length %d", &payload_length_val))
10647         payload_length = 1;
10648       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10649         hop_limit = 1;
10650       else
10651         break;
10652     }
10653
10654   if (version + traffic_class + flow_label + src + dst + proto +
10655       payload_length + hop_limit == 0)
10656     return 0;
10657
10658   /*
10659    * Aligned because we use the real comparison functions
10660    */
10661   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10662
10663   ip = (ip6_header_t *) match;
10664
10665   if (src)
10666     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10667
10668   if (dst)
10669     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10670
10671   if (proto)
10672     ip->protocol = proto_val;
10673
10674   ip_version_traffic_class_and_flow_label = 0;
10675
10676   if (version)
10677     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10678
10679   if (traffic_class)
10680     ip_version_traffic_class_and_flow_label |=
10681       (traffic_class_val & 0xFF) << 20;
10682
10683   if (flow_label)
10684     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10685
10686   ip->ip_version_traffic_class_and_flow_label =
10687     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10688
10689   if (payload_length)
10690     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10691
10692   if (hop_limit)
10693     ip->hop_limit = hop_limit_val;
10694
10695   *matchp = match;
10696   return 1;
10697 }
10698
10699 uword
10700 unformat_l3_match (unformat_input_t * input, va_list * args)
10701 {
10702   u8 **matchp = va_arg (*args, u8 **);
10703
10704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10705     {
10706       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10707         return 1;
10708       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10709         return 1;
10710       else
10711         break;
10712     }
10713   return 0;
10714 }
10715
10716 uword
10717 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10718 {
10719   u8 *tagp = va_arg (*args, u8 *);
10720   u32 tag;
10721
10722   if (unformat (input, "%d", &tag))
10723     {
10724       tagp[0] = (tag >> 8) & 0x0F;
10725       tagp[1] = tag & 0xFF;
10726       return 1;
10727     }
10728
10729   return 0;
10730 }
10731
10732 uword
10733 unformat_l2_match (unformat_input_t * input, va_list * args)
10734 {
10735   u8 **matchp = va_arg (*args, u8 **);
10736   u8 *match = 0;
10737   u8 src = 0;
10738   u8 src_val[6];
10739   u8 dst = 0;
10740   u8 dst_val[6];
10741   u8 proto = 0;
10742   u16 proto_val;
10743   u8 tag1 = 0;
10744   u8 tag1_val[2];
10745   u8 tag2 = 0;
10746   u8 tag2_val[2];
10747   int len = 14;
10748   u8 ignore_tag1 = 0;
10749   u8 ignore_tag2 = 0;
10750   u8 cos1 = 0;
10751   u8 cos2 = 0;
10752   u32 cos1_val = 0;
10753   u32 cos2_val = 0;
10754
10755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10756     {
10757       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10758         src = 1;
10759       else
10760         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10761         dst = 1;
10762       else if (unformat (input, "proto %U",
10763                          unformat_ethernet_type_host_byte_order, &proto_val))
10764         proto = 1;
10765       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10766         tag1 = 1;
10767       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10768         tag2 = 1;
10769       else if (unformat (input, "ignore-tag1"))
10770         ignore_tag1 = 1;
10771       else if (unformat (input, "ignore-tag2"))
10772         ignore_tag2 = 1;
10773       else if (unformat (input, "cos1 %d", &cos1_val))
10774         cos1 = 1;
10775       else if (unformat (input, "cos2 %d", &cos2_val))
10776         cos2 = 1;
10777       else
10778         break;
10779     }
10780   if ((src + dst + proto + tag1 + tag2 +
10781        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10782     return 0;
10783
10784   if (tag1 || ignore_tag1 || cos1)
10785     len = 18;
10786   if (tag2 || ignore_tag2 || cos2)
10787     len = 22;
10788
10789   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10790
10791   if (dst)
10792     clib_memcpy (match, dst_val, 6);
10793
10794   if (src)
10795     clib_memcpy (match + 6, src_val, 6);
10796
10797   if (tag2)
10798     {
10799       /* inner vlan tag */
10800       match[19] = tag2_val[1];
10801       match[18] = tag2_val[0];
10802       if (cos2)
10803         match[18] |= (cos2_val & 0x7) << 5;
10804       if (proto)
10805         {
10806           match[21] = proto_val & 0xff;
10807           match[20] = proto_val >> 8;
10808         }
10809       if (tag1)
10810         {
10811           match[15] = tag1_val[1];
10812           match[14] = tag1_val[0];
10813         }
10814       if (cos1)
10815         match[14] |= (cos1_val & 0x7) << 5;
10816       *matchp = match;
10817       return 1;
10818     }
10819   if (tag1)
10820     {
10821       match[15] = tag1_val[1];
10822       match[14] = tag1_val[0];
10823       if (proto)
10824         {
10825           match[17] = proto_val & 0xff;
10826           match[16] = proto_val >> 8;
10827         }
10828       if (cos1)
10829         match[14] |= (cos1_val & 0x7) << 5;
10830
10831       *matchp = match;
10832       return 1;
10833     }
10834   if (cos2)
10835     match[18] |= (cos2_val & 0x7) << 5;
10836   if (cos1)
10837     match[14] |= (cos1_val & 0x7) << 5;
10838   if (proto)
10839     {
10840       match[13] = proto_val & 0xff;
10841       match[12] = proto_val >> 8;
10842     }
10843
10844   *matchp = match;
10845   return 1;
10846 }
10847 #endif
10848
10849 uword
10850 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10851 {
10852   u8 **matchp = va_arg (*args, u8 **);
10853   u32 skip_n_vectors = va_arg (*args, u32);
10854   u32 match_n_vectors = va_arg (*args, u32);
10855
10856   u8 *match = 0;
10857   u8 *l2 = 0;
10858   u8 *l3 = 0;
10859   u8 *l4 = 0;
10860
10861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10862     {
10863       if (unformat (input, "hex %U", unformat_hex_string, &match))
10864         ;
10865       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10866         ;
10867       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10868         ;
10869       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10870         ;
10871       else
10872         break;
10873     }
10874
10875   if (l4 && !l3)
10876     {
10877       vec_free (match);
10878       vec_free (l2);
10879       vec_free (l4);
10880       return 0;
10881     }
10882
10883   if (match || l2 || l3 || l4)
10884     {
10885       if (l2 || l3 || l4)
10886         {
10887           /* "Win a free Ethernet header in every packet" */
10888           if (l2 == 0)
10889             vec_validate_aligned (l2, 13, sizeof (u32x4));
10890           match = l2;
10891           if (vec_len (l3))
10892             {
10893               vec_append_aligned (match, l3, sizeof (u32x4));
10894               vec_free (l3);
10895             }
10896           if (vec_len (l4))
10897             {
10898               vec_append_aligned (match, l4, sizeof (u32x4));
10899               vec_free (l4);
10900             }
10901         }
10902
10903       /* Make sure the vector is big enough even if key is all 0's */
10904       vec_validate_aligned
10905         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10906          sizeof (u32x4));
10907
10908       /* Set size, include skipped vectors */
10909       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10910
10911       *matchp = match;
10912
10913       return 1;
10914     }
10915
10916   return 0;
10917 }
10918
10919 static int
10920 api_classify_add_del_session (vat_main_t * vam)
10921 {
10922   unformat_input_t *i = vam->input;
10923   vl_api_classify_add_del_session_t *mp;
10924   int is_add = 1;
10925   u32 table_index = ~0;
10926   u32 hit_next_index = ~0;
10927   u32 opaque_index = ~0;
10928   u8 *match = 0;
10929   i32 advance = 0;
10930   u32 skip_n_vectors = 0;
10931   u32 match_n_vectors = 0;
10932   u32 action = 0;
10933   u32 metadata = 0;
10934   int ret;
10935
10936   /*
10937    * Warning: you have to supply skip_n and match_n
10938    * because the API client cant simply look at the classify
10939    * table object.
10940    */
10941
10942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10943     {
10944       if (unformat (i, "del"))
10945         is_add = 0;
10946       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10947                          &hit_next_index))
10948         ;
10949       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10950                          &hit_next_index))
10951         ;
10952       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10953                          &hit_next_index))
10954         ;
10955       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10956         ;
10957       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10958         ;
10959       else if (unformat (i, "opaque-index %d", &opaque_index))
10960         ;
10961       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10962         ;
10963       else if (unformat (i, "match_n %d", &match_n_vectors))
10964         ;
10965       else if (unformat (i, "match %U", api_unformat_classify_match,
10966                          &match, skip_n_vectors, match_n_vectors))
10967         ;
10968       else if (unformat (i, "advance %d", &advance))
10969         ;
10970       else if (unformat (i, "table-index %d", &table_index))
10971         ;
10972       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10973         action = 1;
10974       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10975         action = 2;
10976       else if (unformat (i, "action %d", &action))
10977         ;
10978       else if (unformat (i, "metadata %d", &metadata))
10979         ;
10980       else
10981         break;
10982     }
10983
10984   if (table_index == ~0)
10985     {
10986       errmsg ("Table index required");
10987       return -99;
10988     }
10989
10990   if (is_add && match == 0)
10991     {
10992       errmsg ("Match value required");
10993       return -99;
10994     }
10995
10996   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10997
10998   mp->is_add = is_add;
10999   mp->table_index = ntohl (table_index);
11000   mp->hit_next_index = ntohl (hit_next_index);
11001   mp->opaque_index = ntohl (opaque_index);
11002   mp->advance = ntohl (advance);
11003   mp->action = action;
11004   mp->metadata = ntohl (metadata);
11005   clib_memcpy (mp->match, match, vec_len (match));
11006   vec_free (match);
11007
11008   S (mp);
11009   W (ret);
11010   return ret;
11011 }
11012
11013 static int
11014 api_classify_set_interface_ip_table (vat_main_t * vam)
11015 {
11016   unformat_input_t *i = vam->input;
11017   vl_api_classify_set_interface_ip_table_t *mp;
11018   u32 sw_if_index;
11019   int sw_if_index_set;
11020   u32 table_index = ~0;
11021   u8 is_ipv6 = 0;
11022   int ret;
11023
11024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11025     {
11026       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11027         sw_if_index_set = 1;
11028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11029         sw_if_index_set = 1;
11030       else if (unformat (i, "table %d", &table_index))
11031         ;
11032       else
11033         {
11034           clib_warning ("parse error '%U'", format_unformat_error, i);
11035           return -99;
11036         }
11037     }
11038
11039   if (sw_if_index_set == 0)
11040     {
11041       errmsg ("missing interface name or sw_if_index");
11042       return -99;
11043     }
11044
11045
11046   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11047
11048   mp->sw_if_index = ntohl (sw_if_index);
11049   mp->table_index = ntohl (table_index);
11050   mp->is_ipv6 = is_ipv6;
11051
11052   S (mp);
11053   W (ret);
11054   return ret;
11055 }
11056
11057 static int
11058 api_classify_set_interface_l2_tables (vat_main_t * vam)
11059 {
11060   unformat_input_t *i = vam->input;
11061   vl_api_classify_set_interface_l2_tables_t *mp;
11062   u32 sw_if_index;
11063   int sw_if_index_set;
11064   u32 ip4_table_index = ~0;
11065   u32 ip6_table_index = ~0;
11066   u32 other_table_index = ~0;
11067   u32 is_input = 1;
11068   int ret;
11069
11070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11071     {
11072       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11073         sw_if_index_set = 1;
11074       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11075         sw_if_index_set = 1;
11076       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11077         ;
11078       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11079         ;
11080       else if (unformat (i, "other-table %d", &other_table_index))
11081         ;
11082       else if (unformat (i, "is-input %d", &is_input))
11083         ;
11084       else
11085         {
11086           clib_warning ("parse error '%U'", format_unformat_error, i);
11087           return -99;
11088         }
11089     }
11090
11091   if (sw_if_index_set == 0)
11092     {
11093       errmsg ("missing interface name or sw_if_index");
11094       return -99;
11095     }
11096
11097
11098   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11099
11100   mp->sw_if_index = ntohl (sw_if_index);
11101   mp->ip4_table_index = ntohl (ip4_table_index);
11102   mp->ip6_table_index = ntohl (ip6_table_index);
11103   mp->other_table_index = ntohl (other_table_index);
11104   mp->is_input = (u8) is_input;
11105
11106   S (mp);
11107   W (ret);
11108   return ret;
11109 }
11110
11111 static int
11112 api_set_ipfix_exporter (vat_main_t * vam)
11113 {
11114   unformat_input_t *i = vam->input;
11115   vl_api_set_ipfix_exporter_t *mp;
11116   ip4_address_t collector_address;
11117   u8 collector_address_set = 0;
11118   u32 collector_port = ~0;
11119   ip4_address_t src_address;
11120   u8 src_address_set = 0;
11121   u32 vrf_id = ~0;
11122   u32 path_mtu = ~0;
11123   u32 template_interval = ~0;
11124   u8 udp_checksum = 0;
11125   int ret;
11126
11127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11128     {
11129       if (unformat (i, "collector_address %U", unformat_ip4_address,
11130                     &collector_address))
11131         collector_address_set = 1;
11132       else if (unformat (i, "collector_port %d", &collector_port))
11133         ;
11134       else if (unformat (i, "src_address %U", unformat_ip4_address,
11135                          &src_address))
11136         src_address_set = 1;
11137       else if (unformat (i, "vrf_id %d", &vrf_id))
11138         ;
11139       else if (unformat (i, "path_mtu %d", &path_mtu))
11140         ;
11141       else if (unformat (i, "template_interval %d", &template_interval))
11142         ;
11143       else if (unformat (i, "udp_checksum"))
11144         udp_checksum = 1;
11145       else
11146         break;
11147     }
11148
11149   if (collector_address_set == 0)
11150     {
11151       errmsg ("collector_address required");
11152       return -99;
11153     }
11154
11155   if (src_address_set == 0)
11156     {
11157       errmsg ("src_address required");
11158       return -99;
11159     }
11160
11161   M (SET_IPFIX_EXPORTER, mp);
11162
11163   memcpy (mp->collector_address, collector_address.data,
11164           sizeof (collector_address.data));
11165   mp->collector_port = htons ((u16) collector_port);
11166   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11167   mp->vrf_id = htonl (vrf_id);
11168   mp->path_mtu = htonl (path_mtu);
11169   mp->template_interval = htonl (template_interval);
11170   mp->udp_checksum = udp_checksum;
11171
11172   S (mp);
11173   W (ret);
11174   return ret;
11175 }
11176
11177 static int
11178 api_set_ipfix_classify_stream (vat_main_t * vam)
11179 {
11180   unformat_input_t *i = vam->input;
11181   vl_api_set_ipfix_classify_stream_t *mp;
11182   u32 domain_id = 0;
11183   u32 src_port = UDP_DST_PORT_ipfix;
11184   int ret;
11185
11186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11187     {
11188       if (unformat (i, "domain %d", &domain_id))
11189         ;
11190       else if (unformat (i, "src_port %d", &src_port))
11191         ;
11192       else
11193         {
11194           errmsg ("unknown input `%U'", format_unformat_error, i);
11195           return -99;
11196         }
11197     }
11198
11199   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11200
11201   mp->domain_id = htonl (domain_id);
11202   mp->src_port = htons ((u16) src_port);
11203
11204   S (mp);
11205   W (ret);
11206   return ret;
11207 }
11208
11209 static int
11210 api_ipfix_classify_table_add_del (vat_main_t * vam)
11211 {
11212   unformat_input_t *i = vam->input;
11213   vl_api_ipfix_classify_table_add_del_t *mp;
11214   int is_add = -1;
11215   u32 classify_table_index = ~0;
11216   u8 ip_version = 0;
11217   u8 transport_protocol = 255;
11218   int ret;
11219
11220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11221     {
11222       if (unformat (i, "add"))
11223         is_add = 1;
11224       else if (unformat (i, "del"))
11225         is_add = 0;
11226       else if (unformat (i, "table %d", &classify_table_index))
11227         ;
11228       else if (unformat (i, "ip4"))
11229         ip_version = 4;
11230       else if (unformat (i, "ip6"))
11231         ip_version = 6;
11232       else if (unformat (i, "tcp"))
11233         transport_protocol = 6;
11234       else if (unformat (i, "udp"))
11235         transport_protocol = 17;
11236       else
11237         {
11238           errmsg ("unknown input `%U'", format_unformat_error, i);
11239           return -99;
11240         }
11241     }
11242
11243   if (is_add == -1)
11244     {
11245       errmsg ("expecting: add|del");
11246       return -99;
11247     }
11248   if (classify_table_index == ~0)
11249     {
11250       errmsg ("classifier table not specified");
11251       return -99;
11252     }
11253   if (ip_version == 0)
11254     {
11255       errmsg ("IP version not specified");
11256       return -99;
11257     }
11258
11259   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11260
11261   mp->is_add = is_add;
11262   mp->table_id = htonl (classify_table_index);
11263   mp->ip_version = ip_version;
11264   mp->transport_protocol = transport_protocol;
11265
11266   S (mp);
11267   W (ret);
11268   return ret;
11269 }
11270
11271 static int
11272 api_get_node_index (vat_main_t * vam)
11273 {
11274   unformat_input_t *i = vam->input;
11275   vl_api_get_node_index_t *mp;
11276   u8 *name = 0;
11277   int ret;
11278
11279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11280     {
11281       if (unformat (i, "node %s", &name))
11282         ;
11283       else
11284         break;
11285     }
11286   if (name == 0)
11287     {
11288       errmsg ("node name required");
11289       return -99;
11290     }
11291   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11292     {
11293       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11294       return -99;
11295     }
11296
11297   M (GET_NODE_INDEX, mp);
11298   clib_memcpy (mp->node_name, name, vec_len (name));
11299   vec_free (name);
11300
11301   S (mp);
11302   W (ret);
11303   return ret;
11304 }
11305
11306 static int
11307 api_get_next_index (vat_main_t * vam)
11308 {
11309   unformat_input_t *i = vam->input;
11310   vl_api_get_next_index_t *mp;
11311   u8 *node_name = 0, *next_node_name = 0;
11312   int ret;
11313
11314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11315     {
11316       if (unformat (i, "node-name %s", &node_name))
11317         ;
11318       else if (unformat (i, "next-node-name %s", &next_node_name))
11319         break;
11320     }
11321
11322   if (node_name == 0)
11323     {
11324       errmsg ("node name required");
11325       return -99;
11326     }
11327   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11328     {
11329       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11330       return -99;
11331     }
11332
11333   if (next_node_name == 0)
11334     {
11335       errmsg ("next node name required");
11336       return -99;
11337     }
11338   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11339     {
11340       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11341       return -99;
11342     }
11343
11344   M (GET_NEXT_INDEX, mp);
11345   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11346   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11347   vec_free (node_name);
11348   vec_free (next_node_name);
11349
11350   S (mp);
11351   W (ret);
11352   return ret;
11353 }
11354
11355 static int
11356 api_add_node_next (vat_main_t * vam)
11357 {
11358   unformat_input_t *i = vam->input;
11359   vl_api_add_node_next_t *mp;
11360   u8 *name = 0;
11361   u8 *next = 0;
11362   int ret;
11363
11364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11365     {
11366       if (unformat (i, "node %s", &name))
11367         ;
11368       else if (unformat (i, "next %s", &next))
11369         ;
11370       else
11371         break;
11372     }
11373   if (name == 0)
11374     {
11375       errmsg ("node name required");
11376       return -99;
11377     }
11378   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11379     {
11380       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11381       return -99;
11382     }
11383   if (next == 0)
11384     {
11385       errmsg ("next node required");
11386       return -99;
11387     }
11388   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11389     {
11390       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11391       return -99;
11392     }
11393
11394   M (ADD_NODE_NEXT, mp);
11395   clib_memcpy (mp->node_name, name, vec_len (name));
11396   clib_memcpy (mp->next_name, next, vec_len (next));
11397   vec_free (name);
11398   vec_free (next);
11399
11400   S (mp);
11401   W (ret);
11402   return ret;
11403 }
11404
11405 static int
11406 api_l2tpv3_create_tunnel (vat_main_t * vam)
11407 {
11408   unformat_input_t *i = vam->input;
11409   ip6_address_t client_address, our_address;
11410   int client_address_set = 0;
11411   int our_address_set = 0;
11412   u32 local_session_id = 0;
11413   u32 remote_session_id = 0;
11414   u64 local_cookie = 0;
11415   u64 remote_cookie = 0;
11416   u8 l2_sublayer_present = 0;
11417   vl_api_l2tpv3_create_tunnel_t *mp;
11418   int ret;
11419
11420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11421     {
11422       if (unformat (i, "client_address %U", unformat_ip6_address,
11423                     &client_address))
11424         client_address_set = 1;
11425       else if (unformat (i, "our_address %U", unformat_ip6_address,
11426                          &our_address))
11427         our_address_set = 1;
11428       else if (unformat (i, "local_session_id %d", &local_session_id))
11429         ;
11430       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11431         ;
11432       else if (unformat (i, "local_cookie %lld", &local_cookie))
11433         ;
11434       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11435         ;
11436       else if (unformat (i, "l2-sublayer-present"))
11437         l2_sublayer_present = 1;
11438       else
11439         break;
11440     }
11441
11442   if (client_address_set == 0)
11443     {
11444       errmsg ("client_address required");
11445       return -99;
11446     }
11447
11448   if (our_address_set == 0)
11449     {
11450       errmsg ("our_address required");
11451       return -99;
11452     }
11453
11454   M (L2TPV3_CREATE_TUNNEL, mp);
11455
11456   clib_memcpy (mp->client_address, client_address.as_u8,
11457                sizeof (mp->client_address));
11458
11459   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11460
11461   mp->local_session_id = ntohl (local_session_id);
11462   mp->remote_session_id = ntohl (remote_session_id);
11463   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11464   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11465   mp->l2_sublayer_present = l2_sublayer_present;
11466   mp->is_ipv6 = 1;
11467
11468   S (mp);
11469   W (ret);
11470   return ret;
11471 }
11472
11473 static int
11474 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11475 {
11476   unformat_input_t *i = vam->input;
11477   u32 sw_if_index;
11478   u8 sw_if_index_set = 0;
11479   u64 new_local_cookie = 0;
11480   u64 new_remote_cookie = 0;
11481   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11482   int ret;
11483
11484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11485     {
11486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11487         sw_if_index_set = 1;
11488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11489         sw_if_index_set = 1;
11490       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11491         ;
11492       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11493         ;
11494       else
11495         break;
11496     }
11497
11498   if (sw_if_index_set == 0)
11499     {
11500       errmsg ("missing interface name or sw_if_index");
11501       return -99;
11502     }
11503
11504   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11505
11506   mp->sw_if_index = ntohl (sw_if_index);
11507   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11508   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11509
11510   S (mp);
11511   W (ret);
11512   return ret;
11513 }
11514
11515 static int
11516 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11517 {
11518   unformat_input_t *i = vam->input;
11519   vl_api_l2tpv3_interface_enable_disable_t *mp;
11520   u32 sw_if_index;
11521   u8 sw_if_index_set = 0;
11522   u8 enable_disable = 1;
11523   int ret;
11524
11525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11526     {
11527       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11528         sw_if_index_set = 1;
11529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11530         sw_if_index_set = 1;
11531       else if (unformat (i, "enable"))
11532         enable_disable = 1;
11533       else if (unformat (i, "disable"))
11534         enable_disable = 0;
11535       else
11536         break;
11537     }
11538
11539   if (sw_if_index_set == 0)
11540     {
11541       errmsg ("missing interface name or sw_if_index");
11542       return -99;
11543     }
11544
11545   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11546
11547   mp->sw_if_index = ntohl (sw_if_index);
11548   mp->enable_disable = enable_disable;
11549
11550   S (mp);
11551   W (ret);
11552   return ret;
11553 }
11554
11555 static int
11556 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11557 {
11558   unformat_input_t *i = vam->input;
11559   vl_api_l2tpv3_set_lookup_key_t *mp;
11560   u8 key = ~0;
11561   int ret;
11562
11563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11564     {
11565       if (unformat (i, "lookup_v6_src"))
11566         key = L2T_LOOKUP_SRC_ADDRESS;
11567       else if (unformat (i, "lookup_v6_dst"))
11568         key = L2T_LOOKUP_DST_ADDRESS;
11569       else if (unformat (i, "lookup_session_id"))
11570         key = L2T_LOOKUP_SESSION_ID;
11571       else
11572         break;
11573     }
11574
11575   if (key == (u8) ~ 0)
11576     {
11577       errmsg ("l2tp session lookup key unset");
11578       return -99;
11579     }
11580
11581   M (L2TPV3_SET_LOOKUP_KEY, mp);
11582
11583   mp->key = key;
11584
11585   S (mp);
11586   W (ret);
11587   return ret;
11588 }
11589
11590 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11591   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11592 {
11593   vat_main_t *vam = &vat_main;
11594
11595   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11596          format_ip6_address, mp->our_address,
11597          format_ip6_address, mp->client_address,
11598          clib_net_to_host_u32 (mp->sw_if_index));
11599
11600   print (vam->ofp,
11601          "   local cookies %016llx %016llx remote cookie %016llx",
11602          clib_net_to_host_u64 (mp->local_cookie[0]),
11603          clib_net_to_host_u64 (mp->local_cookie[1]),
11604          clib_net_to_host_u64 (mp->remote_cookie));
11605
11606   print (vam->ofp, "   local session-id %d remote session-id %d",
11607          clib_net_to_host_u32 (mp->local_session_id),
11608          clib_net_to_host_u32 (mp->remote_session_id));
11609
11610   print (vam->ofp, "   l2 specific sublayer %s\n",
11611          mp->l2_sublayer_present ? "preset" : "absent");
11612
11613 }
11614
11615 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11616   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11617 {
11618   vat_main_t *vam = &vat_main;
11619   vat_json_node_t *node = NULL;
11620   struct in6_addr addr;
11621
11622   if (VAT_JSON_ARRAY != vam->json_tree.type)
11623     {
11624       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11625       vat_json_init_array (&vam->json_tree);
11626     }
11627   node = vat_json_array_add (&vam->json_tree);
11628
11629   vat_json_init_object (node);
11630
11631   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11632   vat_json_object_add_ip6 (node, "our_address", addr);
11633   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11634   vat_json_object_add_ip6 (node, "client_address", addr);
11635
11636   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11637   vat_json_init_array (lc);
11638   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11639   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11640   vat_json_object_add_uint (node, "remote_cookie",
11641                             clib_net_to_host_u64 (mp->remote_cookie));
11642
11643   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11644   vat_json_object_add_uint (node, "local_session_id",
11645                             clib_net_to_host_u32 (mp->local_session_id));
11646   vat_json_object_add_uint (node, "remote_session_id",
11647                             clib_net_to_host_u32 (mp->remote_session_id));
11648   vat_json_object_add_string_copy (node, "l2_sublayer",
11649                                    mp->l2_sublayer_present ? (u8 *) "present"
11650                                    : (u8 *) "absent");
11651 }
11652
11653 static int
11654 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11655 {
11656   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11657   vl_api_control_ping_t *mp_ping;
11658   int ret;
11659
11660   /* Get list of l2tpv3-tunnel interfaces */
11661   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11662   S (mp);
11663
11664   /* Use a control ping for synchronization */
11665   MPING (CONTROL_PING, mp_ping);
11666   S (mp_ping);
11667
11668   W (ret);
11669   return ret;
11670 }
11671
11672
11673 static void vl_api_sw_interface_tap_details_t_handler
11674   (vl_api_sw_interface_tap_details_t * mp)
11675 {
11676   vat_main_t *vam = &vat_main;
11677
11678   print (vam->ofp, "%-16s %d",
11679          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11680 }
11681
11682 static void vl_api_sw_interface_tap_details_t_handler_json
11683   (vl_api_sw_interface_tap_details_t * mp)
11684 {
11685   vat_main_t *vam = &vat_main;
11686   vat_json_node_t *node = NULL;
11687
11688   if (VAT_JSON_ARRAY != vam->json_tree.type)
11689     {
11690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11691       vat_json_init_array (&vam->json_tree);
11692     }
11693   node = vat_json_array_add (&vam->json_tree);
11694
11695   vat_json_init_object (node);
11696   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11697   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11698 }
11699
11700 static int
11701 api_sw_interface_tap_dump (vat_main_t * vam)
11702 {
11703   vl_api_sw_interface_tap_dump_t *mp;
11704   vl_api_control_ping_t *mp_ping;
11705   int ret;
11706
11707   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11708   /* Get list of tap interfaces */
11709   M (SW_INTERFACE_TAP_DUMP, mp);
11710   S (mp);
11711
11712   /* Use a control ping for synchronization */
11713   MPING (CONTROL_PING, mp_ping);
11714   S (mp_ping);
11715
11716   W (ret);
11717   return ret;
11718 }
11719
11720 static uword unformat_vxlan_decap_next
11721   (unformat_input_t * input, va_list * args)
11722 {
11723   u32 *result = va_arg (*args, u32 *);
11724   u32 tmp;
11725
11726   if (unformat (input, "l2"))
11727     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11728   else if (unformat (input, "%d", &tmp))
11729     *result = tmp;
11730   else
11731     return 0;
11732   return 1;
11733 }
11734
11735 static int
11736 api_vxlan_add_del_tunnel (vat_main_t * vam)
11737 {
11738   unformat_input_t *line_input = vam->input;
11739   vl_api_vxlan_add_del_tunnel_t *mp;
11740   ip46_address_t src, dst;
11741   u8 is_add = 1;
11742   u8 ipv4_set = 0, ipv6_set = 0;
11743   u8 src_set = 0;
11744   u8 dst_set = 0;
11745   u8 grp_set = 0;
11746   u32 mcast_sw_if_index = ~0;
11747   u32 encap_vrf_id = 0;
11748   u32 decap_next_index = ~0;
11749   u32 vni = 0;
11750   int ret;
11751
11752   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11753   memset (&src, 0, sizeof src);
11754   memset (&dst, 0, sizeof dst);
11755
11756   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11757     {
11758       if (unformat (line_input, "del"))
11759         is_add = 0;
11760       else
11761         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11762         {
11763           ipv4_set = 1;
11764           src_set = 1;
11765         }
11766       else
11767         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11768         {
11769           ipv4_set = 1;
11770           dst_set = 1;
11771         }
11772       else
11773         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11774         {
11775           ipv6_set = 1;
11776           src_set = 1;
11777         }
11778       else
11779         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11780         {
11781           ipv6_set = 1;
11782           dst_set = 1;
11783         }
11784       else if (unformat (line_input, "group %U %U",
11785                          unformat_ip4_address, &dst.ip4,
11786                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11787         {
11788           grp_set = dst_set = 1;
11789           ipv4_set = 1;
11790         }
11791       else if (unformat (line_input, "group %U",
11792                          unformat_ip4_address, &dst.ip4))
11793         {
11794           grp_set = dst_set = 1;
11795           ipv4_set = 1;
11796         }
11797       else if (unformat (line_input, "group %U %U",
11798                          unformat_ip6_address, &dst.ip6,
11799                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11800         {
11801           grp_set = dst_set = 1;
11802           ipv6_set = 1;
11803         }
11804       else if (unformat (line_input, "group %U",
11805                          unformat_ip6_address, &dst.ip6))
11806         {
11807           grp_set = dst_set = 1;
11808           ipv6_set = 1;
11809         }
11810       else
11811         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11812         ;
11813       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11814         ;
11815       else if (unformat (line_input, "decap-next %U",
11816                          unformat_vxlan_decap_next, &decap_next_index))
11817         ;
11818       else if (unformat (line_input, "vni %d", &vni))
11819         ;
11820       else
11821         {
11822           errmsg ("parse error '%U'", format_unformat_error, line_input);
11823           return -99;
11824         }
11825     }
11826
11827   if (src_set == 0)
11828     {
11829       errmsg ("tunnel src address not specified");
11830       return -99;
11831     }
11832   if (dst_set == 0)
11833     {
11834       errmsg ("tunnel dst address not specified");
11835       return -99;
11836     }
11837
11838   if (grp_set && !ip46_address_is_multicast (&dst))
11839     {
11840       errmsg ("tunnel group address not multicast");
11841       return -99;
11842     }
11843   if (grp_set && mcast_sw_if_index == ~0)
11844     {
11845       errmsg ("tunnel nonexistent multicast device");
11846       return -99;
11847     }
11848   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11849     {
11850       errmsg ("tunnel dst address must be unicast");
11851       return -99;
11852     }
11853
11854
11855   if (ipv4_set && ipv6_set)
11856     {
11857       errmsg ("both IPv4 and IPv6 addresses specified");
11858       return -99;
11859     }
11860
11861   if ((vni == 0) || (vni >> 24))
11862     {
11863       errmsg ("vni not specified or out of range");
11864       return -99;
11865     }
11866
11867   M (VXLAN_ADD_DEL_TUNNEL, mp);
11868
11869   if (ipv6_set)
11870     {
11871       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11872       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11873     }
11874   else
11875     {
11876       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11877       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11878     }
11879   mp->encap_vrf_id = ntohl (encap_vrf_id);
11880   mp->decap_next_index = ntohl (decap_next_index);
11881   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11882   mp->vni = ntohl (vni);
11883   mp->is_add = is_add;
11884   mp->is_ipv6 = ipv6_set;
11885
11886   S (mp);
11887   W (ret);
11888   return ret;
11889 }
11890
11891 static void vl_api_vxlan_tunnel_details_t_handler
11892   (vl_api_vxlan_tunnel_details_t * mp)
11893 {
11894   vat_main_t *vam = &vat_main;
11895   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11896   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11897
11898   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11899          ntohl (mp->sw_if_index),
11900          format_ip46_address, &src, IP46_TYPE_ANY,
11901          format_ip46_address, &dst, IP46_TYPE_ANY,
11902          ntohl (mp->encap_vrf_id),
11903          ntohl (mp->decap_next_index), ntohl (mp->vni),
11904          ntohl (mp->mcast_sw_if_index));
11905 }
11906
11907 static void vl_api_vxlan_tunnel_details_t_handler_json
11908   (vl_api_vxlan_tunnel_details_t * mp)
11909 {
11910   vat_main_t *vam = &vat_main;
11911   vat_json_node_t *node = NULL;
11912
11913   if (VAT_JSON_ARRAY != vam->json_tree.type)
11914     {
11915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11916       vat_json_init_array (&vam->json_tree);
11917     }
11918   node = vat_json_array_add (&vam->json_tree);
11919
11920   vat_json_init_object (node);
11921   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11922   if (mp->is_ipv6)
11923     {
11924       struct in6_addr ip6;
11925
11926       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11927       vat_json_object_add_ip6 (node, "src_address", ip6);
11928       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11929       vat_json_object_add_ip6 (node, "dst_address", ip6);
11930     }
11931   else
11932     {
11933       struct in_addr ip4;
11934
11935       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11936       vat_json_object_add_ip4 (node, "src_address", ip4);
11937       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11938       vat_json_object_add_ip4 (node, "dst_address", ip4);
11939     }
11940   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11941   vat_json_object_add_uint (node, "decap_next_index",
11942                             ntohl (mp->decap_next_index));
11943   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11944   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11945   vat_json_object_add_uint (node, "mcast_sw_if_index",
11946                             ntohl (mp->mcast_sw_if_index));
11947 }
11948
11949 static int
11950 api_vxlan_tunnel_dump (vat_main_t * vam)
11951 {
11952   unformat_input_t *i = vam->input;
11953   vl_api_vxlan_tunnel_dump_t *mp;
11954   vl_api_control_ping_t *mp_ping;
11955   u32 sw_if_index;
11956   u8 sw_if_index_set = 0;
11957   int ret;
11958
11959   /* Parse args required to build the message */
11960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11961     {
11962       if (unformat (i, "sw_if_index %d", &sw_if_index))
11963         sw_if_index_set = 1;
11964       else
11965         break;
11966     }
11967
11968   if (sw_if_index_set == 0)
11969     {
11970       sw_if_index = ~0;
11971     }
11972
11973   if (!vam->json_output)
11974     {
11975       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11976              "sw_if_index", "src_address", "dst_address",
11977              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11978     }
11979
11980   /* Get list of vxlan-tunnel interfaces */
11981   M (VXLAN_TUNNEL_DUMP, mp);
11982
11983   mp->sw_if_index = htonl (sw_if_index);
11984
11985   S (mp);
11986
11987   /* Use a control ping for synchronization */
11988   MPING (CONTROL_PING, mp_ping);
11989   S (mp_ping);
11990
11991   W (ret);
11992   return ret;
11993 }
11994
11995 static int
11996 api_gre_add_del_tunnel (vat_main_t * vam)
11997 {
11998   unformat_input_t *line_input = vam->input;
11999   vl_api_gre_add_del_tunnel_t *mp;
12000   ip4_address_t src4, dst4;
12001   ip6_address_t src6, dst6;
12002   u8 is_add = 1;
12003   u8 ipv4_set = 0;
12004   u8 ipv6_set = 0;
12005   u8 teb = 0;
12006   u8 src_set = 0;
12007   u8 dst_set = 0;
12008   u32 outer_fib_id = 0;
12009   int ret;
12010
12011   memset (&src4, 0, sizeof src4);
12012   memset (&dst4, 0, sizeof dst4);
12013   memset (&src6, 0, sizeof src6);
12014   memset (&dst6, 0, sizeof dst6);
12015
12016   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12017     {
12018       if (unformat (line_input, "del"))
12019         is_add = 0;
12020       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12021         {
12022           src_set = 1;
12023           ipv4_set = 1;
12024         }
12025       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12026         {
12027           dst_set = 1;
12028           ipv4_set = 1;
12029         }
12030       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12031         {
12032           src_set = 1;
12033           ipv6_set = 1;
12034         }
12035       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12036         {
12037           dst_set = 1;
12038           ipv6_set = 1;
12039         }
12040       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12041         ;
12042       else if (unformat (line_input, "teb"))
12043         teb = 1;
12044       else
12045         {
12046           errmsg ("parse error '%U'", format_unformat_error, line_input);
12047           return -99;
12048         }
12049     }
12050
12051   if (src_set == 0)
12052     {
12053       errmsg ("tunnel src address not specified");
12054       return -99;
12055     }
12056   if (dst_set == 0)
12057     {
12058       errmsg ("tunnel dst address not specified");
12059       return -99;
12060     }
12061   if (ipv4_set && ipv6_set)
12062     {
12063       errmsg ("both IPv4 and IPv6 addresses specified");
12064       return -99;
12065     }
12066
12067
12068   M (GRE_ADD_DEL_TUNNEL, mp);
12069
12070   if (ipv4_set)
12071     {
12072       clib_memcpy (&mp->src_address, &src4, 4);
12073       clib_memcpy (&mp->dst_address, &dst4, 4);
12074     }
12075   else
12076     {
12077       clib_memcpy (&mp->src_address, &src6, 16);
12078       clib_memcpy (&mp->dst_address, &dst6, 16);
12079     }
12080   mp->outer_fib_id = ntohl (outer_fib_id);
12081   mp->is_add = is_add;
12082   mp->teb = teb;
12083   mp->is_ipv6 = ipv6_set;
12084
12085   S (mp);
12086   W (ret);
12087   return ret;
12088 }
12089
12090 static void vl_api_gre_tunnel_details_t_handler
12091   (vl_api_gre_tunnel_details_t * mp)
12092 {
12093   vat_main_t *vam = &vat_main;
12094   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12095   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12096
12097   print (vam->ofp, "%11d%24U%24U%6d%14d",
12098          ntohl (mp->sw_if_index),
12099          format_ip46_address, &src, IP46_TYPE_ANY,
12100          format_ip46_address, &dst, IP46_TYPE_ANY,
12101          mp->teb, ntohl (mp->outer_fib_id));
12102 }
12103
12104 static void vl_api_gre_tunnel_details_t_handler_json
12105   (vl_api_gre_tunnel_details_t * mp)
12106 {
12107   vat_main_t *vam = &vat_main;
12108   vat_json_node_t *node = NULL;
12109   struct in_addr ip4;
12110   struct in6_addr ip6;
12111
12112   if (VAT_JSON_ARRAY != vam->json_tree.type)
12113     {
12114       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12115       vat_json_init_array (&vam->json_tree);
12116     }
12117   node = vat_json_array_add (&vam->json_tree);
12118
12119   vat_json_init_object (node);
12120   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12121   if (!mp->is_ipv6)
12122     {
12123       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12124       vat_json_object_add_ip4 (node, "src_address", ip4);
12125       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12126       vat_json_object_add_ip4 (node, "dst_address", ip4);
12127     }
12128   else
12129     {
12130       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12131       vat_json_object_add_ip6 (node, "src_address", ip6);
12132       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12133       vat_json_object_add_ip6 (node, "dst_address", ip6);
12134     }
12135   vat_json_object_add_uint (node, "teb", mp->teb);
12136   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12137   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12138 }
12139
12140 static int
12141 api_gre_tunnel_dump (vat_main_t * vam)
12142 {
12143   unformat_input_t *i = vam->input;
12144   vl_api_gre_tunnel_dump_t *mp;
12145   vl_api_control_ping_t *mp_ping;
12146   u32 sw_if_index;
12147   u8 sw_if_index_set = 0;
12148   int ret;
12149
12150   /* Parse args required to build the message */
12151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12152     {
12153       if (unformat (i, "sw_if_index %d", &sw_if_index))
12154         sw_if_index_set = 1;
12155       else
12156         break;
12157     }
12158
12159   if (sw_if_index_set == 0)
12160     {
12161       sw_if_index = ~0;
12162     }
12163
12164   if (!vam->json_output)
12165     {
12166       print (vam->ofp, "%11s%24s%24s%6s%14s",
12167              "sw_if_index", "src_address", "dst_address", "teb",
12168              "outer_fib_id");
12169     }
12170
12171   /* Get list of gre-tunnel interfaces */
12172   M (GRE_TUNNEL_DUMP, mp);
12173
12174   mp->sw_if_index = htonl (sw_if_index);
12175
12176   S (mp);
12177
12178   /* Use a control ping for synchronization */
12179   MPING (CONTROL_PING, mp_ping);
12180   S (mp_ping);
12181
12182   W (ret);
12183   return ret;
12184 }
12185
12186 static int
12187 api_l2_fib_clear_table (vat_main_t * vam)
12188 {
12189 //  unformat_input_t * i = vam->input;
12190   vl_api_l2_fib_clear_table_t *mp;
12191   int ret;
12192
12193   M (L2_FIB_CLEAR_TABLE, mp);
12194
12195   S (mp);
12196   W (ret);
12197   return ret;
12198 }
12199
12200 static int
12201 api_l2_interface_efp_filter (vat_main_t * vam)
12202 {
12203   unformat_input_t *i = vam->input;
12204   vl_api_l2_interface_efp_filter_t *mp;
12205   u32 sw_if_index;
12206   u8 enable = 1;
12207   u8 sw_if_index_set = 0;
12208   int ret;
12209
12210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12211     {
12212       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12213         sw_if_index_set = 1;
12214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12215         sw_if_index_set = 1;
12216       else if (unformat (i, "enable"))
12217         enable = 1;
12218       else if (unformat (i, "disable"))
12219         enable = 0;
12220       else
12221         {
12222           clib_warning ("parse error '%U'", format_unformat_error, i);
12223           return -99;
12224         }
12225     }
12226
12227   if (sw_if_index_set == 0)
12228     {
12229       errmsg ("missing sw_if_index");
12230       return -99;
12231     }
12232
12233   M (L2_INTERFACE_EFP_FILTER, mp);
12234
12235   mp->sw_if_index = ntohl (sw_if_index);
12236   mp->enable_disable = enable;
12237
12238   S (mp);
12239   W (ret);
12240   return ret;
12241 }
12242
12243 #define foreach_vtr_op                          \
12244 _("disable",  L2_VTR_DISABLED)                  \
12245 _("push-1",  L2_VTR_PUSH_1)                     \
12246 _("push-2",  L2_VTR_PUSH_2)                     \
12247 _("pop-1",  L2_VTR_POP_1)                       \
12248 _("pop-2",  L2_VTR_POP_2)                       \
12249 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12250 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12251 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12252 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12253
12254 static int
12255 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12256 {
12257   unformat_input_t *i = vam->input;
12258   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12259   u32 sw_if_index;
12260   u8 sw_if_index_set = 0;
12261   u8 vtr_op_set = 0;
12262   u32 vtr_op = 0;
12263   u32 push_dot1q = 1;
12264   u32 tag1 = ~0;
12265   u32 tag2 = ~0;
12266   int ret;
12267
12268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12269     {
12270       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12271         sw_if_index_set = 1;
12272       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12273         sw_if_index_set = 1;
12274       else if (unformat (i, "vtr_op %d", &vtr_op))
12275         vtr_op_set = 1;
12276 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12277       foreach_vtr_op
12278 #undef _
12279         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12280         ;
12281       else if (unformat (i, "tag1 %d", &tag1))
12282         ;
12283       else if (unformat (i, "tag2 %d", &tag2))
12284         ;
12285       else
12286         {
12287           clib_warning ("parse error '%U'", format_unformat_error, i);
12288           return -99;
12289         }
12290     }
12291
12292   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12293     {
12294       errmsg ("missing vtr operation or sw_if_index");
12295       return -99;
12296     }
12297
12298   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12299   mp->sw_if_index = ntohl (sw_if_index);
12300   mp->vtr_op = ntohl (vtr_op);
12301   mp->push_dot1q = ntohl (push_dot1q);
12302   mp->tag1 = ntohl (tag1);
12303   mp->tag2 = ntohl (tag2);
12304
12305   S (mp);
12306   W (ret);
12307   return ret;
12308 }
12309
12310 static int
12311 api_create_vhost_user_if (vat_main_t * vam)
12312 {
12313   unformat_input_t *i = vam->input;
12314   vl_api_create_vhost_user_if_t *mp;
12315   u8 *file_name;
12316   u8 is_server = 0;
12317   u8 file_name_set = 0;
12318   u32 custom_dev_instance = ~0;
12319   u8 hwaddr[6];
12320   u8 use_custom_mac = 0;
12321   u8 *tag = 0;
12322   int ret;
12323
12324   /* Shut up coverity */
12325   memset (hwaddr, 0, sizeof (hwaddr));
12326
12327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12328     {
12329       if (unformat (i, "socket %s", &file_name))
12330         {
12331           file_name_set = 1;
12332         }
12333       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12334         ;
12335       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12336         use_custom_mac = 1;
12337       else if (unformat (i, "server"))
12338         is_server = 1;
12339       else if (unformat (i, "tag %s", &tag))
12340         ;
12341       else
12342         break;
12343     }
12344
12345   if (file_name_set == 0)
12346     {
12347       errmsg ("missing socket file name");
12348       return -99;
12349     }
12350
12351   if (vec_len (file_name) > 255)
12352     {
12353       errmsg ("socket file name too long");
12354       return -99;
12355     }
12356   vec_add1 (file_name, 0);
12357
12358   M (CREATE_VHOST_USER_IF, mp);
12359
12360   mp->is_server = is_server;
12361   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12362   vec_free (file_name);
12363   if (custom_dev_instance != ~0)
12364     {
12365       mp->renumber = 1;
12366       mp->custom_dev_instance = ntohl (custom_dev_instance);
12367     }
12368   mp->use_custom_mac = use_custom_mac;
12369   clib_memcpy (mp->mac_address, hwaddr, 6);
12370   if (tag)
12371     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12372   vec_free (tag);
12373
12374   S (mp);
12375   W (ret);
12376   return ret;
12377 }
12378
12379 static int
12380 api_modify_vhost_user_if (vat_main_t * vam)
12381 {
12382   unformat_input_t *i = vam->input;
12383   vl_api_modify_vhost_user_if_t *mp;
12384   u8 *file_name;
12385   u8 is_server = 0;
12386   u8 file_name_set = 0;
12387   u32 custom_dev_instance = ~0;
12388   u8 sw_if_index_set = 0;
12389   u32 sw_if_index = (u32) ~ 0;
12390   int ret;
12391
12392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12393     {
12394       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12395         sw_if_index_set = 1;
12396       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12397         sw_if_index_set = 1;
12398       else if (unformat (i, "socket %s", &file_name))
12399         {
12400           file_name_set = 1;
12401         }
12402       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12403         ;
12404       else if (unformat (i, "server"))
12405         is_server = 1;
12406       else
12407         break;
12408     }
12409
12410   if (sw_if_index_set == 0)
12411     {
12412       errmsg ("missing sw_if_index or interface name");
12413       return -99;
12414     }
12415
12416   if (file_name_set == 0)
12417     {
12418       errmsg ("missing socket file name");
12419       return -99;
12420     }
12421
12422   if (vec_len (file_name) > 255)
12423     {
12424       errmsg ("socket file name too long");
12425       return -99;
12426     }
12427   vec_add1 (file_name, 0);
12428
12429   M (MODIFY_VHOST_USER_IF, mp);
12430
12431   mp->sw_if_index = ntohl (sw_if_index);
12432   mp->is_server = is_server;
12433   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12434   vec_free (file_name);
12435   if (custom_dev_instance != ~0)
12436     {
12437       mp->renumber = 1;
12438       mp->custom_dev_instance = ntohl (custom_dev_instance);
12439     }
12440
12441   S (mp);
12442   W (ret);
12443   return ret;
12444 }
12445
12446 static int
12447 api_delete_vhost_user_if (vat_main_t * vam)
12448 {
12449   unformat_input_t *i = vam->input;
12450   vl_api_delete_vhost_user_if_t *mp;
12451   u32 sw_if_index = ~0;
12452   u8 sw_if_index_set = 0;
12453   int ret;
12454
12455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12456     {
12457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12458         sw_if_index_set = 1;
12459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12460         sw_if_index_set = 1;
12461       else
12462         break;
12463     }
12464
12465   if (sw_if_index_set == 0)
12466     {
12467       errmsg ("missing sw_if_index or interface name");
12468       return -99;
12469     }
12470
12471
12472   M (DELETE_VHOST_USER_IF, mp);
12473
12474   mp->sw_if_index = ntohl (sw_if_index);
12475
12476   S (mp);
12477   W (ret);
12478   return ret;
12479 }
12480
12481 static void vl_api_sw_interface_vhost_user_details_t_handler
12482   (vl_api_sw_interface_vhost_user_details_t * mp)
12483 {
12484   vat_main_t *vam = &vat_main;
12485
12486   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12487          (char *) mp->interface_name,
12488          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12489          clib_net_to_host_u64 (mp->features), mp->is_server,
12490          ntohl (mp->num_regions), (char *) mp->sock_filename);
12491   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12492 }
12493
12494 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12495   (vl_api_sw_interface_vhost_user_details_t * mp)
12496 {
12497   vat_main_t *vam = &vat_main;
12498   vat_json_node_t *node = NULL;
12499
12500   if (VAT_JSON_ARRAY != vam->json_tree.type)
12501     {
12502       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12503       vat_json_init_array (&vam->json_tree);
12504     }
12505   node = vat_json_array_add (&vam->json_tree);
12506
12507   vat_json_init_object (node);
12508   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12509   vat_json_object_add_string_copy (node, "interface_name",
12510                                    mp->interface_name);
12511   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12512                             ntohl (mp->virtio_net_hdr_sz));
12513   vat_json_object_add_uint (node, "features",
12514                             clib_net_to_host_u64 (mp->features));
12515   vat_json_object_add_uint (node, "is_server", mp->is_server);
12516   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12517   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12518   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12519 }
12520
12521 static int
12522 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12523 {
12524   vl_api_sw_interface_vhost_user_dump_t *mp;
12525   vl_api_control_ping_t *mp_ping;
12526   int ret;
12527   print (vam->ofp,
12528          "Interface name            idx hdr_sz features server regions filename");
12529
12530   /* Get list of vhost-user interfaces */
12531   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12532   S (mp);
12533
12534   /* Use a control ping for synchronization */
12535   MPING (CONTROL_PING, mp_ping);
12536   S (mp_ping);
12537
12538   W (ret);
12539   return ret;
12540 }
12541
12542 static int
12543 api_show_version (vat_main_t * vam)
12544 {
12545   vl_api_show_version_t *mp;
12546   int ret;
12547
12548   M (SHOW_VERSION, mp);
12549
12550   S (mp);
12551   W (ret);
12552   return ret;
12553 }
12554
12555
12556 static int
12557 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12558 {
12559   unformat_input_t *line_input = vam->input;
12560   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12561   ip4_address_t local4, remote4;
12562   ip6_address_t local6, remote6;
12563   u8 is_add = 1;
12564   u8 ipv4_set = 0, ipv6_set = 0;
12565   u8 local_set = 0;
12566   u8 remote_set = 0;
12567   u8 grp_set = 0;
12568   u32 mcast_sw_if_index = ~0;
12569   u32 encap_vrf_id = 0;
12570   u32 decap_vrf_id = 0;
12571   u8 protocol = ~0;
12572   u32 vni;
12573   u8 vni_set = 0;
12574   int ret;
12575
12576   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12577   memset (&local4, 0, sizeof local4);
12578   memset (&remote4, 0, sizeof remote4);
12579   memset (&local6, 0, sizeof local6);
12580   memset (&remote6, 0, sizeof remote6);
12581
12582   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12583     {
12584       if (unformat (line_input, "del"))
12585         is_add = 0;
12586       else if (unformat (line_input, "local %U",
12587                          unformat_ip4_address, &local4))
12588         {
12589           local_set = 1;
12590           ipv4_set = 1;
12591         }
12592       else if (unformat (line_input, "remote %U",
12593                          unformat_ip4_address, &remote4))
12594         {
12595           remote_set = 1;
12596           ipv4_set = 1;
12597         }
12598       else if (unformat (line_input, "local %U",
12599                          unformat_ip6_address, &local6))
12600         {
12601           local_set = 1;
12602           ipv6_set = 1;
12603         }
12604       else if (unformat (line_input, "remote %U",
12605                          unformat_ip6_address, &remote6))
12606         {
12607           remote_set = 1;
12608           ipv6_set = 1;
12609         }
12610       else if (unformat (line_input, "group %U %U",
12611                          unformat_ip4_address, &remote4,
12612                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12613         {
12614           grp_set = remote_set = 1;
12615           ipv4_set = 1;
12616         }
12617       else if (unformat (line_input, "group %U",
12618                          unformat_ip4_address, &remote4))
12619         {
12620           grp_set = remote_set = 1;
12621           ipv4_set = 1;
12622         }
12623       else if (unformat (line_input, "group %U %U",
12624                          unformat_ip6_address, &remote6,
12625                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12626         {
12627           grp_set = remote_set = 1;
12628           ipv6_set = 1;
12629         }
12630       else if (unformat (line_input, "group %U",
12631                          unformat_ip6_address, &remote6))
12632         {
12633           grp_set = remote_set = 1;
12634           ipv6_set = 1;
12635         }
12636       else
12637         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12638         ;
12639       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12640         ;
12641       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12642         ;
12643       else if (unformat (line_input, "vni %d", &vni))
12644         vni_set = 1;
12645       else if (unformat (line_input, "next-ip4"))
12646         protocol = 1;
12647       else if (unformat (line_input, "next-ip6"))
12648         protocol = 2;
12649       else if (unformat (line_input, "next-ethernet"))
12650         protocol = 3;
12651       else if (unformat (line_input, "next-nsh"))
12652         protocol = 4;
12653       else
12654         {
12655           errmsg ("parse error '%U'", format_unformat_error, line_input);
12656           return -99;
12657         }
12658     }
12659
12660   if (local_set == 0)
12661     {
12662       errmsg ("tunnel local address not specified");
12663       return -99;
12664     }
12665   if (remote_set == 0)
12666     {
12667       errmsg ("tunnel remote address not specified");
12668       return -99;
12669     }
12670   if (grp_set && mcast_sw_if_index == ~0)
12671     {
12672       errmsg ("tunnel nonexistent multicast device");
12673       return -99;
12674     }
12675   if (ipv4_set && ipv6_set)
12676     {
12677       errmsg ("both IPv4 and IPv6 addresses specified");
12678       return -99;
12679     }
12680
12681   if (vni_set == 0)
12682     {
12683       errmsg ("vni not specified");
12684       return -99;
12685     }
12686
12687   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12688
12689
12690   if (ipv6_set)
12691     {
12692       clib_memcpy (&mp->local, &local6, sizeof (local6));
12693       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12694     }
12695   else
12696     {
12697       clib_memcpy (&mp->local, &local4, sizeof (local4));
12698       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12699     }
12700
12701   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12702   mp->encap_vrf_id = ntohl (encap_vrf_id);
12703   mp->decap_vrf_id = ntohl (decap_vrf_id);
12704   mp->protocol = protocol;
12705   mp->vni = ntohl (vni);
12706   mp->is_add = is_add;
12707   mp->is_ipv6 = ipv6_set;
12708
12709   S (mp);
12710   W (ret);
12711   return ret;
12712 }
12713
12714 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12715   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12716 {
12717   vat_main_t *vam = &vat_main;
12718   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12719   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12720
12721   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12722          ntohl (mp->sw_if_index),
12723          format_ip46_address, &local, IP46_TYPE_ANY,
12724          format_ip46_address, &remote, IP46_TYPE_ANY,
12725          ntohl (mp->vni), mp->protocol,
12726          ntohl (mp->mcast_sw_if_index),
12727          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12728 }
12729
12730
12731 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12732   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12733 {
12734   vat_main_t *vam = &vat_main;
12735   vat_json_node_t *node = NULL;
12736   struct in_addr ip4;
12737   struct in6_addr ip6;
12738
12739   if (VAT_JSON_ARRAY != vam->json_tree.type)
12740     {
12741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12742       vat_json_init_array (&vam->json_tree);
12743     }
12744   node = vat_json_array_add (&vam->json_tree);
12745
12746   vat_json_init_object (node);
12747   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12748   if (mp->is_ipv6)
12749     {
12750       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12751       vat_json_object_add_ip6 (node, "local", ip6);
12752       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12753       vat_json_object_add_ip6 (node, "remote", ip6);
12754     }
12755   else
12756     {
12757       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12758       vat_json_object_add_ip4 (node, "local", ip4);
12759       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12760       vat_json_object_add_ip4 (node, "remote", ip4);
12761     }
12762   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12763   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12764   vat_json_object_add_uint (node, "mcast_sw_if_index",
12765                             ntohl (mp->mcast_sw_if_index));
12766   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12767   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12768   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12769 }
12770
12771 static int
12772 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12773 {
12774   unformat_input_t *i = vam->input;
12775   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12776   vl_api_control_ping_t *mp_ping;
12777   u32 sw_if_index;
12778   u8 sw_if_index_set = 0;
12779   int ret;
12780
12781   /* Parse args required to build the message */
12782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12783     {
12784       if (unformat (i, "sw_if_index %d", &sw_if_index))
12785         sw_if_index_set = 1;
12786       else
12787         break;
12788     }
12789
12790   if (sw_if_index_set == 0)
12791     {
12792       sw_if_index = ~0;
12793     }
12794
12795   if (!vam->json_output)
12796     {
12797       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12798              "sw_if_index", "local", "remote", "vni",
12799              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12800     }
12801
12802   /* Get list of vxlan-tunnel interfaces */
12803   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12804
12805   mp->sw_if_index = htonl (sw_if_index);
12806
12807   S (mp);
12808
12809   /* Use a control ping for synchronization */
12810   MPING (CONTROL_PING, mp_ping);
12811   S (mp_ping);
12812
12813   W (ret);
12814   return ret;
12815 }
12816
12817
12818 u8 *
12819 format_l2_fib_mac_address (u8 * s, va_list * args)
12820 {
12821   u8 *a = va_arg (*args, u8 *);
12822
12823   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12824                  a[2], a[3], a[4], a[5], a[6], a[7]);
12825 }
12826
12827 static void vl_api_l2_fib_table_details_t_handler
12828   (vl_api_l2_fib_table_details_t * mp)
12829 {
12830   vat_main_t *vam = &vat_main;
12831
12832   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12833          "       %d       %d     %d",
12834          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12835          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12836          mp->bvi_mac);
12837 }
12838
12839 static void vl_api_l2_fib_table_details_t_handler_json
12840   (vl_api_l2_fib_table_details_t * mp)
12841 {
12842   vat_main_t *vam = &vat_main;
12843   vat_json_node_t *node = NULL;
12844
12845   if (VAT_JSON_ARRAY != vam->json_tree.type)
12846     {
12847       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12848       vat_json_init_array (&vam->json_tree);
12849     }
12850   node = vat_json_array_add (&vam->json_tree);
12851
12852   vat_json_init_object (node);
12853   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12854   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12855   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12856   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12857   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12858   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12859 }
12860
12861 static int
12862 api_l2_fib_table_dump (vat_main_t * vam)
12863 {
12864   unformat_input_t *i = vam->input;
12865   vl_api_l2_fib_table_dump_t *mp;
12866   vl_api_control_ping_t *mp_ping;
12867   u32 bd_id;
12868   u8 bd_id_set = 0;
12869   int ret;
12870
12871   /* Parse args required to build the message */
12872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12873     {
12874       if (unformat (i, "bd_id %d", &bd_id))
12875         bd_id_set = 1;
12876       else
12877         break;
12878     }
12879
12880   if (bd_id_set == 0)
12881     {
12882       errmsg ("missing bridge domain");
12883       return -99;
12884     }
12885
12886   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12887
12888   /* Get list of l2 fib entries */
12889   M (L2_FIB_TABLE_DUMP, mp);
12890
12891   mp->bd_id = ntohl (bd_id);
12892   S (mp);
12893
12894   /* Use a control ping for synchronization */
12895   MPING (CONTROL_PING, mp_ping);
12896   S (mp_ping);
12897
12898   W (ret);
12899   return ret;
12900 }
12901
12902
12903 static int
12904 api_interface_name_renumber (vat_main_t * vam)
12905 {
12906   unformat_input_t *line_input = vam->input;
12907   vl_api_interface_name_renumber_t *mp;
12908   u32 sw_if_index = ~0;
12909   u32 new_show_dev_instance = ~0;
12910   int ret;
12911
12912   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12913     {
12914       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12915                     &sw_if_index))
12916         ;
12917       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12918         ;
12919       else if (unformat (line_input, "new_show_dev_instance %d",
12920                          &new_show_dev_instance))
12921         ;
12922       else
12923         break;
12924     }
12925
12926   if (sw_if_index == ~0)
12927     {
12928       errmsg ("missing interface name or sw_if_index");
12929       return -99;
12930     }
12931
12932   if (new_show_dev_instance == ~0)
12933     {
12934       errmsg ("missing new_show_dev_instance");
12935       return -99;
12936     }
12937
12938   M (INTERFACE_NAME_RENUMBER, mp);
12939
12940   mp->sw_if_index = ntohl (sw_if_index);
12941   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12942
12943   S (mp);
12944   W (ret);
12945   return ret;
12946 }
12947
12948 static int
12949 api_want_ip4_arp_events (vat_main_t * vam)
12950 {
12951   unformat_input_t *line_input = vam->input;
12952   vl_api_want_ip4_arp_events_t *mp;
12953   ip4_address_t address;
12954   int address_set = 0;
12955   u32 enable_disable = 1;
12956   int ret;
12957
12958   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12959     {
12960       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12961         address_set = 1;
12962       else if (unformat (line_input, "del"))
12963         enable_disable = 0;
12964       else
12965         break;
12966     }
12967
12968   if (address_set == 0)
12969     {
12970       errmsg ("missing addresses");
12971       return -99;
12972     }
12973
12974   M (WANT_IP4_ARP_EVENTS, mp);
12975   mp->enable_disable = enable_disable;
12976   mp->pid = htonl (getpid ());
12977   mp->address = address.as_u32;
12978
12979   S (mp);
12980   W (ret);
12981   return ret;
12982 }
12983
12984 static int
12985 api_want_ip6_nd_events (vat_main_t * vam)
12986 {
12987   unformat_input_t *line_input = vam->input;
12988   vl_api_want_ip6_nd_events_t *mp;
12989   ip6_address_t address;
12990   int address_set = 0;
12991   u32 enable_disable = 1;
12992   int ret;
12993
12994   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12995     {
12996       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12997         address_set = 1;
12998       else if (unformat (line_input, "del"))
12999         enable_disable = 0;
13000       else
13001         break;
13002     }
13003
13004   if (address_set == 0)
13005     {
13006       errmsg ("missing addresses");
13007       return -99;
13008     }
13009
13010   M (WANT_IP6_ND_EVENTS, mp);
13011   mp->enable_disable = enable_disable;
13012   mp->pid = htonl (getpid ());
13013   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13014
13015   S (mp);
13016   W (ret);
13017   return ret;
13018 }
13019
13020 static int
13021 api_want_l2_macs_events (vat_main_t * vam)
13022 {
13023   unformat_input_t *line_input = vam->input;
13024   vl_api_want_l2_macs_events_t *mp;
13025   u8 enable_disable = 1;
13026   u32 scan_delay = 0;
13027   u32 max_macs_in_event = 0;
13028   u32 learn_limit = 0;
13029   int ret;
13030
13031   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13032     {
13033       if (unformat (line_input, "learn-limit %d", &learn_limit))
13034         ;
13035       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13036         ;
13037       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13038         ;
13039       else if (unformat (line_input, "disable"))
13040         enable_disable = 0;
13041       else
13042         break;
13043     }
13044
13045   M (WANT_L2_MACS_EVENTS, mp);
13046   mp->enable_disable = enable_disable;
13047   mp->pid = htonl (getpid ());
13048   mp->learn_limit = htonl (learn_limit);
13049   mp->scan_delay = (u8) scan_delay;
13050   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13051   S (mp);
13052   W (ret);
13053   return ret;
13054 }
13055
13056 static int
13057 api_input_acl_set_interface (vat_main_t * vam)
13058 {
13059   unformat_input_t *i = vam->input;
13060   vl_api_input_acl_set_interface_t *mp;
13061   u32 sw_if_index;
13062   int sw_if_index_set;
13063   u32 ip4_table_index = ~0;
13064   u32 ip6_table_index = ~0;
13065   u32 l2_table_index = ~0;
13066   u8 is_add = 1;
13067   int ret;
13068
13069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13070     {
13071       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13072         sw_if_index_set = 1;
13073       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13074         sw_if_index_set = 1;
13075       else if (unformat (i, "del"))
13076         is_add = 0;
13077       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13078         ;
13079       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13080         ;
13081       else if (unformat (i, "l2-table %d", &l2_table_index))
13082         ;
13083       else
13084         {
13085           clib_warning ("parse error '%U'", format_unformat_error, i);
13086           return -99;
13087         }
13088     }
13089
13090   if (sw_if_index_set == 0)
13091     {
13092       errmsg ("missing interface name or sw_if_index");
13093       return -99;
13094     }
13095
13096   M (INPUT_ACL_SET_INTERFACE, mp);
13097
13098   mp->sw_if_index = ntohl (sw_if_index);
13099   mp->ip4_table_index = ntohl (ip4_table_index);
13100   mp->ip6_table_index = ntohl (ip6_table_index);
13101   mp->l2_table_index = ntohl (l2_table_index);
13102   mp->is_add = is_add;
13103
13104   S (mp);
13105   W (ret);
13106   return ret;
13107 }
13108
13109 static int
13110 api_ip_address_dump (vat_main_t * vam)
13111 {
13112   unformat_input_t *i = vam->input;
13113   vl_api_ip_address_dump_t *mp;
13114   vl_api_control_ping_t *mp_ping;
13115   u32 sw_if_index = ~0;
13116   u8 sw_if_index_set = 0;
13117   u8 ipv4_set = 0;
13118   u8 ipv6_set = 0;
13119   int ret;
13120
13121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13122     {
13123       if (unformat (i, "sw_if_index %d", &sw_if_index))
13124         sw_if_index_set = 1;
13125       else
13126         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13127         sw_if_index_set = 1;
13128       else if (unformat (i, "ipv4"))
13129         ipv4_set = 1;
13130       else if (unformat (i, "ipv6"))
13131         ipv6_set = 1;
13132       else
13133         break;
13134     }
13135
13136   if (ipv4_set && ipv6_set)
13137     {
13138       errmsg ("ipv4 and ipv6 flags cannot be both set");
13139       return -99;
13140     }
13141
13142   if ((!ipv4_set) && (!ipv6_set))
13143     {
13144       errmsg ("no ipv4 nor ipv6 flag set");
13145       return -99;
13146     }
13147
13148   if (sw_if_index_set == 0)
13149     {
13150       errmsg ("missing interface name or sw_if_index");
13151       return -99;
13152     }
13153
13154   vam->current_sw_if_index = sw_if_index;
13155   vam->is_ipv6 = ipv6_set;
13156
13157   M (IP_ADDRESS_DUMP, mp);
13158   mp->sw_if_index = ntohl (sw_if_index);
13159   mp->is_ipv6 = ipv6_set;
13160   S (mp);
13161
13162   /* Use a control ping for synchronization */
13163   MPING (CONTROL_PING, mp_ping);
13164   S (mp_ping);
13165
13166   W (ret);
13167   return ret;
13168 }
13169
13170 static int
13171 api_ip_dump (vat_main_t * vam)
13172 {
13173   vl_api_ip_dump_t *mp;
13174   vl_api_control_ping_t *mp_ping;
13175   unformat_input_t *in = vam->input;
13176   int ipv4_set = 0;
13177   int ipv6_set = 0;
13178   int is_ipv6;
13179   int i;
13180   int ret;
13181
13182   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13183     {
13184       if (unformat (in, "ipv4"))
13185         ipv4_set = 1;
13186       else if (unformat (in, "ipv6"))
13187         ipv6_set = 1;
13188       else
13189         break;
13190     }
13191
13192   if (ipv4_set && ipv6_set)
13193     {
13194       errmsg ("ipv4 and ipv6 flags cannot be both set");
13195       return -99;
13196     }
13197
13198   if ((!ipv4_set) && (!ipv6_set))
13199     {
13200       errmsg ("no ipv4 nor ipv6 flag set");
13201       return -99;
13202     }
13203
13204   is_ipv6 = ipv6_set;
13205   vam->is_ipv6 = is_ipv6;
13206
13207   /* free old data */
13208   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13209     {
13210       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13211     }
13212   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13213
13214   M (IP_DUMP, mp);
13215   mp->is_ipv6 = ipv6_set;
13216   S (mp);
13217
13218   /* Use a control ping for synchronization */
13219   MPING (CONTROL_PING, mp_ping);
13220   S (mp_ping);
13221
13222   W (ret);
13223   return ret;
13224 }
13225
13226 static int
13227 api_ipsec_spd_add_del (vat_main_t * vam)
13228 {
13229   unformat_input_t *i = vam->input;
13230   vl_api_ipsec_spd_add_del_t *mp;
13231   u32 spd_id = ~0;
13232   u8 is_add = 1;
13233   int ret;
13234
13235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13236     {
13237       if (unformat (i, "spd_id %d", &spd_id))
13238         ;
13239       else if (unformat (i, "del"))
13240         is_add = 0;
13241       else
13242         {
13243           clib_warning ("parse error '%U'", format_unformat_error, i);
13244           return -99;
13245         }
13246     }
13247   if (spd_id == ~0)
13248     {
13249       errmsg ("spd_id must be set");
13250       return -99;
13251     }
13252
13253   M (IPSEC_SPD_ADD_DEL, mp);
13254
13255   mp->spd_id = ntohl (spd_id);
13256   mp->is_add = is_add;
13257
13258   S (mp);
13259   W (ret);
13260   return ret;
13261 }
13262
13263 static int
13264 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13265 {
13266   unformat_input_t *i = vam->input;
13267   vl_api_ipsec_interface_add_del_spd_t *mp;
13268   u32 sw_if_index;
13269   u8 sw_if_index_set = 0;
13270   u32 spd_id = (u32) ~ 0;
13271   u8 is_add = 1;
13272   int ret;
13273
13274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13275     {
13276       if (unformat (i, "del"))
13277         is_add = 0;
13278       else if (unformat (i, "spd_id %d", &spd_id))
13279         ;
13280       else
13281         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13282         sw_if_index_set = 1;
13283       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13284         sw_if_index_set = 1;
13285       else
13286         {
13287           clib_warning ("parse error '%U'", format_unformat_error, i);
13288           return -99;
13289         }
13290
13291     }
13292
13293   if (spd_id == (u32) ~ 0)
13294     {
13295       errmsg ("spd_id must be set");
13296       return -99;
13297     }
13298
13299   if (sw_if_index_set == 0)
13300     {
13301       errmsg ("missing interface name or sw_if_index");
13302       return -99;
13303     }
13304
13305   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13306
13307   mp->spd_id = ntohl (spd_id);
13308   mp->sw_if_index = ntohl (sw_if_index);
13309   mp->is_add = is_add;
13310
13311   S (mp);
13312   W (ret);
13313   return ret;
13314 }
13315
13316 static int
13317 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13318 {
13319   unformat_input_t *i = vam->input;
13320   vl_api_ipsec_spd_add_del_entry_t *mp;
13321   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13322   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13323   i32 priority = 0;
13324   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13325   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13326   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13327   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13328   int ret;
13329
13330   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13331   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13332   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13333   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13334   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13335   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13336
13337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13338     {
13339       if (unformat (i, "del"))
13340         is_add = 0;
13341       if (unformat (i, "outbound"))
13342         is_outbound = 1;
13343       if (unformat (i, "inbound"))
13344         is_outbound = 0;
13345       else if (unformat (i, "spd_id %d", &spd_id))
13346         ;
13347       else if (unformat (i, "sa_id %d", &sa_id))
13348         ;
13349       else if (unformat (i, "priority %d", &priority))
13350         ;
13351       else if (unformat (i, "protocol %d", &protocol))
13352         ;
13353       else if (unformat (i, "lport_start %d", &lport_start))
13354         ;
13355       else if (unformat (i, "lport_stop %d", &lport_stop))
13356         ;
13357       else if (unformat (i, "rport_start %d", &rport_start))
13358         ;
13359       else if (unformat (i, "rport_stop %d", &rport_stop))
13360         ;
13361       else
13362         if (unformat
13363             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13364         {
13365           is_ipv6 = 0;
13366           is_ip_any = 0;
13367         }
13368       else
13369         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13370         {
13371           is_ipv6 = 0;
13372           is_ip_any = 0;
13373         }
13374       else
13375         if (unformat
13376             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13377         {
13378           is_ipv6 = 0;
13379           is_ip_any = 0;
13380         }
13381       else
13382         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13383         {
13384           is_ipv6 = 0;
13385           is_ip_any = 0;
13386         }
13387       else
13388         if (unformat
13389             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13390         {
13391           is_ipv6 = 1;
13392           is_ip_any = 0;
13393         }
13394       else
13395         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13396         {
13397           is_ipv6 = 1;
13398           is_ip_any = 0;
13399         }
13400       else
13401         if (unformat
13402             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13403         {
13404           is_ipv6 = 1;
13405           is_ip_any = 0;
13406         }
13407       else
13408         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13409         {
13410           is_ipv6 = 1;
13411           is_ip_any = 0;
13412         }
13413       else
13414         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13415         {
13416           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13417             {
13418               clib_warning ("unsupported action: 'resolve'");
13419               return -99;
13420             }
13421         }
13422       else
13423         {
13424           clib_warning ("parse error '%U'", format_unformat_error, i);
13425           return -99;
13426         }
13427
13428     }
13429
13430   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13431
13432   mp->spd_id = ntohl (spd_id);
13433   mp->priority = ntohl (priority);
13434   mp->is_outbound = is_outbound;
13435
13436   mp->is_ipv6 = is_ipv6;
13437   if (is_ipv6 || is_ip_any)
13438     {
13439       clib_memcpy (mp->remote_address_start, &raddr6_start,
13440                    sizeof (ip6_address_t));
13441       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13442                    sizeof (ip6_address_t));
13443       clib_memcpy (mp->local_address_start, &laddr6_start,
13444                    sizeof (ip6_address_t));
13445       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13446                    sizeof (ip6_address_t));
13447     }
13448   else
13449     {
13450       clib_memcpy (mp->remote_address_start, &raddr4_start,
13451                    sizeof (ip4_address_t));
13452       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13453                    sizeof (ip4_address_t));
13454       clib_memcpy (mp->local_address_start, &laddr4_start,
13455                    sizeof (ip4_address_t));
13456       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13457                    sizeof (ip4_address_t));
13458     }
13459   mp->protocol = (u8) protocol;
13460   mp->local_port_start = ntohs ((u16) lport_start);
13461   mp->local_port_stop = ntohs ((u16) lport_stop);
13462   mp->remote_port_start = ntohs ((u16) rport_start);
13463   mp->remote_port_stop = ntohs ((u16) rport_stop);
13464   mp->policy = (u8) policy;
13465   mp->sa_id = ntohl (sa_id);
13466   mp->is_add = is_add;
13467   mp->is_ip_any = is_ip_any;
13468   S (mp);
13469   W (ret);
13470   return ret;
13471 }
13472
13473 static int
13474 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13475 {
13476   unformat_input_t *i = vam->input;
13477   vl_api_ipsec_sad_add_del_entry_t *mp;
13478   u32 sad_id = 0, spi = 0;
13479   u8 *ck = 0, *ik = 0;
13480   u8 is_add = 1;
13481
13482   u8 protocol = IPSEC_PROTOCOL_AH;
13483   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13484   u32 crypto_alg = 0, integ_alg = 0;
13485   ip4_address_t tun_src4;
13486   ip4_address_t tun_dst4;
13487   ip6_address_t tun_src6;
13488   ip6_address_t tun_dst6;
13489   int ret;
13490
13491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13492     {
13493       if (unformat (i, "del"))
13494         is_add = 0;
13495       else if (unformat (i, "sad_id %d", &sad_id))
13496         ;
13497       else if (unformat (i, "spi %d", &spi))
13498         ;
13499       else if (unformat (i, "esp"))
13500         protocol = IPSEC_PROTOCOL_ESP;
13501       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13502         {
13503           is_tunnel = 1;
13504           is_tunnel_ipv6 = 0;
13505         }
13506       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13507         {
13508           is_tunnel = 1;
13509           is_tunnel_ipv6 = 0;
13510         }
13511       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13512         {
13513           is_tunnel = 1;
13514           is_tunnel_ipv6 = 1;
13515         }
13516       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13517         {
13518           is_tunnel = 1;
13519           is_tunnel_ipv6 = 1;
13520         }
13521       else
13522         if (unformat
13523             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13524         {
13525           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13526               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13527             {
13528               clib_warning ("unsupported crypto-alg: '%U'",
13529                             format_ipsec_crypto_alg, crypto_alg);
13530               return -99;
13531             }
13532         }
13533       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13534         ;
13535       else
13536         if (unformat
13537             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13538         {
13539           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13540               integ_alg >= IPSEC_INTEG_N_ALG)
13541             {
13542               clib_warning ("unsupported integ-alg: '%U'",
13543                             format_ipsec_integ_alg, integ_alg);
13544               return -99;
13545             }
13546         }
13547       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13548         ;
13549       else
13550         {
13551           clib_warning ("parse error '%U'", format_unformat_error, i);
13552           return -99;
13553         }
13554
13555     }
13556
13557   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13558
13559   mp->sad_id = ntohl (sad_id);
13560   mp->is_add = is_add;
13561   mp->protocol = protocol;
13562   mp->spi = ntohl (spi);
13563   mp->is_tunnel = is_tunnel;
13564   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13565   mp->crypto_algorithm = crypto_alg;
13566   mp->integrity_algorithm = integ_alg;
13567   mp->crypto_key_length = vec_len (ck);
13568   mp->integrity_key_length = vec_len (ik);
13569
13570   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13571     mp->crypto_key_length = sizeof (mp->crypto_key);
13572
13573   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13574     mp->integrity_key_length = sizeof (mp->integrity_key);
13575
13576   if (ck)
13577     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13578   if (ik)
13579     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13580
13581   if (is_tunnel)
13582     {
13583       if (is_tunnel_ipv6)
13584         {
13585           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13586                        sizeof (ip6_address_t));
13587           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13588                        sizeof (ip6_address_t));
13589         }
13590       else
13591         {
13592           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13593                        sizeof (ip4_address_t));
13594           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13595                        sizeof (ip4_address_t));
13596         }
13597     }
13598
13599   S (mp);
13600   W (ret);
13601   return ret;
13602 }
13603
13604 static int
13605 api_ipsec_sa_set_key (vat_main_t * vam)
13606 {
13607   unformat_input_t *i = vam->input;
13608   vl_api_ipsec_sa_set_key_t *mp;
13609   u32 sa_id;
13610   u8 *ck = 0, *ik = 0;
13611   int ret;
13612
13613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13614     {
13615       if (unformat (i, "sa_id %d", &sa_id))
13616         ;
13617       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13618         ;
13619       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13620         ;
13621       else
13622         {
13623           clib_warning ("parse error '%U'", format_unformat_error, i);
13624           return -99;
13625         }
13626     }
13627
13628   M (IPSEC_SA_SET_KEY, mp);
13629
13630   mp->sa_id = ntohl (sa_id);
13631   mp->crypto_key_length = vec_len (ck);
13632   mp->integrity_key_length = vec_len (ik);
13633
13634   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13635     mp->crypto_key_length = sizeof (mp->crypto_key);
13636
13637   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13638     mp->integrity_key_length = sizeof (mp->integrity_key);
13639
13640   if (ck)
13641     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13642   if (ik)
13643     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13644
13645   S (mp);
13646   W (ret);
13647   return ret;
13648 }
13649
13650 static int
13651 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13652 {
13653   unformat_input_t *i = vam->input;
13654   vl_api_ipsec_tunnel_if_add_del_t *mp;
13655   u32 local_spi = 0, remote_spi = 0;
13656   u32 crypto_alg = 0, integ_alg = 0;
13657   u8 *lck = NULL, *rck = NULL;
13658   u8 *lik = NULL, *rik = NULL;
13659   ip4_address_t local_ip = { {0} };
13660   ip4_address_t remote_ip = { {0} };
13661   u8 is_add = 1;
13662   u8 esn = 0;
13663   u8 anti_replay = 0;
13664   int ret;
13665
13666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13667     {
13668       if (unformat (i, "del"))
13669         is_add = 0;
13670       else if (unformat (i, "esn"))
13671         esn = 1;
13672       else if (unformat (i, "anti_replay"))
13673         anti_replay = 1;
13674       else if (unformat (i, "local_spi %d", &local_spi))
13675         ;
13676       else if (unformat (i, "remote_spi %d", &remote_spi))
13677         ;
13678       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13679         ;
13680       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13681         ;
13682       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13683         ;
13684       else
13685         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13686         ;
13687       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13688         ;
13689       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13690         ;
13691       else
13692         if (unformat
13693             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13694         {
13695           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13696               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13697             {
13698               errmsg ("unsupported crypto-alg: '%U'\n",
13699                       format_ipsec_crypto_alg, crypto_alg);
13700               return -99;
13701             }
13702         }
13703       else
13704         if (unformat
13705             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13706         {
13707           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13708               integ_alg >= IPSEC_INTEG_N_ALG)
13709             {
13710               errmsg ("unsupported integ-alg: '%U'\n",
13711                       format_ipsec_integ_alg, integ_alg);
13712               return -99;
13713             }
13714         }
13715       else
13716         {
13717           errmsg ("parse error '%U'\n", format_unformat_error, i);
13718           return -99;
13719         }
13720     }
13721
13722   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13723
13724   mp->is_add = is_add;
13725   mp->esn = esn;
13726   mp->anti_replay = anti_replay;
13727
13728   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13729   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13730
13731   mp->local_spi = htonl (local_spi);
13732   mp->remote_spi = htonl (remote_spi);
13733   mp->crypto_alg = (u8) crypto_alg;
13734
13735   mp->local_crypto_key_len = 0;
13736   if (lck)
13737     {
13738       mp->local_crypto_key_len = vec_len (lck);
13739       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13740         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13741       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13742     }
13743
13744   mp->remote_crypto_key_len = 0;
13745   if (rck)
13746     {
13747       mp->remote_crypto_key_len = vec_len (rck);
13748       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13749         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13750       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13751     }
13752
13753   mp->integ_alg = (u8) integ_alg;
13754
13755   mp->local_integ_key_len = 0;
13756   if (lik)
13757     {
13758       mp->local_integ_key_len = vec_len (lik);
13759       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13760         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13761       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13762     }
13763
13764   mp->remote_integ_key_len = 0;
13765   if (rik)
13766     {
13767       mp->remote_integ_key_len = vec_len (rik);
13768       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13769         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13770       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13771     }
13772
13773   S (mp);
13774   W (ret);
13775   return ret;
13776 }
13777
13778 static void
13779 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13780 {
13781   vat_main_t *vam = &vat_main;
13782
13783   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13784          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
13785          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
13786          "tunnel_src_addr %U tunnel_dst_addr %U "
13787          "salt %u seq_outbound %lu last_seq_inbound %lu "
13788          "replay_window %lu total_data_size %lu\n",
13789          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
13790          mp->protocol,
13791          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
13792          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
13793          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
13794          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
13795          mp->tunnel_src_addr,
13796          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
13797          mp->tunnel_dst_addr,
13798          ntohl (mp->salt),
13799          clib_net_to_host_u64 (mp->seq_outbound),
13800          clib_net_to_host_u64 (mp->last_seq_inbound),
13801          clib_net_to_host_u64 (mp->replay_window),
13802          clib_net_to_host_u64 (mp->total_data_size));
13803 }
13804
13805 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13806 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13807
13808 static void vl_api_ipsec_sa_details_t_handler_json
13809   (vl_api_ipsec_sa_details_t * mp)
13810 {
13811   vat_main_t *vam = &vat_main;
13812   vat_json_node_t *node = NULL;
13813   struct in_addr src_ip4, dst_ip4;
13814   struct in6_addr src_ip6, dst_ip6;
13815
13816   if (VAT_JSON_ARRAY != vam->json_tree.type)
13817     {
13818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13819       vat_json_init_array (&vam->json_tree);
13820     }
13821   node = vat_json_array_add (&vam->json_tree);
13822
13823   vat_json_init_object (node);
13824   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
13825   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13826   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
13827   vat_json_object_add_uint (node, "proto", mp->protocol);
13828   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
13829   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
13830   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
13831   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
13832   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
13833   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
13834   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
13835                              mp->crypto_key_len);
13836   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
13837                              mp->integ_key_len);
13838   if (mp->is_tunnel_ip6)
13839     {
13840       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
13841       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
13842       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
13843       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
13844     }
13845   else
13846     {
13847       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
13848       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
13849       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
13850       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
13851     }
13852   vat_json_object_add_uint (node, "replay_window",
13853                             clib_net_to_host_u64 (mp->replay_window));
13854   vat_json_object_add_uint (node, "total_data_size",
13855                             clib_net_to_host_u64 (mp->total_data_size));
13856
13857 }
13858
13859 static int
13860 api_ipsec_sa_dump (vat_main_t * vam)
13861 {
13862   unformat_input_t *i = vam->input;
13863   vl_api_ipsec_sa_dump_t *mp;
13864   vl_api_control_ping_t *mp_ping;
13865   u32 sa_id = ~0;
13866   int ret;
13867
13868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13869     {
13870       if (unformat (i, "sa_id %d", &sa_id))
13871         ;
13872       else
13873         {
13874           clib_warning ("parse error '%U'", format_unformat_error, i);
13875           return -99;
13876         }
13877     }
13878
13879   M (IPSEC_SA_DUMP, mp);
13880
13881   mp->sa_id = ntohl (sa_id);
13882
13883   S (mp);
13884
13885   /* Use a control ping for synchronization */
13886   M (CONTROL_PING, mp_ping);
13887   S (mp_ping);
13888
13889   W (ret);
13890   return ret;
13891 }
13892
13893 static int
13894 api_ikev2_profile_add_del (vat_main_t * vam)
13895 {
13896   unformat_input_t *i = vam->input;
13897   vl_api_ikev2_profile_add_del_t *mp;
13898   u8 is_add = 1;
13899   u8 *name = 0;
13900   int ret;
13901
13902   const char *valid_chars = "a-zA-Z0-9_";
13903
13904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13905     {
13906       if (unformat (i, "del"))
13907         is_add = 0;
13908       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13909         vec_add1 (name, 0);
13910       else
13911         {
13912           errmsg ("parse error '%U'", format_unformat_error, i);
13913           return -99;
13914         }
13915     }
13916
13917   if (!vec_len (name))
13918     {
13919       errmsg ("profile name must be specified");
13920       return -99;
13921     }
13922
13923   if (vec_len (name) > 64)
13924     {
13925       errmsg ("profile name too long");
13926       return -99;
13927     }
13928
13929   M (IKEV2_PROFILE_ADD_DEL, mp);
13930
13931   clib_memcpy (mp->name, name, vec_len (name));
13932   mp->is_add = is_add;
13933   vec_free (name);
13934
13935   S (mp);
13936   W (ret);
13937   return ret;
13938 }
13939
13940 static int
13941 api_ikev2_profile_set_auth (vat_main_t * vam)
13942 {
13943   unformat_input_t *i = vam->input;
13944   vl_api_ikev2_profile_set_auth_t *mp;
13945   u8 *name = 0;
13946   u8 *data = 0;
13947   u32 auth_method = 0;
13948   u8 is_hex = 0;
13949   int ret;
13950
13951   const char *valid_chars = "a-zA-Z0-9_";
13952
13953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13954     {
13955       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13956         vec_add1 (name, 0);
13957       else if (unformat (i, "auth_method %U",
13958                          unformat_ikev2_auth_method, &auth_method))
13959         ;
13960       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13961         is_hex = 1;
13962       else if (unformat (i, "auth_data %v", &data))
13963         ;
13964       else
13965         {
13966           errmsg ("parse error '%U'", format_unformat_error, i);
13967           return -99;
13968         }
13969     }
13970
13971   if (!vec_len (name))
13972     {
13973       errmsg ("profile name must be specified");
13974       return -99;
13975     }
13976
13977   if (vec_len (name) > 64)
13978     {
13979       errmsg ("profile name too long");
13980       return -99;
13981     }
13982
13983   if (!vec_len (data))
13984     {
13985       errmsg ("auth_data must be specified");
13986       return -99;
13987     }
13988
13989   if (!auth_method)
13990     {
13991       errmsg ("auth_method must be specified");
13992       return -99;
13993     }
13994
13995   M (IKEV2_PROFILE_SET_AUTH, mp);
13996
13997   mp->is_hex = is_hex;
13998   mp->auth_method = (u8) auth_method;
13999   mp->data_len = vec_len (data);
14000   clib_memcpy (mp->name, name, vec_len (name));
14001   clib_memcpy (mp->data, data, vec_len (data));
14002   vec_free (name);
14003   vec_free (data);
14004
14005   S (mp);
14006   W (ret);
14007   return ret;
14008 }
14009
14010 static int
14011 api_ikev2_profile_set_id (vat_main_t * vam)
14012 {
14013   unformat_input_t *i = vam->input;
14014   vl_api_ikev2_profile_set_id_t *mp;
14015   u8 *name = 0;
14016   u8 *data = 0;
14017   u8 is_local = 0;
14018   u32 id_type = 0;
14019   ip4_address_t ip4;
14020   int ret;
14021
14022   const char *valid_chars = "a-zA-Z0-9_";
14023
14024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14025     {
14026       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14027         vec_add1 (name, 0);
14028       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14029         ;
14030       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14031         {
14032           data = vec_new (u8, 4);
14033           clib_memcpy (data, ip4.as_u8, 4);
14034         }
14035       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14036         ;
14037       else if (unformat (i, "id_data %v", &data))
14038         ;
14039       else if (unformat (i, "local"))
14040         is_local = 1;
14041       else if (unformat (i, "remote"))
14042         is_local = 0;
14043       else
14044         {
14045           errmsg ("parse error '%U'", format_unformat_error, i);
14046           return -99;
14047         }
14048     }
14049
14050   if (!vec_len (name))
14051     {
14052       errmsg ("profile name must be specified");
14053       return -99;
14054     }
14055
14056   if (vec_len (name) > 64)
14057     {
14058       errmsg ("profile name too long");
14059       return -99;
14060     }
14061
14062   if (!vec_len (data))
14063     {
14064       errmsg ("id_data must be specified");
14065       return -99;
14066     }
14067
14068   if (!id_type)
14069     {
14070       errmsg ("id_type must be specified");
14071       return -99;
14072     }
14073
14074   M (IKEV2_PROFILE_SET_ID, mp);
14075
14076   mp->is_local = is_local;
14077   mp->id_type = (u8) id_type;
14078   mp->data_len = vec_len (data);
14079   clib_memcpy (mp->name, name, vec_len (name));
14080   clib_memcpy (mp->data, data, vec_len (data));
14081   vec_free (name);
14082   vec_free (data);
14083
14084   S (mp);
14085   W (ret);
14086   return ret;
14087 }
14088
14089 static int
14090 api_ikev2_profile_set_ts (vat_main_t * vam)
14091 {
14092   unformat_input_t *i = vam->input;
14093   vl_api_ikev2_profile_set_ts_t *mp;
14094   u8 *name = 0;
14095   u8 is_local = 0;
14096   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14097   ip4_address_t start_addr, end_addr;
14098
14099   const char *valid_chars = "a-zA-Z0-9_";
14100   int ret;
14101
14102   start_addr.as_u32 = 0;
14103   end_addr.as_u32 = (u32) ~ 0;
14104
14105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14106     {
14107       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14108         vec_add1 (name, 0);
14109       else if (unformat (i, "protocol %d", &proto))
14110         ;
14111       else if (unformat (i, "start_port %d", &start_port))
14112         ;
14113       else if (unformat (i, "end_port %d", &end_port))
14114         ;
14115       else
14116         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14117         ;
14118       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14119         ;
14120       else if (unformat (i, "local"))
14121         is_local = 1;
14122       else if (unformat (i, "remote"))
14123         is_local = 0;
14124       else
14125         {
14126           errmsg ("parse error '%U'", format_unformat_error, i);
14127           return -99;
14128         }
14129     }
14130
14131   if (!vec_len (name))
14132     {
14133       errmsg ("profile name must be specified");
14134       return -99;
14135     }
14136
14137   if (vec_len (name) > 64)
14138     {
14139       errmsg ("profile name too long");
14140       return -99;
14141     }
14142
14143   M (IKEV2_PROFILE_SET_TS, mp);
14144
14145   mp->is_local = is_local;
14146   mp->proto = (u8) proto;
14147   mp->start_port = (u16) start_port;
14148   mp->end_port = (u16) end_port;
14149   mp->start_addr = start_addr.as_u32;
14150   mp->end_addr = end_addr.as_u32;
14151   clib_memcpy (mp->name, name, vec_len (name));
14152   vec_free (name);
14153
14154   S (mp);
14155   W (ret);
14156   return ret;
14157 }
14158
14159 static int
14160 api_ikev2_set_local_key (vat_main_t * vam)
14161 {
14162   unformat_input_t *i = vam->input;
14163   vl_api_ikev2_set_local_key_t *mp;
14164   u8 *file = 0;
14165   int ret;
14166
14167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14168     {
14169       if (unformat (i, "file %v", &file))
14170         vec_add1 (file, 0);
14171       else
14172         {
14173           errmsg ("parse error '%U'", format_unformat_error, i);
14174           return -99;
14175         }
14176     }
14177
14178   if (!vec_len (file))
14179     {
14180       errmsg ("RSA key file must be specified");
14181       return -99;
14182     }
14183
14184   if (vec_len (file) > 256)
14185     {
14186       errmsg ("file name too long");
14187       return -99;
14188     }
14189
14190   M (IKEV2_SET_LOCAL_KEY, mp);
14191
14192   clib_memcpy (mp->key_file, file, vec_len (file));
14193   vec_free (file);
14194
14195   S (mp);
14196   W (ret);
14197   return ret;
14198 }
14199
14200 static int
14201 api_ikev2_set_responder (vat_main_t * vam)
14202 {
14203   unformat_input_t *i = vam->input;
14204   vl_api_ikev2_set_responder_t *mp;
14205   int ret;
14206   u8 *name = 0;
14207   u32 sw_if_index = ~0;
14208   ip4_address_t address;
14209
14210   const char *valid_chars = "a-zA-Z0-9_";
14211
14212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14213     {
14214       if (unformat
14215           (i, "%U interface %d address %U", unformat_token, valid_chars,
14216            &name, &sw_if_index, unformat_ip4_address, &address))
14217         vec_add1 (name, 0);
14218       else
14219         {
14220           errmsg ("parse error '%U'", format_unformat_error, i);
14221           return -99;
14222         }
14223     }
14224
14225   if (!vec_len (name))
14226     {
14227       errmsg ("profile name must be specified");
14228       return -99;
14229     }
14230
14231   if (vec_len (name) > 64)
14232     {
14233       errmsg ("profile name too long");
14234       return -99;
14235     }
14236
14237   M (IKEV2_SET_RESPONDER, mp);
14238
14239   clib_memcpy (mp->name, name, vec_len (name));
14240   vec_free (name);
14241
14242   mp->sw_if_index = sw_if_index;
14243   clib_memcpy (mp->address, &address, sizeof (address));
14244
14245   S (mp);
14246   W (ret);
14247   return ret;
14248 }
14249
14250 static int
14251 api_ikev2_set_ike_transforms (vat_main_t * vam)
14252 {
14253   unformat_input_t *i = vam->input;
14254   vl_api_ikev2_set_ike_transforms_t *mp;
14255   int ret;
14256   u8 *name = 0;
14257   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14258
14259   const char *valid_chars = "a-zA-Z0-9_";
14260
14261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14262     {
14263       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14264                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14265         vec_add1 (name, 0);
14266       else
14267         {
14268           errmsg ("parse error '%U'", format_unformat_error, i);
14269           return -99;
14270         }
14271     }
14272
14273   if (!vec_len (name))
14274     {
14275       errmsg ("profile name must be specified");
14276       return -99;
14277     }
14278
14279   if (vec_len (name) > 64)
14280     {
14281       errmsg ("profile name too long");
14282       return -99;
14283     }
14284
14285   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14286
14287   clib_memcpy (mp->name, name, vec_len (name));
14288   vec_free (name);
14289   mp->crypto_alg = crypto_alg;
14290   mp->crypto_key_size = crypto_key_size;
14291   mp->integ_alg = integ_alg;
14292   mp->dh_group = dh_group;
14293
14294   S (mp);
14295   W (ret);
14296   return ret;
14297 }
14298
14299
14300 static int
14301 api_ikev2_set_esp_transforms (vat_main_t * vam)
14302 {
14303   unformat_input_t *i = vam->input;
14304   vl_api_ikev2_set_esp_transforms_t *mp;
14305   int ret;
14306   u8 *name = 0;
14307   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14308
14309   const char *valid_chars = "a-zA-Z0-9_";
14310
14311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14312     {
14313       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14314                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14315         vec_add1 (name, 0);
14316       else
14317         {
14318           errmsg ("parse error '%U'", format_unformat_error, i);
14319           return -99;
14320         }
14321     }
14322
14323   if (!vec_len (name))
14324     {
14325       errmsg ("profile name must be specified");
14326       return -99;
14327     }
14328
14329   if (vec_len (name) > 64)
14330     {
14331       errmsg ("profile name too long");
14332       return -99;
14333     }
14334
14335   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14336
14337   clib_memcpy (mp->name, name, vec_len (name));
14338   vec_free (name);
14339   mp->crypto_alg = crypto_alg;
14340   mp->crypto_key_size = crypto_key_size;
14341   mp->integ_alg = integ_alg;
14342   mp->dh_group = dh_group;
14343
14344   S (mp);
14345   W (ret);
14346   return ret;
14347 }
14348
14349 static int
14350 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14351 {
14352   unformat_input_t *i = vam->input;
14353   vl_api_ikev2_set_sa_lifetime_t *mp;
14354   int ret;
14355   u8 *name = 0;
14356   u64 lifetime, lifetime_maxdata;
14357   u32 lifetime_jitter, handover;
14358
14359   const char *valid_chars = "a-zA-Z0-9_";
14360
14361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14362     {
14363       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14364                     &lifetime, &lifetime_jitter, &handover,
14365                     &lifetime_maxdata))
14366         vec_add1 (name, 0);
14367       else
14368         {
14369           errmsg ("parse error '%U'", format_unformat_error, i);
14370           return -99;
14371         }
14372     }
14373
14374   if (!vec_len (name))
14375     {
14376       errmsg ("profile name must be specified");
14377       return -99;
14378     }
14379
14380   if (vec_len (name) > 64)
14381     {
14382       errmsg ("profile name too long");
14383       return -99;
14384     }
14385
14386   M (IKEV2_SET_SA_LIFETIME, mp);
14387
14388   clib_memcpy (mp->name, name, vec_len (name));
14389   vec_free (name);
14390   mp->lifetime = lifetime;
14391   mp->lifetime_jitter = lifetime_jitter;
14392   mp->handover = handover;
14393   mp->lifetime_maxdata = lifetime_maxdata;
14394
14395   S (mp);
14396   W (ret);
14397   return ret;
14398 }
14399
14400 static int
14401 api_ikev2_initiate_sa_init (vat_main_t * vam)
14402 {
14403   unformat_input_t *i = vam->input;
14404   vl_api_ikev2_initiate_sa_init_t *mp;
14405   int ret;
14406   u8 *name = 0;
14407
14408   const char *valid_chars = "a-zA-Z0-9_";
14409
14410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14411     {
14412       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14413         vec_add1 (name, 0);
14414       else
14415         {
14416           errmsg ("parse error '%U'", format_unformat_error, i);
14417           return -99;
14418         }
14419     }
14420
14421   if (!vec_len (name))
14422     {
14423       errmsg ("profile name must be specified");
14424       return -99;
14425     }
14426
14427   if (vec_len (name) > 64)
14428     {
14429       errmsg ("profile name too long");
14430       return -99;
14431     }
14432
14433   M (IKEV2_INITIATE_SA_INIT, mp);
14434
14435   clib_memcpy (mp->name, name, vec_len (name));
14436   vec_free (name);
14437
14438   S (mp);
14439   W (ret);
14440   return ret;
14441 }
14442
14443 static int
14444 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14445 {
14446   unformat_input_t *i = vam->input;
14447   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14448   int ret;
14449   u64 ispi;
14450
14451
14452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14453     {
14454       if (unformat (i, "%lx", &ispi))
14455         ;
14456       else
14457         {
14458           errmsg ("parse error '%U'", format_unformat_error, i);
14459           return -99;
14460         }
14461     }
14462
14463   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14464
14465   mp->ispi = ispi;
14466
14467   S (mp);
14468   W (ret);
14469   return ret;
14470 }
14471
14472 static int
14473 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14474 {
14475   unformat_input_t *i = vam->input;
14476   vl_api_ikev2_initiate_del_child_sa_t *mp;
14477   int ret;
14478   u32 ispi;
14479
14480
14481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14482     {
14483       if (unformat (i, "%x", &ispi))
14484         ;
14485       else
14486         {
14487           errmsg ("parse error '%U'", format_unformat_error, i);
14488           return -99;
14489         }
14490     }
14491
14492   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14493
14494   mp->ispi = ispi;
14495
14496   S (mp);
14497   W (ret);
14498   return ret;
14499 }
14500
14501 static int
14502 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14503 {
14504   unformat_input_t *i = vam->input;
14505   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14506   int ret;
14507   u32 ispi;
14508
14509
14510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14511     {
14512       if (unformat (i, "%x", &ispi))
14513         ;
14514       else
14515         {
14516           errmsg ("parse error '%U'", format_unformat_error, i);
14517           return -99;
14518         }
14519     }
14520
14521   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14522
14523   mp->ispi = ispi;
14524
14525   S (mp);
14526   W (ret);
14527   return ret;
14528 }
14529
14530 /*
14531  * MAP
14532  */
14533 static int
14534 api_map_add_domain (vat_main_t * vam)
14535 {
14536   unformat_input_t *i = vam->input;
14537   vl_api_map_add_domain_t *mp;
14538
14539   ip4_address_t ip4_prefix;
14540   ip6_address_t ip6_prefix;
14541   ip6_address_t ip6_src;
14542   u32 num_m_args = 0;
14543   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14544     0, psid_length = 0;
14545   u8 is_translation = 0;
14546   u32 mtu = 0;
14547   u32 ip6_src_len = 128;
14548   int ret;
14549
14550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14551     {
14552       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14553                     &ip4_prefix, &ip4_prefix_len))
14554         num_m_args++;
14555       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14556                          &ip6_prefix, &ip6_prefix_len))
14557         num_m_args++;
14558       else
14559         if (unformat
14560             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14561              &ip6_src_len))
14562         num_m_args++;
14563       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14564         num_m_args++;
14565       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14566         num_m_args++;
14567       else if (unformat (i, "psid-offset %d", &psid_offset))
14568         num_m_args++;
14569       else if (unformat (i, "psid-len %d", &psid_length))
14570         num_m_args++;
14571       else if (unformat (i, "mtu %d", &mtu))
14572         num_m_args++;
14573       else if (unformat (i, "map-t"))
14574         is_translation = 1;
14575       else
14576         {
14577           clib_warning ("parse error '%U'", format_unformat_error, i);
14578           return -99;
14579         }
14580     }
14581
14582   if (num_m_args < 3)
14583     {
14584       errmsg ("mandatory argument(s) missing");
14585       return -99;
14586     }
14587
14588   /* Construct the API message */
14589   M (MAP_ADD_DOMAIN, mp);
14590
14591   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14592   mp->ip4_prefix_len = ip4_prefix_len;
14593
14594   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14595   mp->ip6_prefix_len = ip6_prefix_len;
14596
14597   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14598   mp->ip6_src_prefix_len = ip6_src_len;
14599
14600   mp->ea_bits_len = ea_bits_len;
14601   mp->psid_offset = psid_offset;
14602   mp->psid_length = psid_length;
14603   mp->is_translation = is_translation;
14604   mp->mtu = htons (mtu);
14605
14606   /* send it... */
14607   S (mp);
14608
14609   /* Wait for a reply, return good/bad news  */
14610   W (ret);
14611   return ret;
14612 }
14613
14614 static int
14615 api_map_del_domain (vat_main_t * vam)
14616 {
14617   unformat_input_t *i = vam->input;
14618   vl_api_map_del_domain_t *mp;
14619
14620   u32 num_m_args = 0;
14621   u32 index;
14622   int ret;
14623
14624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14625     {
14626       if (unformat (i, "index %d", &index))
14627         num_m_args++;
14628       else
14629         {
14630           clib_warning ("parse error '%U'", format_unformat_error, i);
14631           return -99;
14632         }
14633     }
14634
14635   if (num_m_args != 1)
14636     {
14637       errmsg ("mandatory argument(s) missing");
14638       return -99;
14639     }
14640
14641   /* Construct the API message */
14642   M (MAP_DEL_DOMAIN, mp);
14643
14644   mp->index = ntohl (index);
14645
14646   /* send it... */
14647   S (mp);
14648
14649   /* Wait for a reply, return good/bad news  */
14650   W (ret);
14651   return ret;
14652 }
14653
14654 static int
14655 api_map_add_del_rule (vat_main_t * vam)
14656 {
14657   unformat_input_t *i = vam->input;
14658   vl_api_map_add_del_rule_t *mp;
14659   u8 is_add = 1;
14660   ip6_address_t ip6_dst;
14661   u32 num_m_args = 0, index, psid = 0;
14662   int ret;
14663
14664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14665     {
14666       if (unformat (i, "index %d", &index))
14667         num_m_args++;
14668       else if (unformat (i, "psid %d", &psid))
14669         num_m_args++;
14670       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14671         num_m_args++;
14672       else if (unformat (i, "del"))
14673         {
14674           is_add = 0;
14675         }
14676       else
14677         {
14678           clib_warning ("parse error '%U'", format_unformat_error, i);
14679           return -99;
14680         }
14681     }
14682
14683   /* Construct the API message */
14684   M (MAP_ADD_DEL_RULE, mp);
14685
14686   mp->index = ntohl (index);
14687   mp->is_add = is_add;
14688   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14689   mp->psid = ntohs (psid);
14690
14691   /* send it... */
14692   S (mp);
14693
14694   /* Wait for a reply, return good/bad news  */
14695   W (ret);
14696   return ret;
14697 }
14698
14699 static int
14700 api_map_domain_dump (vat_main_t * vam)
14701 {
14702   vl_api_map_domain_dump_t *mp;
14703   vl_api_control_ping_t *mp_ping;
14704   int ret;
14705
14706   /* Construct the API message */
14707   M (MAP_DOMAIN_DUMP, mp);
14708
14709   /* send it... */
14710   S (mp);
14711
14712   /* Use a control ping for synchronization */
14713   MPING (CONTROL_PING, mp_ping);
14714   S (mp_ping);
14715
14716   W (ret);
14717   return ret;
14718 }
14719
14720 static int
14721 api_map_rule_dump (vat_main_t * vam)
14722 {
14723   unformat_input_t *i = vam->input;
14724   vl_api_map_rule_dump_t *mp;
14725   vl_api_control_ping_t *mp_ping;
14726   u32 domain_index = ~0;
14727   int ret;
14728
14729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14730     {
14731       if (unformat (i, "index %u", &domain_index))
14732         ;
14733       else
14734         break;
14735     }
14736
14737   if (domain_index == ~0)
14738     {
14739       clib_warning ("parse error: domain index expected");
14740       return -99;
14741     }
14742
14743   /* Construct the API message */
14744   M (MAP_RULE_DUMP, mp);
14745
14746   mp->domain_index = htonl (domain_index);
14747
14748   /* send it... */
14749   S (mp);
14750
14751   /* Use a control ping for synchronization */
14752   MPING (CONTROL_PING, mp_ping);
14753   S (mp_ping);
14754
14755   W (ret);
14756   return ret;
14757 }
14758
14759 static void vl_api_map_add_domain_reply_t_handler
14760   (vl_api_map_add_domain_reply_t * mp)
14761 {
14762   vat_main_t *vam = &vat_main;
14763   i32 retval = ntohl (mp->retval);
14764
14765   if (vam->async_mode)
14766     {
14767       vam->async_errors += (retval < 0);
14768     }
14769   else
14770     {
14771       vam->retval = retval;
14772       vam->result_ready = 1;
14773     }
14774 }
14775
14776 static void vl_api_map_add_domain_reply_t_handler_json
14777   (vl_api_map_add_domain_reply_t * mp)
14778 {
14779   vat_main_t *vam = &vat_main;
14780   vat_json_node_t node;
14781
14782   vat_json_init_object (&node);
14783   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14784   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14785
14786   vat_json_print (vam->ofp, &node);
14787   vat_json_free (&node);
14788
14789   vam->retval = ntohl (mp->retval);
14790   vam->result_ready = 1;
14791 }
14792
14793 static int
14794 api_get_first_msg_id (vat_main_t * vam)
14795 {
14796   vl_api_get_first_msg_id_t *mp;
14797   unformat_input_t *i = vam->input;
14798   u8 *name;
14799   u8 name_set = 0;
14800   int ret;
14801
14802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14803     {
14804       if (unformat (i, "client %s", &name))
14805         name_set = 1;
14806       else
14807         break;
14808     }
14809
14810   if (name_set == 0)
14811     {
14812       errmsg ("missing client name");
14813       return -99;
14814     }
14815   vec_add1 (name, 0);
14816
14817   if (vec_len (name) > 63)
14818     {
14819       errmsg ("client name too long");
14820       return -99;
14821     }
14822
14823   M (GET_FIRST_MSG_ID, mp);
14824   clib_memcpy (mp->name, name, vec_len (name));
14825   S (mp);
14826   W (ret);
14827   return ret;
14828 }
14829
14830 static int
14831 api_cop_interface_enable_disable (vat_main_t * vam)
14832 {
14833   unformat_input_t *line_input = vam->input;
14834   vl_api_cop_interface_enable_disable_t *mp;
14835   u32 sw_if_index = ~0;
14836   u8 enable_disable = 1;
14837   int ret;
14838
14839   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14840     {
14841       if (unformat (line_input, "disable"))
14842         enable_disable = 0;
14843       if (unformat (line_input, "enable"))
14844         enable_disable = 1;
14845       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14846                          vam, &sw_if_index))
14847         ;
14848       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14849         ;
14850       else
14851         break;
14852     }
14853
14854   if (sw_if_index == ~0)
14855     {
14856       errmsg ("missing interface name or sw_if_index");
14857       return -99;
14858     }
14859
14860   /* Construct the API message */
14861   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14862   mp->sw_if_index = ntohl (sw_if_index);
14863   mp->enable_disable = enable_disable;
14864
14865   /* send it... */
14866   S (mp);
14867   /* Wait for the reply */
14868   W (ret);
14869   return ret;
14870 }
14871
14872 static int
14873 api_cop_whitelist_enable_disable (vat_main_t * vam)
14874 {
14875   unformat_input_t *line_input = vam->input;
14876   vl_api_cop_whitelist_enable_disable_t *mp;
14877   u32 sw_if_index = ~0;
14878   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14879   u32 fib_id = 0;
14880   int ret;
14881
14882   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14883     {
14884       if (unformat (line_input, "ip4"))
14885         ip4 = 1;
14886       else if (unformat (line_input, "ip6"))
14887         ip6 = 1;
14888       else if (unformat (line_input, "default"))
14889         default_cop = 1;
14890       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14891                          vam, &sw_if_index))
14892         ;
14893       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14894         ;
14895       else if (unformat (line_input, "fib-id %d", &fib_id))
14896         ;
14897       else
14898         break;
14899     }
14900
14901   if (sw_if_index == ~0)
14902     {
14903       errmsg ("missing interface name or sw_if_index");
14904       return -99;
14905     }
14906
14907   /* Construct the API message */
14908   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14909   mp->sw_if_index = ntohl (sw_if_index);
14910   mp->fib_id = ntohl (fib_id);
14911   mp->ip4 = ip4;
14912   mp->ip6 = ip6;
14913   mp->default_cop = default_cop;
14914
14915   /* send it... */
14916   S (mp);
14917   /* Wait for the reply */
14918   W (ret);
14919   return ret;
14920 }
14921
14922 static int
14923 api_get_node_graph (vat_main_t * vam)
14924 {
14925   vl_api_get_node_graph_t *mp;
14926   int ret;
14927
14928   M (GET_NODE_GRAPH, mp);
14929
14930   /* send it... */
14931   S (mp);
14932   /* Wait for the reply */
14933   W (ret);
14934   return ret;
14935 }
14936
14937 /* *INDENT-OFF* */
14938 /** Used for parsing LISP eids */
14939 typedef CLIB_PACKED(struct{
14940   u8 addr[16];   /**< eid address */
14941   u32 len;       /**< prefix length if IP */
14942   u8 type;      /**< type of eid */
14943 }) lisp_eid_vat_t;
14944 /* *INDENT-ON* */
14945
14946 static uword
14947 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14948 {
14949   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14950
14951   memset (a, 0, sizeof (a[0]));
14952
14953   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14954     {
14955       a->type = 0;              /* ipv4 type */
14956     }
14957   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14958     {
14959       a->type = 1;              /* ipv6 type */
14960     }
14961   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14962     {
14963       a->type = 2;              /* mac type */
14964     }
14965   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14966     {
14967       a->type = 3;              /* NSH type */
14968       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14969       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14970     }
14971   else
14972     {
14973       return 0;
14974     }
14975
14976   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14977     {
14978       return 0;
14979     }
14980
14981   return 1;
14982 }
14983
14984 static int
14985 lisp_eid_size_vat (u8 type)
14986 {
14987   switch (type)
14988     {
14989     case 0:
14990       return 4;
14991     case 1:
14992       return 16;
14993     case 2:
14994       return 6;
14995     case 3:
14996       return 5;
14997     }
14998   return 0;
14999 }
15000
15001 static void
15002 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15003 {
15004   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15005 }
15006
15007 static int
15008 api_one_add_del_locator_set (vat_main_t * vam)
15009 {
15010   unformat_input_t *input = vam->input;
15011   vl_api_one_add_del_locator_set_t *mp;
15012   u8 is_add = 1;
15013   u8 *locator_set_name = NULL;
15014   u8 locator_set_name_set = 0;
15015   vl_api_local_locator_t locator, *locators = 0;
15016   u32 sw_if_index, priority, weight;
15017   u32 data_len = 0;
15018
15019   int ret;
15020   /* Parse args required to build the message */
15021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (input, "del"))
15024         {
15025           is_add = 0;
15026         }
15027       else if (unformat (input, "locator-set %s", &locator_set_name))
15028         {
15029           locator_set_name_set = 1;
15030         }
15031       else if (unformat (input, "sw_if_index %u p %u w %u",
15032                          &sw_if_index, &priority, &weight))
15033         {
15034           locator.sw_if_index = htonl (sw_if_index);
15035           locator.priority = priority;
15036           locator.weight = weight;
15037           vec_add1 (locators, locator);
15038         }
15039       else
15040         if (unformat
15041             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15042              &sw_if_index, &priority, &weight))
15043         {
15044           locator.sw_if_index = htonl (sw_if_index);
15045           locator.priority = priority;
15046           locator.weight = weight;
15047           vec_add1 (locators, locator);
15048         }
15049       else
15050         break;
15051     }
15052
15053   if (locator_set_name_set == 0)
15054     {
15055       errmsg ("missing locator-set name");
15056       vec_free (locators);
15057       return -99;
15058     }
15059
15060   if (vec_len (locator_set_name) > 64)
15061     {
15062       errmsg ("locator-set name too long");
15063       vec_free (locator_set_name);
15064       vec_free (locators);
15065       return -99;
15066     }
15067   vec_add1 (locator_set_name, 0);
15068
15069   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15070
15071   /* Construct the API message */
15072   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15073
15074   mp->is_add = is_add;
15075   clib_memcpy (mp->locator_set_name, locator_set_name,
15076                vec_len (locator_set_name));
15077   vec_free (locator_set_name);
15078
15079   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15080   if (locators)
15081     clib_memcpy (mp->locators, locators, data_len);
15082   vec_free (locators);
15083
15084   /* send it... */
15085   S (mp);
15086
15087   /* Wait for a reply... */
15088   W (ret);
15089   return ret;
15090 }
15091
15092 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15093
15094 static int
15095 api_one_add_del_locator (vat_main_t * vam)
15096 {
15097   unformat_input_t *input = vam->input;
15098   vl_api_one_add_del_locator_t *mp;
15099   u32 tmp_if_index = ~0;
15100   u32 sw_if_index = ~0;
15101   u8 sw_if_index_set = 0;
15102   u8 sw_if_index_if_name_set = 0;
15103   u32 priority = ~0;
15104   u8 priority_set = 0;
15105   u32 weight = ~0;
15106   u8 weight_set = 0;
15107   u8 is_add = 1;
15108   u8 *locator_set_name = NULL;
15109   u8 locator_set_name_set = 0;
15110   int ret;
15111
15112   /* Parse args required to build the message */
15113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15114     {
15115       if (unformat (input, "del"))
15116         {
15117           is_add = 0;
15118         }
15119       else if (unformat (input, "locator-set %s", &locator_set_name))
15120         {
15121           locator_set_name_set = 1;
15122         }
15123       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15124                          &tmp_if_index))
15125         {
15126           sw_if_index_if_name_set = 1;
15127           sw_if_index = tmp_if_index;
15128         }
15129       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15130         {
15131           sw_if_index_set = 1;
15132           sw_if_index = tmp_if_index;
15133         }
15134       else if (unformat (input, "p %d", &priority))
15135         {
15136           priority_set = 1;
15137         }
15138       else if (unformat (input, "w %d", &weight))
15139         {
15140           weight_set = 1;
15141         }
15142       else
15143         break;
15144     }
15145
15146   if (locator_set_name_set == 0)
15147     {
15148       errmsg ("missing locator-set name");
15149       return -99;
15150     }
15151
15152   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15153     {
15154       errmsg ("missing sw_if_index");
15155       vec_free (locator_set_name);
15156       return -99;
15157     }
15158
15159   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15160     {
15161       errmsg ("cannot use both params interface name and sw_if_index");
15162       vec_free (locator_set_name);
15163       return -99;
15164     }
15165
15166   if (priority_set == 0)
15167     {
15168       errmsg ("missing locator-set priority");
15169       vec_free (locator_set_name);
15170       return -99;
15171     }
15172
15173   if (weight_set == 0)
15174     {
15175       errmsg ("missing locator-set weight");
15176       vec_free (locator_set_name);
15177       return -99;
15178     }
15179
15180   if (vec_len (locator_set_name) > 64)
15181     {
15182       errmsg ("locator-set name too long");
15183       vec_free (locator_set_name);
15184       return -99;
15185     }
15186   vec_add1 (locator_set_name, 0);
15187
15188   /* Construct the API message */
15189   M (ONE_ADD_DEL_LOCATOR, mp);
15190
15191   mp->is_add = is_add;
15192   mp->sw_if_index = ntohl (sw_if_index);
15193   mp->priority = priority;
15194   mp->weight = weight;
15195   clib_memcpy (mp->locator_set_name, locator_set_name,
15196                vec_len (locator_set_name));
15197   vec_free (locator_set_name);
15198
15199   /* send it... */
15200   S (mp);
15201
15202   /* Wait for a reply... */
15203   W (ret);
15204   return ret;
15205 }
15206
15207 #define api_lisp_add_del_locator api_one_add_del_locator
15208
15209 uword
15210 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15211 {
15212   u32 *key_id = va_arg (*args, u32 *);
15213   u8 *s = 0;
15214
15215   if (unformat (input, "%s", &s))
15216     {
15217       if (!strcmp ((char *) s, "sha1"))
15218         key_id[0] = HMAC_SHA_1_96;
15219       else if (!strcmp ((char *) s, "sha256"))
15220         key_id[0] = HMAC_SHA_256_128;
15221       else
15222         {
15223           clib_warning ("invalid key_id: '%s'", s);
15224           key_id[0] = HMAC_NO_KEY;
15225         }
15226     }
15227   else
15228     return 0;
15229
15230   vec_free (s);
15231   return 1;
15232 }
15233
15234 static int
15235 api_one_add_del_local_eid (vat_main_t * vam)
15236 {
15237   unformat_input_t *input = vam->input;
15238   vl_api_one_add_del_local_eid_t *mp;
15239   u8 is_add = 1;
15240   u8 eid_set = 0;
15241   lisp_eid_vat_t _eid, *eid = &_eid;
15242   u8 *locator_set_name = 0;
15243   u8 locator_set_name_set = 0;
15244   u32 vni = 0;
15245   u16 key_id = 0;
15246   u8 *key = 0;
15247   int ret;
15248
15249   /* Parse args required to build the message */
15250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15251     {
15252       if (unformat (input, "del"))
15253         {
15254           is_add = 0;
15255         }
15256       else if (unformat (input, "vni %d", &vni))
15257         {
15258           ;
15259         }
15260       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15261         {
15262           eid_set = 1;
15263         }
15264       else if (unformat (input, "locator-set %s", &locator_set_name))
15265         {
15266           locator_set_name_set = 1;
15267         }
15268       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15269         ;
15270       else if (unformat (input, "secret-key %_%v%_", &key))
15271         ;
15272       else
15273         break;
15274     }
15275
15276   if (locator_set_name_set == 0)
15277     {
15278       errmsg ("missing locator-set name");
15279       return -99;
15280     }
15281
15282   if (0 == eid_set)
15283     {
15284       errmsg ("EID address not set!");
15285       vec_free (locator_set_name);
15286       return -99;
15287     }
15288
15289   if (key && (0 == key_id))
15290     {
15291       errmsg ("invalid key_id!");
15292       return -99;
15293     }
15294
15295   if (vec_len (key) > 64)
15296     {
15297       errmsg ("key too long");
15298       vec_free (key);
15299       return -99;
15300     }
15301
15302   if (vec_len (locator_set_name) > 64)
15303     {
15304       errmsg ("locator-set name too long");
15305       vec_free (locator_set_name);
15306       return -99;
15307     }
15308   vec_add1 (locator_set_name, 0);
15309
15310   /* Construct the API message */
15311   M (ONE_ADD_DEL_LOCAL_EID, mp);
15312
15313   mp->is_add = is_add;
15314   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15315   mp->eid_type = eid->type;
15316   mp->prefix_len = eid->len;
15317   mp->vni = clib_host_to_net_u32 (vni);
15318   mp->key_id = clib_host_to_net_u16 (key_id);
15319   clib_memcpy (mp->locator_set_name, locator_set_name,
15320                vec_len (locator_set_name));
15321   clib_memcpy (mp->key, key, vec_len (key));
15322
15323   vec_free (locator_set_name);
15324   vec_free (key);
15325
15326   /* send it... */
15327   S (mp);
15328
15329   /* Wait for a reply... */
15330   W (ret);
15331   return ret;
15332 }
15333
15334 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15335
15336 static int
15337 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15338 {
15339   u32 dp_table = 0, vni = 0;;
15340   unformat_input_t *input = vam->input;
15341   vl_api_gpe_add_del_fwd_entry_t *mp;
15342   u8 is_add = 1;
15343   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15344   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15345   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15346   u32 action = ~0, w;
15347   ip4_address_t rmt_rloc4, lcl_rloc4;
15348   ip6_address_t rmt_rloc6, lcl_rloc6;
15349   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15350   int ret;
15351
15352   memset (&rloc, 0, sizeof (rloc));
15353
15354   /* Parse args required to build the message */
15355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15356     {
15357       if (unformat (input, "del"))
15358         is_add = 0;
15359       else if (unformat (input, "add"))
15360         is_add = 1;
15361       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15362         {
15363           rmt_eid_set = 1;
15364         }
15365       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15366         {
15367           lcl_eid_set = 1;
15368         }
15369       else if (unformat (input, "vrf %d", &dp_table))
15370         ;
15371       else if (unformat (input, "bd %d", &dp_table))
15372         ;
15373       else if (unformat (input, "vni %d", &vni))
15374         ;
15375       else if (unformat (input, "w %d", &w))
15376         {
15377           if (!curr_rloc)
15378             {
15379               errmsg ("No RLOC configured for setting priority/weight!");
15380               return -99;
15381             }
15382           curr_rloc->weight = w;
15383         }
15384       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15385                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15386         {
15387           rloc.is_ip4 = 1;
15388
15389           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15390           rloc.weight = 0;
15391           vec_add1 (lcl_locs, rloc);
15392
15393           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15394           vec_add1 (rmt_locs, rloc);
15395           /* weight saved in rmt loc */
15396           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15397         }
15398       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15399                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15400         {
15401           rloc.is_ip4 = 0;
15402           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15403           rloc.weight = 0;
15404           vec_add1 (lcl_locs, rloc);
15405
15406           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15407           vec_add1 (rmt_locs, rloc);
15408           /* weight saved in rmt loc */
15409           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15410         }
15411       else if (unformat (input, "action %d", &action))
15412         {
15413           ;
15414         }
15415       else
15416         {
15417           clib_warning ("parse error '%U'", format_unformat_error, input);
15418           return -99;
15419         }
15420     }
15421
15422   if (!rmt_eid_set)
15423     {
15424       errmsg ("remote eid addresses not set");
15425       return -99;
15426     }
15427
15428   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15429     {
15430       errmsg ("eid types don't match");
15431       return -99;
15432     }
15433
15434   if (0 == rmt_locs && (u32) ~ 0 == action)
15435     {
15436       errmsg ("action not set for negative mapping");
15437       return -99;
15438     }
15439
15440   /* Construct the API message */
15441   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15442       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15443
15444   mp->is_add = is_add;
15445   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15446   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15447   mp->eid_type = rmt_eid->type;
15448   mp->dp_table = clib_host_to_net_u32 (dp_table);
15449   mp->vni = clib_host_to_net_u32 (vni);
15450   mp->rmt_len = rmt_eid->len;
15451   mp->lcl_len = lcl_eid->len;
15452   mp->action = action;
15453
15454   if (0 != rmt_locs && 0 != lcl_locs)
15455     {
15456       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15457       clib_memcpy (mp->locs, lcl_locs,
15458                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15459
15460       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15461       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15462                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15463     }
15464   vec_free (lcl_locs);
15465   vec_free (rmt_locs);
15466
15467   /* send it... */
15468   S (mp);
15469
15470   /* Wait for a reply... */
15471   W (ret);
15472   return ret;
15473 }
15474
15475 static int
15476 api_one_add_del_map_server (vat_main_t * vam)
15477 {
15478   unformat_input_t *input = vam->input;
15479   vl_api_one_add_del_map_server_t *mp;
15480   u8 is_add = 1;
15481   u8 ipv4_set = 0;
15482   u8 ipv6_set = 0;
15483   ip4_address_t ipv4;
15484   ip6_address_t ipv6;
15485   int ret;
15486
15487   /* Parse args required to build the message */
15488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15489     {
15490       if (unformat (input, "del"))
15491         {
15492           is_add = 0;
15493         }
15494       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15495         {
15496           ipv4_set = 1;
15497         }
15498       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15499         {
15500           ipv6_set = 1;
15501         }
15502       else
15503         break;
15504     }
15505
15506   if (ipv4_set && ipv6_set)
15507     {
15508       errmsg ("both eid v4 and v6 addresses set");
15509       return -99;
15510     }
15511
15512   if (!ipv4_set && !ipv6_set)
15513     {
15514       errmsg ("eid addresses not set");
15515       return -99;
15516     }
15517
15518   /* Construct the API message */
15519   M (ONE_ADD_DEL_MAP_SERVER, mp);
15520
15521   mp->is_add = is_add;
15522   if (ipv6_set)
15523     {
15524       mp->is_ipv6 = 1;
15525       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15526     }
15527   else
15528     {
15529       mp->is_ipv6 = 0;
15530       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15531     }
15532
15533   /* send it... */
15534   S (mp);
15535
15536   /* Wait for a reply... */
15537   W (ret);
15538   return ret;
15539 }
15540
15541 #define api_lisp_add_del_map_server api_one_add_del_map_server
15542
15543 static int
15544 api_one_add_del_map_resolver (vat_main_t * vam)
15545 {
15546   unformat_input_t *input = vam->input;
15547   vl_api_one_add_del_map_resolver_t *mp;
15548   u8 is_add = 1;
15549   u8 ipv4_set = 0;
15550   u8 ipv6_set = 0;
15551   ip4_address_t ipv4;
15552   ip6_address_t ipv6;
15553   int ret;
15554
15555   /* Parse args required to build the message */
15556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15557     {
15558       if (unformat (input, "del"))
15559         {
15560           is_add = 0;
15561         }
15562       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15563         {
15564           ipv4_set = 1;
15565         }
15566       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15567         {
15568           ipv6_set = 1;
15569         }
15570       else
15571         break;
15572     }
15573
15574   if (ipv4_set && ipv6_set)
15575     {
15576       errmsg ("both eid v4 and v6 addresses set");
15577       return -99;
15578     }
15579
15580   if (!ipv4_set && !ipv6_set)
15581     {
15582       errmsg ("eid addresses not set");
15583       return -99;
15584     }
15585
15586   /* Construct the API message */
15587   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15588
15589   mp->is_add = is_add;
15590   if (ipv6_set)
15591     {
15592       mp->is_ipv6 = 1;
15593       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15594     }
15595   else
15596     {
15597       mp->is_ipv6 = 0;
15598       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15599     }
15600
15601   /* send it... */
15602   S (mp);
15603
15604   /* Wait for a reply... */
15605   W (ret);
15606   return ret;
15607 }
15608
15609 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15610
15611 static int
15612 api_lisp_gpe_enable_disable (vat_main_t * vam)
15613 {
15614   unformat_input_t *input = vam->input;
15615   vl_api_gpe_enable_disable_t *mp;
15616   u8 is_set = 0;
15617   u8 is_en = 1;
15618   int ret;
15619
15620   /* Parse args required to build the message */
15621   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15622     {
15623       if (unformat (input, "enable"))
15624         {
15625           is_set = 1;
15626           is_en = 1;
15627         }
15628       else if (unformat (input, "disable"))
15629         {
15630           is_set = 1;
15631           is_en = 0;
15632         }
15633       else
15634         break;
15635     }
15636
15637   if (is_set == 0)
15638     {
15639       errmsg ("Value not set");
15640       return -99;
15641     }
15642
15643   /* Construct the API message */
15644   M (GPE_ENABLE_DISABLE, mp);
15645
15646   mp->is_en = is_en;
15647
15648   /* send it... */
15649   S (mp);
15650
15651   /* Wait for a reply... */
15652   W (ret);
15653   return ret;
15654 }
15655
15656 static int
15657 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15658 {
15659   unformat_input_t *input = vam->input;
15660   vl_api_one_rloc_probe_enable_disable_t *mp;
15661   u8 is_set = 0;
15662   u8 is_en = 0;
15663   int ret;
15664
15665   /* Parse args required to build the message */
15666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15667     {
15668       if (unformat (input, "enable"))
15669         {
15670           is_set = 1;
15671           is_en = 1;
15672         }
15673       else if (unformat (input, "disable"))
15674         is_set = 1;
15675       else
15676         break;
15677     }
15678
15679   if (!is_set)
15680     {
15681       errmsg ("Value not set");
15682       return -99;
15683     }
15684
15685   /* Construct the API message */
15686   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15687
15688   mp->is_enabled = is_en;
15689
15690   /* send it... */
15691   S (mp);
15692
15693   /* Wait for a reply... */
15694   W (ret);
15695   return ret;
15696 }
15697
15698 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15699
15700 static int
15701 api_one_map_register_enable_disable (vat_main_t * vam)
15702 {
15703   unformat_input_t *input = vam->input;
15704   vl_api_one_map_register_enable_disable_t *mp;
15705   u8 is_set = 0;
15706   u8 is_en = 0;
15707   int ret;
15708
15709   /* Parse args required to build the message */
15710   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15711     {
15712       if (unformat (input, "enable"))
15713         {
15714           is_set = 1;
15715           is_en = 1;
15716         }
15717       else if (unformat (input, "disable"))
15718         is_set = 1;
15719       else
15720         break;
15721     }
15722
15723   if (!is_set)
15724     {
15725       errmsg ("Value not set");
15726       return -99;
15727     }
15728
15729   /* Construct the API message */
15730   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15731
15732   mp->is_enabled = is_en;
15733
15734   /* send it... */
15735   S (mp);
15736
15737   /* Wait for a reply... */
15738   W (ret);
15739   return ret;
15740 }
15741
15742 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15743
15744 static int
15745 api_one_enable_disable (vat_main_t * vam)
15746 {
15747   unformat_input_t *input = vam->input;
15748   vl_api_one_enable_disable_t *mp;
15749   u8 is_set = 0;
15750   u8 is_en = 0;
15751   int ret;
15752
15753   /* Parse args required to build the message */
15754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15755     {
15756       if (unformat (input, "enable"))
15757         {
15758           is_set = 1;
15759           is_en = 1;
15760         }
15761       else if (unformat (input, "disable"))
15762         {
15763           is_set = 1;
15764         }
15765       else
15766         break;
15767     }
15768
15769   if (!is_set)
15770     {
15771       errmsg ("Value not set");
15772       return -99;
15773     }
15774
15775   /* Construct the API message */
15776   M (ONE_ENABLE_DISABLE, mp);
15777
15778   mp->is_en = is_en;
15779
15780   /* send it... */
15781   S (mp);
15782
15783   /* Wait for a reply... */
15784   W (ret);
15785   return ret;
15786 }
15787
15788 #define api_lisp_enable_disable api_one_enable_disable
15789
15790 static int
15791 api_show_one_map_register_state (vat_main_t * vam)
15792 {
15793   vl_api_show_one_map_register_state_t *mp;
15794   int ret;
15795
15796   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15797
15798   /* send */
15799   S (mp);
15800
15801   /* wait for reply */
15802   W (ret);
15803   return ret;
15804 }
15805
15806 #define api_show_lisp_map_register_state api_show_one_map_register_state
15807
15808 static int
15809 api_show_one_rloc_probe_state (vat_main_t * vam)
15810 {
15811   vl_api_show_one_rloc_probe_state_t *mp;
15812   int ret;
15813
15814   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15815
15816   /* send */
15817   S (mp);
15818
15819   /* wait for reply */
15820   W (ret);
15821   return ret;
15822 }
15823
15824 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15825
15826 static int
15827 api_one_add_del_ndp_entry (vat_main_t * vam)
15828 {
15829   vl_api_one_add_del_ndp_entry_t *mp;
15830   unformat_input_t *input = vam->input;
15831   u8 is_add = 1;
15832   u8 mac_set = 0;
15833   u8 bd_set = 0;
15834   u8 ip_set = 0;
15835   u8 mac[6] = { 0, };
15836   u8 ip6[16] = { 0, };
15837   u32 bd = ~0;
15838   int ret;
15839
15840   /* Parse args required to build the message */
15841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15842     {
15843       if (unformat (input, "del"))
15844         is_add = 0;
15845       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15846         mac_set = 1;
15847       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15848         ip_set = 1;
15849       else if (unformat (input, "bd %d", &bd))
15850         bd_set = 1;
15851       else
15852         {
15853           errmsg ("parse error '%U'", format_unformat_error, input);
15854           return -99;
15855         }
15856     }
15857
15858   if (!bd_set || !ip_set || (!mac_set && is_add))
15859     {
15860       errmsg ("Missing BD, IP or MAC!");
15861       return -99;
15862     }
15863
15864   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15865   mp->is_add = is_add;
15866   clib_memcpy (mp->mac, mac, 6);
15867   mp->bd = clib_host_to_net_u32 (bd);
15868   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15869
15870   /* send */
15871   S (mp);
15872
15873   /* wait for reply */
15874   W (ret);
15875   return ret;
15876 }
15877
15878 static int
15879 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15880 {
15881   vl_api_one_add_del_l2_arp_entry_t *mp;
15882   unformat_input_t *input = vam->input;
15883   u8 is_add = 1;
15884   u8 mac_set = 0;
15885   u8 bd_set = 0;
15886   u8 ip_set = 0;
15887   u8 mac[6] = { 0, };
15888   u32 ip4 = 0, bd = ~0;
15889   int ret;
15890
15891   /* Parse args required to build the message */
15892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15893     {
15894       if (unformat (input, "del"))
15895         is_add = 0;
15896       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15897         mac_set = 1;
15898       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15899         ip_set = 1;
15900       else if (unformat (input, "bd %d", &bd))
15901         bd_set = 1;
15902       else
15903         {
15904           errmsg ("parse error '%U'", format_unformat_error, input);
15905           return -99;
15906         }
15907     }
15908
15909   if (!bd_set || !ip_set || (!mac_set && is_add))
15910     {
15911       errmsg ("Missing BD, IP or MAC!");
15912       return -99;
15913     }
15914
15915   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15916   mp->is_add = is_add;
15917   clib_memcpy (mp->mac, mac, 6);
15918   mp->bd = clib_host_to_net_u32 (bd);
15919   mp->ip4 = ip4;
15920
15921   /* send */
15922   S (mp);
15923
15924   /* wait for reply */
15925   W (ret);
15926   return ret;
15927 }
15928
15929 static int
15930 api_one_ndp_bd_get (vat_main_t * vam)
15931 {
15932   vl_api_one_ndp_bd_get_t *mp;
15933   int ret;
15934
15935   M (ONE_NDP_BD_GET, mp);
15936
15937   /* send */
15938   S (mp);
15939
15940   /* wait for reply */
15941   W (ret);
15942   return ret;
15943 }
15944
15945 static int
15946 api_one_ndp_entries_get (vat_main_t * vam)
15947 {
15948   vl_api_one_ndp_entries_get_t *mp;
15949   unformat_input_t *input = vam->input;
15950   u8 bd_set = 0;
15951   u32 bd = ~0;
15952   int ret;
15953
15954   /* Parse args required to build the message */
15955   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15956     {
15957       if (unformat (input, "bd %d", &bd))
15958         bd_set = 1;
15959       else
15960         {
15961           errmsg ("parse error '%U'", format_unformat_error, input);
15962           return -99;
15963         }
15964     }
15965
15966   if (!bd_set)
15967     {
15968       errmsg ("Expected bridge domain!");
15969       return -99;
15970     }
15971
15972   M (ONE_NDP_ENTRIES_GET, mp);
15973   mp->bd = clib_host_to_net_u32 (bd);
15974
15975   /* send */
15976   S (mp);
15977
15978   /* wait for reply */
15979   W (ret);
15980   return ret;
15981 }
15982
15983 static int
15984 api_one_l2_arp_bd_get (vat_main_t * vam)
15985 {
15986   vl_api_one_l2_arp_bd_get_t *mp;
15987   int ret;
15988
15989   M (ONE_L2_ARP_BD_GET, mp);
15990
15991   /* send */
15992   S (mp);
15993
15994   /* wait for reply */
15995   W (ret);
15996   return ret;
15997 }
15998
15999 static int
16000 api_one_l2_arp_entries_get (vat_main_t * vam)
16001 {
16002   vl_api_one_l2_arp_entries_get_t *mp;
16003   unformat_input_t *input = vam->input;
16004   u8 bd_set = 0;
16005   u32 bd = ~0;
16006   int ret;
16007
16008   /* Parse args required to build the message */
16009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16010     {
16011       if (unformat (input, "bd %d", &bd))
16012         bd_set = 1;
16013       else
16014         {
16015           errmsg ("parse error '%U'", format_unformat_error, input);
16016           return -99;
16017         }
16018     }
16019
16020   if (!bd_set)
16021     {
16022       errmsg ("Expected bridge domain!");
16023       return -99;
16024     }
16025
16026   M (ONE_L2_ARP_ENTRIES_GET, mp);
16027   mp->bd = clib_host_to_net_u32 (bd);
16028
16029   /* send */
16030   S (mp);
16031
16032   /* wait for reply */
16033   W (ret);
16034   return ret;
16035 }
16036
16037 static int
16038 api_one_stats_enable_disable (vat_main_t * vam)
16039 {
16040   vl_api_one_stats_enable_disable_t *mp;
16041   unformat_input_t *input = vam->input;
16042   u8 is_set = 0;
16043   u8 is_en = 0;
16044   int ret;
16045
16046   /* Parse args required to build the message */
16047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16048     {
16049       if (unformat (input, "enable"))
16050         {
16051           is_set = 1;
16052           is_en = 1;
16053         }
16054       else if (unformat (input, "disable"))
16055         {
16056           is_set = 1;
16057         }
16058       else
16059         break;
16060     }
16061
16062   if (!is_set)
16063     {
16064       errmsg ("Value not set");
16065       return -99;
16066     }
16067
16068   M (ONE_STATS_ENABLE_DISABLE, mp);
16069   mp->is_en = is_en;
16070
16071   /* send */
16072   S (mp);
16073
16074   /* wait for reply */
16075   W (ret);
16076   return ret;
16077 }
16078
16079 static int
16080 api_show_one_stats_enable_disable (vat_main_t * vam)
16081 {
16082   vl_api_show_one_stats_enable_disable_t *mp;
16083   int ret;
16084
16085   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16086
16087   /* send */
16088   S (mp);
16089
16090   /* wait for reply */
16091   W (ret);
16092   return ret;
16093 }
16094
16095 static int
16096 api_show_one_map_request_mode (vat_main_t * vam)
16097 {
16098   vl_api_show_one_map_request_mode_t *mp;
16099   int ret;
16100
16101   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16102
16103   /* send */
16104   S (mp);
16105
16106   /* wait for reply */
16107   W (ret);
16108   return ret;
16109 }
16110
16111 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16112
16113 static int
16114 api_one_map_request_mode (vat_main_t * vam)
16115 {
16116   unformat_input_t *input = vam->input;
16117   vl_api_one_map_request_mode_t *mp;
16118   u8 mode = 0;
16119   int ret;
16120
16121   /* Parse args required to build the message */
16122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16123     {
16124       if (unformat (input, "dst-only"))
16125         mode = 0;
16126       else if (unformat (input, "src-dst"))
16127         mode = 1;
16128       else
16129         {
16130           errmsg ("parse error '%U'", format_unformat_error, input);
16131           return -99;
16132         }
16133     }
16134
16135   M (ONE_MAP_REQUEST_MODE, mp);
16136
16137   mp->mode = mode;
16138
16139   /* send */
16140   S (mp);
16141
16142   /* wait for reply */
16143   W (ret);
16144   return ret;
16145 }
16146
16147 #define api_lisp_map_request_mode api_one_map_request_mode
16148
16149 /**
16150  * Enable/disable ONE proxy ITR.
16151  *
16152  * @param vam vpp API test context
16153  * @return return code
16154  */
16155 static int
16156 api_one_pitr_set_locator_set (vat_main_t * vam)
16157 {
16158   u8 ls_name_set = 0;
16159   unformat_input_t *input = vam->input;
16160   vl_api_one_pitr_set_locator_set_t *mp;
16161   u8 is_add = 1;
16162   u8 *ls_name = 0;
16163   int ret;
16164
16165   /* Parse args required to build the message */
16166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16167     {
16168       if (unformat (input, "del"))
16169         is_add = 0;
16170       else if (unformat (input, "locator-set %s", &ls_name))
16171         ls_name_set = 1;
16172       else
16173         {
16174           errmsg ("parse error '%U'", format_unformat_error, input);
16175           return -99;
16176         }
16177     }
16178
16179   if (!ls_name_set)
16180     {
16181       errmsg ("locator-set name not set!");
16182       return -99;
16183     }
16184
16185   M (ONE_PITR_SET_LOCATOR_SET, mp);
16186
16187   mp->is_add = is_add;
16188   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16189   vec_free (ls_name);
16190
16191   /* send */
16192   S (mp);
16193
16194   /* wait for reply */
16195   W (ret);
16196   return ret;
16197 }
16198
16199 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16200
16201 static int
16202 api_one_nsh_set_locator_set (vat_main_t * vam)
16203 {
16204   u8 ls_name_set = 0;
16205   unformat_input_t *input = vam->input;
16206   vl_api_one_nsh_set_locator_set_t *mp;
16207   u8 is_add = 1;
16208   u8 *ls_name = 0;
16209   int ret;
16210
16211   /* Parse args required to build the message */
16212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16213     {
16214       if (unformat (input, "del"))
16215         is_add = 0;
16216       else if (unformat (input, "ls %s", &ls_name))
16217         ls_name_set = 1;
16218       else
16219         {
16220           errmsg ("parse error '%U'", format_unformat_error, input);
16221           return -99;
16222         }
16223     }
16224
16225   if (!ls_name_set && is_add)
16226     {
16227       errmsg ("locator-set name not set!");
16228       return -99;
16229     }
16230
16231   M (ONE_NSH_SET_LOCATOR_SET, mp);
16232
16233   mp->is_add = is_add;
16234   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16235   vec_free (ls_name);
16236
16237   /* send */
16238   S (mp);
16239
16240   /* wait for reply */
16241   W (ret);
16242   return ret;
16243 }
16244
16245 static int
16246 api_show_one_pitr (vat_main_t * vam)
16247 {
16248   vl_api_show_one_pitr_t *mp;
16249   int ret;
16250
16251   if (!vam->json_output)
16252     {
16253       print (vam->ofp, "%=20s", "lisp status:");
16254     }
16255
16256   M (SHOW_ONE_PITR, mp);
16257   /* send it... */
16258   S (mp);
16259
16260   /* Wait for a reply... */
16261   W (ret);
16262   return ret;
16263 }
16264
16265 #define api_show_lisp_pitr api_show_one_pitr
16266
16267 static int
16268 api_one_use_petr (vat_main_t * vam)
16269 {
16270   unformat_input_t *input = vam->input;
16271   vl_api_one_use_petr_t *mp;
16272   u8 is_add = 0;
16273   ip_address_t ip;
16274   int ret;
16275
16276   memset (&ip, 0, sizeof (ip));
16277
16278   /* Parse args required to build the message */
16279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16280     {
16281       if (unformat (input, "disable"))
16282         is_add = 0;
16283       else
16284         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16285         {
16286           is_add = 1;
16287           ip_addr_version (&ip) = IP4;
16288         }
16289       else
16290         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16291         {
16292           is_add = 1;
16293           ip_addr_version (&ip) = IP6;
16294         }
16295       else
16296         {
16297           errmsg ("parse error '%U'", format_unformat_error, input);
16298           return -99;
16299         }
16300     }
16301
16302   M (ONE_USE_PETR, mp);
16303
16304   mp->is_add = is_add;
16305   if (is_add)
16306     {
16307       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16308       if (mp->is_ip4)
16309         clib_memcpy (mp->address, &ip, 4);
16310       else
16311         clib_memcpy (mp->address, &ip, 16);
16312     }
16313
16314   /* send */
16315   S (mp);
16316
16317   /* wait for reply */
16318   W (ret);
16319   return ret;
16320 }
16321
16322 #define api_lisp_use_petr api_one_use_petr
16323
16324 static int
16325 api_show_one_nsh_mapping (vat_main_t * vam)
16326 {
16327   vl_api_show_one_use_petr_t *mp;
16328   int ret;
16329
16330   if (!vam->json_output)
16331     {
16332       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16333     }
16334
16335   M (SHOW_ONE_NSH_MAPPING, mp);
16336   /* send it... */
16337   S (mp);
16338
16339   /* Wait for a reply... */
16340   W (ret);
16341   return ret;
16342 }
16343
16344 static int
16345 api_show_one_use_petr (vat_main_t * vam)
16346 {
16347   vl_api_show_one_use_petr_t *mp;
16348   int ret;
16349
16350   if (!vam->json_output)
16351     {
16352       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16353     }
16354
16355   M (SHOW_ONE_USE_PETR, mp);
16356   /* send it... */
16357   S (mp);
16358
16359   /* Wait for a reply... */
16360   W (ret);
16361   return ret;
16362 }
16363
16364 #define api_show_lisp_use_petr api_show_one_use_petr
16365
16366 /**
16367  * Add/delete mapping between vni and vrf
16368  */
16369 static int
16370 api_one_eid_table_add_del_map (vat_main_t * vam)
16371 {
16372   unformat_input_t *input = vam->input;
16373   vl_api_one_eid_table_add_del_map_t *mp;
16374   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16375   u32 vni, vrf, bd_index;
16376   int ret;
16377
16378   /* Parse args required to build the message */
16379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16380     {
16381       if (unformat (input, "del"))
16382         is_add = 0;
16383       else if (unformat (input, "vrf %d", &vrf))
16384         vrf_set = 1;
16385       else if (unformat (input, "bd_index %d", &bd_index))
16386         bd_index_set = 1;
16387       else if (unformat (input, "vni %d", &vni))
16388         vni_set = 1;
16389       else
16390         break;
16391     }
16392
16393   if (!vni_set || (!vrf_set && !bd_index_set))
16394     {
16395       errmsg ("missing arguments!");
16396       return -99;
16397     }
16398
16399   if (vrf_set && bd_index_set)
16400     {
16401       errmsg ("error: both vrf and bd entered!");
16402       return -99;
16403     }
16404
16405   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16406
16407   mp->is_add = is_add;
16408   mp->vni = htonl (vni);
16409   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16410   mp->is_l2 = bd_index_set;
16411
16412   /* send */
16413   S (mp);
16414
16415   /* wait for reply */
16416   W (ret);
16417   return ret;
16418 }
16419
16420 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16421
16422 uword
16423 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16424 {
16425   u32 *action = va_arg (*args, u32 *);
16426   u8 *s = 0;
16427
16428   if (unformat (input, "%s", &s))
16429     {
16430       if (!strcmp ((char *) s, "no-action"))
16431         action[0] = 0;
16432       else if (!strcmp ((char *) s, "natively-forward"))
16433         action[0] = 1;
16434       else if (!strcmp ((char *) s, "send-map-request"))
16435         action[0] = 2;
16436       else if (!strcmp ((char *) s, "drop"))
16437         action[0] = 3;
16438       else
16439         {
16440           clib_warning ("invalid action: '%s'", s);
16441           action[0] = 3;
16442         }
16443     }
16444   else
16445     return 0;
16446
16447   vec_free (s);
16448   return 1;
16449 }
16450
16451 /**
16452  * Add/del remote mapping to/from ONE control plane
16453  *
16454  * @param vam vpp API test context
16455  * @return return code
16456  */
16457 static int
16458 api_one_add_del_remote_mapping (vat_main_t * vam)
16459 {
16460   unformat_input_t *input = vam->input;
16461   vl_api_one_add_del_remote_mapping_t *mp;
16462   u32 vni = 0;
16463   lisp_eid_vat_t _eid, *eid = &_eid;
16464   lisp_eid_vat_t _seid, *seid = &_seid;
16465   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16466   u32 action = ~0, p, w, data_len;
16467   ip4_address_t rloc4;
16468   ip6_address_t rloc6;
16469   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16470   int ret;
16471
16472   memset (&rloc, 0, sizeof (rloc));
16473
16474   /* Parse args required to build the message */
16475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16476     {
16477       if (unformat (input, "del-all"))
16478         {
16479           del_all = 1;
16480         }
16481       else if (unformat (input, "del"))
16482         {
16483           is_add = 0;
16484         }
16485       else if (unformat (input, "add"))
16486         {
16487           is_add = 1;
16488         }
16489       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16490         {
16491           eid_set = 1;
16492         }
16493       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16494         {
16495           seid_set = 1;
16496         }
16497       else if (unformat (input, "vni %d", &vni))
16498         {
16499           ;
16500         }
16501       else if (unformat (input, "p %d w %d", &p, &w))
16502         {
16503           if (!curr_rloc)
16504             {
16505               errmsg ("No RLOC configured for setting priority/weight!");
16506               return -99;
16507             }
16508           curr_rloc->priority = p;
16509           curr_rloc->weight = w;
16510         }
16511       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16512         {
16513           rloc.is_ip4 = 1;
16514           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16515           vec_add1 (rlocs, rloc);
16516           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16517         }
16518       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16519         {
16520           rloc.is_ip4 = 0;
16521           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16522           vec_add1 (rlocs, rloc);
16523           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16524         }
16525       else if (unformat (input, "action %U",
16526                          unformat_negative_mapping_action, &action))
16527         {
16528           ;
16529         }
16530       else
16531         {
16532           clib_warning ("parse error '%U'", format_unformat_error, input);
16533           return -99;
16534         }
16535     }
16536
16537   if (0 == eid_set)
16538     {
16539       errmsg ("missing params!");
16540       return -99;
16541     }
16542
16543   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16544     {
16545       errmsg ("no action set for negative map-reply!");
16546       return -99;
16547     }
16548
16549   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16550
16551   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16552   mp->is_add = is_add;
16553   mp->vni = htonl (vni);
16554   mp->action = (u8) action;
16555   mp->is_src_dst = seid_set;
16556   mp->eid_len = eid->len;
16557   mp->seid_len = seid->len;
16558   mp->del_all = del_all;
16559   mp->eid_type = eid->type;
16560   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16561   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16562
16563   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16564   clib_memcpy (mp->rlocs, rlocs, data_len);
16565   vec_free (rlocs);
16566
16567   /* send it... */
16568   S (mp);
16569
16570   /* Wait for a reply... */
16571   W (ret);
16572   return ret;
16573 }
16574
16575 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16576
16577 /**
16578  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16579  * forwarding entries in data-plane accordingly.
16580  *
16581  * @param vam vpp API test context
16582  * @return return code
16583  */
16584 static int
16585 api_one_add_del_adjacency (vat_main_t * vam)
16586 {
16587   unformat_input_t *input = vam->input;
16588   vl_api_one_add_del_adjacency_t *mp;
16589   u32 vni = 0;
16590   ip4_address_t leid4, reid4;
16591   ip6_address_t leid6, reid6;
16592   u8 reid_mac[6] = { 0 };
16593   u8 leid_mac[6] = { 0 };
16594   u8 reid_type, leid_type;
16595   u32 leid_len = 0, reid_len = 0, len;
16596   u8 is_add = 1;
16597   int ret;
16598
16599   leid_type = reid_type = (u8) ~ 0;
16600
16601   /* Parse args required to build the message */
16602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16603     {
16604       if (unformat (input, "del"))
16605         {
16606           is_add = 0;
16607         }
16608       else if (unformat (input, "add"))
16609         {
16610           is_add = 1;
16611         }
16612       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16613                          &reid4, &len))
16614         {
16615           reid_type = 0;        /* ipv4 */
16616           reid_len = len;
16617         }
16618       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16619                          &reid6, &len))
16620         {
16621           reid_type = 1;        /* ipv6 */
16622           reid_len = len;
16623         }
16624       else if (unformat (input, "reid %U", unformat_ethernet_address,
16625                          reid_mac))
16626         {
16627           reid_type = 2;        /* mac */
16628         }
16629       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16630                          &leid4, &len))
16631         {
16632           leid_type = 0;        /* ipv4 */
16633           leid_len = len;
16634         }
16635       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16636                          &leid6, &len))
16637         {
16638           leid_type = 1;        /* ipv6 */
16639           leid_len = len;
16640         }
16641       else if (unformat (input, "leid %U", unformat_ethernet_address,
16642                          leid_mac))
16643         {
16644           leid_type = 2;        /* mac */
16645         }
16646       else if (unformat (input, "vni %d", &vni))
16647         {
16648           ;
16649         }
16650       else
16651         {
16652           errmsg ("parse error '%U'", format_unformat_error, input);
16653           return -99;
16654         }
16655     }
16656
16657   if ((u8) ~ 0 == reid_type)
16658     {
16659       errmsg ("missing params!");
16660       return -99;
16661     }
16662
16663   if (leid_type != reid_type)
16664     {
16665       errmsg ("remote and local EIDs are of different types!");
16666       return -99;
16667     }
16668
16669   M (ONE_ADD_DEL_ADJACENCY, mp);
16670   mp->is_add = is_add;
16671   mp->vni = htonl (vni);
16672   mp->leid_len = leid_len;
16673   mp->reid_len = reid_len;
16674   mp->eid_type = reid_type;
16675
16676   switch (mp->eid_type)
16677     {
16678     case 0:
16679       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16680       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16681       break;
16682     case 1:
16683       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16684       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16685       break;
16686     case 2:
16687       clib_memcpy (mp->leid, leid_mac, 6);
16688       clib_memcpy (mp->reid, reid_mac, 6);
16689       break;
16690     default:
16691       errmsg ("unknown EID type %d!", mp->eid_type);
16692       return 0;
16693     }
16694
16695   /* send it... */
16696   S (mp);
16697
16698   /* Wait for a reply... */
16699   W (ret);
16700   return ret;
16701 }
16702
16703 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16704
16705 uword
16706 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16707 {
16708   u32 *mode = va_arg (*args, u32 *);
16709
16710   if (unformat (input, "lisp"))
16711     *mode = 0;
16712   else if (unformat (input, "vxlan"))
16713     *mode = 1;
16714   else
16715     return 0;
16716
16717   return 1;
16718 }
16719
16720 static int
16721 api_gpe_get_encap_mode (vat_main_t * vam)
16722 {
16723   vl_api_gpe_get_encap_mode_t *mp;
16724   int ret;
16725
16726   /* Construct the API message */
16727   M (GPE_GET_ENCAP_MODE, mp);
16728
16729   /* send it... */
16730   S (mp);
16731
16732   /* Wait for a reply... */
16733   W (ret);
16734   return ret;
16735 }
16736
16737 static int
16738 api_gpe_set_encap_mode (vat_main_t * vam)
16739 {
16740   unformat_input_t *input = vam->input;
16741   vl_api_gpe_set_encap_mode_t *mp;
16742   int ret;
16743   u32 mode = 0;
16744
16745   /* Parse args required to build the message */
16746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16747     {
16748       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16749         ;
16750       else
16751         break;
16752     }
16753
16754   /* Construct the API message */
16755   M (GPE_SET_ENCAP_MODE, mp);
16756
16757   mp->mode = mode;
16758
16759   /* send it... */
16760   S (mp);
16761
16762   /* Wait for a reply... */
16763   W (ret);
16764   return ret;
16765 }
16766
16767 static int
16768 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16769 {
16770   unformat_input_t *input = vam->input;
16771   vl_api_gpe_add_del_iface_t *mp;
16772   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16773   u32 dp_table = 0, vni = 0;
16774   int ret;
16775
16776   /* Parse args required to build the message */
16777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16778     {
16779       if (unformat (input, "up"))
16780         {
16781           action_set = 1;
16782           is_add = 1;
16783         }
16784       else if (unformat (input, "down"))
16785         {
16786           action_set = 1;
16787           is_add = 0;
16788         }
16789       else if (unformat (input, "table_id %d", &dp_table))
16790         {
16791           dp_table_set = 1;
16792         }
16793       else if (unformat (input, "bd_id %d", &dp_table))
16794         {
16795           dp_table_set = 1;
16796           is_l2 = 1;
16797         }
16798       else if (unformat (input, "vni %d", &vni))
16799         {
16800           vni_set = 1;
16801         }
16802       else
16803         break;
16804     }
16805
16806   if (action_set == 0)
16807     {
16808       errmsg ("Action not set");
16809       return -99;
16810     }
16811   if (dp_table_set == 0 || vni_set == 0)
16812     {
16813       errmsg ("vni and dp_table must be set");
16814       return -99;
16815     }
16816
16817   /* Construct the API message */
16818   M (GPE_ADD_DEL_IFACE, mp);
16819
16820   mp->is_add = is_add;
16821   mp->dp_table = clib_host_to_net_u32 (dp_table);
16822   mp->is_l2 = is_l2;
16823   mp->vni = clib_host_to_net_u32 (vni);
16824
16825   /* send it... */
16826   S (mp);
16827
16828   /* Wait for a reply... */
16829   W (ret);
16830   return ret;
16831 }
16832
16833 static int
16834 api_one_map_register_fallback_threshold (vat_main_t * vam)
16835 {
16836   unformat_input_t *input = vam->input;
16837   vl_api_one_map_register_fallback_threshold_t *mp;
16838   u32 value = 0;
16839   u8 is_set = 0;
16840   int ret;
16841
16842   /* Parse args required to build the message */
16843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16844     {
16845       if (unformat (input, "%u", &value))
16846         is_set = 1;
16847       else
16848         {
16849           clib_warning ("parse error '%U'", format_unformat_error, input);
16850           return -99;
16851         }
16852     }
16853
16854   if (!is_set)
16855     {
16856       errmsg ("fallback threshold value is missing!");
16857       return -99;
16858     }
16859
16860   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16861   mp->value = clib_host_to_net_u32 (value);
16862
16863   /* send it... */
16864   S (mp);
16865
16866   /* Wait for a reply... */
16867   W (ret);
16868   return ret;
16869 }
16870
16871 static int
16872 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16873 {
16874   vl_api_show_one_map_register_fallback_threshold_t *mp;
16875   int ret;
16876
16877   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16878
16879   /* send it... */
16880   S (mp);
16881
16882   /* Wait for a reply... */
16883   W (ret);
16884   return ret;
16885 }
16886
16887 uword
16888 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16889 {
16890   u32 *proto = va_arg (*args, u32 *);
16891
16892   if (unformat (input, "udp"))
16893     *proto = 1;
16894   else if (unformat (input, "api"))
16895     *proto = 2;
16896   else
16897     return 0;
16898
16899   return 1;
16900 }
16901
16902 static int
16903 api_one_set_transport_protocol (vat_main_t * vam)
16904 {
16905   unformat_input_t *input = vam->input;
16906   vl_api_one_set_transport_protocol_t *mp;
16907   u8 is_set = 0;
16908   u32 protocol = 0;
16909   int ret;
16910
16911   /* Parse args required to build the message */
16912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16913     {
16914       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16915         is_set = 1;
16916       else
16917         {
16918           clib_warning ("parse error '%U'", format_unformat_error, input);
16919           return -99;
16920         }
16921     }
16922
16923   if (!is_set)
16924     {
16925       errmsg ("Transport protocol missing!");
16926       return -99;
16927     }
16928
16929   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16930   mp->protocol = (u8) protocol;
16931
16932   /* send it... */
16933   S (mp);
16934
16935   /* Wait for a reply... */
16936   W (ret);
16937   return ret;
16938 }
16939
16940 static int
16941 api_one_get_transport_protocol (vat_main_t * vam)
16942 {
16943   vl_api_one_get_transport_protocol_t *mp;
16944   int ret;
16945
16946   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16947
16948   /* send it... */
16949   S (mp);
16950
16951   /* Wait for a reply... */
16952   W (ret);
16953   return ret;
16954 }
16955
16956 static int
16957 api_one_map_register_set_ttl (vat_main_t * vam)
16958 {
16959   unformat_input_t *input = vam->input;
16960   vl_api_one_map_register_set_ttl_t *mp;
16961   u32 ttl = 0;
16962   u8 is_set = 0;
16963   int ret;
16964
16965   /* Parse args required to build the message */
16966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16967     {
16968       if (unformat (input, "%u", &ttl))
16969         is_set = 1;
16970       else
16971         {
16972           clib_warning ("parse error '%U'", format_unformat_error, input);
16973           return -99;
16974         }
16975     }
16976
16977   if (!is_set)
16978     {
16979       errmsg ("TTL value missing!");
16980       return -99;
16981     }
16982
16983   M (ONE_MAP_REGISTER_SET_TTL, mp);
16984   mp->ttl = clib_host_to_net_u32 (ttl);
16985
16986   /* send it... */
16987   S (mp);
16988
16989   /* Wait for a reply... */
16990   W (ret);
16991   return ret;
16992 }
16993
16994 static int
16995 api_show_one_map_register_ttl (vat_main_t * vam)
16996 {
16997   vl_api_show_one_map_register_ttl_t *mp;
16998   int ret;
16999
17000   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17001
17002   /* send it... */
17003   S (mp);
17004
17005   /* Wait for a reply... */
17006   W (ret);
17007   return ret;
17008 }
17009
17010 /**
17011  * Add/del map request itr rlocs from ONE control plane and updates
17012  *
17013  * @param vam vpp API test context
17014  * @return return code
17015  */
17016 static int
17017 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17018 {
17019   unformat_input_t *input = vam->input;
17020   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17021   u8 *locator_set_name = 0;
17022   u8 locator_set_name_set = 0;
17023   u8 is_add = 1;
17024   int ret;
17025
17026   /* Parse args required to build the message */
17027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17028     {
17029       if (unformat (input, "del"))
17030         {
17031           is_add = 0;
17032         }
17033       else if (unformat (input, "%_%v%_", &locator_set_name))
17034         {
17035           locator_set_name_set = 1;
17036         }
17037       else
17038         {
17039           clib_warning ("parse error '%U'", format_unformat_error, input);
17040           return -99;
17041         }
17042     }
17043
17044   if (is_add && !locator_set_name_set)
17045     {
17046       errmsg ("itr-rloc is not set!");
17047       return -99;
17048     }
17049
17050   if (is_add && vec_len (locator_set_name) > 64)
17051     {
17052       errmsg ("itr-rloc locator-set name too long");
17053       vec_free (locator_set_name);
17054       return -99;
17055     }
17056
17057   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17058   mp->is_add = is_add;
17059   if (is_add)
17060     {
17061       clib_memcpy (mp->locator_set_name, locator_set_name,
17062                    vec_len (locator_set_name));
17063     }
17064   else
17065     {
17066       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17067     }
17068   vec_free (locator_set_name);
17069
17070   /* send it... */
17071   S (mp);
17072
17073   /* Wait for a reply... */
17074   W (ret);
17075   return ret;
17076 }
17077
17078 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17079
17080 static int
17081 api_one_locator_dump (vat_main_t * vam)
17082 {
17083   unformat_input_t *input = vam->input;
17084   vl_api_one_locator_dump_t *mp;
17085   vl_api_control_ping_t *mp_ping;
17086   u8 is_index_set = 0, is_name_set = 0;
17087   u8 *ls_name = 0;
17088   u32 ls_index = ~0;
17089   int ret;
17090
17091   /* Parse args required to build the message */
17092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17093     {
17094       if (unformat (input, "ls_name %_%v%_", &ls_name))
17095         {
17096           is_name_set = 1;
17097         }
17098       else if (unformat (input, "ls_index %d", &ls_index))
17099         {
17100           is_index_set = 1;
17101         }
17102       else
17103         {
17104           errmsg ("parse error '%U'", format_unformat_error, input);
17105           return -99;
17106         }
17107     }
17108
17109   if (!is_index_set && !is_name_set)
17110     {
17111       errmsg ("error: expected one of index or name!");
17112       return -99;
17113     }
17114
17115   if (is_index_set && is_name_set)
17116     {
17117       errmsg ("error: only one param expected!");
17118       return -99;
17119     }
17120
17121   if (vec_len (ls_name) > 62)
17122     {
17123       errmsg ("error: locator set name too long!");
17124       return -99;
17125     }
17126
17127   if (!vam->json_output)
17128     {
17129       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17130     }
17131
17132   M (ONE_LOCATOR_DUMP, mp);
17133   mp->is_index_set = is_index_set;
17134
17135   if (is_index_set)
17136     mp->ls_index = clib_host_to_net_u32 (ls_index);
17137   else
17138     {
17139       vec_add1 (ls_name, 0);
17140       strncpy ((char *) mp->ls_name, (char *) ls_name,
17141                sizeof (mp->ls_name) - 1);
17142     }
17143
17144   /* send it... */
17145   S (mp);
17146
17147   /* Use a control ping for synchronization */
17148   MPING (CONTROL_PING, mp_ping);
17149   S (mp_ping);
17150
17151   /* Wait for a reply... */
17152   W (ret);
17153   return ret;
17154 }
17155
17156 #define api_lisp_locator_dump api_one_locator_dump
17157
17158 static int
17159 api_one_locator_set_dump (vat_main_t * vam)
17160 {
17161   vl_api_one_locator_set_dump_t *mp;
17162   vl_api_control_ping_t *mp_ping;
17163   unformat_input_t *input = vam->input;
17164   u8 filter = 0;
17165   int ret;
17166
17167   /* Parse args required to build the message */
17168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17169     {
17170       if (unformat (input, "local"))
17171         {
17172           filter = 1;
17173         }
17174       else if (unformat (input, "remote"))
17175         {
17176           filter = 2;
17177         }
17178       else
17179         {
17180           errmsg ("parse error '%U'", format_unformat_error, input);
17181           return -99;
17182         }
17183     }
17184
17185   if (!vam->json_output)
17186     {
17187       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17188     }
17189
17190   M (ONE_LOCATOR_SET_DUMP, mp);
17191
17192   mp->filter = filter;
17193
17194   /* send it... */
17195   S (mp);
17196
17197   /* Use a control ping for synchronization */
17198   MPING (CONTROL_PING, mp_ping);
17199   S (mp_ping);
17200
17201   /* Wait for a reply... */
17202   W (ret);
17203   return ret;
17204 }
17205
17206 #define api_lisp_locator_set_dump api_one_locator_set_dump
17207
17208 static int
17209 api_one_eid_table_map_dump (vat_main_t * vam)
17210 {
17211   u8 is_l2 = 0;
17212   u8 mode_set = 0;
17213   unformat_input_t *input = vam->input;
17214   vl_api_one_eid_table_map_dump_t *mp;
17215   vl_api_control_ping_t *mp_ping;
17216   int ret;
17217
17218   /* Parse args required to build the message */
17219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17220     {
17221       if (unformat (input, "l2"))
17222         {
17223           is_l2 = 1;
17224           mode_set = 1;
17225         }
17226       else if (unformat (input, "l3"))
17227         {
17228           is_l2 = 0;
17229           mode_set = 1;
17230         }
17231       else
17232         {
17233           errmsg ("parse error '%U'", format_unformat_error, input);
17234           return -99;
17235         }
17236     }
17237
17238   if (!mode_set)
17239     {
17240       errmsg ("expected one of 'l2' or 'l3' parameter!");
17241       return -99;
17242     }
17243
17244   if (!vam->json_output)
17245     {
17246       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17247     }
17248
17249   M (ONE_EID_TABLE_MAP_DUMP, mp);
17250   mp->is_l2 = is_l2;
17251
17252   /* send it... */
17253   S (mp);
17254
17255   /* Use a control ping for synchronization */
17256   MPING (CONTROL_PING, mp_ping);
17257   S (mp_ping);
17258
17259   /* Wait for a reply... */
17260   W (ret);
17261   return ret;
17262 }
17263
17264 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17265
17266 static int
17267 api_one_eid_table_vni_dump (vat_main_t * vam)
17268 {
17269   vl_api_one_eid_table_vni_dump_t *mp;
17270   vl_api_control_ping_t *mp_ping;
17271   int ret;
17272
17273   if (!vam->json_output)
17274     {
17275       print (vam->ofp, "VNI");
17276     }
17277
17278   M (ONE_EID_TABLE_VNI_DUMP, mp);
17279
17280   /* send it... */
17281   S (mp);
17282
17283   /* Use a control ping for synchronization */
17284   MPING (CONTROL_PING, mp_ping);
17285   S (mp_ping);
17286
17287   /* Wait for a reply... */
17288   W (ret);
17289   return ret;
17290 }
17291
17292 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17293
17294 static int
17295 api_one_eid_table_dump (vat_main_t * vam)
17296 {
17297   unformat_input_t *i = vam->input;
17298   vl_api_one_eid_table_dump_t *mp;
17299   vl_api_control_ping_t *mp_ping;
17300   struct in_addr ip4;
17301   struct in6_addr ip6;
17302   u8 mac[6];
17303   u8 eid_type = ~0, eid_set = 0;
17304   u32 prefix_length = ~0, t, vni = 0;
17305   u8 filter = 0;
17306   int ret;
17307   lisp_nsh_api_t nsh;
17308
17309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17310     {
17311       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17312         {
17313           eid_set = 1;
17314           eid_type = 0;
17315           prefix_length = t;
17316         }
17317       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17318         {
17319           eid_set = 1;
17320           eid_type = 1;
17321           prefix_length = t;
17322         }
17323       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17324         {
17325           eid_set = 1;
17326           eid_type = 2;
17327         }
17328       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17329         {
17330           eid_set = 1;
17331           eid_type = 3;
17332         }
17333       else if (unformat (i, "vni %d", &t))
17334         {
17335           vni = t;
17336         }
17337       else if (unformat (i, "local"))
17338         {
17339           filter = 1;
17340         }
17341       else if (unformat (i, "remote"))
17342         {
17343           filter = 2;
17344         }
17345       else
17346         {
17347           errmsg ("parse error '%U'", format_unformat_error, i);
17348           return -99;
17349         }
17350     }
17351
17352   if (!vam->json_output)
17353     {
17354       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17355              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17356     }
17357
17358   M (ONE_EID_TABLE_DUMP, mp);
17359
17360   mp->filter = filter;
17361   if (eid_set)
17362     {
17363       mp->eid_set = 1;
17364       mp->vni = htonl (vni);
17365       mp->eid_type = eid_type;
17366       switch (eid_type)
17367         {
17368         case 0:
17369           mp->prefix_length = prefix_length;
17370           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17371           break;
17372         case 1:
17373           mp->prefix_length = prefix_length;
17374           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17375           break;
17376         case 2:
17377           clib_memcpy (mp->eid, mac, sizeof (mac));
17378           break;
17379         case 3:
17380           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17381           break;
17382         default:
17383           errmsg ("unknown EID type %d!", eid_type);
17384           return -99;
17385         }
17386     }
17387
17388   /* send it... */
17389   S (mp);
17390
17391   /* Use a control ping for synchronization */
17392   MPING (CONTROL_PING, mp_ping);
17393   S (mp_ping);
17394
17395   /* Wait for a reply... */
17396   W (ret);
17397   return ret;
17398 }
17399
17400 #define api_lisp_eid_table_dump api_one_eid_table_dump
17401
17402 static int
17403 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17404 {
17405   unformat_input_t *i = vam->input;
17406   vl_api_gpe_fwd_entries_get_t *mp;
17407   u8 vni_set = 0;
17408   u32 vni = ~0;
17409   int ret;
17410
17411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17412     {
17413       if (unformat (i, "vni %d", &vni))
17414         {
17415           vni_set = 1;
17416         }
17417       else
17418         {
17419           errmsg ("parse error '%U'", format_unformat_error, i);
17420           return -99;
17421         }
17422     }
17423
17424   if (!vni_set)
17425     {
17426       errmsg ("vni not set!");
17427       return -99;
17428     }
17429
17430   if (!vam->json_output)
17431     {
17432       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17433              "leid", "reid");
17434     }
17435
17436   M (GPE_FWD_ENTRIES_GET, mp);
17437   mp->vni = clib_host_to_net_u32 (vni);
17438
17439   /* send it... */
17440   S (mp);
17441
17442   /* Wait for a reply... */
17443   W (ret);
17444   return ret;
17445 }
17446
17447 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17448 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17449 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17450 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17451 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17452 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17453 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17454 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17455
17456 static int
17457 api_one_adjacencies_get (vat_main_t * vam)
17458 {
17459   unformat_input_t *i = vam->input;
17460   vl_api_one_adjacencies_get_t *mp;
17461   u8 vni_set = 0;
17462   u32 vni = ~0;
17463   int ret;
17464
17465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17466     {
17467       if (unformat (i, "vni %d", &vni))
17468         {
17469           vni_set = 1;
17470         }
17471       else
17472         {
17473           errmsg ("parse error '%U'", format_unformat_error, i);
17474           return -99;
17475         }
17476     }
17477
17478   if (!vni_set)
17479     {
17480       errmsg ("vni not set!");
17481       return -99;
17482     }
17483
17484   if (!vam->json_output)
17485     {
17486       print (vam->ofp, "%s %40s", "leid", "reid");
17487     }
17488
17489   M (ONE_ADJACENCIES_GET, mp);
17490   mp->vni = clib_host_to_net_u32 (vni);
17491
17492   /* send it... */
17493   S (mp);
17494
17495   /* Wait for a reply... */
17496   W (ret);
17497   return ret;
17498 }
17499
17500 #define api_lisp_adjacencies_get api_one_adjacencies_get
17501
17502 static int
17503 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17504 {
17505   unformat_input_t *i = vam->input;
17506   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17507   int ret;
17508   u8 ip_family_set = 0, is_ip4 = 1;
17509
17510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17511     {
17512       if (unformat (i, "ip4"))
17513         {
17514           ip_family_set = 1;
17515           is_ip4 = 1;
17516         }
17517       else if (unformat (i, "ip6"))
17518         {
17519           ip_family_set = 1;
17520           is_ip4 = 0;
17521         }
17522       else
17523         {
17524           errmsg ("parse error '%U'", format_unformat_error, i);
17525           return -99;
17526         }
17527     }
17528
17529   if (!ip_family_set)
17530     {
17531       errmsg ("ip family not set!");
17532       return -99;
17533     }
17534
17535   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17536   mp->is_ip4 = is_ip4;
17537
17538   /* send it... */
17539   S (mp);
17540
17541   /* Wait for a reply... */
17542   W (ret);
17543   return ret;
17544 }
17545
17546 static int
17547 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17548 {
17549   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17550   int ret;
17551
17552   if (!vam->json_output)
17553     {
17554       print (vam->ofp, "VNIs");
17555     }
17556
17557   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17558
17559   /* send it... */
17560   S (mp);
17561
17562   /* Wait for a reply... */
17563   W (ret);
17564   return ret;
17565 }
17566
17567 static int
17568 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17569 {
17570   unformat_input_t *i = vam->input;
17571   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17572   int ret = 0;
17573   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17574   struct in_addr ip4;
17575   struct in6_addr ip6;
17576   u32 table_id = 0, nh_sw_if_index = ~0;
17577
17578   memset (&ip4, 0, sizeof (ip4));
17579   memset (&ip6, 0, sizeof (ip6));
17580
17581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17582     {
17583       if (unformat (i, "del"))
17584         is_add = 0;
17585       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17586                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17587         {
17588           ip_set = 1;
17589           is_ip4 = 1;
17590         }
17591       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17592                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17593         {
17594           ip_set = 1;
17595           is_ip4 = 0;
17596         }
17597       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17598         {
17599           ip_set = 1;
17600           is_ip4 = 1;
17601           nh_sw_if_index = ~0;
17602         }
17603       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17604         {
17605           ip_set = 1;
17606           is_ip4 = 0;
17607           nh_sw_if_index = ~0;
17608         }
17609       else if (unformat (i, "table %d", &table_id))
17610         ;
17611       else
17612         {
17613           errmsg ("parse error '%U'", format_unformat_error, i);
17614           return -99;
17615         }
17616     }
17617
17618   if (!ip_set)
17619     {
17620       errmsg ("nh addr not set!");
17621       return -99;
17622     }
17623
17624   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17625   mp->is_add = is_add;
17626   mp->table_id = clib_host_to_net_u32 (table_id);
17627   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17628   mp->is_ip4 = is_ip4;
17629   if (is_ip4)
17630     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17631   else
17632     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17633
17634   /* send it... */
17635   S (mp);
17636
17637   /* Wait for a reply... */
17638   W (ret);
17639   return ret;
17640 }
17641
17642 static int
17643 api_one_map_server_dump (vat_main_t * vam)
17644 {
17645   vl_api_one_map_server_dump_t *mp;
17646   vl_api_control_ping_t *mp_ping;
17647   int ret;
17648
17649   if (!vam->json_output)
17650     {
17651       print (vam->ofp, "%=20s", "Map server");
17652     }
17653
17654   M (ONE_MAP_SERVER_DUMP, mp);
17655   /* send it... */
17656   S (mp);
17657
17658   /* Use a control ping for synchronization */
17659   MPING (CONTROL_PING, mp_ping);
17660   S (mp_ping);
17661
17662   /* Wait for a reply... */
17663   W (ret);
17664   return ret;
17665 }
17666
17667 #define api_lisp_map_server_dump api_one_map_server_dump
17668
17669 static int
17670 api_one_map_resolver_dump (vat_main_t * vam)
17671 {
17672   vl_api_one_map_resolver_dump_t *mp;
17673   vl_api_control_ping_t *mp_ping;
17674   int ret;
17675
17676   if (!vam->json_output)
17677     {
17678       print (vam->ofp, "%=20s", "Map resolver");
17679     }
17680
17681   M (ONE_MAP_RESOLVER_DUMP, mp);
17682   /* send it... */
17683   S (mp);
17684
17685   /* Use a control ping for synchronization */
17686   MPING (CONTROL_PING, mp_ping);
17687   S (mp_ping);
17688
17689   /* Wait for a reply... */
17690   W (ret);
17691   return ret;
17692 }
17693
17694 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17695
17696 static int
17697 api_one_stats_flush (vat_main_t * vam)
17698 {
17699   vl_api_one_stats_flush_t *mp;
17700   int ret = 0;
17701
17702   M (ONE_STATS_FLUSH, mp);
17703   S (mp);
17704   W (ret);
17705   return ret;
17706 }
17707
17708 static int
17709 api_one_stats_dump (vat_main_t * vam)
17710 {
17711   vl_api_one_stats_dump_t *mp;
17712   vl_api_control_ping_t *mp_ping;
17713   int ret;
17714
17715   M (ONE_STATS_DUMP, mp);
17716   /* send it... */
17717   S (mp);
17718
17719   /* Use a control ping for synchronization */
17720   MPING (CONTROL_PING, mp_ping);
17721   S (mp_ping);
17722
17723   /* Wait for a reply... */
17724   W (ret);
17725   return ret;
17726 }
17727
17728 static int
17729 api_show_one_status (vat_main_t * vam)
17730 {
17731   vl_api_show_one_status_t *mp;
17732   int ret;
17733
17734   if (!vam->json_output)
17735     {
17736       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17737     }
17738
17739   M (SHOW_ONE_STATUS, mp);
17740   /* send it... */
17741   S (mp);
17742   /* Wait for a reply... */
17743   W (ret);
17744   return ret;
17745 }
17746
17747 #define api_show_lisp_status api_show_one_status
17748
17749 static int
17750 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17751 {
17752   vl_api_gpe_fwd_entry_path_dump_t *mp;
17753   vl_api_control_ping_t *mp_ping;
17754   unformat_input_t *i = vam->input;
17755   u32 fwd_entry_index = ~0;
17756   int ret;
17757
17758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17759     {
17760       if (unformat (i, "index %d", &fwd_entry_index))
17761         ;
17762       else
17763         break;
17764     }
17765
17766   if (~0 == fwd_entry_index)
17767     {
17768       errmsg ("no index specified!");
17769       return -99;
17770     }
17771
17772   if (!vam->json_output)
17773     {
17774       print (vam->ofp, "first line");
17775     }
17776
17777   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17778
17779   /* send it... */
17780   S (mp);
17781   /* Use a control ping for synchronization */
17782   MPING (CONTROL_PING, mp_ping);
17783   S (mp_ping);
17784
17785   /* Wait for a reply... */
17786   W (ret);
17787   return ret;
17788 }
17789
17790 static int
17791 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17792 {
17793   vl_api_one_get_map_request_itr_rlocs_t *mp;
17794   int ret;
17795
17796   if (!vam->json_output)
17797     {
17798       print (vam->ofp, "%=20s", "itr-rlocs:");
17799     }
17800
17801   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17802   /* send it... */
17803   S (mp);
17804   /* Wait for a reply... */
17805   W (ret);
17806   return ret;
17807 }
17808
17809 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17810
17811 static int
17812 api_af_packet_create (vat_main_t * vam)
17813 {
17814   unformat_input_t *i = vam->input;
17815   vl_api_af_packet_create_t *mp;
17816   u8 *host_if_name = 0;
17817   u8 hw_addr[6];
17818   u8 random_hw_addr = 1;
17819   int ret;
17820
17821   memset (hw_addr, 0, sizeof (hw_addr));
17822
17823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17824     {
17825       if (unformat (i, "name %s", &host_if_name))
17826         vec_add1 (host_if_name, 0);
17827       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17828         random_hw_addr = 0;
17829       else
17830         break;
17831     }
17832
17833   if (!vec_len (host_if_name))
17834     {
17835       errmsg ("host-interface name must be specified");
17836       return -99;
17837     }
17838
17839   if (vec_len (host_if_name) > 64)
17840     {
17841       errmsg ("host-interface name too long");
17842       return -99;
17843     }
17844
17845   M (AF_PACKET_CREATE, mp);
17846
17847   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17848   clib_memcpy (mp->hw_addr, hw_addr, 6);
17849   mp->use_random_hw_addr = random_hw_addr;
17850   vec_free (host_if_name);
17851
17852   S (mp);
17853
17854   /* *INDENT-OFF* */
17855   W2 (ret,
17856       ({
17857         if (ret == 0)
17858           fprintf (vam->ofp ? vam->ofp : stderr,
17859                    " new sw_if_index = %d\n", vam->sw_if_index);
17860       }));
17861   /* *INDENT-ON* */
17862   return ret;
17863 }
17864
17865 static int
17866 api_af_packet_delete (vat_main_t * vam)
17867 {
17868   unformat_input_t *i = vam->input;
17869   vl_api_af_packet_delete_t *mp;
17870   u8 *host_if_name = 0;
17871   int ret;
17872
17873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17874     {
17875       if (unformat (i, "name %s", &host_if_name))
17876         vec_add1 (host_if_name, 0);
17877       else
17878         break;
17879     }
17880
17881   if (!vec_len (host_if_name))
17882     {
17883       errmsg ("host-interface name must be specified");
17884       return -99;
17885     }
17886
17887   if (vec_len (host_if_name) > 64)
17888     {
17889       errmsg ("host-interface name too long");
17890       return -99;
17891     }
17892
17893   M (AF_PACKET_DELETE, mp);
17894
17895   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17896   vec_free (host_if_name);
17897
17898   S (mp);
17899   W (ret);
17900   return ret;
17901 }
17902
17903 static int
17904 api_policer_add_del (vat_main_t * vam)
17905 {
17906   unformat_input_t *i = vam->input;
17907   vl_api_policer_add_del_t *mp;
17908   u8 is_add = 1;
17909   u8 *name = 0;
17910   u32 cir = 0;
17911   u32 eir = 0;
17912   u64 cb = 0;
17913   u64 eb = 0;
17914   u8 rate_type = 0;
17915   u8 round_type = 0;
17916   u8 type = 0;
17917   u8 color_aware = 0;
17918   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17919   int ret;
17920
17921   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17922   conform_action.dscp = 0;
17923   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17924   exceed_action.dscp = 0;
17925   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17926   violate_action.dscp = 0;
17927
17928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17929     {
17930       if (unformat (i, "del"))
17931         is_add = 0;
17932       else if (unformat (i, "name %s", &name))
17933         vec_add1 (name, 0);
17934       else if (unformat (i, "cir %u", &cir))
17935         ;
17936       else if (unformat (i, "eir %u", &eir))
17937         ;
17938       else if (unformat (i, "cb %u", &cb))
17939         ;
17940       else if (unformat (i, "eb %u", &eb))
17941         ;
17942       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17943                          &rate_type))
17944         ;
17945       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17946                          &round_type))
17947         ;
17948       else if (unformat (i, "type %U", unformat_policer_type, &type))
17949         ;
17950       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17951                          &conform_action))
17952         ;
17953       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17954                          &exceed_action))
17955         ;
17956       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17957                          &violate_action))
17958         ;
17959       else if (unformat (i, "color-aware"))
17960         color_aware = 1;
17961       else
17962         break;
17963     }
17964
17965   if (!vec_len (name))
17966     {
17967       errmsg ("policer name must be specified");
17968       return -99;
17969     }
17970
17971   if (vec_len (name) > 64)
17972     {
17973       errmsg ("policer name too long");
17974       return -99;
17975     }
17976
17977   M (POLICER_ADD_DEL, mp);
17978
17979   clib_memcpy (mp->name, name, vec_len (name));
17980   vec_free (name);
17981   mp->is_add = is_add;
17982   mp->cir = cir;
17983   mp->eir = eir;
17984   mp->cb = cb;
17985   mp->eb = eb;
17986   mp->rate_type = rate_type;
17987   mp->round_type = round_type;
17988   mp->type = type;
17989   mp->conform_action_type = conform_action.action_type;
17990   mp->conform_dscp = conform_action.dscp;
17991   mp->exceed_action_type = exceed_action.action_type;
17992   mp->exceed_dscp = exceed_action.dscp;
17993   mp->violate_action_type = violate_action.action_type;
17994   mp->violate_dscp = violate_action.dscp;
17995   mp->color_aware = color_aware;
17996
17997   S (mp);
17998   W (ret);
17999   return ret;
18000 }
18001
18002 static int
18003 api_policer_dump (vat_main_t * vam)
18004 {
18005   unformat_input_t *i = vam->input;
18006   vl_api_policer_dump_t *mp;
18007   vl_api_control_ping_t *mp_ping;
18008   u8 *match_name = 0;
18009   u8 match_name_valid = 0;
18010   int ret;
18011
18012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18013     {
18014       if (unformat (i, "name %s", &match_name))
18015         {
18016           vec_add1 (match_name, 0);
18017           match_name_valid = 1;
18018         }
18019       else
18020         break;
18021     }
18022
18023   M (POLICER_DUMP, mp);
18024   mp->match_name_valid = match_name_valid;
18025   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18026   vec_free (match_name);
18027   /* send it... */
18028   S (mp);
18029
18030   /* Use a control ping for synchronization */
18031   MPING (CONTROL_PING, mp_ping);
18032   S (mp_ping);
18033
18034   /* Wait for a reply... */
18035   W (ret);
18036   return ret;
18037 }
18038
18039 static int
18040 api_policer_classify_set_interface (vat_main_t * vam)
18041 {
18042   unformat_input_t *i = vam->input;
18043   vl_api_policer_classify_set_interface_t *mp;
18044   u32 sw_if_index;
18045   int sw_if_index_set;
18046   u32 ip4_table_index = ~0;
18047   u32 ip6_table_index = ~0;
18048   u32 l2_table_index = ~0;
18049   u8 is_add = 1;
18050   int ret;
18051
18052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18053     {
18054       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18055         sw_if_index_set = 1;
18056       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18057         sw_if_index_set = 1;
18058       else if (unformat (i, "del"))
18059         is_add = 0;
18060       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18061         ;
18062       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18063         ;
18064       else if (unformat (i, "l2-table %d", &l2_table_index))
18065         ;
18066       else
18067         {
18068           clib_warning ("parse error '%U'", format_unformat_error, i);
18069           return -99;
18070         }
18071     }
18072
18073   if (sw_if_index_set == 0)
18074     {
18075       errmsg ("missing interface name or sw_if_index");
18076       return -99;
18077     }
18078
18079   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18080
18081   mp->sw_if_index = ntohl (sw_if_index);
18082   mp->ip4_table_index = ntohl (ip4_table_index);
18083   mp->ip6_table_index = ntohl (ip6_table_index);
18084   mp->l2_table_index = ntohl (l2_table_index);
18085   mp->is_add = is_add;
18086
18087   S (mp);
18088   W (ret);
18089   return ret;
18090 }
18091
18092 static int
18093 api_policer_classify_dump (vat_main_t * vam)
18094 {
18095   unformat_input_t *i = vam->input;
18096   vl_api_policer_classify_dump_t *mp;
18097   vl_api_control_ping_t *mp_ping;
18098   u8 type = POLICER_CLASSIFY_N_TABLES;
18099   int ret;
18100
18101   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18102     ;
18103   else
18104     {
18105       errmsg ("classify table type must be specified");
18106       return -99;
18107     }
18108
18109   if (!vam->json_output)
18110     {
18111       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18112     }
18113
18114   M (POLICER_CLASSIFY_DUMP, mp);
18115   mp->type = type;
18116   /* send it... */
18117   S (mp);
18118
18119   /* Use a control ping for synchronization */
18120   MPING (CONTROL_PING, mp_ping);
18121   S (mp_ping);
18122
18123   /* Wait for a reply... */
18124   W (ret);
18125   return ret;
18126 }
18127
18128 static int
18129 api_netmap_create (vat_main_t * vam)
18130 {
18131   unformat_input_t *i = vam->input;
18132   vl_api_netmap_create_t *mp;
18133   u8 *if_name = 0;
18134   u8 hw_addr[6];
18135   u8 random_hw_addr = 1;
18136   u8 is_pipe = 0;
18137   u8 is_master = 0;
18138   int ret;
18139
18140   memset (hw_addr, 0, sizeof (hw_addr));
18141
18142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18143     {
18144       if (unformat (i, "name %s", &if_name))
18145         vec_add1 (if_name, 0);
18146       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18147         random_hw_addr = 0;
18148       else if (unformat (i, "pipe"))
18149         is_pipe = 1;
18150       else if (unformat (i, "master"))
18151         is_master = 1;
18152       else if (unformat (i, "slave"))
18153         is_master = 0;
18154       else
18155         break;
18156     }
18157
18158   if (!vec_len (if_name))
18159     {
18160       errmsg ("interface name must be specified");
18161       return -99;
18162     }
18163
18164   if (vec_len (if_name) > 64)
18165     {
18166       errmsg ("interface name too long");
18167       return -99;
18168     }
18169
18170   M (NETMAP_CREATE, mp);
18171
18172   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18173   clib_memcpy (mp->hw_addr, hw_addr, 6);
18174   mp->use_random_hw_addr = random_hw_addr;
18175   mp->is_pipe = is_pipe;
18176   mp->is_master = is_master;
18177   vec_free (if_name);
18178
18179   S (mp);
18180   W (ret);
18181   return ret;
18182 }
18183
18184 static int
18185 api_netmap_delete (vat_main_t * vam)
18186 {
18187   unformat_input_t *i = vam->input;
18188   vl_api_netmap_delete_t *mp;
18189   u8 *if_name = 0;
18190   int ret;
18191
18192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18193     {
18194       if (unformat (i, "name %s", &if_name))
18195         vec_add1 (if_name, 0);
18196       else
18197         break;
18198     }
18199
18200   if (!vec_len (if_name))
18201     {
18202       errmsg ("interface name must be specified");
18203       return -99;
18204     }
18205
18206   if (vec_len (if_name) > 64)
18207     {
18208       errmsg ("interface name too long");
18209       return -99;
18210     }
18211
18212   M (NETMAP_DELETE, mp);
18213
18214   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18215   vec_free (if_name);
18216
18217   S (mp);
18218   W (ret);
18219   return ret;
18220 }
18221
18222 static void
18223 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18224 {
18225   if (fp->afi == IP46_TYPE_IP6)
18226     print (vam->ofp,
18227            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18228            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18229            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18230            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18231            format_ip6_address, fp->next_hop);
18232   else if (fp->afi == IP46_TYPE_IP4)
18233     print (vam->ofp,
18234            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18235            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18236            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18237            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18238            format_ip4_address, fp->next_hop);
18239 }
18240
18241 static void
18242 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18243                                  vl_api_fib_path2_t * fp)
18244 {
18245   struct in_addr ip4;
18246   struct in6_addr ip6;
18247
18248   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18249   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18250   vat_json_object_add_uint (node, "is_local", fp->is_local);
18251   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18252   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18253   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18254   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18255   if (fp->afi == IP46_TYPE_IP4)
18256     {
18257       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18258       vat_json_object_add_ip4 (node, "next_hop", ip4);
18259     }
18260   else if (fp->afi == IP46_TYPE_IP6)
18261     {
18262       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18263       vat_json_object_add_ip6 (node, "next_hop", ip6);
18264     }
18265 }
18266
18267 static void
18268 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18269 {
18270   vat_main_t *vam = &vat_main;
18271   int count = ntohl (mp->mt_count);
18272   vl_api_fib_path2_t *fp;
18273   i32 i;
18274
18275   print (vam->ofp, "[%d]: sw_if_index %d via:",
18276          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18277   fp = mp->mt_paths;
18278   for (i = 0; i < count; i++)
18279     {
18280       vl_api_mpls_fib_path_print (vam, fp);
18281       fp++;
18282     }
18283
18284   print (vam->ofp, "");
18285 }
18286
18287 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18288 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18289
18290 static void
18291 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18292 {
18293   vat_main_t *vam = &vat_main;
18294   vat_json_node_t *node = NULL;
18295   int count = ntohl (mp->mt_count);
18296   vl_api_fib_path2_t *fp;
18297   i32 i;
18298
18299   if (VAT_JSON_ARRAY != vam->json_tree.type)
18300     {
18301       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18302       vat_json_init_array (&vam->json_tree);
18303     }
18304   node = vat_json_array_add (&vam->json_tree);
18305
18306   vat_json_init_object (node);
18307   vat_json_object_add_uint (node, "tunnel_index",
18308                             ntohl (mp->mt_tunnel_index));
18309   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18310
18311   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18312
18313   fp = mp->mt_paths;
18314   for (i = 0; i < count; i++)
18315     {
18316       vl_api_mpls_fib_path_json_print (node, fp);
18317       fp++;
18318     }
18319 }
18320
18321 static int
18322 api_mpls_tunnel_dump (vat_main_t * vam)
18323 {
18324   vl_api_mpls_tunnel_dump_t *mp;
18325   vl_api_control_ping_t *mp_ping;
18326   i32 index = -1;
18327   int ret;
18328
18329   /* Parse args required to build the message */
18330   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18331     {
18332       if (!unformat (vam->input, "tunnel_index %d", &index))
18333         {
18334           index = -1;
18335           break;
18336         }
18337     }
18338
18339   print (vam->ofp, "  tunnel_index %d", index);
18340
18341   M (MPLS_TUNNEL_DUMP, mp);
18342   mp->tunnel_index = htonl (index);
18343   S (mp);
18344
18345   /* Use a control ping for synchronization */
18346   MPING (CONTROL_PING, mp_ping);
18347   S (mp_ping);
18348
18349   W (ret);
18350   return ret;
18351 }
18352
18353 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18354 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18355
18356
18357 static void
18358 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18359 {
18360   vat_main_t *vam = &vat_main;
18361   int count = ntohl (mp->count);
18362   vl_api_fib_path2_t *fp;
18363   int i;
18364
18365   print (vam->ofp,
18366          "table-id %d, label %u, ess_bit %u",
18367          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18368   fp = mp->path;
18369   for (i = 0; i < count; i++)
18370     {
18371       vl_api_mpls_fib_path_print (vam, fp);
18372       fp++;
18373     }
18374 }
18375
18376 static void vl_api_mpls_fib_details_t_handler_json
18377   (vl_api_mpls_fib_details_t * mp)
18378 {
18379   vat_main_t *vam = &vat_main;
18380   int count = ntohl (mp->count);
18381   vat_json_node_t *node = NULL;
18382   vl_api_fib_path2_t *fp;
18383   int i;
18384
18385   if (VAT_JSON_ARRAY != vam->json_tree.type)
18386     {
18387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18388       vat_json_init_array (&vam->json_tree);
18389     }
18390   node = vat_json_array_add (&vam->json_tree);
18391
18392   vat_json_init_object (node);
18393   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18394   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18395   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18396   vat_json_object_add_uint (node, "path_count", count);
18397   fp = mp->path;
18398   for (i = 0; i < count; i++)
18399     {
18400       vl_api_mpls_fib_path_json_print (node, fp);
18401       fp++;
18402     }
18403 }
18404
18405 static int
18406 api_mpls_fib_dump (vat_main_t * vam)
18407 {
18408   vl_api_mpls_fib_dump_t *mp;
18409   vl_api_control_ping_t *mp_ping;
18410   int ret;
18411
18412   M (MPLS_FIB_DUMP, mp);
18413   S (mp);
18414
18415   /* Use a control ping for synchronization */
18416   MPING (CONTROL_PING, mp_ping);
18417   S (mp_ping);
18418
18419   W (ret);
18420   return ret;
18421 }
18422
18423 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18424 #define vl_api_ip_fib_details_t_print vl_noop_handler
18425
18426 static void
18427 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18428 {
18429   vat_main_t *vam = &vat_main;
18430   int count = ntohl (mp->count);
18431   vl_api_fib_path_t *fp;
18432   int i;
18433
18434   print (vam->ofp,
18435          "table-id %d, prefix %U/%d",
18436          ntohl (mp->table_id), format_ip4_address, mp->address,
18437          mp->address_length);
18438   fp = mp->path;
18439   for (i = 0; i < count; i++)
18440     {
18441       if (fp->afi == IP46_TYPE_IP6)
18442         print (vam->ofp,
18443                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18444                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18445                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18446                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18447                format_ip6_address, fp->next_hop);
18448       else if (fp->afi == IP46_TYPE_IP4)
18449         print (vam->ofp,
18450                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18451                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18452                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18453                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18454                format_ip4_address, fp->next_hop);
18455       fp++;
18456     }
18457 }
18458
18459 static void vl_api_ip_fib_details_t_handler_json
18460   (vl_api_ip_fib_details_t * mp)
18461 {
18462   vat_main_t *vam = &vat_main;
18463   int count = ntohl (mp->count);
18464   vat_json_node_t *node = NULL;
18465   struct in_addr ip4;
18466   struct in6_addr ip6;
18467   vl_api_fib_path_t *fp;
18468   int i;
18469
18470   if (VAT_JSON_ARRAY != vam->json_tree.type)
18471     {
18472       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18473       vat_json_init_array (&vam->json_tree);
18474     }
18475   node = vat_json_array_add (&vam->json_tree);
18476
18477   vat_json_init_object (node);
18478   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18479   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18480   vat_json_object_add_ip4 (node, "prefix", ip4);
18481   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18482   vat_json_object_add_uint (node, "path_count", count);
18483   fp = mp->path;
18484   for (i = 0; i < count; i++)
18485     {
18486       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18487       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18488       vat_json_object_add_uint (node, "is_local", fp->is_local);
18489       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18490       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18491       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18492       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18493       if (fp->afi == IP46_TYPE_IP4)
18494         {
18495           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18496           vat_json_object_add_ip4 (node, "next_hop", ip4);
18497         }
18498       else if (fp->afi == IP46_TYPE_IP6)
18499         {
18500           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18501           vat_json_object_add_ip6 (node, "next_hop", ip6);
18502         }
18503     }
18504 }
18505
18506 static int
18507 api_ip_fib_dump (vat_main_t * vam)
18508 {
18509   vl_api_ip_fib_dump_t *mp;
18510   vl_api_control_ping_t *mp_ping;
18511   int ret;
18512
18513   M (IP_FIB_DUMP, mp);
18514   S (mp);
18515
18516   /* Use a control ping for synchronization */
18517   MPING (CONTROL_PING, mp_ping);
18518   S (mp_ping);
18519
18520   W (ret);
18521   return ret;
18522 }
18523
18524 static int
18525 api_ip_mfib_dump (vat_main_t * vam)
18526 {
18527   vl_api_ip_mfib_dump_t *mp;
18528   vl_api_control_ping_t *mp_ping;
18529   int ret;
18530
18531   M (IP_MFIB_DUMP, mp);
18532   S (mp);
18533
18534   /* Use a control ping for synchronization */
18535   MPING (CONTROL_PING, mp_ping);
18536   S (mp_ping);
18537
18538   W (ret);
18539   return ret;
18540 }
18541
18542 static void vl_api_ip_neighbor_details_t_handler
18543   (vl_api_ip_neighbor_details_t * mp)
18544 {
18545   vat_main_t *vam = &vat_main;
18546
18547   print (vam->ofp, "%c %U %U",
18548          (mp->is_static) ? 'S' : 'D',
18549          format_ethernet_address, &mp->mac_address,
18550          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
18551          &mp->ip_address);
18552 }
18553
18554 static void vl_api_ip_neighbor_details_t_handler_json
18555   (vl_api_ip_neighbor_details_t * mp)
18556 {
18557
18558   vat_main_t *vam = &vat_main;
18559   vat_json_node_t *node;
18560   struct in_addr ip4;
18561   struct in6_addr ip6;
18562
18563   if (VAT_JSON_ARRAY != vam->json_tree.type)
18564     {
18565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18566       vat_json_init_array (&vam->json_tree);
18567     }
18568   node = vat_json_array_add (&vam->json_tree);
18569
18570   vat_json_init_object (node);
18571   vat_json_object_add_string_copy (node, "flag",
18572                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
18573                                    "dynamic");
18574
18575   vat_json_object_add_string_copy (node, "link_layer",
18576                                    format (0, "%U", format_ethernet_address,
18577                                            &mp->mac_address));
18578
18579   if (mp->is_ipv6)
18580     {
18581       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
18582       vat_json_object_add_ip6 (node, "ip_address", ip6);
18583     }
18584   else
18585     {
18586       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
18587       vat_json_object_add_ip4 (node, "ip_address", ip4);
18588     }
18589 }
18590
18591 static int
18592 api_ip_neighbor_dump (vat_main_t * vam)
18593 {
18594   unformat_input_t *i = vam->input;
18595   vl_api_ip_neighbor_dump_t *mp;
18596   vl_api_control_ping_t *mp_ping;
18597   u8 is_ipv6 = 0;
18598   u32 sw_if_index = ~0;
18599   int ret;
18600
18601   /* Parse args required to build the message */
18602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18603     {
18604       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18605         ;
18606       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18607         ;
18608       else if (unformat (i, "ip6"))
18609         is_ipv6 = 1;
18610       else
18611         break;
18612     }
18613
18614   if (sw_if_index == ~0)
18615     {
18616       errmsg ("missing interface name or sw_if_index");
18617       return -99;
18618     }
18619
18620   M (IP_NEIGHBOR_DUMP, mp);
18621   mp->is_ipv6 = (u8) is_ipv6;
18622   mp->sw_if_index = ntohl (sw_if_index);
18623   S (mp);
18624
18625   /* Use a control ping for synchronization */
18626   MPING (CONTROL_PING, mp_ping);
18627   S (mp_ping);
18628
18629   W (ret);
18630   return ret;
18631 }
18632
18633 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
18634 #define vl_api_ip6_fib_details_t_print vl_noop_handler
18635
18636 static void
18637 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
18638 {
18639   vat_main_t *vam = &vat_main;
18640   int count = ntohl (mp->count);
18641   vl_api_fib_path_t *fp;
18642   int i;
18643
18644   print (vam->ofp,
18645          "table-id %d, prefix %U/%d",
18646          ntohl (mp->table_id), format_ip6_address, mp->address,
18647          mp->address_length);
18648   fp = mp->path;
18649   for (i = 0; i < count; i++)
18650     {
18651       if (fp->afi == IP46_TYPE_IP6)
18652         print (vam->ofp,
18653                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18654                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18655                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18656                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18657                format_ip6_address, fp->next_hop);
18658       else if (fp->afi == IP46_TYPE_IP4)
18659         print (vam->ofp,
18660                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18661                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18662                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18663                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18664                format_ip4_address, fp->next_hop);
18665       fp++;
18666     }
18667 }
18668
18669 static void vl_api_ip6_fib_details_t_handler_json
18670   (vl_api_ip6_fib_details_t * mp)
18671 {
18672   vat_main_t *vam = &vat_main;
18673   int count = ntohl (mp->count);
18674   vat_json_node_t *node = NULL;
18675   struct in_addr ip4;
18676   struct in6_addr ip6;
18677   vl_api_fib_path_t *fp;
18678   int i;
18679
18680   if (VAT_JSON_ARRAY != vam->json_tree.type)
18681     {
18682       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18683       vat_json_init_array (&vam->json_tree);
18684     }
18685   node = vat_json_array_add (&vam->json_tree);
18686
18687   vat_json_init_object (node);
18688   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18689   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
18690   vat_json_object_add_ip6 (node, "prefix", ip6);
18691   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18692   vat_json_object_add_uint (node, "path_count", count);
18693   fp = mp->path;
18694   for (i = 0; i < count; i++)
18695     {
18696       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18697       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18698       vat_json_object_add_uint (node, "is_local", fp->is_local);
18699       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18700       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18701       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18702       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18703       if (fp->afi == IP46_TYPE_IP4)
18704         {
18705           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18706           vat_json_object_add_ip4 (node, "next_hop", ip4);
18707         }
18708       else if (fp->afi == IP46_TYPE_IP6)
18709         {
18710           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18711           vat_json_object_add_ip6 (node, "next_hop", ip6);
18712         }
18713     }
18714 }
18715
18716 static int
18717 api_ip6_fib_dump (vat_main_t * vam)
18718 {
18719   vl_api_ip6_fib_dump_t *mp;
18720   vl_api_control_ping_t *mp_ping;
18721   int ret;
18722
18723   M (IP6_FIB_DUMP, mp);
18724   S (mp);
18725
18726   /* Use a control ping for synchronization */
18727   MPING (CONTROL_PING, mp_ping);
18728   S (mp_ping);
18729
18730   W (ret);
18731   return ret;
18732 }
18733
18734 static int
18735 api_ip6_mfib_dump (vat_main_t * vam)
18736 {
18737   vl_api_ip6_mfib_dump_t *mp;
18738   vl_api_control_ping_t *mp_ping;
18739   int ret;
18740
18741   M (IP6_MFIB_DUMP, mp);
18742   S (mp);
18743
18744   /* Use a control ping for synchronization */
18745   MPING (CONTROL_PING, mp_ping);
18746   S (mp_ping);
18747
18748   W (ret);
18749   return ret;
18750 }
18751
18752 int
18753 api_classify_table_ids (vat_main_t * vam)
18754 {
18755   vl_api_classify_table_ids_t *mp;
18756   int ret;
18757
18758   /* Construct the API message */
18759   M (CLASSIFY_TABLE_IDS, mp);
18760   mp->context = 0;
18761
18762   S (mp);
18763   W (ret);
18764   return ret;
18765 }
18766
18767 int
18768 api_classify_table_by_interface (vat_main_t * vam)
18769 {
18770   unformat_input_t *input = vam->input;
18771   vl_api_classify_table_by_interface_t *mp;
18772
18773   u32 sw_if_index = ~0;
18774   int ret;
18775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18776     {
18777       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18778         ;
18779       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18780         ;
18781       else
18782         break;
18783     }
18784   if (sw_if_index == ~0)
18785     {
18786       errmsg ("missing interface name or sw_if_index");
18787       return -99;
18788     }
18789
18790   /* Construct the API message */
18791   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18792   mp->context = 0;
18793   mp->sw_if_index = ntohl (sw_if_index);
18794
18795   S (mp);
18796   W (ret);
18797   return ret;
18798 }
18799
18800 int
18801 api_classify_table_info (vat_main_t * vam)
18802 {
18803   unformat_input_t *input = vam->input;
18804   vl_api_classify_table_info_t *mp;
18805
18806   u32 table_id = ~0;
18807   int ret;
18808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18809     {
18810       if (unformat (input, "table_id %d", &table_id))
18811         ;
18812       else
18813         break;
18814     }
18815   if (table_id == ~0)
18816     {
18817       errmsg ("missing table id");
18818       return -99;
18819     }
18820
18821   /* Construct the API message */
18822   M (CLASSIFY_TABLE_INFO, mp);
18823   mp->context = 0;
18824   mp->table_id = ntohl (table_id);
18825
18826   S (mp);
18827   W (ret);
18828   return ret;
18829 }
18830
18831 int
18832 api_classify_session_dump (vat_main_t * vam)
18833 {
18834   unformat_input_t *input = vam->input;
18835   vl_api_classify_session_dump_t *mp;
18836   vl_api_control_ping_t *mp_ping;
18837
18838   u32 table_id = ~0;
18839   int ret;
18840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18841     {
18842       if (unformat (input, "table_id %d", &table_id))
18843         ;
18844       else
18845         break;
18846     }
18847   if (table_id == ~0)
18848     {
18849       errmsg ("missing table id");
18850       return -99;
18851     }
18852
18853   /* Construct the API message */
18854   M (CLASSIFY_SESSION_DUMP, mp);
18855   mp->context = 0;
18856   mp->table_id = ntohl (table_id);
18857   S (mp);
18858
18859   /* Use a control ping for synchronization */
18860   MPING (CONTROL_PING, mp_ping);
18861   S (mp_ping);
18862
18863   W (ret);
18864   return ret;
18865 }
18866
18867 static void
18868 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18869 {
18870   vat_main_t *vam = &vat_main;
18871
18872   print (vam->ofp, "collector_address %U, collector_port %d, "
18873          "src_address %U, vrf_id %d, path_mtu %u, "
18874          "template_interval %u, udp_checksum %d",
18875          format_ip4_address, mp->collector_address,
18876          ntohs (mp->collector_port),
18877          format_ip4_address, mp->src_address,
18878          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18879          ntohl (mp->template_interval), mp->udp_checksum);
18880
18881   vam->retval = 0;
18882   vam->result_ready = 1;
18883 }
18884
18885 static void
18886   vl_api_ipfix_exporter_details_t_handler_json
18887   (vl_api_ipfix_exporter_details_t * mp)
18888 {
18889   vat_main_t *vam = &vat_main;
18890   vat_json_node_t node;
18891   struct in_addr collector_address;
18892   struct in_addr src_address;
18893
18894   vat_json_init_object (&node);
18895   clib_memcpy (&collector_address, &mp->collector_address,
18896                sizeof (collector_address));
18897   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18898   vat_json_object_add_uint (&node, "collector_port",
18899                             ntohs (mp->collector_port));
18900   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18901   vat_json_object_add_ip4 (&node, "src_address", src_address);
18902   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18903   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18904   vat_json_object_add_uint (&node, "template_interval",
18905                             ntohl (mp->template_interval));
18906   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18907
18908   vat_json_print (vam->ofp, &node);
18909   vat_json_free (&node);
18910   vam->retval = 0;
18911   vam->result_ready = 1;
18912 }
18913
18914 int
18915 api_ipfix_exporter_dump (vat_main_t * vam)
18916 {
18917   vl_api_ipfix_exporter_dump_t *mp;
18918   int ret;
18919
18920   /* Construct the API message */
18921   M (IPFIX_EXPORTER_DUMP, mp);
18922   mp->context = 0;
18923
18924   S (mp);
18925   W (ret);
18926   return ret;
18927 }
18928
18929 static int
18930 api_ipfix_classify_stream_dump (vat_main_t * vam)
18931 {
18932   vl_api_ipfix_classify_stream_dump_t *mp;
18933   int ret;
18934
18935   /* Construct the API message */
18936   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18937   mp->context = 0;
18938
18939   S (mp);
18940   W (ret);
18941   return ret;
18942   /* NOTREACHED */
18943   return 0;
18944 }
18945
18946 static void
18947   vl_api_ipfix_classify_stream_details_t_handler
18948   (vl_api_ipfix_classify_stream_details_t * mp)
18949 {
18950   vat_main_t *vam = &vat_main;
18951   print (vam->ofp, "domain_id %d, src_port %d",
18952          ntohl (mp->domain_id), ntohs (mp->src_port));
18953   vam->retval = 0;
18954   vam->result_ready = 1;
18955 }
18956
18957 static void
18958   vl_api_ipfix_classify_stream_details_t_handler_json
18959   (vl_api_ipfix_classify_stream_details_t * mp)
18960 {
18961   vat_main_t *vam = &vat_main;
18962   vat_json_node_t node;
18963
18964   vat_json_init_object (&node);
18965   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18966   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18967
18968   vat_json_print (vam->ofp, &node);
18969   vat_json_free (&node);
18970   vam->retval = 0;
18971   vam->result_ready = 1;
18972 }
18973
18974 static int
18975 api_ipfix_classify_table_dump (vat_main_t * vam)
18976 {
18977   vl_api_ipfix_classify_table_dump_t *mp;
18978   vl_api_control_ping_t *mp_ping;
18979   int ret;
18980
18981   if (!vam->json_output)
18982     {
18983       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18984              "transport_protocol");
18985     }
18986
18987   /* Construct the API message */
18988   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18989
18990   /* send it... */
18991   S (mp);
18992
18993   /* Use a control ping for synchronization */
18994   MPING (CONTROL_PING, mp_ping);
18995   S (mp_ping);
18996
18997   W (ret);
18998   return ret;
18999 }
19000
19001 static void
19002   vl_api_ipfix_classify_table_details_t_handler
19003   (vl_api_ipfix_classify_table_details_t * mp)
19004 {
19005   vat_main_t *vam = &vat_main;
19006   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19007          mp->transport_protocol);
19008 }
19009
19010 static void
19011   vl_api_ipfix_classify_table_details_t_handler_json
19012   (vl_api_ipfix_classify_table_details_t * mp)
19013 {
19014   vat_json_node_t *node = NULL;
19015   vat_main_t *vam = &vat_main;
19016
19017   if (VAT_JSON_ARRAY != vam->json_tree.type)
19018     {
19019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19020       vat_json_init_array (&vam->json_tree);
19021     }
19022
19023   node = vat_json_array_add (&vam->json_tree);
19024   vat_json_init_object (node);
19025
19026   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19027   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19028   vat_json_object_add_uint (node, "transport_protocol",
19029                             mp->transport_protocol);
19030 }
19031
19032 static int
19033 api_sw_interface_span_enable_disable (vat_main_t * vam)
19034 {
19035   unformat_input_t *i = vam->input;
19036   vl_api_sw_interface_span_enable_disable_t *mp;
19037   u32 src_sw_if_index = ~0;
19038   u32 dst_sw_if_index = ~0;
19039   u8 state = 3;
19040   int ret;
19041   u8 is_l2 = 0;
19042
19043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19044     {
19045       if (unformat
19046           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19047         ;
19048       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19049         ;
19050       else
19051         if (unformat
19052             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19053         ;
19054       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19055         ;
19056       else if (unformat (i, "disable"))
19057         state = 0;
19058       else if (unformat (i, "rx"))
19059         state = 1;
19060       else if (unformat (i, "tx"))
19061         state = 2;
19062       else if (unformat (i, "both"))
19063         state = 3;
19064       else if (unformat (i, "l2"))
19065         is_l2 = 1;
19066       else
19067         break;
19068     }
19069
19070   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19071
19072   mp->sw_if_index_from = htonl (src_sw_if_index);
19073   mp->sw_if_index_to = htonl (dst_sw_if_index);
19074   mp->state = state;
19075   mp->is_l2 = is_l2;
19076
19077   S (mp);
19078   W (ret);
19079   return ret;
19080 }
19081
19082 static void
19083 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19084                                             * mp)
19085 {
19086   vat_main_t *vam = &vat_main;
19087   u8 *sw_if_from_name = 0;
19088   u8 *sw_if_to_name = 0;
19089   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19090   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19091   char *states[] = { "none", "rx", "tx", "both" };
19092   hash_pair_t *p;
19093
19094   /* *INDENT-OFF* */
19095   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19096   ({
19097     if ((u32) p->value[0] == sw_if_index_from)
19098       {
19099         sw_if_from_name = (u8 *)(p->key);
19100         if (sw_if_to_name)
19101           break;
19102       }
19103     if ((u32) p->value[0] == sw_if_index_to)
19104       {
19105         sw_if_to_name = (u8 *)(p->key);
19106         if (sw_if_from_name)
19107           break;
19108       }
19109   }));
19110   /* *INDENT-ON* */
19111   print (vam->ofp, "%20s => %20s (%s)",
19112          sw_if_from_name, sw_if_to_name, states[mp->state]);
19113 }
19114
19115 static void
19116   vl_api_sw_interface_span_details_t_handler_json
19117   (vl_api_sw_interface_span_details_t * mp)
19118 {
19119   vat_main_t *vam = &vat_main;
19120   vat_json_node_t *node = NULL;
19121   u8 *sw_if_from_name = 0;
19122   u8 *sw_if_to_name = 0;
19123   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19124   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19125   hash_pair_t *p;
19126
19127   /* *INDENT-OFF* */
19128   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19129   ({
19130     if ((u32) p->value[0] == sw_if_index_from)
19131       {
19132         sw_if_from_name = (u8 *)(p->key);
19133         if (sw_if_to_name)
19134           break;
19135       }
19136     if ((u32) p->value[0] == sw_if_index_to)
19137       {
19138         sw_if_to_name = (u8 *)(p->key);
19139         if (sw_if_from_name)
19140           break;
19141       }
19142   }));
19143   /* *INDENT-ON* */
19144
19145   if (VAT_JSON_ARRAY != vam->json_tree.type)
19146     {
19147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19148       vat_json_init_array (&vam->json_tree);
19149     }
19150   node = vat_json_array_add (&vam->json_tree);
19151
19152   vat_json_init_object (node);
19153   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19154   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19155   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19156   if (0 != sw_if_to_name)
19157     {
19158       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19159     }
19160   vat_json_object_add_uint (node, "state", mp->state);
19161 }
19162
19163 static int
19164 api_sw_interface_span_dump (vat_main_t * vam)
19165 {
19166   unformat_input_t *input = vam->input;
19167   vl_api_sw_interface_span_dump_t *mp;
19168   vl_api_control_ping_t *mp_ping;
19169   u8 is_l2 = 0;
19170   int ret;
19171
19172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19173     {
19174       if (unformat (input, "l2"))
19175         is_l2 = 1;
19176       else
19177         break;
19178     }
19179
19180   M (SW_INTERFACE_SPAN_DUMP, mp);
19181   mp->is_l2 = is_l2;
19182   S (mp);
19183
19184   /* Use a control ping for synchronization */
19185   MPING (CONTROL_PING, mp_ping);
19186   S (mp_ping);
19187
19188   W (ret);
19189   return ret;
19190 }
19191
19192 int
19193 api_pg_create_interface (vat_main_t * vam)
19194 {
19195   unformat_input_t *input = vam->input;
19196   vl_api_pg_create_interface_t *mp;
19197
19198   u32 if_id = ~0;
19199   int ret;
19200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19201     {
19202       if (unformat (input, "if_id %d", &if_id))
19203         ;
19204       else
19205         break;
19206     }
19207   if (if_id == ~0)
19208     {
19209       errmsg ("missing pg interface index");
19210       return -99;
19211     }
19212
19213   /* Construct the API message */
19214   M (PG_CREATE_INTERFACE, mp);
19215   mp->context = 0;
19216   mp->interface_id = ntohl (if_id);
19217
19218   S (mp);
19219   W (ret);
19220   return ret;
19221 }
19222
19223 int
19224 api_pg_capture (vat_main_t * vam)
19225 {
19226   unformat_input_t *input = vam->input;
19227   vl_api_pg_capture_t *mp;
19228
19229   u32 if_id = ~0;
19230   u8 enable = 1;
19231   u32 count = 1;
19232   u8 pcap_file_set = 0;
19233   u8 *pcap_file = 0;
19234   int ret;
19235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19236     {
19237       if (unformat (input, "if_id %d", &if_id))
19238         ;
19239       else if (unformat (input, "pcap %s", &pcap_file))
19240         pcap_file_set = 1;
19241       else if (unformat (input, "count %d", &count))
19242         ;
19243       else if (unformat (input, "disable"))
19244         enable = 0;
19245       else
19246         break;
19247     }
19248   if (if_id == ~0)
19249     {
19250       errmsg ("missing pg interface index");
19251       return -99;
19252     }
19253   if (pcap_file_set > 0)
19254     {
19255       if (vec_len (pcap_file) > 255)
19256         {
19257           errmsg ("pcap file name is too long");
19258           return -99;
19259         }
19260     }
19261
19262   u32 name_len = vec_len (pcap_file);
19263   /* Construct the API message */
19264   M (PG_CAPTURE, mp);
19265   mp->context = 0;
19266   mp->interface_id = ntohl (if_id);
19267   mp->is_enabled = enable;
19268   mp->count = ntohl (count);
19269   mp->pcap_name_length = ntohl (name_len);
19270   if (pcap_file_set != 0)
19271     {
19272       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19273     }
19274   vec_free (pcap_file);
19275
19276   S (mp);
19277   W (ret);
19278   return ret;
19279 }
19280
19281 int
19282 api_pg_enable_disable (vat_main_t * vam)
19283 {
19284   unformat_input_t *input = vam->input;
19285   vl_api_pg_enable_disable_t *mp;
19286
19287   u8 enable = 1;
19288   u8 stream_name_set = 0;
19289   u8 *stream_name = 0;
19290   int ret;
19291   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19292     {
19293       if (unformat (input, "stream %s", &stream_name))
19294         stream_name_set = 1;
19295       else if (unformat (input, "disable"))
19296         enable = 0;
19297       else
19298         break;
19299     }
19300
19301   if (stream_name_set > 0)
19302     {
19303       if (vec_len (stream_name) > 255)
19304         {
19305           errmsg ("stream name too long");
19306           return -99;
19307         }
19308     }
19309
19310   u32 name_len = vec_len (stream_name);
19311   /* Construct the API message */
19312   M (PG_ENABLE_DISABLE, mp);
19313   mp->context = 0;
19314   mp->is_enabled = enable;
19315   if (stream_name_set != 0)
19316     {
19317       mp->stream_name_length = ntohl (name_len);
19318       clib_memcpy (mp->stream_name, stream_name, name_len);
19319     }
19320   vec_free (stream_name);
19321
19322   S (mp);
19323   W (ret);
19324   return ret;
19325 }
19326
19327 int
19328 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19329 {
19330   unformat_input_t *input = vam->input;
19331   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19332
19333   u16 *low_ports = 0;
19334   u16 *high_ports = 0;
19335   u16 this_low;
19336   u16 this_hi;
19337   ip4_address_t ip4_addr;
19338   ip6_address_t ip6_addr;
19339   u32 length;
19340   u32 tmp, tmp2;
19341   u8 prefix_set = 0;
19342   u32 vrf_id = ~0;
19343   u8 is_add = 1;
19344   u8 is_ipv6 = 0;
19345   int ret;
19346
19347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19348     {
19349       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19350         {
19351           prefix_set = 1;
19352         }
19353       else
19354         if (unformat
19355             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19356         {
19357           prefix_set = 1;
19358           is_ipv6 = 1;
19359         }
19360       else if (unformat (input, "vrf %d", &vrf_id))
19361         ;
19362       else if (unformat (input, "del"))
19363         is_add = 0;
19364       else if (unformat (input, "port %d", &tmp))
19365         {
19366           if (tmp == 0 || tmp > 65535)
19367             {
19368               errmsg ("port %d out of range", tmp);
19369               return -99;
19370             }
19371           this_low = tmp;
19372           this_hi = this_low + 1;
19373           vec_add1 (low_ports, this_low);
19374           vec_add1 (high_ports, this_hi);
19375         }
19376       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19377         {
19378           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19379             {
19380               errmsg ("incorrect range parameters");
19381               return -99;
19382             }
19383           this_low = tmp;
19384           /* Note: in debug CLI +1 is added to high before
19385              passing to real fn that does "the work"
19386              (ip_source_and_port_range_check_add_del).
19387              This fn is a wrapper around the binary API fn a
19388              control plane will call, which expects this increment
19389              to have occurred. Hence letting the binary API control
19390              plane fn do the increment for consistency between VAT
19391              and other control planes.
19392            */
19393           this_hi = tmp2;
19394           vec_add1 (low_ports, this_low);
19395           vec_add1 (high_ports, this_hi);
19396         }
19397       else
19398         break;
19399     }
19400
19401   if (prefix_set == 0)
19402     {
19403       errmsg ("<address>/<mask> not specified");
19404       return -99;
19405     }
19406
19407   if (vrf_id == ~0)
19408     {
19409       errmsg ("VRF ID required, not specified");
19410       return -99;
19411     }
19412
19413   if (vrf_id == 0)
19414     {
19415       errmsg
19416         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19417       return -99;
19418     }
19419
19420   if (vec_len (low_ports) == 0)
19421     {
19422       errmsg ("At least one port or port range required");
19423       return -99;
19424     }
19425
19426   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19427
19428   mp->is_add = is_add;
19429
19430   if (is_ipv6)
19431     {
19432       mp->is_ipv6 = 1;
19433       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19434     }
19435   else
19436     {
19437       mp->is_ipv6 = 0;
19438       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19439     }
19440
19441   mp->mask_length = length;
19442   mp->number_of_ranges = vec_len (low_ports);
19443
19444   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19445   vec_free (low_ports);
19446
19447   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19448   vec_free (high_ports);
19449
19450   mp->vrf_id = ntohl (vrf_id);
19451
19452   S (mp);
19453   W (ret);
19454   return ret;
19455 }
19456
19457 int
19458 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19459 {
19460   unformat_input_t *input = vam->input;
19461   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19462   u32 sw_if_index = ~0;
19463   int vrf_set = 0;
19464   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19465   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19466   u8 is_add = 1;
19467   int ret;
19468
19469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19470     {
19471       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19472         ;
19473       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19474         ;
19475       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19476         vrf_set = 1;
19477       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19478         vrf_set = 1;
19479       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19480         vrf_set = 1;
19481       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19482         vrf_set = 1;
19483       else if (unformat (input, "del"))
19484         is_add = 0;
19485       else
19486         break;
19487     }
19488
19489   if (sw_if_index == ~0)
19490     {
19491       errmsg ("Interface required but not specified");
19492       return -99;
19493     }
19494
19495   if (vrf_set == 0)
19496     {
19497       errmsg ("VRF ID required but not specified");
19498       return -99;
19499     }
19500
19501   if (tcp_out_vrf_id == 0
19502       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19503     {
19504       errmsg
19505         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19506       return -99;
19507     }
19508
19509   /* Construct the API message */
19510   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19511
19512   mp->sw_if_index = ntohl (sw_if_index);
19513   mp->is_add = is_add;
19514   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19515   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19516   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19517   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19518
19519   /* send it... */
19520   S (mp);
19521
19522   /* Wait for a reply... */
19523   W (ret);
19524   return ret;
19525 }
19526
19527 static int
19528 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
19529 {
19530   unformat_input_t *i = vam->input;
19531   vl_api_ipsec_gre_add_del_tunnel_t *mp;
19532   u32 local_sa_id = 0;
19533   u32 remote_sa_id = 0;
19534   ip4_address_t src_address;
19535   ip4_address_t dst_address;
19536   u8 is_add = 1;
19537   int ret;
19538
19539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19540     {
19541       if (unformat (i, "local_sa %d", &local_sa_id))
19542         ;
19543       else if (unformat (i, "remote_sa %d", &remote_sa_id))
19544         ;
19545       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
19546         ;
19547       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
19548         ;
19549       else if (unformat (i, "del"))
19550         is_add = 0;
19551       else
19552         {
19553           clib_warning ("parse error '%U'", format_unformat_error, i);
19554           return -99;
19555         }
19556     }
19557
19558   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
19559
19560   mp->local_sa_id = ntohl (local_sa_id);
19561   mp->remote_sa_id = ntohl (remote_sa_id);
19562   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
19563   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
19564   mp->is_add = is_add;
19565
19566   S (mp);
19567   W (ret);
19568   return ret;
19569 }
19570
19571 static int
19572 api_punt (vat_main_t * vam)
19573 {
19574   unformat_input_t *i = vam->input;
19575   vl_api_punt_t *mp;
19576   u32 ipv = ~0;
19577   u32 protocol = ~0;
19578   u32 port = ~0;
19579   int is_add = 1;
19580   int ret;
19581
19582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19583     {
19584       if (unformat (i, "ip %d", &ipv))
19585         ;
19586       else if (unformat (i, "protocol %d", &protocol))
19587         ;
19588       else if (unformat (i, "port %d", &port))
19589         ;
19590       else if (unformat (i, "del"))
19591         is_add = 0;
19592       else
19593         {
19594           clib_warning ("parse error '%U'", format_unformat_error, i);
19595           return -99;
19596         }
19597     }
19598
19599   M (PUNT, mp);
19600
19601   mp->is_add = (u8) is_add;
19602   mp->ipv = (u8) ipv;
19603   mp->l4_protocol = (u8) protocol;
19604   mp->l4_port = htons ((u16) port);
19605
19606   S (mp);
19607   W (ret);
19608   return ret;
19609 }
19610
19611 static void vl_api_ipsec_gre_tunnel_details_t_handler
19612   (vl_api_ipsec_gre_tunnel_details_t * mp)
19613 {
19614   vat_main_t *vam = &vat_main;
19615
19616   print (vam->ofp, "%11d%15U%15U%14d%14d",
19617          ntohl (mp->sw_if_index),
19618          format_ip4_address, &mp->src_address,
19619          format_ip4_address, &mp->dst_address,
19620          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
19621 }
19622
19623 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
19624   (vl_api_ipsec_gre_tunnel_details_t * mp)
19625 {
19626   vat_main_t *vam = &vat_main;
19627   vat_json_node_t *node = NULL;
19628   struct in_addr ip4;
19629
19630   if (VAT_JSON_ARRAY != vam->json_tree.type)
19631     {
19632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19633       vat_json_init_array (&vam->json_tree);
19634     }
19635   node = vat_json_array_add (&vam->json_tree);
19636
19637   vat_json_init_object (node);
19638   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19639   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
19640   vat_json_object_add_ip4 (node, "src_address", ip4);
19641   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
19642   vat_json_object_add_ip4 (node, "dst_address", ip4);
19643   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
19644   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
19645 }
19646
19647 static int
19648 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
19649 {
19650   unformat_input_t *i = vam->input;
19651   vl_api_ipsec_gre_tunnel_dump_t *mp;
19652   vl_api_control_ping_t *mp_ping;
19653   u32 sw_if_index;
19654   u8 sw_if_index_set = 0;
19655   int ret;
19656
19657   /* Parse args required to build the message */
19658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19659     {
19660       if (unformat (i, "sw_if_index %d", &sw_if_index))
19661         sw_if_index_set = 1;
19662       else
19663         break;
19664     }
19665
19666   if (sw_if_index_set == 0)
19667     {
19668       sw_if_index = ~0;
19669     }
19670
19671   if (!vam->json_output)
19672     {
19673       print (vam->ofp, "%11s%15s%15s%14s%14s",
19674              "sw_if_index", "src_address", "dst_address",
19675              "local_sa_id", "remote_sa_id");
19676     }
19677
19678   /* Get list of gre-tunnel interfaces */
19679   M (IPSEC_GRE_TUNNEL_DUMP, mp);
19680
19681   mp->sw_if_index = htonl (sw_if_index);
19682
19683   S (mp);
19684
19685   /* Use a control ping for synchronization */
19686   MPING (CONTROL_PING, mp_ping);
19687   S (mp_ping);
19688
19689   W (ret);
19690   return ret;
19691 }
19692
19693 static int
19694 api_delete_subif (vat_main_t * vam)
19695 {
19696   unformat_input_t *i = vam->input;
19697   vl_api_delete_subif_t *mp;
19698   u32 sw_if_index = ~0;
19699   int ret;
19700
19701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19702     {
19703       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19704         ;
19705       if (unformat (i, "sw_if_index %d", &sw_if_index))
19706         ;
19707       else
19708         break;
19709     }
19710
19711   if (sw_if_index == ~0)
19712     {
19713       errmsg ("missing sw_if_index");
19714       return -99;
19715     }
19716
19717   /* Construct the API message */
19718   M (DELETE_SUBIF, mp);
19719   mp->sw_if_index = ntohl (sw_if_index);
19720
19721   S (mp);
19722   W (ret);
19723   return ret;
19724 }
19725
19726 #define foreach_pbb_vtr_op      \
19727 _("disable",  L2_VTR_DISABLED)  \
19728 _("pop",  L2_VTR_POP_2)         \
19729 _("push",  L2_VTR_PUSH_2)
19730
19731 static int
19732 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19733 {
19734   unformat_input_t *i = vam->input;
19735   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19736   u32 sw_if_index = ~0, vtr_op = ~0;
19737   u16 outer_tag = ~0;
19738   u8 dmac[6], smac[6];
19739   u8 dmac_set = 0, smac_set = 0;
19740   u16 vlanid = 0;
19741   u32 sid = ~0;
19742   u32 tmp;
19743   int ret;
19744
19745   /* Shut up coverity */
19746   memset (dmac, 0, sizeof (dmac));
19747   memset (smac, 0, sizeof (smac));
19748
19749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19750     {
19751       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19752         ;
19753       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19754         ;
19755       else if (unformat (i, "vtr_op %d", &vtr_op))
19756         ;
19757 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19758       foreach_pbb_vtr_op
19759 #undef _
19760         else if (unformat (i, "translate_pbb_stag"))
19761         {
19762           if (unformat (i, "%d", &tmp))
19763             {
19764               vtr_op = L2_VTR_TRANSLATE_2_1;
19765               outer_tag = tmp;
19766             }
19767           else
19768             {
19769               errmsg
19770                 ("translate_pbb_stag operation requires outer tag definition");
19771               return -99;
19772             }
19773         }
19774       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19775         dmac_set++;
19776       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19777         smac_set++;
19778       else if (unformat (i, "sid %d", &sid))
19779         ;
19780       else if (unformat (i, "vlanid %d", &tmp))
19781         vlanid = tmp;
19782       else
19783         {
19784           clib_warning ("parse error '%U'", format_unformat_error, i);
19785           return -99;
19786         }
19787     }
19788
19789   if ((sw_if_index == ~0) || (vtr_op == ~0))
19790     {
19791       errmsg ("missing sw_if_index or vtr operation");
19792       return -99;
19793     }
19794   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19795       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19796     {
19797       errmsg
19798         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19799       return -99;
19800     }
19801
19802   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19803   mp->sw_if_index = ntohl (sw_if_index);
19804   mp->vtr_op = ntohl (vtr_op);
19805   mp->outer_tag = ntohs (outer_tag);
19806   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19807   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19808   mp->b_vlanid = ntohs (vlanid);
19809   mp->i_sid = ntohl (sid);
19810
19811   S (mp);
19812   W (ret);
19813   return ret;
19814 }
19815
19816 static int
19817 api_flow_classify_set_interface (vat_main_t * vam)
19818 {
19819   unformat_input_t *i = vam->input;
19820   vl_api_flow_classify_set_interface_t *mp;
19821   u32 sw_if_index;
19822   int sw_if_index_set;
19823   u32 ip4_table_index = ~0;
19824   u32 ip6_table_index = ~0;
19825   u8 is_add = 1;
19826   int ret;
19827
19828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19829     {
19830       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19831         sw_if_index_set = 1;
19832       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19833         sw_if_index_set = 1;
19834       else if (unformat (i, "del"))
19835         is_add = 0;
19836       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19837         ;
19838       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19839         ;
19840       else
19841         {
19842           clib_warning ("parse error '%U'", format_unformat_error, i);
19843           return -99;
19844         }
19845     }
19846
19847   if (sw_if_index_set == 0)
19848     {
19849       errmsg ("missing interface name or sw_if_index");
19850       return -99;
19851     }
19852
19853   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19854
19855   mp->sw_if_index = ntohl (sw_if_index);
19856   mp->ip4_table_index = ntohl (ip4_table_index);
19857   mp->ip6_table_index = ntohl (ip6_table_index);
19858   mp->is_add = is_add;
19859
19860   S (mp);
19861   W (ret);
19862   return ret;
19863 }
19864
19865 static int
19866 api_flow_classify_dump (vat_main_t * vam)
19867 {
19868   unformat_input_t *i = vam->input;
19869   vl_api_flow_classify_dump_t *mp;
19870   vl_api_control_ping_t *mp_ping;
19871   u8 type = FLOW_CLASSIFY_N_TABLES;
19872   int ret;
19873
19874   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19875     ;
19876   else
19877     {
19878       errmsg ("classify table type must be specified");
19879       return -99;
19880     }
19881
19882   if (!vam->json_output)
19883     {
19884       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19885     }
19886
19887   M (FLOW_CLASSIFY_DUMP, mp);
19888   mp->type = type;
19889   /* send it... */
19890   S (mp);
19891
19892   /* Use a control ping for synchronization */
19893   MPING (CONTROL_PING, mp_ping);
19894   S (mp_ping);
19895
19896   /* Wait for a reply... */
19897   W (ret);
19898   return ret;
19899 }
19900
19901 static int
19902 api_feature_enable_disable (vat_main_t * vam)
19903 {
19904   unformat_input_t *i = vam->input;
19905   vl_api_feature_enable_disable_t *mp;
19906   u8 *arc_name = 0;
19907   u8 *feature_name = 0;
19908   u32 sw_if_index = ~0;
19909   u8 enable = 1;
19910   int ret;
19911
19912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19913     {
19914       if (unformat (i, "arc_name %s", &arc_name))
19915         ;
19916       else if (unformat (i, "feature_name %s", &feature_name))
19917         ;
19918       else
19919         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19920         ;
19921       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19922         ;
19923       else if (unformat (i, "disable"))
19924         enable = 0;
19925       else
19926         break;
19927     }
19928
19929   if (arc_name == 0)
19930     {
19931       errmsg ("missing arc name");
19932       return -99;
19933     }
19934   if (vec_len (arc_name) > 63)
19935     {
19936       errmsg ("arc name too long");
19937     }
19938
19939   if (feature_name == 0)
19940     {
19941       errmsg ("missing feature name");
19942       return -99;
19943     }
19944   if (vec_len (feature_name) > 63)
19945     {
19946       errmsg ("feature name too long");
19947     }
19948
19949   if (sw_if_index == ~0)
19950     {
19951       errmsg ("missing interface name or sw_if_index");
19952       return -99;
19953     }
19954
19955   /* Construct the API message */
19956   M (FEATURE_ENABLE_DISABLE, mp);
19957   mp->sw_if_index = ntohl (sw_if_index);
19958   mp->enable = enable;
19959   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19960   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19961   vec_free (arc_name);
19962   vec_free (feature_name);
19963
19964   S (mp);
19965   W (ret);
19966   return ret;
19967 }
19968
19969 static int
19970 api_sw_interface_tag_add_del (vat_main_t * vam)
19971 {
19972   unformat_input_t *i = vam->input;
19973   vl_api_sw_interface_tag_add_del_t *mp;
19974   u32 sw_if_index = ~0;
19975   u8 *tag = 0;
19976   u8 enable = 1;
19977   int ret;
19978
19979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19980     {
19981       if (unformat (i, "tag %s", &tag))
19982         ;
19983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19984         ;
19985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19986         ;
19987       else if (unformat (i, "del"))
19988         enable = 0;
19989       else
19990         break;
19991     }
19992
19993   if (sw_if_index == ~0)
19994     {
19995       errmsg ("missing interface name or sw_if_index");
19996       return -99;
19997     }
19998
19999   if (enable && (tag == 0))
20000     {
20001       errmsg ("no tag specified");
20002       return -99;
20003     }
20004
20005   /* Construct the API message */
20006   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20007   mp->sw_if_index = ntohl (sw_if_index);
20008   mp->is_add = enable;
20009   if (enable)
20010     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20011   vec_free (tag);
20012
20013   S (mp);
20014   W (ret);
20015   return ret;
20016 }
20017
20018 static void vl_api_l2_xconnect_details_t_handler
20019   (vl_api_l2_xconnect_details_t * mp)
20020 {
20021   vat_main_t *vam = &vat_main;
20022
20023   print (vam->ofp, "%15d%15d",
20024          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20025 }
20026
20027 static void vl_api_l2_xconnect_details_t_handler_json
20028   (vl_api_l2_xconnect_details_t * mp)
20029 {
20030   vat_main_t *vam = &vat_main;
20031   vat_json_node_t *node = NULL;
20032
20033   if (VAT_JSON_ARRAY != vam->json_tree.type)
20034     {
20035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20036       vat_json_init_array (&vam->json_tree);
20037     }
20038   node = vat_json_array_add (&vam->json_tree);
20039
20040   vat_json_init_object (node);
20041   vat_json_object_add_uint (node, "rx_sw_if_index",
20042                             ntohl (mp->rx_sw_if_index));
20043   vat_json_object_add_uint (node, "tx_sw_if_index",
20044                             ntohl (mp->tx_sw_if_index));
20045 }
20046
20047 static int
20048 api_l2_xconnect_dump (vat_main_t * vam)
20049 {
20050   vl_api_l2_xconnect_dump_t *mp;
20051   vl_api_control_ping_t *mp_ping;
20052   int ret;
20053
20054   if (!vam->json_output)
20055     {
20056       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20057     }
20058
20059   M (L2_XCONNECT_DUMP, mp);
20060
20061   S (mp);
20062
20063   /* Use a control ping for synchronization */
20064   MPING (CONTROL_PING, mp_ping);
20065   S (mp_ping);
20066
20067   W (ret);
20068   return ret;
20069 }
20070
20071 static int
20072 api_sw_interface_set_mtu (vat_main_t * vam)
20073 {
20074   unformat_input_t *i = vam->input;
20075   vl_api_sw_interface_set_mtu_t *mp;
20076   u32 sw_if_index = ~0;
20077   u32 mtu = 0;
20078   int ret;
20079
20080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20081     {
20082       if (unformat (i, "mtu %d", &mtu))
20083         ;
20084       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20085         ;
20086       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20087         ;
20088       else
20089         break;
20090     }
20091
20092   if (sw_if_index == ~0)
20093     {
20094       errmsg ("missing interface name or sw_if_index");
20095       return -99;
20096     }
20097
20098   if (mtu == 0)
20099     {
20100       errmsg ("no mtu specified");
20101       return -99;
20102     }
20103
20104   /* Construct the API message */
20105   M (SW_INTERFACE_SET_MTU, mp);
20106   mp->sw_if_index = ntohl (sw_if_index);
20107   mp->mtu = ntohs ((u16) mtu);
20108
20109   S (mp);
20110   W (ret);
20111   return ret;
20112 }
20113
20114 static int
20115 api_p2p_ethernet_add (vat_main_t * vam)
20116 {
20117   unformat_input_t *i = vam->input;
20118   vl_api_p2p_ethernet_add_t *mp;
20119   u32 parent_if_index = ~0;
20120   u32 sub_id = ~0;
20121   u8 remote_mac[6];
20122   u8 mac_set = 0;
20123   int ret;
20124
20125   memset (remote_mac, 0, sizeof (remote_mac));
20126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20127     {
20128       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20129         ;
20130       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20131         ;
20132       else
20133         if (unformat
20134             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20135         mac_set++;
20136       else if (unformat (i, "sub_id %d", &sub_id))
20137         ;
20138       else
20139         {
20140           clib_warning ("parse error '%U'", format_unformat_error, i);
20141           return -99;
20142         }
20143     }
20144
20145   if (parent_if_index == ~0)
20146     {
20147       errmsg ("missing interface name or sw_if_index");
20148       return -99;
20149     }
20150   if (mac_set == 0)
20151     {
20152       errmsg ("missing remote mac address");
20153       return -99;
20154     }
20155   if (sub_id == ~0)
20156     {
20157       errmsg ("missing sub-interface id");
20158       return -99;
20159     }
20160
20161   M (P2P_ETHERNET_ADD, mp);
20162   mp->parent_if_index = ntohl (parent_if_index);
20163   mp->subif_id = ntohl (sub_id);
20164   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20165
20166   S (mp);
20167   W (ret);
20168   return ret;
20169 }
20170
20171 static int
20172 api_p2p_ethernet_del (vat_main_t * vam)
20173 {
20174   unformat_input_t *i = vam->input;
20175   vl_api_p2p_ethernet_del_t *mp;
20176   u32 parent_if_index = ~0;
20177   u8 remote_mac[6];
20178   u8 mac_set = 0;
20179   int ret;
20180
20181   memset (remote_mac, 0, sizeof (remote_mac));
20182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20183     {
20184       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20185         ;
20186       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20187         ;
20188       else
20189         if (unformat
20190             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20191         mac_set++;
20192       else
20193         {
20194           clib_warning ("parse error '%U'", format_unformat_error, i);
20195           return -99;
20196         }
20197     }
20198
20199   if (parent_if_index == ~0)
20200     {
20201       errmsg ("missing interface name or sw_if_index");
20202       return -99;
20203     }
20204   if (mac_set == 0)
20205     {
20206       errmsg ("missing remote mac address");
20207       return -99;
20208     }
20209
20210   M (P2P_ETHERNET_DEL, mp);
20211   mp->parent_if_index = ntohl (parent_if_index);
20212   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20213
20214   S (mp);
20215   W (ret);
20216   return ret;
20217 }
20218
20219 static int
20220 api_lldp_config (vat_main_t * vam)
20221 {
20222   unformat_input_t *i = vam->input;
20223   vl_api_lldp_config_t *mp;
20224   int tx_hold = 0;
20225   int tx_interval = 0;
20226   u8 *sys_name = NULL;
20227   int ret;
20228
20229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20230     {
20231       if (unformat (i, "system-name %s", &sys_name))
20232         ;
20233       else if (unformat (i, "tx-hold %d", &tx_hold))
20234         ;
20235       else if (unformat (i, "tx-interval %d", &tx_interval))
20236         ;
20237       else
20238         {
20239           clib_warning ("parse error '%U'", format_unformat_error, i);
20240           return -99;
20241         }
20242     }
20243
20244   vec_add1 (sys_name, 0);
20245
20246   M (LLDP_CONFIG, mp);
20247   mp->tx_hold = htonl (tx_hold);
20248   mp->tx_interval = htonl (tx_interval);
20249   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20250   vec_free (sys_name);
20251
20252   S (mp);
20253   W (ret);
20254   return ret;
20255 }
20256
20257 static int
20258 api_sw_interface_set_lldp (vat_main_t * vam)
20259 {
20260   unformat_input_t *i = vam->input;
20261   vl_api_sw_interface_set_lldp_t *mp;
20262   u32 sw_if_index = ~0;
20263   u32 enable = 1;
20264   u8 *port_desc = NULL;
20265   int ret;
20266
20267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20268     {
20269       if (unformat (i, "disable"))
20270         enable = 0;
20271       else
20272         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20273         ;
20274       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20275         ;
20276       else if (unformat (i, "port-desc %s", &port_desc))
20277         ;
20278       else
20279         break;
20280     }
20281
20282   if (sw_if_index == ~0)
20283     {
20284       errmsg ("missing interface name or sw_if_index");
20285       return -99;
20286     }
20287
20288   /* Construct the API message */
20289   vec_add1 (port_desc, 0);
20290   M (SW_INTERFACE_SET_LLDP, mp);
20291   mp->sw_if_index = ntohl (sw_if_index);
20292   mp->enable = enable;
20293   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20294   vec_free (port_desc);
20295
20296   S (mp);
20297   W (ret);
20298   return ret;
20299 }
20300
20301 static int
20302 api_tcp_configure_src_addresses (vat_main_t * vam)
20303 {
20304   vl_api_tcp_configure_src_addresses_t *mp;
20305   unformat_input_t *i = vam->input;
20306   ip4_address_t v4first, v4last;
20307   ip6_address_t v6first, v6last;
20308   u8 range_set = 0;
20309   u32 vrf_id = 0;
20310   int ret;
20311
20312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20313     {
20314       if (unformat (i, "%U - %U",
20315                     unformat_ip4_address, &v4first,
20316                     unformat_ip4_address, &v4last))
20317         {
20318           if (range_set)
20319             {
20320               errmsg ("one range per message (range already set)");
20321               return -99;
20322             }
20323           range_set = 1;
20324         }
20325       else if (unformat (i, "%U - %U",
20326                          unformat_ip6_address, &v6first,
20327                          unformat_ip6_address, &v6last))
20328         {
20329           if (range_set)
20330             {
20331               errmsg ("one range per message (range already set)");
20332               return -99;
20333             }
20334           range_set = 2;
20335         }
20336       else if (unformat (i, "vrf %d", &vrf_id))
20337         ;
20338       else
20339         break;
20340     }
20341
20342   if (range_set == 0)
20343     {
20344       errmsg ("address range not set");
20345       return -99;
20346     }
20347
20348   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20349   mp->vrf_id = ntohl (vrf_id);
20350   /* ipv6? */
20351   if (range_set == 2)
20352     {
20353       mp->is_ipv6 = 1;
20354       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20355       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20356     }
20357   else
20358     {
20359       mp->is_ipv6 = 0;
20360       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20361       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20362     }
20363   S (mp);
20364   W (ret);
20365   return ret;
20366 }
20367
20368 static int
20369 api_memfd_segment_create (vat_main_t * vam)
20370 {
20371   unformat_input_t *i = vam->input;
20372   vl_api_memfd_segment_create_t *mp;
20373   u64 size = 64 << 20;
20374   int ret;
20375
20376 #if VPP_API_TEST_BUILTIN == 1
20377   errmsg ("memfd_segment_create (builtin) not supported");
20378   return -99;
20379 #endif
20380
20381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20382     {
20383       if (unformat (i, "size %U", unformat_memory_size, &size))
20384         ;
20385       else
20386         break;
20387     }
20388
20389   M (MEMFD_SEGMENT_CREATE, mp);
20390   mp->requested_size = size;
20391   S (mp);
20392   W (ret);
20393   return ret;
20394 }
20395
20396 static int
20397 q_or_quit (vat_main_t * vam)
20398 {
20399 #if VPP_API_TEST_BUILTIN == 0
20400   longjmp (vam->jump_buf, 1);
20401 #endif
20402   return 0;                     /* not so much */
20403 }
20404
20405 static int
20406 q (vat_main_t * vam)
20407 {
20408   return q_or_quit (vam);
20409 }
20410
20411 static int
20412 quit (vat_main_t * vam)
20413 {
20414   return q_or_quit (vam);
20415 }
20416
20417 static int
20418 comment (vat_main_t * vam)
20419 {
20420   return 0;
20421 }
20422
20423 static int
20424 cmd_cmp (void *a1, void *a2)
20425 {
20426   u8 **c1 = a1;
20427   u8 **c2 = a2;
20428
20429   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20430 }
20431
20432 static int
20433 help (vat_main_t * vam)
20434 {
20435   u8 **cmds = 0;
20436   u8 *name = 0;
20437   hash_pair_t *p;
20438   unformat_input_t *i = vam->input;
20439   int j;
20440
20441   if (unformat (i, "%s", &name))
20442     {
20443       uword *hs;
20444
20445       vec_add1 (name, 0);
20446
20447       hs = hash_get_mem (vam->help_by_name, name);
20448       if (hs)
20449         print (vam->ofp, "usage: %s %s", name, hs[0]);
20450       else
20451         print (vam->ofp, "No such msg / command '%s'", name);
20452       vec_free (name);
20453       return 0;
20454     }
20455
20456   print (vam->ofp, "Help is available for the following:");
20457
20458     /* *INDENT-OFF* */
20459     hash_foreach_pair (p, vam->function_by_name,
20460     ({
20461       vec_add1 (cmds, (u8 *)(p->key));
20462     }));
20463     /* *INDENT-ON* */
20464
20465   vec_sort_with_function (cmds, cmd_cmp);
20466
20467   for (j = 0; j < vec_len (cmds); j++)
20468     print (vam->ofp, "%s", cmds[j]);
20469
20470   vec_free (cmds);
20471   return 0;
20472 }
20473
20474 static int
20475 set (vat_main_t * vam)
20476 {
20477   u8 *name = 0, *value = 0;
20478   unformat_input_t *i = vam->input;
20479
20480   if (unformat (i, "%s", &name))
20481     {
20482       /* The input buffer is a vector, not a string. */
20483       value = vec_dup (i->buffer);
20484       vec_delete (value, i->index, 0);
20485       /* Almost certainly has a trailing newline */
20486       if (value[vec_len (value) - 1] == '\n')
20487         value[vec_len (value) - 1] = 0;
20488       /* Make sure it's a proper string, one way or the other */
20489       vec_add1 (value, 0);
20490       (void) clib_macro_set_value (&vam->macro_main,
20491                                    (char *) name, (char *) value);
20492     }
20493   else
20494     errmsg ("usage: set <name> <value>");
20495
20496   vec_free (name);
20497   vec_free (value);
20498   return 0;
20499 }
20500
20501 static int
20502 unset (vat_main_t * vam)
20503 {
20504   u8 *name = 0;
20505
20506   if (unformat (vam->input, "%s", &name))
20507     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20508       errmsg ("unset: %s wasn't set", name);
20509   vec_free (name);
20510   return 0;
20511 }
20512
20513 typedef struct
20514 {
20515   u8 *name;
20516   u8 *value;
20517 } macro_sort_t;
20518
20519
20520 static int
20521 macro_sort_cmp (void *a1, void *a2)
20522 {
20523   macro_sort_t *s1 = a1;
20524   macro_sort_t *s2 = a2;
20525
20526   return strcmp ((char *) (s1->name), (char *) (s2->name));
20527 }
20528
20529 static int
20530 dump_macro_table (vat_main_t * vam)
20531 {
20532   macro_sort_t *sort_me = 0, *sm;
20533   int i;
20534   hash_pair_t *p;
20535
20536     /* *INDENT-OFF* */
20537     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20538     ({
20539       vec_add2 (sort_me, sm, 1);
20540       sm->name = (u8 *)(p->key);
20541       sm->value = (u8 *) (p->value[0]);
20542     }));
20543     /* *INDENT-ON* */
20544
20545   vec_sort_with_function (sort_me, macro_sort_cmp);
20546
20547   if (vec_len (sort_me))
20548     print (vam->ofp, "%-15s%s", "Name", "Value");
20549   else
20550     print (vam->ofp, "The macro table is empty...");
20551
20552   for (i = 0; i < vec_len (sort_me); i++)
20553     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20554   return 0;
20555 }
20556
20557 static int
20558 dump_node_table (vat_main_t * vam)
20559 {
20560   int i, j;
20561   vlib_node_t *node, *next_node;
20562
20563   if (vec_len (vam->graph_nodes) == 0)
20564     {
20565       print (vam->ofp, "Node table empty, issue get_node_graph...");
20566       return 0;
20567     }
20568
20569   for (i = 0; i < vec_len (vam->graph_nodes); i++)
20570     {
20571       node = vam->graph_nodes[i];
20572       print (vam->ofp, "[%d] %s", i, node->name);
20573       for (j = 0; j < vec_len (node->next_nodes); j++)
20574         {
20575           if (node->next_nodes[j] != ~0)
20576             {
20577               next_node = vam->graph_nodes[node->next_nodes[j]];
20578               print (vam->ofp, "  [%d] %s", j, next_node->name);
20579             }
20580         }
20581     }
20582   return 0;
20583 }
20584
20585 static int
20586 value_sort_cmp (void *a1, void *a2)
20587 {
20588   name_sort_t *n1 = a1;
20589   name_sort_t *n2 = a2;
20590
20591   if (n1->value < n2->value)
20592     return -1;
20593   if (n1->value > n2->value)
20594     return 1;
20595   return 0;
20596 }
20597
20598
20599 static int
20600 dump_msg_api_table (vat_main_t * vam)
20601 {
20602   api_main_t *am = &api_main;
20603   name_sort_t *nses = 0, *ns;
20604   hash_pair_t *hp;
20605   int i;
20606
20607   /* *INDENT-OFF* */
20608   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20609   ({
20610     vec_add2 (nses, ns, 1);
20611     ns->name = (u8 *)(hp->key);
20612     ns->value = (u32) hp->value[0];
20613   }));
20614   /* *INDENT-ON* */
20615
20616   vec_sort_with_function (nses, value_sort_cmp);
20617
20618   for (i = 0; i < vec_len (nses); i++)
20619     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20620   vec_free (nses);
20621   return 0;
20622 }
20623
20624 static int
20625 get_msg_id (vat_main_t * vam)
20626 {
20627   u8 *name_and_crc;
20628   u32 message_index;
20629
20630   if (unformat (vam->input, "%s", &name_and_crc))
20631     {
20632       message_index = vl_api_get_msg_index (name_and_crc);
20633       if (message_index == ~0)
20634         {
20635           print (vam->ofp, " '%s' not found", name_and_crc);
20636           return 0;
20637         }
20638       print (vam->ofp, " '%s' has message index %d",
20639              name_and_crc, message_index);
20640       return 0;
20641     }
20642   errmsg ("name_and_crc required...");
20643   return 0;
20644 }
20645
20646 static int
20647 search_node_table (vat_main_t * vam)
20648 {
20649   unformat_input_t *line_input = vam->input;
20650   u8 *node_to_find;
20651   int j;
20652   vlib_node_t *node, *next_node;
20653   uword *p;
20654
20655   if (vam->graph_node_index_by_name == 0)
20656     {
20657       print (vam->ofp, "Node table empty, issue get_node_graph...");
20658       return 0;
20659     }
20660
20661   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20662     {
20663       if (unformat (line_input, "%s", &node_to_find))
20664         {
20665           vec_add1 (node_to_find, 0);
20666           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20667           if (p == 0)
20668             {
20669               print (vam->ofp, "%s not found...", node_to_find);
20670               goto out;
20671             }
20672           node = vam->graph_nodes[p[0]];
20673           print (vam->ofp, "[%d] %s", p[0], node->name);
20674           for (j = 0; j < vec_len (node->next_nodes); j++)
20675             {
20676               if (node->next_nodes[j] != ~0)
20677                 {
20678                   next_node = vam->graph_nodes[node->next_nodes[j]];
20679                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20680                 }
20681             }
20682         }
20683
20684       else
20685         {
20686           clib_warning ("parse error '%U'", format_unformat_error,
20687                         line_input);
20688           return -99;
20689         }
20690
20691     out:
20692       vec_free (node_to_find);
20693
20694     }
20695
20696   return 0;
20697 }
20698
20699
20700 static int
20701 script (vat_main_t * vam)
20702 {
20703 #if (VPP_API_TEST_BUILTIN==0)
20704   u8 *s = 0;
20705   char *save_current_file;
20706   unformat_input_t save_input;
20707   jmp_buf save_jump_buf;
20708   u32 save_line_number;
20709
20710   FILE *new_fp, *save_ifp;
20711
20712   if (unformat (vam->input, "%s", &s))
20713     {
20714       new_fp = fopen ((char *) s, "r");
20715       if (new_fp == 0)
20716         {
20717           errmsg ("Couldn't open script file %s", s);
20718           vec_free (s);
20719           return -99;
20720         }
20721     }
20722   else
20723     {
20724       errmsg ("Missing script name");
20725       return -99;
20726     }
20727
20728   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20729   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20730   save_ifp = vam->ifp;
20731   save_line_number = vam->input_line_number;
20732   save_current_file = (char *) vam->current_file;
20733
20734   vam->input_line_number = 0;
20735   vam->ifp = new_fp;
20736   vam->current_file = s;
20737   do_one_file (vam);
20738
20739   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
20740   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20741   vam->ifp = save_ifp;
20742   vam->input_line_number = save_line_number;
20743   vam->current_file = (u8 *) save_current_file;
20744   vec_free (s);
20745
20746   return 0;
20747 #else
20748   clib_warning ("use the exec command...");
20749   return -99;
20750 #endif
20751 }
20752
20753 static int
20754 echo (vat_main_t * vam)
20755 {
20756   print (vam->ofp, "%v", vam->input->buffer);
20757   return 0;
20758 }
20759
20760 /* List of API message constructors, CLI names map to api_xxx */
20761 #define foreach_vpe_api_msg                                             \
20762 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20763 _(sw_interface_dump,"")                                                 \
20764 _(sw_interface_set_flags,                                               \
20765   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20766 _(sw_interface_add_del_address,                                         \
20767   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20768 _(sw_interface_set_table,                                               \
20769   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20770 _(sw_interface_set_mpls_enable,                                         \
20771   "<intfc> | sw_if_index [disable | dis]")                              \
20772 _(sw_interface_set_vpath,                                               \
20773   "<intfc> | sw_if_index <id> enable | disable")                        \
20774 _(sw_interface_set_vxlan_bypass,                                        \
20775   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20776 _(sw_interface_set_l2_xconnect,                                         \
20777   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20778   "enable | disable")                                                   \
20779 _(sw_interface_set_l2_bridge,                                           \
20780   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20781   "[shg <split-horizon-group>] [bvi]\n"                                 \
20782   "enable | disable")                                                   \
20783 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20784 _(bridge_domain_add_del,                                                \
20785   "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 <tag>] [del]\n") \
20786 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20787 _(l2fib_add_del,                                                        \
20788   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20789 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20790 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20791 _(l2_flags,                                                             \
20792   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20793 _(bridge_flags,                                                         \
20794   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20795 _(tap_connect,                                                          \
20796   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
20797 _(tap_modify,                                                           \
20798   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
20799 _(tap_delete,                                                           \
20800   "<vpp-if-name> | sw_if_index <id>")                                   \
20801 _(sw_interface_tap_dump, "")                                            \
20802 _(ip_table_add_del,                                                     \
20803   "table-id <n> [ipv6]\n")                                              \
20804 _(ip_add_del_route,                                                     \
20805   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
20806   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20807   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20808   "[multipath] [count <n>]")                                            \
20809 _(ip_mroute_add_del,                                                    \
20810   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20811   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20812 _(mpls_table_add_del,                                                   \
20813   "table-id <n>\n")                                                     \
20814 _(mpls_route_add_del,                                                   \
20815   "<label> <eos> via <addr> [table-id <n>]\n"                           \
20816   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20817   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20818   "[multipath] [count <n>]")                                            \
20819 _(mpls_ip_bind_unbind,                                                  \
20820   "<label> <addr/len>")                                                 \
20821 _(mpls_tunnel_add_del,                                                  \
20822   " via <addr> [table-id <n>]\n"                                        \
20823   "sw_if_index <id>] [l2]  [del]")                                      \
20824 _(proxy_arp_add_del,                                                    \
20825   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
20826 _(proxy_arp_intfc_enable_disable,                                       \
20827   "<intfc> | sw_if_index <id> enable | disable")                        \
20828 _(sw_interface_set_unnumbered,                                          \
20829   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20830 _(ip_neighbor_add_del,                                                  \
20831   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
20832   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
20833 _(reset_vrf, "vrf <id> [ipv6]")                                         \
20834 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20835 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20836   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20837   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20838   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20839 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
20840 _(reset_fib, "vrf <n> [ipv6]")                                          \
20841 _(dhcp_proxy_config,                                                    \
20842   "svr <v46-address> src <v46-address>\n"                               \
20843    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
20844 _(dhcp_proxy_set_vss,                                                   \
20845   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
20846 _(dhcp_proxy_dump, "ip6")                                               \
20847 _(dhcp_client_config,                                                   \
20848   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
20849 _(set_ip_flow_hash,                                                     \
20850   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20851 _(sw_interface_ip6_enable_disable,                                      \
20852   "<intfc> | sw_if_index <id> enable | disable")                        \
20853 _(sw_interface_ip6_set_link_local_address,                              \
20854   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
20855 _(ip6nd_proxy_add_del,                                                  \
20856   "<intfc> | sw_if_index <id> <ip6-address>")                           \
20857 _(ip6nd_proxy_dump, "")                                                 \
20858 _(sw_interface_ip6nd_ra_prefix,                                         \
20859   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
20860   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
20861   "[nolink] [isno]")                                                    \
20862 _(sw_interface_ip6nd_ra_config,                                         \
20863   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
20864   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
20865   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
20866 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
20867 _(l2_patch_add_del,                                                     \
20868   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20869   "enable | disable")                                                   \
20870 _(sr_localsid_add_del,                                                  \
20871   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20872   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20873 _(classify_add_del_table,                                               \
20874   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20875   " [del] [del-chain] mask <mask-value>\n"                              \
20876   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20877   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20878 _(classify_add_del_session,                                             \
20879   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20880   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20881   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20882   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20883 _(classify_set_interface_ip_table,                                      \
20884   "<intfc> | sw_if_index <nn> table <nn>")                              \
20885 _(classify_set_interface_l2_tables,                                     \
20886   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20887   "  [other-table <nn>]")                                               \
20888 _(get_node_index, "node <node-name")                                    \
20889 _(add_node_next, "node <node-name> next <next-node-name>")              \
20890 _(l2tpv3_create_tunnel,                                                 \
20891   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20892   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20893   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20894 _(l2tpv3_set_tunnel_cookies,                                            \
20895   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20896   "[new_remote_cookie <nn>]\n")                                         \
20897 _(l2tpv3_interface_enable_disable,                                      \
20898   "<intfc> | sw_if_index <nn> enable | disable")                        \
20899 _(l2tpv3_set_lookup_key,                                                \
20900   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20901 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20902 _(vxlan_add_del_tunnel,                                                 \
20903   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20904   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20905   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20906 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20907 _(gre_add_del_tunnel,                                                   \
20908   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20909 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20910 _(l2_fib_clear_table, "")                                               \
20911 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20912 _(l2_interface_vlan_tag_rewrite,                                        \
20913   "<intfc> | sw_if_index <nn> \n"                                       \
20914   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20915   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20916 _(create_vhost_user_if,                                                 \
20917         "socket <filename> [server] [renumber <dev_instance>] "         \
20918         "[mac <mac_address>]")                                          \
20919 _(modify_vhost_user_if,                                                 \
20920         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20921         "[server] [renumber <dev_instance>]")                           \
20922 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20923 _(sw_interface_vhost_user_dump, "")                                     \
20924 _(show_version, "")                                                     \
20925 _(vxlan_gpe_add_del_tunnel,                                             \
20926   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20927   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20928   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20929   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20930 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20931 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20932 _(interface_name_renumber,                                              \
20933   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20934 _(input_acl_set_interface,                                              \
20935   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20936   "  [l2-table <nn>] [del]")                                            \
20937 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20938 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20939 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20940 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20941 _(ip_dump, "ipv4 | ipv6")                                               \
20942 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20943 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20944   "  spid_id <n> ")                                                     \
20945 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20946   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20947   "  integ_alg <alg> integ_key <hex>")                                  \
20948 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20949   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20950   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20951   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20952 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20953 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20954   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20955   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20956   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20957 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20958 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20959 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20960   "(auth_data 0x<data> | auth_data <data>)")                            \
20961 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20962   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20963 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20964   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20965   "(local|remote)")                                                     \
20966 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20967 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20968 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20969 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20970 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20971 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20972 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20973 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20974 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20975 _(delete_loopback,"sw_if_index <nn>")                                   \
20976 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20977 _(map_add_domain,                                                       \
20978   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20979   "ip6-src <ip6addr> "                                                  \
20980   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20981 _(map_del_domain, "index <n>")                                          \
20982 _(map_add_del_rule,                                                     \
20983   "index <n> psid <n> dst <ip6addr> [del]")                             \
20984 _(map_domain_dump, "")                                                  \
20985 _(map_rule_dump, "index <map-domain>")                                  \
20986 _(want_interface_events,  "enable|disable")                             \
20987 _(want_stats,"enable|disable")                                          \
20988 _(get_first_msg_id, "client <name>")                                    \
20989 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20990 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20991   "fib-id <nn> [ip4][ip6][default]")                                    \
20992 _(get_node_graph, " ")                                                  \
20993 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20994 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20995 _(ioam_disable, "")                                                     \
20996 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20997                             " sw_if_index <sw_if_index> p <priority> "  \
20998                             "w <weight>] [del]")                        \
20999 _(one_add_del_locator, "locator-set <locator_name> "                    \
21000                         "iface <intf> | sw_if_index <sw_if_index> "     \
21001                         "p <priority> w <weight> [del]")                \
21002 _(one_add_del_local_eid,"vni <vni> eid "                                \
21003                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21004                          "locator-set <locator_name> [del]"             \
21005                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21006 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21007 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21008 _(one_enable_disable, "enable|disable")                                 \
21009 _(one_map_register_enable_disable, "enable|disable")                    \
21010 _(one_map_register_fallback_threshold, "<value>")                       \
21011 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21012 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21013                                "[seid <seid>] "                         \
21014                                "rloc <locator> p <prio> "               \
21015                                "w <weight> [rloc <loc> ... ] "          \
21016                                "action <action> [del-all]")             \
21017 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21018                           "<local-eid>")                                \
21019 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21020 _(one_use_petr, "ip-address> | disable")                                \
21021 _(one_map_request_mode, "src-dst|dst-only")                             \
21022 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21023 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21024 _(one_locator_set_dump, "[local | remote]")                             \
21025 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21026 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21027                        "[local] | [remote]")                            \
21028 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21029 _(one_ndp_bd_get, "")                                                   \
21030 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21031 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21032 _(one_l2_arp_bd_get, "")                                                \
21033 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21034 _(one_stats_enable_disable, "enable|disalbe")                           \
21035 _(show_one_stats_enable_disable, "")                                    \
21036 _(one_eid_table_vni_dump, "")                                           \
21037 _(one_eid_table_map_dump, "l2|l3")                                      \
21038 _(one_map_resolver_dump, "")                                            \
21039 _(one_map_server_dump, "")                                              \
21040 _(one_adjacencies_get, "vni <vni>")                                     \
21041 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21042 _(show_one_rloc_probe_state, "")                                        \
21043 _(show_one_map_register_state, "")                                      \
21044 _(show_one_status, "")                                                  \
21045 _(one_stats_dump, "")                                                   \
21046 _(one_stats_flush, "")                                                  \
21047 _(one_get_map_request_itr_rlocs, "")                                    \
21048 _(one_map_register_set_ttl, "<ttl>")                                    \
21049 _(one_set_transport_protocol, "udp|api")                                \
21050 _(one_get_transport_protocol, "")                                       \
21051 _(show_one_nsh_mapping, "")                                             \
21052 _(show_one_pitr, "")                                                    \
21053 _(show_one_use_petr, "")                                                \
21054 _(show_one_map_request_mode, "")                                        \
21055 _(show_one_map_register_ttl, "")                                        \
21056 _(show_one_map_register_fallback_threshold, "")                         \
21057 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21058                             " sw_if_index <sw_if_index> p <priority> "  \
21059                             "w <weight>] [del]")                        \
21060 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21061                         "iface <intf> | sw_if_index <sw_if_index> "     \
21062                         "p <priority> w <weight> [del]")                \
21063 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21064                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21065                          "locator-set <locator_name> [del]"             \
21066                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21067 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21068 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21069 _(lisp_enable_disable, "enable|disable")                                \
21070 _(lisp_map_register_enable_disable, "enable|disable")                   \
21071 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21072 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21073                                "[seid <seid>] "                         \
21074                                "rloc <locator> p <prio> "               \
21075                                "w <weight> [rloc <loc> ... ] "          \
21076                                "action <action> [del-all]")             \
21077 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21078                           "<local-eid>")                                \
21079 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21080 _(lisp_use_petr, "<ip-address> | disable")                              \
21081 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21082 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21083 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21084 _(lisp_locator_set_dump, "[local | remote]")                            \
21085 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21086 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21087                        "[local] | [remote]")                            \
21088 _(lisp_eid_table_vni_dump, "")                                          \
21089 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21090 _(lisp_map_resolver_dump, "")                                           \
21091 _(lisp_map_server_dump, "")                                             \
21092 _(lisp_adjacencies_get, "vni <vni>")                                    \
21093 _(gpe_fwd_entry_vnis_get, "")                                           \
21094 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21095 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21096                                 "[table <table-id>]")                   \
21097 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21098 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21099 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21100 _(gpe_get_encap_mode, "")                                               \
21101 _(lisp_gpe_add_del_iface, "up|down")                                    \
21102 _(lisp_gpe_enable_disable, "enable|disable")                            \
21103 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21104   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21105 _(show_lisp_rloc_probe_state, "")                                       \
21106 _(show_lisp_map_register_state, "")                                     \
21107 _(show_lisp_status, "")                                                 \
21108 _(lisp_get_map_request_itr_rlocs, "")                                   \
21109 _(show_lisp_pitr, "")                                                   \
21110 _(show_lisp_use_petr, "")                                               \
21111 _(show_lisp_map_request_mode, "")                                       \
21112 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21113 _(af_packet_delete, "name <host interface name>")                       \
21114 _(policer_add_del, "name <policer name> <params> [del]")                \
21115 _(policer_dump, "[name <policer name>]")                                \
21116 _(policer_classify_set_interface,                                       \
21117   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21118   "  [l2-table <nn>] [del]")                                            \
21119 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21120 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21121     "[master|slave]")                                                   \
21122 _(netmap_delete, "name <interface name>")                               \
21123 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21124 _(mpls_fib_dump, "")                                                    \
21125 _(classify_table_ids, "")                                               \
21126 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21127 _(classify_table_info, "table_id <nn>")                                 \
21128 _(classify_session_dump, "table_id <nn>")                               \
21129 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21130     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21131     "[template_interval <nn>] [udp_checksum]")                          \
21132 _(ipfix_exporter_dump, "")                                              \
21133 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21134 _(ipfix_classify_stream_dump, "")                                       \
21135 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21136 _(ipfix_classify_table_dump, "")                                        \
21137 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21138 _(sw_interface_span_dump, "[l2]")                                           \
21139 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21140 _(pg_create_interface, "if_id <nn>")                                    \
21141 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21142 _(pg_enable_disable, "[stream <id>] disable")                           \
21143 _(ip_source_and_port_range_check_add_del,                               \
21144   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21145 _(ip_source_and_port_range_check_interface_add_del,                     \
21146   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21147   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21148 _(ipsec_gre_add_del_tunnel,                                             \
21149   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21150 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21151 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21152 _(l2_interface_pbb_tag_rewrite,                                         \
21153   "<intfc> | sw_if_index <nn> \n"                                       \
21154   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21155   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21156 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21157 _(flow_classify_set_interface,                                          \
21158   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21159 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21160 _(ip_fib_dump, "")                                                      \
21161 _(ip_mfib_dump, "")                                                     \
21162 _(ip6_fib_dump, "")                                                     \
21163 _(ip6_mfib_dump, "")                                                    \
21164 _(feature_enable_disable, "arc_name <arc_name> "                        \
21165   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21166 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21167 "[disable]")                                                            \
21168 _(l2_xconnect_dump, "")                                                 \
21169 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21170 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21171 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21172 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21173 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21174 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21175 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]") \
21176 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21177 _(memfd_segment_create,"size <nnn>")
21178
21179 /* List of command functions, CLI names map directly to functions */
21180 #define foreach_cli_function                                    \
21181 _(comment, "usage: comment <ignore-rest-of-line>")              \
21182 _(dump_interface_table, "usage: dump_interface_table")          \
21183 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21184 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21185 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21186 _(dump_stats_table, "usage: dump_stats_table")                  \
21187 _(dump_macro_table, "usage: dump_macro_table ")                 \
21188 _(dump_node_table, "usage: dump_node_table")                    \
21189 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21190 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21191 _(echo, "usage: echo <message>")                                \
21192 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21193 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21194 _(help, "usage: help")                                          \
21195 _(q, "usage: quit")                                             \
21196 _(quit, "usage: quit")                                          \
21197 _(search_node_table, "usage: search_node_table <name>...")      \
21198 _(set, "usage: set <variable-name> <value>")                    \
21199 _(script, "usage: script <file-name>")                          \
21200 _(unset, "usage: unset <variable-name>")
21201 #define _(N,n)                                  \
21202     static void vl_api_##n##_t_handler_uni      \
21203     (vl_api_##n##_t * mp)                       \
21204     {                                           \
21205         vat_main_t * vam = &vat_main;           \
21206         if (vam->json_output) {                 \
21207             vl_api_##n##_t_handler_json(mp);    \
21208         } else {                                \
21209             vl_api_##n##_t_handler(mp);         \
21210         }                                       \
21211     }
21212 foreach_vpe_api_reply_msg;
21213 #if VPP_API_TEST_BUILTIN == 0
21214 foreach_standalone_reply_msg;
21215 #endif
21216 #undef _
21217
21218 void
21219 vat_api_hookup (vat_main_t * vam)
21220 {
21221 #define _(N,n)                                                  \
21222     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21223                            vl_api_##n##_t_handler_uni,          \
21224                            vl_noop_handler,                     \
21225                            vl_api_##n##_t_endian,               \
21226                            vl_api_##n##_t_print,                \
21227                            sizeof(vl_api_##n##_t), 1);
21228   foreach_vpe_api_reply_msg;
21229 #if VPP_API_TEST_BUILTIN == 0
21230   foreach_standalone_reply_msg;
21231 #endif
21232 #undef _
21233
21234 #if (VPP_API_TEST_BUILTIN==0)
21235   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21236
21237   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21238
21239   vam->function_by_name = hash_create_string (0, sizeof (uword));
21240
21241   vam->help_by_name = hash_create_string (0, sizeof (uword));
21242 #endif
21243
21244   /* API messages we can send */
21245 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21246   foreach_vpe_api_msg;
21247 #undef _
21248
21249   /* Help strings */
21250 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21251   foreach_vpe_api_msg;
21252 #undef _
21253
21254   /* CLI functions */
21255 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21256   foreach_cli_function;
21257 #undef _
21258
21259   /* Help strings */
21260 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21261   foreach_cli_function;
21262 #undef _
21263 }
21264
21265 #if VPP_API_TEST_BUILTIN
21266 static clib_error_t *
21267 vat_api_hookup_shim (vlib_main_t * vm)
21268 {
21269   vat_api_hookup (&vat_main);
21270   return 0;
21271 }
21272
21273 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21274 #endif
21275
21276 /*
21277  * fd.io coding-style-patch-verification: ON
21278  *
21279  * Local Variables:
21280  * eval: (c-set-style "gnu")
21281  * End:
21282  */