Repair vlib API socket server
[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   uword 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_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5236 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5237 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5238 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5239 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5240 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5241 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5242 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5243 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5244 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5245 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5246 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5247 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5248 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5249 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5250 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5251 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5252 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5253 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5254 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5255 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5256 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5257 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5258 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5259 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5260 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5261 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5262 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5263 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5264 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5265 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5266 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5267 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5268 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5269 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5270 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5271 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5272 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5273 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5274 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5275 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5276   one_map_register_enable_disable_reply)                                \
5277 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5278 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5279 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5280 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5281   one_map_register_fallback_threshold_reply)                            \
5282 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5283   one_rloc_probe_enable_disable_reply)                                  \
5284 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5285 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5286 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5287 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5288 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5289 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5290 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5291 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5292 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5293 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5294 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5295 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5296 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5297 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5298 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5299 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5300   show_one_stats_enable_disable_reply)                                  \
5301 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5302 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5303 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5304 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5305 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5306 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5307 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5308 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5309 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5310 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5311 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5312 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5313 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5314 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5315 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5316   gpe_add_del_native_fwd_rpath_reply)                                   \
5317 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5318   gpe_fwd_entry_path_details)                                           \
5319 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5320 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5321   one_add_del_map_request_itr_rlocs_reply)                              \
5322 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5323   one_get_map_request_itr_rlocs_reply)                                  \
5324 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5325 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5326 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5327 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5328 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5329 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5330   show_one_map_register_state_reply)                                    \
5331 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5332 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5333   show_one_map_register_fallback_threshold_reply)                       \
5334 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5335 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5336 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5337 _(POLICER_DETAILS, policer_details)                                     \
5338 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5339 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5340 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5341 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5342 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5343 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5344 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5345 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5346 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5347 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5348 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5349 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5350 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5351 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5352 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5353 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5354 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5355 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5356 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5357 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5358 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5359 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5360 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5361 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5362 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5363  ip_source_and_port_range_check_add_del_reply)                          \
5364 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5365  ip_source_and_port_range_check_interface_add_del_reply)                \
5366 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5367 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5368 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5369 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5370 _(PUNT_REPLY, punt_reply)                                               \
5371 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5372 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5373 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5374 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5375 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5376 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5377 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5378 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5379 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5380 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5381 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5382 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5383 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply)
5384
5385 #define foreach_standalone_reply_msg                                    \
5386 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5387 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5388 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5389 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5390 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5391 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5392 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5393 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)
5394
5395 typedef struct
5396 {
5397   u8 *name;
5398   u32 value;
5399 } name_sort_t;
5400
5401
5402 #define STR_VTR_OP_CASE(op)     \
5403     case L2_VTR_ ## op:         \
5404         return "" # op;
5405
5406 static const char *
5407 str_vtr_op (u32 vtr_op)
5408 {
5409   switch (vtr_op)
5410     {
5411       STR_VTR_OP_CASE (DISABLED);
5412       STR_VTR_OP_CASE (PUSH_1);
5413       STR_VTR_OP_CASE (PUSH_2);
5414       STR_VTR_OP_CASE (POP_1);
5415       STR_VTR_OP_CASE (POP_2);
5416       STR_VTR_OP_CASE (TRANSLATE_1_1);
5417       STR_VTR_OP_CASE (TRANSLATE_1_2);
5418       STR_VTR_OP_CASE (TRANSLATE_2_1);
5419       STR_VTR_OP_CASE (TRANSLATE_2_2);
5420     }
5421
5422   return "UNKNOWN";
5423 }
5424
5425 static int
5426 dump_sub_interface_table (vat_main_t * vam)
5427 {
5428   const sw_interface_subif_t *sub = NULL;
5429
5430   if (vam->json_output)
5431     {
5432       clib_warning
5433         ("JSON output supported only for VPE API calls and dump_stats_table");
5434       return -99;
5435     }
5436
5437   print (vam->ofp,
5438          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5439          "Interface", "sw_if_index",
5440          "sub id", "dot1ad", "tags", "outer id",
5441          "inner id", "exact", "default", "outer any", "inner any");
5442
5443   vec_foreach (sub, vam->sw_if_subif_table)
5444   {
5445     print (vam->ofp,
5446            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5447            sub->interface_name,
5448            sub->sw_if_index,
5449            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5450            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5451            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5452            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5453     if (sub->vtr_op != L2_VTR_DISABLED)
5454       {
5455         print (vam->ofp,
5456                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5457                "tag1: %d tag2: %d ]",
5458                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5459                sub->vtr_tag1, sub->vtr_tag2);
5460       }
5461   }
5462
5463   return 0;
5464 }
5465
5466 static int
5467 name_sort_cmp (void *a1, void *a2)
5468 {
5469   name_sort_t *n1 = a1;
5470   name_sort_t *n2 = a2;
5471
5472   return strcmp ((char *) n1->name, (char *) n2->name);
5473 }
5474
5475 static int
5476 dump_interface_table (vat_main_t * vam)
5477 {
5478   hash_pair_t *p;
5479   name_sort_t *nses = 0, *ns;
5480
5481   if (vam->json_output)
5482     {
5483       clib_warning
5484         ("JSON output supported only for VPE API calls and dump_stats_table");
5485       return -99;
5486     }
5487
5488   /* *INDENT-OFF* */
5489   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5490   ({
5491     vec_add2 (nses, ns, 1);
5492     ns->name = (u8 *)(p->key);
5493     ns->value = (u32) p->value[0];
5494   }));
5495   /* *INDENT-ON* */
5496
5497   vec_sort_with_function (nses, name_sort_cmp);
5498
5499   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5500   vec_foreach (ns, nses)
5501   {
5502     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5503   }
5504   vec_free (nses);
5505   return 0;
5506 }
5507
5508 static int
5509 dump_ip_table (vat_main_t * vam, int is_ipv6)
5510 {
5511   const ip_details_t *det = NULL;
5512   const ip_address_details_t *address = NULL;
5513   u32 i = ~0;
5514
5515   print (vam->ofp, "%-12s", "sw_if_index");
5516
5517   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5518   {
5519     i++;
5520     if (!det->present)
5521       {
5522         continue;
5523       }
5524     print (vam->ofp, "%-12d", i);
5525     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5526     if (!det->addr)
5527       {
5528         continue;
5529       }
5530     vec_foreach (address, det->addr)
5531     {
5532       print (vam->ofp,
5533              "            %-30U%-13d",
5534              is_ipv6 ? format_ip6_address : format_ip4_address,
5535              address->ip, address->prefix_length);
5536     }
5537   }
5538
5539   return 0;
5540 }
5541
5542 static int
5543 dump_ipv4_table (vat_main_t * vam)
5544 {
5545   if (vam->json_output)
5546     {
5547       clib_warning
5548         ("JSON output supported only for VPE API calls and dump_stats_table");
5549       return -99;
5550     }
5551
5552   return dump_ip_table (vam, 0);
5553 }
5554
5555 static int
5556 dump_ipv6_table (vat_main_t * vam)
5557 {
5558   if (vam->json_output)
5559     {
5560       clib_warning
5561         ("JSON output supported only for VPE API calls and dump_stats_table");
5562       return -99;
5563     }
5564
5565   return dump_ip_table (vam, 1);
5566 }
5567
5568 static char *
5569 counter_type_to_str (u8 counter_type, u8 is_combined)
5570 {
5571   if (!is_combined)
5572     {
5573       switch (counter_type)
5574         {
5575         case VNET_INTERFACE_COUNTER_DROP:
5576           return "drop";
5577         case VNET_INTERFACE_COUNTER_PUNT:
5578           return "punt";
5579         case VNET_INTERFACE_COUNTER_IP4:
5580           return "ip4";
5581         case VNET_INTERFACE_COUNTER_IP6:
5582           return "ip6";
5583         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5584           return "rx-no-buf";
5585         case VNET_INTERFACE_COUNTER_RX_MISS:
5586           return "rx-miss";
5587         case VNET_INTERFACE_COUNTER_RX_ERROR:
5588           return "rx-error";
5589         case VNET_INTERFACE_COUNTER_TX_ERROR:
5590           return "tx-error";
5591         default:
5592           return "INVALID-COUNTER-TYPE";
5593         }
5594     }
5595   else
5596     {
5597       switch (counter_type)
5598         {
5599         case VNET_INTERFACE_COUNTER_RX:
5600           return "rx";
5601         case VNET_INTERFACE_COUNTER_TX:
5602           return "tx";
5603         default:
5604           return "INVALID-COUNTER-TYPE";
5605         }
5606     }
5607 }
5608
5609 static int
5610 dump_stats_table (vat_main_t * vam)
5611 {
5612   vat_json_node_t node;
5613   vat_json_node_t *msg_array;
5614   vat_json_node_t *msg;
5615   vat_json_node_t *counter_array;
5616   vat_json_node_t *counter;
5617   interface_counter_t c;
5618   u64 packets;
5619   ip4_fib_counter_t *c4;
5620   ip6_fib_counter_t *c6;
5621   ip4_nbr_counter_t *n4;
5622   ip6_nbr_counter_t *n6;
5623   int i, j;
5624
5625   if (!vam->json_output)
5626     {
5627       clib_warning ("dump_stats_table supported only in JSON format");
5628       return -99;
5629     }
5630
5631   vat_json_init_object (&node);
5632
5633   /* interface counters */
5634   msg_array = vat_json_object_add (&node, "interface_counters");
5635   vat_json_init_array (msg_array);
5636   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5637     {
5638       msg = vat_json_array_add (msg_array);
5639       vat_json_init_object (msg);
5640       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5641                                        (u8 *) counter_type_to_str (i, 0));
5642       vat_json_object_add_int (msg, "is_combined", 0);
5643       counter_array = vat_json_object_add (msg, "data");
5644       vat_json_init_array (counter_array);
5645       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5646         {
5647           packets = vam->simple_interface_counters[i][j];
5648           vat_json_array_add_uint (counter_array, packets);
5649         }
5650     }
5651   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5652     {
5653       msg = vat_json_array_add (msg_array);
5654       vat_json_init_object (msg);
5655       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5656                                        (u8 *) counter_type_to_str (i, 1));
5657       vat_json_object_add_int (msg, "is_combined", 1);
5658       counter_array = vat_json_object_add (msg, "data");
5659       vat_json_init_array (counter_array);
5660       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5661         {
5662           c = vam->combined_interface_counters[i][j];
5663           counter = vat_json_array_add (counter_array);
5664           vat_json_init_object (counter);
5665           vat_json_object_add_uint (counter, "packets", c.packets);
5666           vat_json_object_add_uint (counter, "bytes", c.bytes);
5667         }
5668     }
5669
5670   /* ip4 fib counters */
5671   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5672   vat_json_init_array (msg_array);
5673   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5674     {
5675       msg = vat_json_array_add (msg_array);
5676       vat_json_init_object (msg);
5677       vat_json_object_add_uint (msg, "vrf_id",
5678                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5679       counter_array = vat_json_object_add (msg, "c");
5680       vat_json_init_array (counter_array);
5681       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5682         {
5683           counter = vat_json_array_add (counter_array);
5684           vat_json_init_object (counter);
5685           c4 = &vam->ip4_fib_counters[i][j];
5686           vat_json_object_add_ip4 (counter, "address", c4->address);
5687           vat_json_object_add_uint (counter, "address_length",
5688                                     c4->address_length);
5689           vat_json_object_add_uint (counter, "packets", c4->packets);
5690           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5691         }
5692     }
5693
5694   /* ip6 fib counters */
5695   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5696   vat_json_init_array (msg_array);
5697   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5698     {
5699       msg = vat_json_array_add (msg_array);
5700       vat_json_init_object (msg);
5701       vat_json_object_add_uint (msg, "vrf_id",
5702                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5703       counter_array = vat_json_object_add (msg, "c");
5704       vat_json_init_array (counter_array);
5705       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5706         {
5707           counter = vat_json_array_add (counter_array);
5708           vat_json_init_object (counter);
5709           c6 = &vam->ip6_fib_counters[i][j];
5710           vat_json_object_add_ip6 (counter, "address", c6->address);
5711           vat_json_object_add_uint (counter, "address_length",
5712                                     c6->address_length);
5713           vat_json_object_add_uint (counter, "packets", c6->packets);
5714           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5715         }
5716     }
5717
5718   /* ip4 nbr counters */
5719   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5720   vat_json_init_array (msg_array);
5721   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5722     {
5723       msg = vat_json_array_add (msg_array);
5724       vat_json_init_object (msg);
5725       vat_json_object_add_uint (msg, "sw_if_index", i);
5726       counter_array = vat_json_object_add (msg, "c");
5727       vat_json_init_array (counter_array);
5728       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5729         {
5730           counter = vat_json_array_add (counter_array);
5731           vat_json_init_object (counter);
5732           n4 = &vam->ip4_nbr_counters[i][j];
5733           vat_json_object_add_ip4 (counter, "address", n4->address);
5734           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5735           vat_json_object_add_uint (counter, "packets", n4->packets);
5736           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5737         }
5738     }
5739
5740   /* ip6 nbr counters */
5741   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5742   vat_json_init_array (msg_array);
5743   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5744     {
5745       msg = vat_json_array_add (msg_array);
5746       vat_json_init_object (msg);
5747       vat_json_object_add_uint (msg, "sw_if_index", i);
5748       counter_array = vat_json_object_add (msg, "c");
5749       vat_json_init_array (counter_array);
5750       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5751         {
5752           counter = vat_json_array_add (counter_array);
5753           vat_json_init_object (counter);
5754           n6 = &vam->ip6_nbr_counters[i][j];
5755           vat_json_object_add_ip6 (counter, "address", n6->address);
5756           vat_json_object_add_uint (counter, "packets", n6->packets);
5757           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5758         }
5759     }
5760
5761   vat_json_print (vam->ofp, &node);
5762   vat_json_free (&node);
5763
5764   return 0;
5765 }
5766
5767 /*
5768  * Pass CLI buffers directly in the CLI_INBAND API message,
5769  * instead of an additional shared memory area.
5770  */
5771 static int
5772 exec_inband (vat_main_t * vam)
5773 {
5774   vl_api_cli_inband_t *mp;
5775   unformat_input_t *i = vam->input;
5776   int ret;
5777
5778   if (vec_len (i->buffer) == 0)
5779     return -1;
5780
5781   if (vam->exec_mode == 0 && unformat (i, "mode"))
5782     {
5783       vam->exec_mode = 1;
5784       return 0;
5785     }
5786   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5787     {
5788       vam->exec_mode = 0;
5789       return 0;
5790     }
5791
5792   /*
5793    * In order for the CLI command to work, it
5794    * must be a vector ending in \n, not a C-string ending
5795    * in \n\0.
5796    */
5797   u32 len = vec_len (vam->input->buffer);
5798   M2 (CLI_INBAND, mp, len);
5799   clib_memcpy (mp->cmd, vam->input->buffer, len);
5800   mp->length = htonl (len);
5801
5802   S (mp);
5803   W (ret);
5804   /* json responses may or may not include a useful reply... */
5805   if (vec_len (vam->cmd_reply))
5806     print (vam->ofp, (char *) (vam->cmd_reply));
5807   return ret;
5808 }
5809
5810 int
5811 exec (vat_main_t * vam)
5812 {
5813   return exec_inband (vam);
5814 }
5815
5816 static int
5817 api_create_loopback (vat_main_t * vam)
5818 {
5819   unformat_input_t *i = vam->input;
5820   vl_api_create_loopback_t *mp;
5821   vl_api_create_loopback_instance_t *mp_lbi;
5822   u8 mac_address[6];
5823   u8 mac_set = 0;
5824   u8 is_specified = 0;
5825   u32 user_instance = 0;
5826   int ret;
5827
5828   memset (mac_address, 0, sizeof (mac_address));
5829
5830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5831     {
5832       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5833         mac_set = 1;
5834       if (unformat (i, "instance %d", &user_instance))
5835         is_specified = 1;
5836       else
5837         break;
5838     }
5839
5840   if (is_specified)
5841     {
5842       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5843       mp_lbi->is_specified = is_specified;
5844       if (is_specified)
5845         mp_lbi->user_instance = htonl (user_instance);
5846       if (mac_set)
5847         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5848       S (mp_lbi);
5849     }
5850   else
5851     {
5852       /* Construct the API message */
5853       M (CREATE_LOOPBACK, mp);
5854       if (mac_set)
5855         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5856       S (mp);
5857     }
5858
5859   W (ret);
5860   return ret;
5861 }
5862
5863 static int
5864 api_delete_loopback (vat_main_t * vam)
5865 {
5866   unformat_input_t *i = vam->input;
5867   vl_api_delete_loopback_t *mp;
5868   u32 sw_if_index = ~0;
5869   int ret;
5870
5871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5872     {
5873       if (unformat (i, "sw_if_index %d", &sw_if_index))
5874         ;
5875       else
5876         break;
5877     }
5878
5879   if (sw_if_index == ~0)
5880     {
5881       errmsg ("missing sw_if_index");
5882       return -99;
5883     }
5884
5885   /* Construct the API message */
5886   M (DELETE_LOOPBACK, mp);
5887   mp->sw_if_index = ntohl (sw_if_index);
5888
5889   S (mp);
5890   W (ret);
5891   return ret;
5892 }
5893
5894 static int
5895 api_want_stats (vat_main_t * vam)
5896 {
5897   unformat_input_t *i = vam->input;
5898   vl_api_want_stats_t *mp;
5899   int enable = -1;
5900   int ret;
5901
5902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5903     {
5904       if (unformat (i, "enable"))
5905         enable = 1;
5906       else if (unformat (i, "disable"))
5907         enable = 0;
5908       else
5909         break;
5910     }
5911
5912   if (enable == -1)
5913     {
5914       errmsg ("missing enable|disable");
5915       return -99;
5916     }
5917
5918   M (WANT_STATS, mp);
5919   mp->enable_disable = enable;
5920
5921   S (mp);
5922   W (ret);
5923   return ret;
5924 }
5925
5926 static int
5927 api_want_interface_events (vat_main_t * vam)
5928 {
5929   unformat_input_t *i = vam->input;
5930   vl_api_want_interface_events_t *mp;
5931   int enable = -1;
5932   int ret;
5933
5934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5935     {
5936       if (unformat (i, "enable"))
5937         enable = 1;
5938       else if (unformat (i, "disable"))
5939         enable = 0;
5940       else
5941         break;
5942     }
5943
5944   if (enable == -1)
5945     {
5946       errmsg ("missing enable|disable");
5947       return -99;
5948     }
5949
5950   M (WANT_INTERFACE_EVENTS, mp);
5951   mp->enable_disable = enable;
5952
5953   vam->interface_event_display = enable;
5954
5955   S (mp);
5956   W (ret);
5957   return ret;
5958 }
5959
5960
5961 /* Note: non-static, called once to set up the initial intfc table */
5962 int
5963 api_sw_interface_dump (vat_main_t * vam)
5964 {
5965   vl_api_sw_interface_dump_t *mp;
5966   vl_api_control_ping_t *mp_ping;
5967   hash_pair_t *p;
5968   name_sort_t *nses = 0, *ns;
5969   sw_interface_subif_t *sub = NULL;
5970   int ret;
5971
5972   /* Toss the old name table */
5973   /* *INDENT-OFF* */
5974   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5975   ({
5976     vec_add2 (nses, ns, 1);
5977     ns->name = (u8 *)(p->key);
5978     ns->value = (u32) p->value[0];
5979   }));
5980   /* *INDENT-ON* */
5981
5982   hash_free (vam->sw_if_index_by_interface_name);
5983
5984   vec_foreach (ns, nses) vec_free (ns->name);
5985
5986   vec_free (nses);
5987
5988   vec_foreach (sub, vam->sw_if_subif_table)
5989   {
5990     vec_free (sub->interface_name);
5991   }
5992   vec_free (vam->sw_if_subif_table);
5993
5994   /* recreate the interface name hash table */
5995   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5996
5997   /* Get list of ethernets */
5998   M (SW_INTERFACE_DUMP, mp);
5999   mp->name_filter_valid = 1;
6000   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6001   S (mp);
6002
6003   /* and local / loopback interfaces */
6004   M (SW_INTERFACE_DUMP, mp);
6005   mp->name_filter_valid = 1;
6006   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6007   S (mp);
6008
6009   /* and packet-generator interfaces */
6010   M (SW_INTERFACE_DUMP, mp);
6011   mp->name_filter_valid = 1;
6012   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6013   S (mp);
6014
6015   /* and vxlan-gpe tunnel interfaces */
6016   M (SW_INTERFACE_DUMP, mp);
6017   mp->name_filter_valid = 1;
6018   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6019            sizeof (mp->name_filter) - 1);
6020   S (mp);
6021
6022   /* and vxlan tunnel interfaces */
6023   M (SW_INTERFACE_DUMP, mp);
6024   mp->name_filter_valid = 1;
6025   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6026   S (mp);
6027
6028   /* and host (af_packet) interfaces */
6029   M (SW_INTERFACE_DUMP, mp);
6030   mp->name_filter_valid = 1;
6031   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6032   S (mp);
6033
6034   /* and l2tpv3 tunnel interfaces */
6035   M (SW_INTERFACE_DUMP, mp);
6036   mp->name_filter_valid = 1;
6037   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6038            sizeof (mp->name_filter) - 1);
6039   S (mp);
6040
6041   /* and GRE tunnel interfaces */
6042   M (SW_INTERFACE_DUMP, mp);
6043   mp->name_filter_valid = 1;
6044   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6045   S (mp);
6046
6047   /* and LISP-GPE interfaces */
6048   M (SW_INTERFACE_DUMP, mp);
6049   mp->name_filter_valid = 1;
6050   strncpy ((char *) mp->name_filter, "lisp_gpe",
6051            sizeof (mp->name_filter) - 1);
6052   S (mp);
6053
6054   /* and IPSEC tunnel interfaces */
6055   M (SW_INTERFACE_DUMP, mp);
6056   mp->name_filter_valid = 1;
6057   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6058   S (mp);
6059
6060   /* Use a control ping for synchronization */
6061   MPING (CONTROL_PING, mp_ping);
6062   S (mp_ping);
6063
6064   W (ret);
6065   return ret;
6066 }
6067
6068 static int
6069 api_sw_interface_set_flags (vat_main_t * vam)
6070 {
6071   unformat_input_t *i = vam->input;
6072   vl_api_sw_interface_set_flags_t *mp;
6073   u32 sw_if_index;
6074   u8 sw_if_index_set = 0;
6075   u8 admin_up = 0;
6076   int ret;
6077
6078   /* Parse args required to build the message */
6079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6080     {
6081       if (unformat (i, "admin-up"))
6082         admin_up = 1;
6083       else if (unformat (i, "admin-down"))
6084         admin_up = 0;
6085       else
6086         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6087         sw_if_index_set = 1;
6088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6089         sw_if_index_set = 1;
6090       else
6091         break;
6092     }
6093
6094   if (sw_if_index_set == 0)
6095     {
6096       errmsg ("missing interface name or sw_if_index");
6097       return -99;
6098     }
6099
6100   /* Construct the API message */
6101   M (SW_INTERFACE_SET_FLAGS, mp);
6102   mp->sw_if_index = ntohl (sw_if_index);
6103   mp->admin_up_down = admin_up;
6104
6105   /* send it... */
6106   S (mp);
6107
6108   /* Wait for a reply, return the good/bad news... */
6109   W (ret);
6110   return ret;
6111 }
6112
6113 static int
6114 api_sw_interface_clear_stats (vat_main_t * vam)
6115 {
6116   unformat_input_t *i = vam->input;
6117   vl_api_sw_interface_clear_stats_t *mp;
6118   u32 sw_if_index;
6119   u8 sw_if_index_set = 0;
6120   int ret;
6121
6122   /* Parse args required to build the message */
6123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6124     {
6125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6126         sw_if_index_set = 1;
6127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6128         sw_if_index_set = 1;
6129       else
6130         break;
6131     }
6132
6133   /* Construct the API message */
6134   M (SW_INTERFACE_CLEAR_STATS, mp);
6135
6136   if (sw_if_index_set == 1)
6137     mp->sw_if_index = ntohl (sw_if_index);
6138   else
6139     mp->sw_if_index = ~0;
6140
6141   /* send it... */
6142   S (mp);
6143
6144   /* Wait for a reply, return the good/bad news... */
6145   W (ret);
6146   return ret;
6147 }
6148
6149 static int
6150 api_sw_interface_add_del_address (vat_main_t * vam)
6151 {
6152   unformat_input_t *i = vam->input;
6153   vl_api_sw_interface_add_del_address_t *mp;
6154   u32 sw_if_index;
6155   u8 sw_if_index_set = 0;
6156   u8 is_add = 1, del_all = 0;
6157   u32 address_length = 0;
6158   u8 v4_address_set = 0;
6159   u8 v6_address_set = 0;
6160   ip4_address_t v4address;
6161   ip6_address_t v6address;
6162   int ret;
6163
6164   /* Parse args required to build the message */
6165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6166     {
6167       if (unformat (i, "del-all"))
6168         del_all = 1;
6169       else if (unformat (i, "del"))
6170         is_add = 0;
6171       else
6172         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6173         sw_if_index_set = 1;
6174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6175         sw_if_index_set = 1;
6176       else if (unformat (i, "%U/%d",
6177                          unformat_ip4_address, &v4address, &address_length))
6178         v4_address_set = 1;
6179       else if (unformat (i, "%U/%d",
6180                          unformat_ip6_address, &v6address, &address_length))
6181         v6_address_set = 1;
6182       else
6183         break;
6184     }
6185
6186   if (sw_if_index_set == 0)
6187     {
6188       errmsg ("missing interface name or sw_if_index");
6189       return -99;
6190     }
6191   if (v4_address_set && v6_address_set)
6192     {
6193       errmsg ("both v4 and v6 addresses set");
6194       return -99;
6195     }
6196   if (!v4_address_set && !v6_address_set && !del_all)
6197     {
6198       errmsg ("no addresses set");
6199       return -99;
6200     }
6201
6202   /* Construct the API message */
6203   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6204
6205   mp->sw_if_index = ntohl (sw_if_index);
6206   mp->is_add = is_add;
6207   mp->del_all = del_all;
6208   if (v6_address_set)
6209     {
6210       mp->is_ipv6 = 1;
6211       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6212     }
6213   else
6214     {
6215       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6216     }
6217   mp->address_length = address_length;
6218
6219   /* send it... */
6220   S (mp);
6221
6222   /* Wait for a reply, return good/bad news  */
6223   W (ret);
6224   return ret;
6225 }
6226
6227 static int
6228 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6229 {
6230   unformat_input_t *i = vam->input;
6231   vl_api_sw_interface_set_mpls_enable_t *mp;
6232   u32 sw_if_index;
6233   u8 sw_if_index_set = 0;
6234   u8 enable = 1;
6235   int ret;
6236
6237   /* Parse args required to build the message */
6238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6239     {
6240       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6241         sw_if_index_set = 1;
6242       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6243         sw_if_index_set = 1;
6244       else if (unformat (i, "disable"))
6245         enable = 0;
6246       else if (unformat (i, "dis"))
6247         enable = 0;
6248       else
6249         break;
6250     }
6251
6252   if (sw_if_index_set == 0)
6253     {
6254       errmsg ("missing interface name or sw_if_index");
6255       return -99;
6256     }
6257
6258   /* Construct the API message */
6259   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6260
6261   mp->sw_if_index = ntohl (sw_if_index);
6262   mp->enable = enable;
6263
6264   /* send it... */
6265   S (mp);
6266
6267   /* Wait for a reply... */
6268   W (ret);
6269   return ret;
6270 }
6271
6272 static int
6273 api_sw_interface_set_table (vat_main_t * vam)
6274 {
6275   unformat_input_t *i = vam->input;
6276   vl_api_sw_interface_set_table_t *mp;
6277   u32 sw_if_index, vrf_id = 0;
6278   u8 sw_if_index_set = 0;
6279   u8 is_ipv6 = 0;
6280   int ret;
6281
6282   /* Parse args required to build the message */
6283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6284     {
6285       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6286         sw_if_index_set = 1;
6287       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6288         sw_if_index_set = 1;
6289       else if (unformat (i, "vrf %d", &vrf_id))
6290         ;
6291       else if (unformat (i, "ipv6"))
6292         is_ipv6 = 1;
6293       else
6294         break;
6295     }
6296
6297   if (sw_if_index_set == 0)
6298     {
6299       errmsg ("missing interface name or sw_if_index");
6300       return -99;
6301     }
6302
6303   /* Construct the API message */
6304   M (SW_INTERFACE_SET_TABLE, mp);
6305
6306   mp->sw_if_index = ntohl (sw_if_index);
6307   mp->is_ipv6 = is_ipv6;
6308   mp->vrf_id = ntohl (vrf_id);
6309
6310   /* send it... */
6311   S (mp);
6312
6313   /* Wait for a reply... */
6314   W (ret);
6315   return ret;
6316 }
6317
6318 static void vl_api_sw_interface_get_table_reply_t_handler
6319   (vl_api_sw_interface_get_table_reply_t * mp)
6320 {
6321   vat_main_t *vam = &vat_main;
6322
6323   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6324
6325   vam->retval = ntohl (mp->retval);
6326   vam->result_ready = 1;
6327
6328 }
6329
6330 static void vl_api_sw_interface_get_table_reply_t_handler_json
6331   (vl_api_sw_interface_get_table_reply_t * mp)
6332 {
6333   vat_main_t *vam = &vat_main;
6334   vat_json_node_t node;
6335
6336   vat_json_init_object (&node);
6337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6338   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6339
6340   vat_json_print (vam->ofp, &node);
6341   vat_json_free (&node);
6342
6343   vam->retval = ntohl (mp->retval);
6344   vam->result_ready = 1;
6345 }
6346
6347 static int
6348 api_sw_interface_get_table (vat_main_t * vam)
6349 {
6350   unformat_input_t *i = vam->input;
6351   vl_api_sw_interface_get_table_t *mp;
6352   u32 sw_if_index;
6353   u8 sw_if_index_set = 0;
6354   u8 is_ipv6 = 0;
6355   int ret;
6356
6357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6358     {
6359       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6360         sw_if_index_set = 1;
6361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6362         sw_if_index_set = 1;
6363       else if (unformat (i, "ipv6"))
6364         is_ipv6 = 1;
6365       else
6366         break;
6367     }
6368
6369   if (sw_if_index_set == 0)
6370     {
6371       errmsg ("missing interface name or sw_if_index");
6372       return -99;
6373     }
6374
6375   M (SW_INTERFACE_GET_TABLE, mp);
6376   mp->sw_if_index = htonl (sw_if_index);
6377   mp->is_ipv6 = is_ipv6;
6378
6379   S (mp);
6380   W (ret);
6381   return ret;
6382 }
6383
6384 static int
6385 api_sw_interface_set_vpath (vat_main_t * vam)
6386 {
6387   unformat_input_t *i = vam->input;
6388   vl_api_sw_interface_set_vpath_t *mp;
6389   u32 sw_if_index = 0;
6390   u8 sw_if_index_set = 0;
6391   u8 is_enable = 0;
6392   int ret;
6393
6394   /* Parse args required to build the message */
6395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6396     {
6397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6398         sw_if_index_set = 1;
6399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6400         sw_if_index_set = 1;
6401       else if (unformat (i, "enable"))
6402         is_enable = 1;
6403       else if (unformat (i, "disable"))
6404         is_enable = 0;
6405       else
6406         break;
6407     }
6408
6409   if (sw_if_index_set == 0)
6410     {
6411       errmsg ("missing interface name or sw_if_index");
6412       return -99;
6413     }
6414
6415   /* Construct the API message */
6416   M (SW_INTERFACE_SET_VPATH, mp);
6417
6418   mp->sw_if_index = ntohl (sw_if_index);
6419   mp->enable = is_enable;
6420
6421   /* send it... */
6422   S (mp);
6423
6424   /* Wait for a reply... */
6425   W (ret);
6426   return ret;
6427 }
6428
6429 static int
6430 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6431 {
6432   unformat_input_t *i = vam->input;
6433   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6434   u32 sw_if_index = 0;
6435   u8 sw_if_index_set = 0;
6436   u8 is_enable = 1;
6437   u8 is_ipv6 = 0;
6438   int ret;
6439
6440   /* Parse args required to build the message */
6441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6442     {
6443       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6444         sw_if_index_set = 1;
6445       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6446         sw_if_index_set = 1;
6447       else if (unformat (i, "enable"))
6448         is_enable = 1;
6449       else if (unformat (i, "disable"))
6450         is_enable = 0;
6451       else if (unformat (i, "ip4"))
6452         is_ipv6 = 0;
6453       else if (unformat (i, "ip6"))
6454         is_ipv6 = 1;
6455       else
6456         break;
6457     }
6458
6459   if (sw_if_index_set == 0)
6460     {
6461       errmsg ("missing interface name or sw_if_index");
6462       return -99;
6463     }
6464
6465   /* Construct the API message */
6466   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6467
6468   mp->sw_if_index = ntohl (sw_if_index);
6469   mp->enable = is_enable;
6470   mp->is_ipv6 = is_ipv6;
6471
6472   /* send it... */
6473   S (mp);
6474
6475   /* Wait for a reply... */
6476   W (ret);
6477   return ret;
6478 }
6479
6480
6481 static int
6482 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6483 {
6484   unformat_input_t *i = vam->input;
6485   vl_api_sw_interface_set_l2_xconnect_t *mp;
6486   u32 rx_sw_if_index;
6487   u8 rx_sw_if_index_set = 0;
6488   u32 tx_sw_if_index;
6489   u8 tx_sw_if_index_set = 0;
6490   u8 enable = 1;
6491   int ret;
6492
6493   /* Parse args required to build the message */
6494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6495     {
6496       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6497         rx_sw_if_index_set = 1;
6498       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6499         tx_sw_if_index_set = 1;
6500       else if (unformat (i, "rx"))
6501         {
6502           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6503             {
6504               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6505                             &rx_sw_if_index))
6506                 rx_sw_if_index_set = 1;
6507             }
6508           else
6509             break;
6510         }
6511       else if (unformat (i, "tx"))
6512         {
6513           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6514             {
6515               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6516                             &tx_sw_if_index))
6517                 tx_sw_if_index_set = 1;
6518             }
6519           else
6520             break;
6521         }
6522       else if (unformat (i, "enable"))
6523         enable = 1;
6524       else if (unformat (i, "disable"))
6525         enable = 0;
6526       else
6527         break;
6528     }
6529
6530   if (rx_sw_if_index_set == 0)
6531     {
6532       errmsg ("missing rx interface name or rx_sw_if_index");
6533       return -99;
6534     }
6535
6536   if (enable && (tx_sw_if_index_set == 0))
6537     {
6538       errmsg ("missing tx interface name or tx_sw_if_index");
6539       return -99;
6540     }
6541
6542   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6543
6544   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6545   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6546   mp->enable = enable;
6547
6548   S (mp);
6549   W (ret);
6550   return ret;
6551 }
6552
6553 static int
6554 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6555 {
6556   unformat_input_t *i = vam->input;
6557   vl_api_sw_interface_set_l2_bridge_t *mp;
6558   u32 rx_sw_if_index;
6559   u8 rx_sw_if_index_set = 0;
6560   u32 bd_id;
6561   u8 bd_id_set = 0;
6562   u8 bvi = 0;
6563   u32 shg = 0;
6564   u8 enable = 1;
6565   int ret;
6566
6567   /* Parse args required to build the message */
6568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6569     {
6570       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6571         rx_sw_if_index_set = 1;
6572       else if (unformat (i, "bd_id %d", &bd_id))
6573         bd_id_set = 1;
6574       else
6575         if (unformat
6576             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6577         rx_sw_if_index_set = 1;
6578       else if (unformat (i, "shg %d", &shg))
6579         ;
6580       else if (unformat (i, "bvi"))
6581         bvi = 1;
6582       else if (unformat (i, "enable"))
6583         enable = 1;
6584       else if (unformat (i, "disable"))
6585         enable = 0;
6586       else
6587         break;
6588     }
6589
6590   if (rx_sw_if_index_set == 0)
6591     {
6592       errmsg ("missing rx interface name or sw_if_index");
6593       return -99;
6594     }
6595
6596   if (enable && (bd_id_set == 0))
6597     {
6598       errmsg ("missing bridge domain");
6599       return -99;
6600     }
6601
6602   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6603
6604   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6605   mp->bd_id = ntohl (bd_id);
6606   mp->shg = (u8) shg;
6607   mp->bvi = bvi;
6608   mp->enable = enable;
6609
6610   S (mp);
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_bridge_domain_dump (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_bridge_domain_dump_t *mp;
6620   vl_api_control_ping_t *mp_ping;
6621   u32 bd_id = ~0;
6622   int ret;
6623
6624   /* Parse args required to build the message */
6625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6626     {
6627       if (unformat (i, "bd_id %d", &bd_id))
6628         ;
6629       else
6630         break;
6631     }
6632
6633   M (BRIDGE_DOMAIN_DUMP, mp);
6634   mp->bd_id = ntohl (bd_id);
6635   S (mp);
6636
6637   /* Use a control ping for synchronization */
6638   MPING (CONTROL_PING, mp_ping);
6639   S (mp_ping);
6640
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_bridge_domain_add_del (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_bridge_domain_add_del_t *mp;
6650   u32 bd_id = ~0;
6651   u8 is_add = 1;
6652   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6653   u8 *bd_tag = NULL;
6654   u32 mac_age = 0;
6655   int ret;
6656
6657   /* Parse args required to build the message */
6658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659     {
6660       if (unformat (i, "bd_id %d", &bd_id))
6661         ;
6662       else if (unformat (i, "flood %d", &flood))
6663         ;
6664       else if (unformat (i, "uu-flood %d", &uu_flood))
6665         ;
6666       else if (unformat (i, "forward %d", &forward))
6667         ;
6668       else if (unformat (i, "learn %d", &learn))
6669         ;
6670       else if (unformat (i, "arp-term %d", &arp_term))
6671         ;
6672       else if (unformat (i, "mac-age %d", &mac_age))
6673         ;
6674       else if (unformat (i, "bd-tag %s", &bd_tag))
6675         ;
6676       else if (unformat (i, "del"))
6677         {
6678           is_add = 0;
6679           flood = uu_flood = forward = learn = 0;
6680         }
6681       else
6682         break;
6683     }
6684
6685   if (bd_id == ~0)
6686     {
6687       errmsg ("missing bridge domain");
6688       ret = -99;
6689       goto done;
6690     }
6691
6692   if (mac_age > 255)
6693     {
6694       errmsg ("mac age must be less than 256 ");
6695       ret = -99;
6696       goto done;
6697     }
6698
6699   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6700     {
6701       errmsg ("bd-tag cannot be longer than 63");
6702       ret = -99;
6703       goto done;
6704     }
6705
6706   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6707
6708   mp->bd_id = ntohl (bd_id);
6709   mp->flood = flood;
6710   mp->uu_flood = uu_flood;
6711   mp->forward = forward;
6712   mp->learn = learn;
6713   mp->arp_term = arp_term;
6714   mp->is_add = is_add;
6715   mp->mac_age = (u8) mac_age;
6716   if (bd_tag)
6717     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6718
6719   S (mp);
6720   W (ret);
6721
6722 done:
6723   vec_free (bd_tag);
6724   return ret;
6725 }
6726
6727 static int
6728 api_l2fib_flush_bd (vat_main_t * vam)
6729 {
6730   unformat_input_t *i = vam->input;
6731   vl_api_l2fib_flush_bd_t *mp;
6732   u32 bd_id = ~0;
6733   int ret;
6734
6735   /* Parse args required to build the message */
6736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6737     {
6738       if (unformat (i, "bd_id %d", &bd_id));
6739       else
6740         break;
6741     }
6742
6743   if (bd_id == ~0)
6744     {
6745       errmsg ("missing bridge domain");
6746       return -99;
6747     }
6748
6749   M (L2FIB_FLUSH_BD, mp);
6750
6751   mp->bd_id = htonl (bd_id);
6752
6753   S (mp);
6754   W (ret);
6755   return ret;
6756 }
6757
6758 static int
6759 api_l2fib_flush_int (vat_main_t * vam)
6760 {
6761   unformat_input_t *i = vam->input;
6762   vl_api_l2fib_flush_int_t *mp;
6763   u32 sw_if_index = ~0;
6764   int ret;
6765
6766   /* Parse args required to build the message */
6767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6768     {
6769       if (unformat (i, "sw_if_index %d", &sw_if_index));
6770       else
6771         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6772       else
6773         break;
6774     }
6775
6776   if (sw_if_index == ~0)
6777     {
6778       errmsg ("missing interface name or sw_if_index");
6779       return -99;
6780     }
6781
6782   M (L2FIB_FLUSH_INT, mp);
6783
6784   mp->sw_if_index = ntohl (sw_if_index);
6785
6786   S (mp);
6787   W (ret);
6788   return ret;
6789 }
6790
6791 static int
6792 api_l2fib_add_del (vat_main_t * vam)
6793 {
6794   unformat_input_t *i = vam->input;
6795   vl_api_l2fib_add_del_t *mp;
6796   f64 timeout;
6797   u64 mac = 0;
6798   u8 mac_set = 0;
6799   u32 bd_id;
6800   u8 bd_id_set = 0;
6801   u32 sw_if_index = ~0;
6802   u8 sw_if_index_set = 0;
6803   u8 is_add = 1;
6804   u8 static_mac = 0;
6805   u8 filter_mac = 0;
6806   u8 bvi_mac = 0;
6807   int count = 1;
6808   f64 before = 0;
6809   int j;
6810
6811   /* Parse args required to build the message */
6812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6813     {
6814       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6815         mac_set = 1;
6816       else if (unformat (i, "bd_id %d", &bd_id))
6817         bd_id_set = 1;
6818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6819         sw_if_index_set = 1;
6820       else if (unformat (i, "sw_if"))
6821         {
6822           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6823             {
6824               if (unformat
6825                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6826                 sw_if_index_set = 1;
6827             }
6828           else
6829             break;
6830         }
6831       else if (unformat (i, "static"))
6832         static_mac = 1;
6833       else if (unformat (i, "filter"))
6834         {
6835           filter_mac = 1;
6836           static_mac = 1;
6837         }
6838       else if (unformat (i, "bvi"))
6839         {
6840           bvi_mac = 1;
6841           static_mac = 1;
6842         }
6843       else if (unformat (i, "del"))
6844         is_add = 0;
6845       else if (unformat (i, "count %d", &count))
6846         ;
6847       else
6848         break;
6849     }
6850
6851   if (mac_set == 0)
6852     {
6853       errmsg ("missing mac address");
6854       return -99;
6855     }
6856
6857   if (bd_id_set == 0)
6858     {
6859       errmsg ("missing bridge domain");
6860       return -99;
6861     }
6862
6863   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6864     {
6865       errmsg ("missing interface name or sw_if_index");
6866       return -99;
6867     }
6868
6869   if (count > 1)
6870     {
6871       /* Turn on async mode */
6872       vam->async_mode = 1;
6873       vam->async_errors = 0;
6874       before = vat_time_now (vam);
6875     }
6876
6877   for (j = 0; j < count; j++)
6878     {
6879       M (L2FIB_ADD_DEL, mp);
6880
6881       mp->mac = mac;
6882       mp->bd_id = ntohl (bd_id);
6883       mp->is_add = is_add;
6884
6885       if (is_add)
6886         {
6887           mp->sw_if_index = ntohl (sw_if_index);
6888           mp->static_mac = static_mac;
6889           mp->filter_mac = filter_mac;
6890           mp->bvi_mac = bvi_mac;
6891         }
6892       increment_mac_address (&mac);
6893       /* send it... */
6894       S (mp);
6895     }
6896
6897   if (count > 1)
6898     {
6899       vl_api_control_ping_t *mp_ping;
6900       f64 after;
6901
6902       /* Shut off async mode */
6903       vam->async_mode = 0;
6904
6905       MPING (CONTROL_PING, mp_ping);
6906       S (mp_ping);
6907
6908       timeout = vat_time_now (vam) + 1.0;
6909       while (vat_time_now (vam) < timeout)
6910         if (vam->result_ready == 1)
6911           goto out;
6912       vam->retval = -99;
6913
6914     out:
6915       if (vam->retval == -99)
6916         errmsg ("timeout");
6917
6918       if (vam->async_errors > 0)
6919         {
6920           errmsg ("%d asynchronous errors", vam->async_errors);
6921           vam->retval = -98;
6922         }
6923       vam->async_errors = 0;
6924       after = vat_time_now (vam);
6925
6926       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6927              count, after - before, count / (after - before));
6928     }
6929   else
6930     {
6931       int ret;
6932
6933       /* Wait for a reply... */
6934       W (ret);
6935       return ret;
6936     }
6937   /* Return the good/bad news */
6938   return (vam->retval);
6939 }
6940
6941 static int
6942 api_bridge_domain_set_mac_age (vat_main_t * vam)
6943 {
6944   unformat_input_t *i = vam->input;
6945   vl_api_bridge_domain_set_mac_age_t *mp;
6946   u32 bd_id = ~0;
6947   u32 mac_age = 0;
6948   int ret;
6949
6950   /* Parse args required to build the message */
6951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6952     {
6953       if (unformat (i, "bd_id %d", &bd_id));
6954       else if (unformat (i, "mac-age %d", &mac_age));
6955       else
6956         break;
6957     }
6958
6959   if (bd_id == ~0)
6960     {
6961       errmsg ("missing bridge domain");
6962       return -99;
6963     }
6964
6965   if (mac_age > 255)
6966     {
6967       errmsg ("mac age must be less than 256 ");
6968       return -99;
6969     }
6970
6971   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6972
6973   mp->bd_id = htonl (bd_id);
6974   mp->mac_age = (u8) mac_age;
6975
6976   S (mp);
6977   W (ret);
6978   return ret;
6979 }
6980
6981 static int
6982 api_l2_flags (vat_main_t * vam)
6983 {
6984   unformat_input_t *i = vam->input;
6985   vl_api_l2_flags_t *mp;
6986   u32 sw_if_index;
6987   u32 flags = 0;
6988   u8 sw_if_index_set = 0;
6989   u8 is_set = 0;
6990   int ret;
6991
6992   /* Parse args required to build the message */
6993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6994     {
6995       if (unformat (i, "sw_if_index %d", &sw_if_index))
6996         sw_if_index_set = 1;
6997       else if (unformat (i, "sw_if"))
6998         {
6999           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7000             {
7001               if (unformat
7002                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7003                 sw_if_index_set = 1;
7004             }
7005           else
7006             break;
7007         }
7008       else if (unformat (i, "learn"))
7009         flags |= L2_LEARN;
7010       else if (unformat (i, "forward"))
7011         flags |= L2_FWD;
7012       else if (unformat (i, "flood"))
7013         flags |= L2_FLOOD;
7014       else if (unformat (i, "uu-flood"))
7015         flags |= L2_UU_FLOOD;
7016       else if (unformat (i, "arp-term"))
7017         flags |= L2_ARP_TERM;
7018       else if (unformat (i, "off"))
7019         is_set = 0;
7020       else if (unformat (i, "disable"))
7021         is_set = 0;
7022       else
7023         break;
7024     }
7025
7026   if (sw_if_index_set == 0)
7027     {
7028       errmsg ("missing interface name or sw_if_index");
7029       return -99;
7030     }
7031
7032   M (L2_FLAGS, mp);
7033
7034   mp->sw_if_index = ntohl (sw_if_index);
7035   mp->feature_bitmap = ntohl (flags);
7036   mp->is_set = is_set;
7037
7038   S (mp);
7039   W (ret);
7040   return ret;
7041 }
7042
7043 static int
7044 api_bridge_flags (vat_main_t * vam)
7045 {
7046   unformat_input_t *i = vam->input;
7047   vl_api_bridge_flags_t *mp;
7048   u32 bd_id;
7049   u8 bd_id_set = 0;
7050   u8 is_set = 1;
7051   u32 flags = 0;
7052   int ret;
7053
7054   /* Parse args required to build the message */
7055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7056     {
7057       if (unformat (i, "bd_id %d", &bd_id))
7058         bd_id_set = 1;
7059       else if (unformat (i, "learn"))
7060         flags |= L2_LEARN;
7061       else if (unformat (i, "forward"))
7062         flags |= L2_FWD;
7063       else if (unformat (i, "flood"))
7064         flags |= L2_FLOOD;
7065       else if (unformat (i, "uu-flood"))
7066         flags |= L2_UU_FLOOD;
7067       else if (unformat (i, "arp-term"))
7068         flags |= L2_ARP_TERM;
7069       else if (unformat (i, "off"))
7070         is_set = 0;
7071       else if (unformat (i, "disable"))
7072         is_set = 0;
7073       else
7074         break;
7075     }
7076
7077   if (bd_id_set == 0)
7078     {
7079       errmsg ("missing bridge domain");
7080       return -99;
7081     }
7082
7083   M (BRIDGE_FLAGS, mp);
7084
7085   mp->bd_id = ntohl (bd_id);
7086   mp->feature_bitmap = ntohl (flags);
7087   mp->is_set = is_set;
7088
7089   S (mp);
7090   W (ret);
7091   return ret;
7092 }
7093
7094 static int
7095 api_bd_ip_mac_add_del (vat_main_t * vam)
7096 {
7097   unformat_input_t *i = vam->input;
7098   vl_api_bd_ip_mac_add_del_t *mp;
7099   u32 bd_id;
7100   u8 is_ipv6 = 0;
7101   u8 is_add = 1;
7102   u8 bd_id_set = 0;
7103   u8 ip_set = 0;
7104   u8 mac_set = 0;
7105   ip4_address_t v4addr;
7106   ip6_address_t v6addr;
7107   u8 macaddr[6];
7108   int ret;
7109
7110
7111   /* Parse args required to build the message */
7112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7113     {
7114       if (unformat (i, "bd_id %d", &bd_id))
7115         {
7116           bd_id_set++;
7117         }
7118       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7119         {
7120           ip_set++;
7121         }
7122       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7123         {
7124           ip_set++;
7125           is_ipv6++;
7126         }
7127       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7128         {
7129           mac_set++;
7130         }
7131       else if (unformat (i, "del"))
7132         is_add = 0;
7133       else
7134         break;
7135     }
7136
7137   if (bd_id_set == 0)
7138     {
7139       errmsg ("missing bridge domain");
7140       return -99;
7141     }
7142   else if (ip_set == 0)
7143     {
7144       errmsg ("missing IP address");
7145       return -99;
7146     }
7147   else if (mac_set == 0)
7148     {
7149       errmsg ("missing MAC address");
7150       return -99;
7151     }
7152
7153   M (BD_IP_MAC_ADD_DEL, mp);
7154
7155   mp->bd_id = ntohl (bd_id);
7156   mp->is_ipv6 = is_ipv6;
7157   mp->is_add = is_add;
7158   if (is_ipv6)
7159     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7160   else
7161     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7162   clib_memcpy (mp->mac_address, macaddr, 6);
7163   S (mp);
7164   W (ret);
7165   return ret;
7166 }
7167
7168 static int
7169 api_tap_connect (vat_main_t * vam)
7170 {
7171   unformat_input_t *i = vam->input;
7172   vl_api_tap_connect_t *mp;
7173   u8 mac_address[6];
7174   u8 random_mac = 1;
7175   u8 name_set = 0;
7176   u8 *tap_name;
7177   u8 *tag = 0;
7178   ip4_address_t ip4_address;
7179   u32 ip4_mask_width;
7180   int ip4_address_set = 0;
7181   ip6_address_t ip6_address;
7182   u32 ip6_mask_width;
7183   int ip6_address_set = 0;
7184   int ret;
7185
7186   memset (mac_address, 0, sizeof (mac_address));
7187
7188   /* Parse args required to build the message */
7189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7190     {
7191       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7192         {
7193           random_mac = 0;
7194         }
7195       else if (unformat (i, "random-mac"))
7196         random_mac = 1;
7197       else if (unformat (i, "tapname %s", &tap_name))
7198         name_set = 1;
7199       else if (unformat (i, "tag %s", &tag))
7200         ;
7201       else if (unformat (i, "address %U/%d",
7202                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7203         ip4_address_set = 1;
7204       else if (unformat (i, "address %U/%d",
7205                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7206         ip6_address_set = 1;
7207       else
7208         break;
7209     }
7210
7211   if (name_set == 0)
7212     {
7213       errmsg ("missing tap name");
7214       return -99;
7215     }
7216   if (vec_len (tap_name) > 63)
7217     {
7218       errmsg ("tap name too long");
7219       return -99;
7220     }
7221   vec_add1 (tap_name, 0);
7222
7223   if (vec_len (tag) > 63)
7224     {
7225       errmsg ("tag too long");
7226       return -99;
7227     }
7228
7229   /* Construct the API message */
7230   M (TAP_CONNECT, mp);
7231
7232   mp->use_random_mac = random_mac;
7233   clib_memcpy (mp->mac_address, mac_address, 6);
7234   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7235   if (tag)
7236     clib_memcpy (mp->tag, tag, vec_len (tag));
7237
7238   if (ip4_address_set)
7239     {
7240       mp->ip4_address_set = 1;
7241       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7242       mp->ip4_mask_width = ip4_mask_width;
7243     }
7244   if (ip6_address_set)
7245     {
7246       mp->ip6_address_set = 1;
7247       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7248       mp->ip6_mask_width = ip6_mask_width;
7249     }
7250
7251   vec_free (tap_name);
7252   vec_free (tag);
7253
7254   /* send it... */
7255   S (mp);
7256
7257   /* Wait for a reply... */
7258   W (ret);
7259   return ret;
7260 }
7261
7262 static int
7263 api_tap_modify (vat_main_t * vam)
7264 {
7265   unformat_input_t *i = vam->input;
7266   vl_api_tap_modify_t *mp;
7267   u8 mac_address[6];
7268   u8 random_mac = 1;
7269   u8 name_set = 0;
7270   u8 *tap_name;
7271   u32 sw_if_index = ~0;
7272   u8 sw_if_index_set = 0;
7273   int ret;
7274
7275   memset (mac_address, 0, sizeof (mac_address));
7276
7277   /* Parse args required to build the message */
7278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7279     {
7280       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7281         sw_if_index_set = 1;
7282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7283         sw_if_index_set = 1;
7284       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7285         {
7286           random_mac = 0;
7287         }
7288       else if (unformat (i, "random-mac"))
7289         random_mac = 1;
7290       else if (unformat (i, "tapname %s", &tap_name))
7291         name_set = 1;
7292       else
7293         break;
7294     }
7295
7296   if (sw_if_index_set == 0)
7297     {
7298       errmsg ("missing vpp interface name");
7299       return -99;
7300     }
7301   if (name_set == 0)
7302     {
7303       errmsg ("missing tap name");
7304       return -99;
7305     }
7306   if (vec_len (tap_name) > 63)
7307     {
7308       errmsg ("tap name too long");
7309     }
7310   vec_add1 (tap_name, 0);
7311
7312   /* Construct the API message */
7313   M (TAP_MODIFY, mp);
7314
7315   mp->use_random_mac = random_mac;
7316   mp->sw_if_index = ntohl (sw_if_index);
7317   clib_memcpy (mp->mac_address, mac_address, 6);
7318   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7319   vec_free (tap_name);
7320
7321   /* send it... */
7322   S (mp);
7323
7324   /* Wait for a reply... */
7325   W (ret);
7326   return ret;
7327 }
7328
7329 static int
7330 api_tap_delete (vat_main_t * vam)
7331 {
7332   unformat_input_t *i = vam->input;
7333   vl_api_tap_delete_t *mp;
7334   u32 sw_if_index = ~0;
7335   u8 sw_if_index_set = 0;
7336   int ret;
7337
7338   /* Parse args required to build the message */
7339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7340     {
7341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7342         sw_if_index_set = 1;
7343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7344         sw_if_index_set = 1;
7345       else
7346         break;
7347     }
7348
7349   if (sw_if_index_set == 0)
7350     {
7351       errmsg ("missing vpp interface name");
7352       return -99;
7353     }
7354
7355   /* Construct the API message */
7356   M (TAP_DELETE, mp);
7357
7358   mp->sw_if_index = ntohl (sw_if_index);
7359
7360   /* send it... */
7361   S (mp);
7362
7363   /* Wait for a reply... */
7364   W (ret);
7365   return ret;
7366 }
7367
7368 static int
7369 api_ip_table_add_del (vat_main_t * vam)
7370 {
7371   unformat_input_t *i = vam->input;
7372   vl_api_ip_table_add_del_t *mp;
7373   u32 table_id = ~0;
7374   u8 is_ipv6 = 0;
7375   u8 is_add = 1;
7376   int ret = 0;
7377
7378   /* Parse args required to build the message */
7379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7380     {
7381       if (unformat (i, "ipv6"))
7382         is_ipv6 = 1;
7383       else if (unformat (i, "del"))
7384         is_add = 0;
7385       else if (unformat (i, "add"))
7386         is_add = 1;
7387       else if (unformat (i, "table %d", &table_id))
7388         ;
7389       else
7390         {
7391           clib_warning ("parse error '%U'", format_unformat_error, i);
7392           return -99;
7393         }
7394     }
7395
7396   if (~0 == table_id)
7397     {
7398       errmsg ("missing table-ID");
7399       return -99;
7400     }
7401
7402   /* Construct the API message */
7403   M (IP_TABLE_ADD_DEL, mp);
7404
7405   mp->table_id = ntohl (table_id);
7406   mp->is_ipv6 = is_ipv6;
7407   mp->is_add = is_add;
7408
7409   /* send it... */
7410   S (mp);
7411
7412   /* Wait for a reply... */
7413   W (ret);
7414
7415   return ret;
7416 }
7417
7418 static int
7419 api_ip_add_del_route (vat_main_t * vam)
7420 {
7421   unformat_input_t *i = vam->input;
7422   vl_api_ip_add_del_route_t *mp;
7423   u32 sw_if_index = ~0, vrf_id = 0;
7424   u8 is_ipv6 = 0;
7425   u8 is_local = 0, is_drop = 0;
7426   u8 is_unreach = 0, is_prohibit = 0;
7427   u8 create_vrf_if_needed = 0;
7428   u8 is_add = 1;
7429   u32 next_hop_weight = 1;
7430   u8 not_last = 0;
7431   u8 is_multipath = 0;
7432   u8 address_set = 0;
7433   u8 address_length_set = 0;
7434   u32 next_hop_table_id = 0;
7435   u32 resolve_attempts = 0;
7436   u32 dst_address_length = 0;
7437   u8 next_hop_set = 0;
7438   ip4_address_t v4_dst_address, v4_next_hop_address;
7439   ip6_address_t v6_dst_address, v6_next_hop_address;
7440   int count = 1;
7441   int j;
7442   f64 before = 0;
7443   u32 random_add_del = 0;
7444   u32 *random_vector = 0;
7445   uword *random_hash;
7446   u32 random_seed = 0xdeaddabe;
7447   u32 classify_table_index = ~0;
7448   u8 is_classify = 0;
7449   u8 resolve_host = 0, resolve_attached = 0;
7450   mpls_label_t *next_hop_out_label_stack = NULL;
7451   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7452   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7453
7454   /* Parse args required to build the message */
7455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7456     {
7457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7458         ;
7459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7460         ;
7461       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7462         {
7463           address_set = 1;
7464           is_ipv6 = 0;
7465         }
7466       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7467         {
7468           address_set = 1;
7469           is_ipv6 = 1;
7470         }
7471       else if (unformat (i, "/%d", &dst_address_length))
7472         {
7473           address_length_set = 1;
7474         }
7475
7476       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7477                                          &v4_next_hop_address))
7478         {
7479           next_hop_set = 1;
7480         }
7481       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7482                                          &v6_next_hop_address))
7483         {
7484           next_hop_set = 1;
7485         }
7486       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7487         ;
7488       else if (unformat (i, "weight %d", &next_hop_weight))
7489         ;
7490       else if (unformat (i, "drop"))
7491         {
7492           is_drop = 1;
7493         }
7494       else if (unformat (i, "null-send-unreach"))
7495         {
7496           is_unreach = 1;
7497         }
7498       else if (unformat (i, "null-send-prohibit"))
7499         {
7500           is_prohibit = 1;
7501         }
7502       else if (unformat (i, "local"))
7503         {
7504           is_local = 1;
7505         }
7506       else if (unformat (i, "classify %d", &classify_table_index))
7507         {
7508           is_classify = 1;
7509         }
7510       else if (unformat (i, "del"))
7511         is_add = 0;
7512       else if (unformat (i, "add"))
7513         is_add = 1;
7514       else if (unformat (i, "not-last"))
7515         not_last = 1;
7516       else if (unformat (i, "resolve-via-host"))
7517         resolve_host = 1;
7518       else if (unformat (i, "resolve-via-attached"))
7519         resolve_attached = 1;
7520       else if (unformat (i, "multipath"))
7521         is_multipath = 1;
7522       else if (unformat (i, "vrf %d", &vrf_id))
7523         ;
7524       else if (unformat (i, "create-vrf"))
7525         create_vrf_if_needed = 1;
7526       else if (unformat (i, "count %d", &count))
7527         ;
7528       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7529         ;
7530       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7531         ;
7532       else if (unformat (i, "out-label %d", &next_hop_out_label))
7533         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7534       else if (unformat (i, "via-label %d", &next_hop_via_label))
7535         ;
7536       else if (unformat (i, "random"))
7537         random_add_del = 1;
7538       else if (unformat (i, "seed %d", &random_seed))
7539         ;
7540       else
7541         {
7542           clib_warning ("parse error '%U'", format_unformat_error, i);
7543           return -99;
7544         }
7545     }
7546
7547   if (!next_hop_set && !is_drop && !is_local &&
7548       !is_classify && !is_unreach && !is_prohibit &&
7549       MPLS_LABEL_INVALID == next_hop_via_label)
7550     {
7551       errmsg
7552         ("next hop / local / drop / unreach / prohibit / classify not set");
7553       return -99;
7554     }
7555
7556   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7557     {
7558       errmsg ("next hop and next-hop via label set");
7559       return -99;
7560     }
7561   if (address_set == 0)
7562     {
7563       errmsg ("missing addresses");
7564       return -99;
7565     }
7566
7567   if (address_length_set == 0)
7568     {
7569       errmsg ("missing address length");
7570       return -99;
7571     }
7572
7573   /* Generate a pile of unique, random routes */
7574   if (random_add_del)
7575     {
7576       u32 this_random_address;
7577       random_hash = hash_create (count, sizeof (uword));
7578
7579       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7580       for (j = 0; j <= count; j++)
7581         {
7582           do
7583             {
7584               this_random_address = random_u32 (&random_seed);
7585               this_random_address =
7586                 clib_host_to_net_u32 (this_random_address);
7587             }
7588           while (hash_get (random_hash, this_random_address));
7589           vec_add1 (random_vector, this_random_address);
7590           hash_set (random_hash, this_random_address, 1);
7591         }
7592       hash_free (random_hash);
7593       v4_dst_address.as_u32 = random_vector[0];
7594     }
7595
7596   if (count > 1)
7597     {
7598       /* Turn on async mode */
7599       vam->async_mode = 1;
7600       vam->async_errors = 0;
7601       before = vat_time_now (vam);
7602     }
7603
7604   for (j = 0; j < count; j++)
7605     {
7606       /* Construct the API message */
7607       M2 (IP_ADD_DEL_ROUTE, mp,
7608           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7609
7610       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7611       mp->table_id = ntohl (vrf_id);
7612       mp->create_vrf_if_needed = create_vrf_if_needed;
7613
7614       mp->is_add = is_add;
7615       mp->is_drop = is_drop;
7616       mp->is_unreach = is_unreach;
7617       mp->is_prohibit = is_prohibit;
7618       mp->is_ipv6 = is_ipv6;
7619       mp->is_local = is_local;
7620       mp->is_classify = is_classify;
7621       mp->is_multipath = is_multipath;
7622       mp->is_resolve_host = resolve_host;
7623       mp->is_resolve_attached = resolve_attached;
7624       mp->not_last = not_last;
7625       mp->next_hop_weight = next_hop_weight;
7626       mp->dst_address_length = dst_address_length;
7627       mp->next_hop_table_id = ntohl (next_hop_table_id);
7628       mp->classify_table_index = ntohl (classify_table_index);
7629       mp->next_hop_via_label = ntohl (next_hop_via_label);
7630       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7631       if (0 != mp->next_hop_n_out_labels)
7632         {
7633           memcpy (mp->next_hop_out_label_stack,
7634                   next_hop_out_label_stack,
7635                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7636           vec_free (next_hop_out_label_stack);
7637         }
7638
7639       if (is_ipv6)
7640         {
7641           clib_memcpy (mp->dst_address, &v6_dst_address,
7642                        sizeof (v6_dst_address));
7643           if (next_hop_set)
7644             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7645                          sizeof (v6_next_hop_address));
7646           increment_v6_address (&v6_dst_address);
7647         }
7648       else
7649         {
7650           clib_memcpy (mp->dst_address, &v4_dst_address,
7651                        sizeof (v4_dst_address));
7652           if (next_hop_set)
7653             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7654                          sizeof (v4_next_hop_address));
7655           if (random_add_del)
7656             v4_dst_address.as_u32 = random_vector[j + 1];
7657           else
7658             increment_v4_address (&v4_dst_address);
7659         }
7660       /* send it... */
7661       S (mp);
7662       /* If we receive SIGTERM, stop now... */
7663       if (vam->do_exit)
7664         break;
7665     }
7666
7667   /* When testing multiple add/del ops, use a control-ping to sync */
7668   if (count > 1)
7669     {
7670       vl_api_control_ping_t *mp_ping;
7671       f64 after;
7672       f64 timeout;
7673
7674       /* Shut off async mode */
7675       vam->async_mode = 0;
7676
7677       MPING (CONTROL_PING, mp_ping);
7678       S (mp_ping);
7679
7680       timeout = vat_time_now (vam) + 1.0;
7681       while (vat_time_now (vam) < timeout)
7682         if (vam->result_ready == 1)
7683           goto out;
7684       vam->retval = -99;
7685
7686     out:
7687       if (vam->retval == -99)
7688         errmsg ("timeout");
7689
7690       if (vam->async_errors > 0)
7691         {
7692           errmsg ("%d asynchronous errors", vam->async_errors);
7693           vam->retval = -98;
7694         }
7695       vam->async_errors = 0;
7696       after = vat_time_now (vam);
7697
7698       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7699       if (j > 0)
7700         count = j;
7701
7702       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7703              count, after - before, count / (after - before));
7704     }
7705   else
7706     {
7707       int ret;
7708
7709       /* Wait for a reply... */
7710       W (ret);
7711       return ret;
7712     }
7713
7714   /* Return the good/bad news */
7715   return (vam->retval);
7716 }
7717
7718 static int
7719 api_ip_mroute_add_del (vat_main_t * vam)
7720 {
7721   unformat_input_t *i = vam->input;
7722   vl_api_ip_mroute_add_del_t *mp;
7723   u32 sw_if_index = ~0, vrf_id = 0;
7724   u8 is_ipv6 = 0;
7725   u8 is_local = 0;
7726   u8 create_vrf_if_needed = 0;
7727   u8 is_add = 1;
7728   u8 address_set = 0;
7729   u32 grp_address_length = 0;
7730   ip4_address_t v4_grp_address, v4_src_address;
7731   ip6_address_t v6_grp_address, v6_src_address;
7732   mfib_itf_flags_t iflags = 0;
7733   mfib_entry_flags_t eflags = 0;
7734   int ret;
7735
7736   /* Parse args required to build the message */
7737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7738     {
7739       if (unformat (i, "sw_if_index %d", &sw_if_index))
7740         ;
7741       else if (unformat (i, "%U %U",
7742                          unformat_ip4_address, &v4_src_address,
7743                          unformat_ip4_address, &v4_grp_address))
7744         {
7745           grp_address_length = 64;
7746           address_set = 1;
7747           is_ipv6 = 0;
7748         }
7749       else if (unformat (i, "%U %U",
7750                          unformat_ip6_address, &v6_src_address,
7751                          unformat_ip6_address, &v6_grp_address))
7752         {
7753           grp_address_length = 256;
7754           address_set = 1;
7755           is_ipv6 = 1;
7756         }
7757       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7758         {
7759           memset (&v4_src_address, 0, sizeof (v4_src_address));
7760           grp_address_length = 32;
7761           address_set = 1;
7762           is_ipv6 = 0;
7763         }
7764       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7765         {
7766           memset (&v6_src_address, 0, sizeof (v6_src_address));
7767           grp_address_length = 128;
7768           address_set = 1;
7769           is_ipv6 = 1;
7770         }
7771       else if (unformat (i, "/%d", &grp_address_length))
7772         ;
7773       else if (unformat (i, "local"))
7774         {
7775           is_local = 1;
7776         }
7777       else if (unformat (i, "del"))
7778         is_add = 0;
7779       else if (unformat (i, "add"))
7780         is_add = 1;
7781       else if (unformat (i, "vrf %d", &vrf_id))
7782         ;
7783       else if (unformat (i, "create-vrf"))
7784         create_vrf_if_needed = 1;
7785       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7786         ;
7787       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7788         ;
7789       else
7790         {
7791           clib_warning ("parse error '%U'", format_unformat_error, i);
7792           return -99;
7793         }
7794     }
7795
7796   if (address_set == 0)
7797     {
7798       errmsg ("missing addresses\n");
7799       return -99;
7800     }
7801
7802   /* Construct the API message */
7803   M (IP_MROUTE_ADD_DEL, mp);
7804
7805   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7806   mp->table_id = ntohl (vrf_id);
7807   mp->create_vrf_if_needed = create_vrf_if_needed;
7808
7809   mp->is_add = is_add;
7810   mp->is_ipv6 = is_ipv6;
7811   mp->is_local = is_local;
7812   mp->itf_flags = ntohl (iflags);
7813   mp->entry_flags = ntohl (eflags);
7814   mp->grp_address_length = grp_address_length;
7815   mp->grp_address_length = ntohs (mp->grp_address_length);
7816
7817   if (is_ipv6)
7818     {
7819       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7820       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7821     }
7822   else
7823     {
7824       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7825       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7826
7827     }
7828
7829   /* send it... */
7830   S (mp);
7831   /* Wait for a reply... */
7832   W (ret);
7833   return ret;
7834 }
7835
7836 static int
7837 api_mpls_table_add_del (vat_main_t * vam)
7838 {
7839   unformat_input_t *i = vam->input;
7840   vl_api_mpls_table_add_del_t *mp;
7841   u32 table_id = ~0;
7842   u8 is_add = 1;
7843   int ret = 0;
7844
7845   /* Parse args required to build the message */
7846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7847     {
7848       if (unformat (i, "table %d", &table_id))
7849         ;
7850       else if (unformat (i, "del"))
7851         is_add = 0;
7852       else if (unformat (i, "add"))
7853         is_add = 1;
7854       else
7855         {
7856           clib_warning ("parse error '%U'", format_unformat_error, i);
7857           return -99;
7858         }
7859     }
7860
7861   if (~0 == table_id)
7862     {
7863       errmsg ("missing table-ID");
7864       return -99;
7865     }
7866
7867   /* Construct the API message */
7868   M (MPLS_TABLE_ADD_DEL, mp);
7869
7870   mp->mt_table_id = ntohl (table_id);
7871   mp->mt_is_add = is_add;
7872
7873   /* send it... */
7874   S (mp);
7875
7876   /* Wait for a reply... */
7877   W (ret);
7878
7879   return ret;
7880 }
7881
7882 static int
7883 api_mpls_route_add_del (vat_main_t * vam)
7884 {
7885   unformat_input_t *i = vam->input;
7886   vl_api_mpls_route_add_del_t *mp;
7887   u32 sw_if_index = ~0, table_id = 0;
7888   u8 create_table_if_needed = 0;
7889   u8 is_add = 1;
7890   u32 next_hop_weight = 1;
7891   u8 is_multipath = 0;
7892   u32 next_hop_table_id = 0;
7893   u8 next_hop_set = 0;
7894   ip4_address_t v4_next_hop_address = {
7895     .as_u32 = 0,
7896   };
7897   ip6_address_t v6_next_hop_address = { {0} };
7898   int count = 1;
7899   int j;
7900   f64 before = 0;
7901   u32 classify_table_index = ~0;
7902   u8 is_classify = 0;
7903   u8 resolve_host = 0, resolve_attached = 0;
7904   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7905   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7906   mpls_label_t *next_hop_out_label_stack = NULL;
7907   mpls_label_t local_label = MPLS_LABEL_INVALID;
7908   u8 is_eos = 0;
7909   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
7910
7911   /* Parse args required to build the message */
7912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7913     {
7914       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7915         ;
7916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7917         ;
7918       else if (unformat (i, "%d", &local_label))
7919         ;
7920       else if (unformat (i, "eos"))
7921         is_eos = 1;
7922       else if (unformat (i, "non-eos"))
7923         is_eos = 0;
7924       else if (unformat (i, "via %U", unformat_ip4_address,
7925                          &v4_next_hop_address))
7926         {
7927           next_hop_set = 1;
7928           next_hop_proto = DPO_PROTO_IP4;
7929         }
7930       else if (unformat (i, "via %U", unformat_ip6_address,
7931                          &v6_next_hop_address))
7932         {
7933           next_hop_set = 1;
7934           next_hop_proto = DPO_PROTO_IP6;
7935         }
7936       else if (unformat (i, "weight %d", &next_hop_weight))
7937         ;
7938       else if (unformat (i, "create-table"))
7939         create_table_if_needed = 1;
7940       else if (unformat (i, "classify %d", &classify_table_index))
7941         {
7942           is_classify = 1;
7943         }
7944       else if (unformat (i, "del"))
7945         is_add = 0;
7946       else if (unformat (i, "add"))
7947         is_add = 1;
7948       else if (unformat (i, "resolve-via-host"))
7949         resolve_host = 1;
7950       else if (unformat (i, "resolve-via-attached"))
7951         resolve_attached = 1;
7952       else if (unformat (i, "multipath"))
7953         is_multipath = 1;
7954       else if (unformat (i, "count %d", &count))
7955         ;
7956       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7957         {
7958           next_hop_set = 1;
7959           next_hop_proto = DPO_PROTO_IP4;
7960         }
7961       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7962         {
7963           next_hop_set = 1;
7964           next_hop_proto = DPO_PROTO_IP6;
7965         }
7966       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7967         ;
7968       else if (unformat (i, "via-label %d", &next_hop_via_label))
7969         ;
7970       else if (unformat (i, "out-label %d", &next_hop_out_label))
7971         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7972       else
7973         {
7974           clib_warning ("parse error '%U'", format_unformat_error, i);
7975           return -99;
7976         }
7977     }
7978
7979   if (!next_hop_set && !is_classify)
7980     {
7981       errmsg ("next hop / classify not set");
7982       return -99;
7983     }
7984
7985   if (MPLS_LABEL_INVALID == local_label)
7986     {
7987       errmsg ("missing label");
7988       return -99;
7989     }
7990
7991   if (count > 1)
7992     {
7993       /* Turn on async mode */
7994       vam->async_mode = 1;
7995       vam->async_errors = 0;
7996       before = vat_time_now (vam);
7997     }
7998
7999   for (j = 0; j < count; j++)
8000     {
8001       /* Construct the API message */
8002       M2 (MPLS_ROUTE_ADD_DEL, mp,
8003           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8004
8005       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8006       mp->mr_table_id = ntohl (table_id);
8007       mp->mr_create_table_if_needed = create_table_if_needed;
8008
8009       mp->mr_is_add = is_add;
8010       mp->mr_next_hop_proto = next_hop_proto;
8011       mp->mr_is_classify = is_classify;
8012       mp->mr_is_multipath = is_multipath;
8013       mp->mr_is_resolve_host = resolve_host;
8014       mp->mr_is_resolve_attached = resolve_attached;
8015       mp->mr_next_hop_weight = next_hop_weight;
8016       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8017       mp->mr_classify_table_index = ntohl (classify_table_index);
8018       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8019       mp->mr_label = ntohl (local_label);
8020       mp->mr_eos = is_eos;
8021
8022       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8023       if (0 != mp->mr_next_hop_n_out_labels)
8024         {
8025           memcpy (mp->mr_next_hop_out_label_stack,
8026                   next_hop_out_label_stack,
8027                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8028           vec_free (next_hop_out_label_stack);
8029         }
8030
8031       if (next_hop_set)
8032         {
8033           if (DPO_PROTO_IP4 == next_hop_proto)
8034             {
8035               clib_memcpy (mp->mr_next_hop,
8036                            &v4_next_hop_address,
8037                            sizeof (v4_next_hop_address));
8038             }
8039           else if (DPO_PROTO_IP6 == next_hop_proto)
8040
8041             {
8042               clib_memcpy (mp->mr_next_hop,
8043                            &v6_next_hop_address,
8044                            sizeof (v6_next_hop_address));
8045             }
8046         }
8047       local_label++;
8048
8049       /* send it... */
8050       S (mp);
8051       /* If we receive SIGTERM, stop now... */
8052       if (vam->do_exit)
8053         break;
8054     }
8055
8056   /* When testing multiple add/del ops, use a control-ping to sync */
8057   if (count > 1)
8058     {
8059       vl_api_control_ping_t *mp_ping;
8060       f64 after;
8061       f64 timeout;
8062
8063       /* Shut off async mode */
8064       vam->async_mode = 0;
8065
8066       MPING (CONTROL_PING, mp_ping);
8067       S (mp_ping);
8068
8069       timeout = vat_time_now (vam) + 1.0;
8070       while (vat_time_now (vam) < timeout)
8071         if (vam->result_ready == 1)
8072           goto out;
8073       vam->retval = -99;
8074
8075     out:
8076       if (vam->retval == -99)
8077         errmsg ("timeout");
8078
8079       if (vam->async_errors > 0)
8080         {
8081           errmsg ("%d asynchronous errors", vam->async_errors);
8082           vam->retval = -98;
8083         }
8084       vam->async_errors = 0;
8085       after = vat_time_now (vam);
8086
8087       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8088       if (j > 0)
8089         count = j;
8090
8091       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8092              count, after - before, count / (after - before));
8093     }
8094   else
8095     {
8096       int ret;
8097
8098       /* Wait for a reply... */
8099       W (ret);
8100       return ret;
8101     }
8102
8103   /* Return the good/bad news */
8104   return (vam->retval);
8105 }
8106
8107 static int
8108 api_mpls_ip_bind_unbind (vat_main_t * vam)
8109 {
8110   unformat_input_t *i = vam->input;
8111   vl_api_mpls_ip_bind_unbind_t *mp;
8112   u32 ip_table_id = 0;
8113   u8 create_table_if_needed = 0;
8114   u8 is_bind = 1;
8115   u8 is_ip4 = 1;
8116   ip4_address_t v4_address;
8117   ip6_address_t v6_address;
8118   u32 address_length;
8119   u8 address_set = 0;
8120   mpls_label_t local_label = MPLS_LABEL_INVALID;
8121   int ret;
8122
8123   /* Parse args required to build the message */
8124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8125     {
8126       if (unformat (i, "%U/%d", unformat_ip4_address,
8127                     &v4_address, &address_length))
8128         {
8129           is_ip4 = 1;
8130           address_set = 1;
8131         }
8132       else if (unformat (i, "%U/%d", unformat_ip6_address,
8133                          &v6_address, &address_length))
8134         {
8135           is_ip4 = 0;
8136           address_set = 1;
8137         }
8138       else if (unformat (i, "%d", &local_label))
8139         ;
8140       else if (unformat (i, "create-table"))
8141         create_table_if_needed = 1;
8142       else if (unformat (i, "table-id %d", &ip_table_id))
8143         ;
8144       else if (unformat (i, "unbind"))
8145         is_bind = 0;
8146       else if (unformat (i, "bind"))
8147         is_bind = 1;
8148       else
8149         {
8150           clib_warning ("parse error '%U'", format_unformat_error, i);
8151           return -99;
8152         }
8153     }
8154
8155   if (!address_set)
8156     {
8157       errmsg ("IP addres not set");
8158       return -99;
8159     }
8160
8161   if (MPLS_LABEL_INVALID == local_label)
8162     {
8163       errmsg ("missing label");
8164       return -99;
8165     }
8166
8167   /* Construct the API message */
8168   M (MPLS_IP_BIND_UNBIND, mp);
8169
8170   mp->mb_create_table_if_needed = create_table_if_needed;
8171   mp->mb_is_bind = is_bind;
8172   mp->mb_is_ip4 = is_ip4;
8173   mp->mb_ip_table_id = ntohl (ip_table_id);
8174   mp->mb_mpls_table_id = 0;
8175   mp->mb_label = ntohl (local_label);
8176   mp->mb_address_length = address_length;
8177
8178   if (is_ip4)
8179     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8180   else
8181     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8182
8183   /* send it... */
8184   S (mp);
8185
8186   /* Wait for a reply... */
8187   W (ret);
8188   return ret;
8189 }
8190
8191 static int
8192 api_proxy_arp_add_del (vat_main_t * vam)
8193 {
8194   unformat_input_t *i = vam->input;
8195   vl_api_proxy_arp_add_del_t *mp;
8196   u32 vrf_id = 0;
8197   u8 is_add = 1;
8198   ip4_address_t lo, hi;
8199   u8 range_set = 0;
8200   int ret;
8201
8202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8203     {
8204       if (unformat (i, "vrf %d", &vrf_id))
8205         ;
8206       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8207                          unformat_ip4_address, &hi))
8208         range_set = 1;
8209       else if (unformat (i, "del"))
8210         is_add = 0;
8211       else
8212         {
8213           clib_warning ("parse error '%U'", format_unformat_error, i);
8214           return -99;
8215         }
8216     }
8217
8218   if (range_set == 0)
8219     {
8220       errmsg ("address range not set");
8221       return -99;
8222     }
8223
8224   M (PROXY_ARP_ADD_DEL, mp);
8225
8226   mp->vrf_id = ntohl (vrf_id);
8227   mp->is_add = is_add;
8228   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8229   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8230
8231   S (mp);
8232   W (ret);
8233   return ret;
8234 }
8235
8236 static int
8237 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8238 {
8239   unformat_input_t *i = vam->input;
8240   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8241   u32 sw_if_index;
8242   u8 enable = 1;
8243   u8 sw_if_index_set = 0;
8244   int ret;
8245
8246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8247     {
8248       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8249         sw_if_index_set = 1;
8250       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8251         sw_if_index_set = 1;
8252       else if (unformat (i, "enable"))
8253         enable = 1;
8254       else if (unformat (i, "disable"))
8255         enable = 0;
8256       else
8257         {
8258           clib_warning ("parse error '%U'", format_unformat_error, i);
8259           return -99;
8260         }
8261     }
8262
8263   if (sw_if_index_set == 0)
8264     {
8265       errmsg ("missing interface name or sw_if_index");
8266       return -99;
8267     }
8268
8269   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8270
8271   mp->sw_if_index = ntohl (sw_if_index);
8272   mp->enable_disable = enable;
8273
8274   S (mp);
8275   W (ret);
8276   return ret;
8277 }
8278
8279 static int
8280 api_mpls_tunnel_add_del (vat_main_t * vam)
8281 {
8282   unformat_input_t *i = vam->input;
8283   vl_api_mpls_tunnel_add_del_t *mp;
8284
8285   u8 is_add = 1;
8286   u8 l2_only = 0;
8287   u32 sw_if_index = ~0;
8288   u32 next_hop_sw_if_index = ~0;
8289   u32 next_hop_proto_is_ip4 = 1;
8290
8291   u32 next_hop_table_id = 0;
8292   ip4_address_t v4_next_hop_address = {
8293     .as_u32 = 0,
8294   };
8295   ip6_address_t v6_next_hop_address = { {0} };
8296   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8297   int ret;
8298
8299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8300     {
8301       if (unformat (i, "add"))
8302         is_add = 1;
8303       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8304         is_add = 0;
8305       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8306         ;
8307       else if (unformat (i, "via %U",
8308                          unformat_ip4_address, &v4_next_hop_address))
8309         {
8310           next_hop_proto_is_ip4 = 1;
8311         }
8312       else if (unformat (i, "via %U",
8313                          unformat_ip6_address, &v6_next_hop_address))
8314         {
8315           next_hop_proto_is_ip4 = 0;
8316         }
8317       else if (unformat (i, "l2-only"))
8318         l2_only = 1;
8319       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8320         ;
8321       else if (unformat (i, "out-label %d", &next_hop_out_label))
8322         vec_add1 (labels, ntohl (next_hop_out_label));
8323       else
8324         {
8325           clib_warning ("parse error '%U'", format_unformat_error, i);
8326           return -99;
8327         }
8328     }
8329
8330   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8331
8332   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8333   mp->mt_sw_if_index = ntohl (sw_if_index);
8334   mp->mt_is_add = is_add;
8335   mp->mt_l2_only = l2_only;
8336   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8337   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8338
8339   mp->mt_next_hop_n_out_labels = vec_len (labels);
8340
8341   if (0 != mp->mt_next_hop_n_out_labels)
8342     {
8343       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8344                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8345       vec_free (labels);
8346     }
8347
8348   if (next_hop_proto_is_ip4)
8349     {
8350       clib_memcpy (mp->mt_next_hop,
8351                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8352     }
8353   else
8354     {
8355       clib_memcpy (mp->mt_next_hop,
8356                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8357     }
8358
8359   S (mp);
8360   W (ret);
8361   return ret;
8362 }
8363
8364 static int
8365 api_sw_interface_set_unnumbered (vat_main_t * vam)
8366 {
8367   unformat_input_t *i = vam->input;
8368   vl_api_sw_interface_set_unnumbered_t *mp;
8369   u32 sw_if_index;
8370   u32 unnum_sw_index = ~0;
8371   u8 is_add = 1;
8372   u8 sw_if_index_set = 0;
8373   int ret;
8374
8375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8376     {
8377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8378         sw_if_index_set = 1;
8379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8380         sw_if_index_set = 1;
8381       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8382         ;
8383       else if (unformat (i, "del"))
8384         is_add = 0;
8385       else
8386         {
8387           clib_warning ("parse error '%U'", format_unformat_error, i);
8388           return -99;
8389         }
8390     }
8391
8392   if (sw_if_index_set == 0)
8393     {
8394       errmsg ("missing interface name or sw_if_index");
8395       return -99;
8396     }
8397
8398   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8399
8400   mp->sw_if_index = ntohl (sw_if_index);
8401   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8402   mp->is_add = is_add;
8403
8404   S (mp);
8405   W (ret);
8406   return ret;
8407 }
8408
8409 static int
8410 api_ip_neighbor_add_del (vat_main_t * vam)
8411 {
8412   unformat_input_t *i = vam->input;
8413   vl_api_ip_neighbor_add_del_t *mp;
8414   u32 sw_if_index;
8415   u8 sw_if_index_set = 0;
8416   u8 is_add = 1;
8417   u8 is_static = 0;
8418   u8 is_no_fib_entry = 0;
8419   u8 mac_address[6];
8420   u8 mac_set = 0;
8421   u8 v4_address_set = 0;
8422   u8 v6_address_set = 0;
8423   ip4_address_t v4address;
8424   ip6_address_t v6address;
8425   int ret;
8426
8427   memset (mac_address, 0, sizeof (mac_address));
8428
8429   /* Parse args required to build the message */
8430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8431     {
8432       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8433         {
8434           mac_set = 1;
8435         }
8436       else if (unformat (i, "del"))
8437         is_add = 0;
8438       else
8439         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8440         sw_if_index_set = 1;
8441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8442         sw_if_index_set = 1;
8443       else if (unformat (i, "is_static"))
8444         is_static = 1;
8445       else if (unformat (i, "no-fib-entry"))
8446         is_no_fib_entry = 1;
8447       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8448         v4_address_set = 1;
8449       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8450         v6_address_set = 1;
8451       else
8452         {
8453           clib_warning ("parse error '%U'", format_unformat_error, i);
8454           return -99;
8455         }
8456     }
8457
8458   if (sw_if_index_set == 0)
8459     {
8460       errmsg ("missing interface name or sw_if_index");
8461       return -99;
8462     }
8463   if (v4_address_set && v6_address_set)
8464     {
8465       errmsg ("both v4 and v6 addresses set");
8466       return -99;
8467     }
8468   if (!v4_address_set && !v6_address_set)
8469     {
8470       errmsg ("no address set");
8471       return -99;
8472     }
8473
8474   /* Construct the API message */
8475   M (IP_NEIGHBOR_ADD_DEL, mp);
8476
8477   mp->sw_if_index = ntohl (sw_if_index);
8478   mp->is_add = is_add;
8479   mp->is_static = is_static;
8480   mp->is_no_adj_fib = is_no_fib_entry;
8481   if (mac_set)
8482     clib_memcpy (mp->mac_address, mac_address, 6);
8483   if (v6_address_set)
8484     {
8485       mp->is_ipv6 = 1;
8486       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8487     }
8488   else
8489     {
8490       /* mp->is_ipv6 = 0; via memset in M macro above */
8491       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8492     }
8493
8494   /* send it... */
8495   S (mp);
8496
8497   /* Wait for a reply, return good/bad news  */
8498   W (ret);
8499   return ret;
8500 }
8501
8502 static int
8503 api_reset_vrf (vat_main_t * vam)
8504 {
8505   unformat_input_t *i = vam->input;
8506   vl_api_reset_vrf_t *mp;
8507   u32 vrf_id = 0;
8508   u8 is_ipv6 = 0;
8509   u8 vrf_id_set = 0;
8510   int ret;
8511
8512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8513     {
8514       if (unformat (i, "vrf %d", &vrf_id))
8515         vrf_id_set = 1;
8516       else if (unformat (i, "ipv6"))
8517         is_ipv6 = 1;
8518       else
8519         {
8520           clib_warning ("parse error '%U'", format_unformat_error, i);
8521           return -99;
8522         }
8523     }
8524
8525   if (vrf_id_set == 0)
8526     {
8527       errmsg ("missing vrf id");
8528       return -99;
8529     }
8530
8531   M (RESET_VRF, mp);
8532
8533   mp->vrf_id = ntohl (vrf_id);
8534   mp->is_ipv6 = is_ipv6;
8535
8536   S (mp);
8537   W (ret);
8538   return ret;
8539 }
8540
8541 static int
8542 api_create_vlan_subif (vat_main_t * vam)
8543 {
8544   unformat_input_t *i = vam->input;
8545   vl_api_create_vlan_subif_t *mp;
8546   u32 sw_if_index;
8547   u8 sw_if_index_set = 0;
8548   u32 vlan_id;
8549   u8 vlan_id_set = 0;
8550   int ret;
8551
8552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8553     {
8554       if (unformat (i, "sw_if_index %d", &sw_if_index))
8555         sw_if_index_set = 1;
8556       else
8557         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8558         sw_if_index_set = 1;
8559       else if (unformat (i, "vlan %d", &vlan_id))
8560         vlan_id_set = 1;
8561       else
8562         {
8563           clib_warning ("parse error '%U'", format_unformat_error, i);
8564           return -99;
8565         }
8566     }
8567
8568   if (sw_if_index_set == 0)
8569     {
8570       errmsg ("missing interface name or sw_if_index");
8571       return -99;
8572     }
8573
8574   if (vlan_id_set == 0)
8575     {
8576       errmsg ("missing vlan_id");
8577       return -99;
8578     }
8579   M (CREATE_VLAN_SUBIF, mp);
8580
8581   mp->sw_if_index = ntohl (sw_if_index);
8582   mp->vlan_id = ntohl (vlan_id);
8583
8584   S (mp);
8585   W (ret);
8586   return ret;
8587 }
8588
8589 #define foreach_create_subif_bit                \
8590 _(no_tags)                                      \
8591 _(one_tag)                                      \
8592 _(two_tags)                                     \
8593 _(dot1ad)                                       \
8594 _(exact_match)                                  \
8595 _(default_sub)                                  \
8596 _(outer_vlan_id_any)                            \
8597 _(inner_vlan_id_any)
8598
8599 static int
8600 api_create_subif (vat_main_t * vam)
8601 {
8602   unformat_input_t *i = vam->input;
8603   vl_api_create_subif_t *mp;
8604   u32 sw_if_index;
8605   u8 sw_if_index_set = 0;
8606   u32 sub_id;
8607   u8 sub_id_set = 0;
8608   u32 no_tags = 0;
8609   u32 one_tag = 0;
8610   u32 two_tags = 0;
8611   u32 dot1ad = 0;
8612   u32 exact_match = 0;
8613   u32 default_sub = 0;
8614   u32 outer_vlan_id_any = 0;
8615   u32 inner_vlan_id_any = 0;
8616   u32 tmp;
8617   u16 outer_vlan_id = 0;
8618   u16 inner_vlan_id = 0;
8619   int ret;
8620
8621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8622     {
8623       if (unformat (i, "sw_if_index %d", &sw_if_index))
8624         sw_if_index_set = 1;
8625       else
8626         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8627         sw_if_index_set = 1;
8628       else if (unformat (i, "sub_id %d", &sub_id))
8629         sub_id_set = 1;
8630       else if (unformat (i, "outer_vlan_id %d", &tmp))
8631         outer_vlan_id = tmp;
8632       else if (unformat (i, "inner_vlan_id %d", &tmp))
8633         inner_vlan_id = tmp;
8634
8635 #define _(a) else if (unformat (i, #a)) a = 1 ;
8636       foreach_create_subif_bit
8637 #undef _
8638         else
8639         {
8640           clib_warning ("parse error '%U'", format_unformat_error, i);
8641           return -99;
8642         }
8643     }
8644
8645   if (sw_if_index_set == 0)
8646     {
8647       errmsg ("missing interface name or sw_if_index");
8648       return -99;
8649     }
8650
8651   if (sub_id_set == 0)
8652     {
8653       errmsg ("missing sub_id");
8654       return -99;
8655     }
8656   M (CREATE_SUBIF, mp);
8657
8658   mp->sw_if_index = ntohl (sw_if_index);
8659   mp->sub_id = ntohl (sub_id);
8660
8661 #define _(a) mp->a = a;
8662   foreach_create_subif_bit;
8663 #undef _
8664
8665   mp->outer_vlan_id = ntohs (outer_vlan_id);
8666   mp->inner_vlan_id = ntohs (inner_vlan_id);
8667
8668   S (mp);
8669   W (ret);
8670   return ret;
8671 }
8672
8673 static int
8674 api_oam_add_del (vat_main_t * vam)
8675 {
8676   unformat_input_t *i = vam->input;
8677   vl_api_oam_add_del_t *mp;
8678   u32 vrf_id = 0;
8679   u8 is_add = 1;
8680   ip4_address_t src, dst;
8681   u8 src_set = 0;
8682   u8 dst_set = 0;
8683   int ret;
8684
8685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8686     {
8687       if (unformat (i, "vrf %d", &vrf_id))
8688         ;
8689       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8690         src_set = 1;
8691       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8692         dst_set = 1;
8693       else if (unformat (i, "del"))
8694         is_add = 0;
8695       else
8696         {
8697           clib_warning ("parse error '%U'", format_unformat_error, i);
8698           return -99;
8699         }
8700     }
8701
8702   if (src_set == 0)
8703     {
8704       errmsg ("missing src addr");
8705       return -99;
8706     }
8707
8708   if (dst_set == 0)
8709     {
8710       errmsg ("missing dst addr");
8711       return -99;
8712     }
8713
8714   M (OAM_ADD_DEL, mp);
8715
8716   mp->vrf_id = ntohl (vrf_id);
8717   mp->is_add = is_add;
8718   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8719   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8720
8721   S (mp);
8722   W (ret);
8723   return ret;
8724 }
8725
8726 static int
8727 api_reset_fib (vat_main_t * vam)
8728 {
8729   unformat_input_t *i = vam->input;
8730   vl_api_reset_fib_t *mp;
8731   u32 vrf_id = 0;
8732   u8 is_ipv6 = 0;
8733   u8 vrf_id_set = 0;
8734
8735   int ret;
8736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8737     {
8738       if (unformat (i, "vrf %d", &vrf_id))
8739         vrf_id_set = 1;
8740       else if (unformat (i, "ipv6"))
8741         is_ipv6 = 1;
8742       else
8743         {
8744           clib_warning ("parse error '%U'", format_unformat_error, i);
8745           return -99;
8746         }
8747     }
8748
8749   if (vrf_id_set == 0)
8750     {
8751       errmsg ("missing vrf id");
8752       return -99;
8753     }
8754
8755   M (RESET_FIB, mp);
8756
8757   mp->vrf_id = ntohl (vrf_id);
8758   mp->is_ipv6 = is_ipv6;
8759
8760   S (mp);
8761   W (ret);
8762   return ret;
8763 }
8764
8765 static int
8766 api_dhcp_proxy_config (vat_main_t * vam)
8767 {
8768   unformat_input_t *i = vam->input;
8769   vl_api_dhcp_proxy_config_t *mp;
8770   u32 rx_vrf_id = 0;
8771   u32 server_vrf_id = 0;
8772   u8 is_add = 1;
8773   u8 v4_address_set = 0;
8774   u8 v6_address_set = 0;
8775   ip4_address_t v4address;
8776   ip6_address_t v6address;
8777   u8 v4_src_address_set = 0;
8778   u8 v6_src_address_set = 0;
8779   ip4_address_t v4srcaddress;
8780   ip6_address_t v6srcaddress;
8781   int ret;
8782
8783   /* Parse args required to build the message */
8784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8785     {
8786       if (unformat (i, "del"))
8787         is_add = 0;
8788       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8789         ;
8790       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8791         ;
8792       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8793         v4_address_set = 1;
8794       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8795         v6_address_set = 1;
8796       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8797         v4_src_address_set = 1;
8798       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8799         v6_src_address_set = 1;
8800       else
8801         break;
8802     }
8803
8804   if (v4_address_set && v6_address_set)
8805     {
8806       errmsg ("both v4 and v6 server addresses set");
8807       return -99;
8808     }
8809   if (!v4_address_set && !v6_address_set)
8810     {
8811       errmsg ("no server addresses set");
8812       return -99;
8813     }
8814
8815   if (v4_src_address_set && v6_src_address_set)
8816     {
8817       errmsg ("both v4 and v6  src addresses set");
8818       return -99;
8819     }
8820   if (!v4_src_address_set && !v6_src_address_set)
8821     {
8822       errmsg ("no src addresses set");
8823       return -99;
8824     }
8825
8826   if (!(v4_src_address_set && v4_address_set) &&
8827       !(v6_src_address_set && v6_address_set))
8828     {
8829       errmsg ("no matching server and src addresses set");
8830       return -99;
8831     }
8832
8833   /* Construct the API message */
8834   M (DHCP_PROXY_CONFIG, mp);
8835
8836   mp->is_add = is_add;
8837   mp->rx_vrf_id = ntohl (rx_vrf_id);
8838   mp->server_vrf_id = ntohl (server_vrf_id);
8839   if (v6_address_set)
8840     {
8841       mp->is_ipv6 = 1;
8842       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8843       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8844     }
8845   else
8846     {
8847       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8848       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8849     }
8850
8851   /* send it... */
8852   S (mp);
8853
8854   /* Wait for a reply, return good/bad news  */
8855   W (ret);
8856   return ret;
8857 }
8858
8859 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8860 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8861
8862 static void
8863 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8864 {
8865   vat_main_t *vam = &vat_main;
8866   u32 i, count = mp->count;
8867   vl_api_dhcp_server_t *s;
8868
8869   if (mp->is_ipv6)
8870     print (vam->ofp,
8871            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8872            ntohl (mp->rx_vrf_id),
8873            format_ip6_address, mp->dhcp_src_address,
8874            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8875   else
8876     print (vam->ofp,
8877            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8878            ntohl (mp->rx_vrf_id),
8879            format_ip4_address, mp->dhcp_src_address,
8880            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8881
8882   for (i = 0; i < count; i++)
8883     {
8884       s = &mp->servers[i];
8885
8886       if (mp->is_ipv6)
8887         print (vam->ofp,
8888                " Server Table-ID %d, Server Address %U",
8889                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8890       else
8891         print (vam->ofp,
8892                " Server Table-ID %d, Server Address %U",
8893                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8894     }
8895 }
8896
8897 static void vl_api_dhcp_proxy_details_t_handler_json
8898   (vl_api_dhcp_proxy_details_t * mp)
8899 {
8900   vat_main_t *vam = &vat_main;
8901   vat_json_node_t *node = NULL;
8902   u32 i, count = mp->count;
8903   struct in_addr ip4;
8904   struct in6_addr ip6;
8905   vl_api_dhcp_server_t *s;
8906
8907   if (VAT_JSON_ARRAY != vam->json_tree.type)
8908     {
8909       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8910       vat_json_init_array (&vam->json_tree);
8911     }
8912   node = vat_json_array_add (&vam->json_tree);
8913
8914   vat_json_init_object (node);
8915   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8916   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8917   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8918
8919   if (mp->is_ipv6)
8920     {
8921       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8922       vat_json_object_add_ip6 (node, "src_address", ip6);
8923     }
8924   else
8925     {
8926       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8927       vat_json_object_add_ip4 (node, "src_address", ip4);
8928     }
8929
8930   for (i = 0; i < count; i++)
8931     {
8932       s = &mp->servers[i];
8933
8934       vat_json_object_add_uint (node, "server-table-id",
8935                                 ntohl (s->server_vrf_id));
8936
8937       if (mp->is_ipv6)
8938         {
8939           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8940           vat_json_object_add_ip4 (node, "src_address", ip4);
8941         }
8942       else
8943         {
8944           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8945           vat_json_object_add_ip6 (node, "server_address", ip6);
8946         }
8947     }
8948 }
8949
8950 static int
8951 api_dhcp_proxy_dump (vat_main_t * vam)
8952 {
8953   unformat_input_t *i = vam->input;
8954   vl_api_control_ping_t *mp_ping;
8955   vl_api_dhcp_proxy_dump_t *mp;
8956   u8 is_ipv6 = 0;
8957   int ret;
8958
8959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8960     {
8961       if (unformat (i, "ipv6"))
8962         is_ipv6 = 1;
8963       else
8964         {
8965           clib_warning ("parse error '%U'", format_unformat_error, i);
8966           return -99;
8967         }
8968     }
8969
8970   M (DHCP_PROXY_DUMP, mp);
8971
8972   mp->is_ip6 = is_ipv6;
8973   S (mp);
8974
8975   /* Use a control ping for synchronization */
8976   MPING (CONTROL_PING, mp_ping);
8977   S (mp_ping);
8978
8979   W (ret);
8980   return ret;
8981 }
8982
8983 static int
8984 api_dhcp_proxy_set_vss (vat_main_t * vam)
8985 {
8986   unformat_input_t *i = vam->input;
8987   vl_api_dhcp_proxy_set_vss_t *mp;
8988   u8 is_ipv6 = 0;
8989   u8 is_add = 1;
8990   u32 tbl_id;
8991   u8 tbl_id_set = 0;
8992   u32 oui;
8993   u8 oui_set = 0;
8994   u32 fib_id;
8995   u8 fib_id_set = 0;
8996   int ret;
8997
8998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8999     {
9000       if (unformat (i, "tbl_id %d", &tbl_id))
9001         tbl_id_set = 1;
9002       if (unformat (i, "fib_id %d", &fib_id))
9003         fib_id_set = 1;
9004       if (unformat (i, "oui %d", &oui))
9005         oui_set = 1;
9006       else if (unformat (i, "ipv6"))
9007         is_ipv6 = 1;
9008       else if (unformat (i, "del"))
9009         is_add = 0;
9010       else
9011         {
9012           clib_warning ("parse error '%U'", format_unformat_error, i);
9013           return -99;
9014         }
9015     }
9016
9017   if (tbl_id_set == 0)
9018     {
9019       errmsg ("missing tbl id");
9020       return -99;
9021     }
9022
9023   if (fib_id_set == 0)
9024     {
9025       errmsg ("missing fib id");
9026       return -99;
9027     }
9028   if (oui_set == 0)
9029     {
9030       errmsg ("missing oui");
9031       return -99;
9032     }
9033
9034   M (DHCP_PROXY_SET_VSS, mp);
9035   mp->tbl_id = ntohl (tbl_id);
9036   mp->fib_id = ntohl (fib_id);
9037   mp->oui = ntohl (oui);
9038   mp->is_ipv6 = is_ipv6;
9039   mp->is_add = is_add;
9040
9041   S (mp);
9042   W (ret);
9043   return ret;
9044 }
9045
9046 static int
9047 api_dhcp_client_config (vat_main_t * vam)
9048 {
9049   unformat_input_t *i = vam->input;
9050   vl_api_dhcp_client_config_t *mp;
9051   u32 sw_if_index;
9052   u8 sw_if_index_set = 0;
9053   u8 is_add = 1;
9054   u8 *hostname = 0;
9055   u8 disable_event = 0;
9056   int ret;
9057
9058   /* Parse args required to build the message */
9059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9060     {
9061       if (unformat (i, "del"))
9062         is_add = 0;
9063       else
9064         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9065         sw_if_index_set = 1;
9066       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9067         sw_if_index_set = 1;
9068       else if (unformat (i, "hostname %s", &hostname))
9069         ;
9070       else if (unformat (i, "disable_event"))
9071         disable_event = 1;
9072       else
9073         break;
9074     }
9075
9076   if (sw_if_index_set == 0)
9077     {
9078       errmsg ("missing interface name or sw_if_index");
9079       return -99;
9080     }
9081
9082   if (vec_len (hostname) > 63)
9083     {
9084       errmsg ("hostname too long");
9085     }
9086   vec_add1 (hostname, 0);
9087
9088   /* Construct the API message */
9089   M (DHCP_CLIENT_CONFIG, mp);
9090
9091   mp->sw_if_index = htonl (sw_if_index);
9092   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9093   vec_free (hostname);
9094   mp->is_add = is_add;
9095   mp->want_dhcp_event = disable_event ? 0 : 1;
9096   mp->pid = htonl (getpid ());
9097
9098   /* send it... */
9099   S (mp);
9100
9101   /* Wait for a reply, return good/bad news  */
9102   W (ret);
9103   return ret;
9104 }
9105
9106 static int
9107 api_set_ip_flow_hash (vat_main_t * vam)
9108 {
9109   unformat_input_t *i = vam->input;
9110   vl_api_set_ip_flow_hash_t *mp;
9111   u32 vrf_id = 0;
9112   u8 is_ipv6 = 0;
9113   u8 vrf_id_set = 0;
9114   u8 src = 0;
9115   u8 dst = 0;
9116   u8 sport = 0;
9117   u8 dport = 0;
9118   u8 proto = 0;
9119   u8 reverse = 0;
9120   int ret;
9121
9122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9123     {
9124       if (unformat (i, "vrf %d", &vrf_id))
9125         vrf_id_set = 1;
9126       else if (unformat (i, "ipv6"))
9127         is_ipv6 = 1;
9128       else if (unformat (i, "src"))
9129         src = 1;
9130       else if (unformat (i, "dst"))
9131         dst = 1;
9132       else if (unformat (i, "sport"))
9133         sport = 1;
9134       else if (unformat (i, "dport"))
9135         dport = 1;
9136       else if (unformat (i, "proto"))
9137         proto = 1;
9138       else if (unformat (i, "reverse"))
9139         reverse = 1;
9140
9141       else
9142         {
9143           clib_warning ("parse error '%U'", format_unformat_error, i);
9144           return -99;
9145         }
9146     }
9147
9148   if (vrf_id_set == 0)
9149     {
9150       errmsg ("missing vrf id");
9151       return -99;
9152     }
9153
9154   M (SET_IP_FLOW_HASH, mp);
9155   mp->src = src;
9156   mp->dst = dst;
9157   mp->sport = sport;
9158   mp->dport = dport;
9159   mp->proto = proto;
9160   mp->reverse = reverse;
9161   mp->vrf_id = ntohl (vrf_id);
9162   mp->is_ipv6 = is_ipv6;
9163
9164   S (mp);
9165   W (ret);
9166   return ret;
9167 }
9168
9169 static int
9170 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9171 {
9172   unformat_input_t *i = vam->input;
9173   vl_api_sw_interface_ip6_enable_disable_t *mp;
9174   u32 sw_if_index;
9175   u8 sw_if_index_set = 0;
9176   u8 enable = 0;
9177   int ret;
9178
9179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9180     {
9181       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9182         sw_if_index_set = 1;
9183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9184         sw_if_index_set = 1;
9185       else if (unformat (i, "enable"))
9186         enable = 1;
9187       else if (unformat (i, "disable"))
9188         enable = 0;
9189       else
9190         {
9191           clib_warning ("parse error '%U'", format_unformat_error, i);
9192           return -99;
9193         }
9194     }
9195
9196   if (sw_if_index_set == 0)
9197     {
9198       errmsg ("missing interface name or sw_if_index");
9199       return -99;
9200     }
9201
9202   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9203
9204   mp->sw_if_index = ntohl (sw_if_index);
9205   mp->enable = enable;
9206
9207   S (mp);
9208   W (ret);
9209   return ret;
9210 }
9211
9212 static int
9213 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9214 {
9215   unformat_input_t *i = vam->input;
9216   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9217   u32 sw_if_index;
9218   u8 sw_if_index_set = 0;
9219   u8 v6_address_set = 0;
9220   ip6_address_t v6address;
9221   int ret;
9222
9223   /* Parse args required to build the message */
9224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9225     {
9226       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9227         sw_if_index_set = 1;
9228       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9229         sw_if_index_set = 1;
9230       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9231         v6_address_set = 1;
9232       else
9233         break;
9234     }
9235
9236   if (sw_if_index_set == 0)
9237     {
9238       errmsg ("missing interface name or sw_if_index");
9239       return -99;
9240     }
9241   if (!v6_address_set)
9242     {
9243       errmsg ("no address set");
9244       return -99;
9245     }
9246
9247   /* Construct the API message */
9248   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9249
9250   mp->sw_if_index = ntohl (sw_if_index);
9251   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9252
9253   /* send it... */
9254   S (mp);
9255
9256   /* Wait for a reply, return good/bad news  */
9257   W (ret);
9258   return ret;
9259 }
9260
9261 static int
9262 api_ip6nd_proxy_add_del (vat_main_t * vam)
9263 {
9264   unformat_input_t *i = vam->input;
9265   vl_api_ip6nd_proxy_add_del_t *mp;
9266   u32 sw_if_index = ~0;
9267   u8 v6_address_set = 0;
9268   ip6_address_t v6address;
9269   u8 is_del = 0;
9270   int ret;
9271
9272   /* Parse args required to build the message */
9273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9274     {
9275       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9276         ;
9277       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9278         ;
9279       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9280         v6_address_set = 1;
9281       if (unformat (i, "del"))
9282         is_del = 1;
9283       else
9284         {
9285           clib_warning ("parse error '%U'", format_unformat_error, i);
9286           return -99;
9287         }
9288     }
9289
9290   if (sw_if_index == ~0)
9291     {
9292       errmsg ("missing interface name or sw_if_index");
9293       return -99;
9294     }
9295   if (!v6_address_set)
9296     {
9297       errmsg ("no address set");
9298       return -99;
9299     }
9300
9301   /* Construct the API message */
9302   M (IP6ND_PROXY_ADD_DEL, mp);
9303
9304   mp->is_del = is_del;
9305   mp->sw_if_index = ntohl (sw_if_index);
9306   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9307
9308   /* send it... */
9309   S (mp);
9310
9311   /* Wait for a reply, return good/bad news  */
9312   W (ret);
9313   return ret;
9314 }
9315
9316 static int
9317 api_ip6nd_proxy_dump (vat_main_t * vam)
9318 {
9319   vl_api_ip6nd_proxy_dump_t *mp;
9320   vl_api_control_ping_t *mp_ping;
9321   int ret;
9322
9323   M (IP6ND_PROXY_DUMP, mp);
9324
9325   S (mp);
9326
9327   /* Use a control ping for synchronization */
9328   MPING (CONTROL_PING, mp_ping);
9329   S (mp_ping);
9330
9331   W (ret);
9332   return ret;
9333 }
9334
9335 static void vl_api_ip6nd_proxy_details_t_handler
9336   (vl_api_ip6nd_proxy_details_t * mp)
9337 {
9338   vat_main_t *vam = &vat_main;
9339
9340   print (vam->ofp, "host %U sw_if_index %d",
9341          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9342 }
9343
9344 static void vl_api_ip6nd_proxy_details_t_handler_json
9345   (vl_api_ip6nd_proxy_details_t * mp)
9346 {
9347   vat_main_t *vam = &vat_main;
9348   struct in6_addr ip6;
9349   vat_json_node_t *node = NULL;
9350
9351   if (VAT_JSON_ARRAY != vam->json_tree.type)
9352     {
9353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9354       vat_json_init_array (&vam->json_tree);
9355     }
9356   node = vat_json_array_add (&vam->json_tree);
9357
9358   vat_json_init_object (node);
9359   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9360
9361   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9362   vat_json_object_add_ip6 (node, "host", ip6);
9363 }
9364
9365 static int
9366 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9367 {
9368   unformat_input_t *i = vam->input;
9369   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9370   u32 sw_if_index;
9371   u8 sw_if_index_set = 0;
9372   u32 address_length = 0;
9373   u8 v6_address_set = 0;
9374   ip6_address_t v6address;
9375   u8 use_default = 0;
9376   u8 no_advertise = 0;
9377   u8 off_link = 0;
9378   u8 no_autoconfig = 0;
9379   u8 no_onlink = 0;
9380   u8 is_no = 0;
9381   u32 val_lifetime = 0;
9382   u32 pref_lifetime = 0;
9383   int ret;
9384
9385   /* Parse args required to build the message */
9386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9387     {
9388       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9389         sw_if_index_set = 1;
9390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9391         sw_if_index_set = 1;
9392       else if (unformat (i, "%U/%d",
9393                          unformat_ip6_address, &v6address, &address_length))
9394         v6_address_set = 1;
9395       else if (unformat (i, "val_life %d", &val_lifetime))
9396         ;
9397       else if (unformat (i, "pref_life %d", &pref_lifetime))
9398         ;
9399       else if (unformat (i, "def"))
9400         use_default = 1;
9401       else if (unformat (i, "noadv"))
9402         no_advertise = 1;
9403       else if (unformat (i, "offl"))
9404         off_link = 1;
9405       else if (unformat (i, "noauto"))
9406         no_autoconfig = 1;
9407       else if (unformat (i, "nolink"))
9408         no_onlink = 1;
9409       else if (unformat (i, "isno"))
9410         is_no = 1;
9411       else
9412         {
9413           clib_warning ("parse error '%U'", format_unformat_error, i);
9414           return -99;
9415         }
9416     }
9417
9418   if (sw_if_index_set == 0)
9419     {
9420       errmsg ("missing interface name or sw_if_index");
9421       return -99;
9422     }
9423   if (!v6_address_set)
9424     {
9425       errmsg ("no address set");
9426       return -99;
9427     }
9428
9429   /* Construct the API message */
9430   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9431
9432   mp->sw_if_index = ntohl (sw_if_index);
9433   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9434   mp->address_length = address_length;
9435   mp->use_default = use_default;
9436   mp->no_advertise = no_advertise;
9437   mp->off_link = off_link;
9438   mp->no_autoconfig = no_autoconfig;
9439   mp->no_onlink = no_onlink;
9440   mp->is_no = is_no;
9441   mp->val_lifetime = ntohl (val_lifetime);
9442   mp->pref_lifetime = ntohl (pref_lifetime);
9443
9444   /* send it... */
9445   S (mp);
9446
9447   /* Wait for a reply, return good/bad news  */
9448   W (ret);
9449   return ret;
9450 }
9451
9452 static int
9453 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9454 {
9455   unformat_input_t *i = vam->input;
9456   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9457   u32 sw_if_index;
9458   u8 sw_if_index_set = 0;
9459   u8 suppress = 0;
9460   u8 managed = 0;
9461   u8 other = 0;
9462   u8 ll_option = 0;
9463   u8 send_unicast = 0;
9464   u8 cease = 0;
9465   u8 is_no = 0;
9466   u8 default_router = 0;
9467   u32 max_interval = 0;
9468   u32 min_interval = 0;
9469   u32 lifetime = 0;
9470   u32 initial_count = 0;
9471   u32 initial_interval = 0;
9472   int ret;
9473
9474
9475   /* Parse args required to build the message */
9476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9477     {
9478       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9479         sw_if_index_set = 1;
9480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9481         sw_if_index_set = 1;
9482       else if (unformat (i, "maxint %d", &max_interval))
9483         ;
9484       else if (unformat (i, "minint %d", &min_interval))
9485         ;
9486       else if (unformat (i, "life %d", &lifetime))
9487         ;
9488       else if (unformat (i, "count %d", &initial_count))
9489         ;
9490       else if (unformat (i, "interval %d", &initial_interval))
9491         ;
9492       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9493         suppress = 1;
9494       else if (unformat (i, "managed"))
9495         managed = 1;
9496       else if (unformat (i, "other"))
9497         other = 1;
9498       else if (unformat (i, "ll"))
9499         ll_option = 1;
9500       else if (unformat (i, "send"))
9501         send_unicast = 1;
9502       else if (unformat (i, "cease"))
9503         cease = 1;
9504       else if (unformat (i, "isno"))
9505         is_no = 1;
9506       else if (unformat (i, "def"))
9507         default_router = 1;
9508       else
9509         {
9510           clib_warning ("parse error '%U'", format_unformat_error, i);
9511           return -99;
9512         }
9513     }
9514
9515   if (sw_if_index_set == 0)
9516     {
9517       errmsg ("missing interface name or sw_if_index");
9518       return -99;
9519     }
9520
9521   /* Construct the API message */
9522   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9523
9524   mp->sw_if_index = ntohl (sw_if_index);
9525   mp->max_interval = ntohl (max_interval);
9526   mp->min_interval = ntohl (min_interval);
9527   mp->lifetime = ntohl (lifetime);
9528   mp->initial_count = ntohl (initial_count);
9529   mp->initial_interval = ntohl (initial_interval);
9530   mp->suppress = suppress;
9531   mp->managed = managed;
9532   mp->other = other;
9533   mp->ll_option = ll_option;
9534   mp->send_unicast = send_unicast;
9535   mp->cease = cease;
9536   mp->is_no = is_no;
9537   mp->default_router = default_router;
9538
9539   /* send it... */
9540   S (mp);
9541
9542   /* Wait for a reply, return good/bad news  */
9543   W (ret);
9544   return ret;
9545 }
9546
9547 static int
9548 api_set_arp_neighbor_limit (vat_main_t * vam)
9549 {
9550   unformat_input_t *i = vam->input;
9551   vl_api_set_arp_neighbor_limit_t *mp;
9552   u32 arp_nbr_limit;
9553   u8 limit_set = 0;
9554   u8 is_ipv6 = 0;
9555   int ret;
9556
9557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9558     {
9559       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9560         limit_set = 1;
9561       else if (unformat (i, "ipv6"))
9562         is_ipv6 = 1;
9563       else
9564         {
9565           clib_warning ("parse error '%U'", format_unformat_error, i);
9566           return -99;
9567         }
9568     }
9569
9570   if (limit_set == 0)
9571     {
9572       errmsg ("missing limit value");
9573       return -99;
9574     }
9575
9576   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9577
9578   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9579   mp->is_ipv6 = is_ipv6;
9580
9581   S (mp);
9582   W (ret);
9583   return ret;
9584 }
9585
9586 static int
9587 api_l2_patch_add_del (vat_main_t * vam)
9588 {
9589   unformat_input_t *i = vam->input;
9590   vl_api_l2_patch_add_del_t *mp;
9591   u32 rx_sw_if_index;
9592   u8 rx_sw_if_index_set = 0;
9593   u32 tx_sw_if_index;
9594   u8 tx_sw_if_index_set = 0;
9595   u8 is_add = 1;
9596   int ret;
9597
9598   /* Parse args required to build the message */
9599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9600     {
9601       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9602         rx_sw_if_index_set = 1;
9603       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9604         tx_sw_if_index_set = 1;
9605       else if (unformat (i, "rx"))
9606         {
9607           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9608             {
9609               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9610                             &rx_sw_if_index))
9611                 rx_sw_if_index_set = 1;
9612             }
9613           else
9614             break;
9615         }
9616       else if (unformat (i, "tx"))
9617         {
9618           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9619             {
9620               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9621                             &tx_sw_if_index))
9622                 tx_sw_if_index_set = 1;
9623             }
9624           else
9625             break;
9626         }
9627       else if (unformat (i, "del"))
9628         is_add = 0;
9629       else
9630         break;
9631     }
9632
9633   if (rx_sw_if_index_set == 0)
9634     {
9635       errmsg ("missing rx interface name or rx_sw_if_index");
9636       return -99;
9637     }
9638
9639   if (tx_sw_if_index_set == 0)
9640     {
9641       errmsg ("missing tx interface name or tx_sw_if_index");
9642       return -99;
9643     }
9644
9645   M (L2_PATCH_ADD_DEL, mp);
9646
9647   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9648   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9649   mp->is_add = is_add;
9650
9651   S (mp);
9652   W (ret);
9653   return ret;
9654 }
9655
9656 u8 is_del;
9657 u8 localsid_addr[16];
9658 u8 end_psp;
9659 u8 behavior;
9660 u32 sw_if_index;
9661 u32 vlan_index;
9662 u32 fib_table;
9663 u8 nh_addr[16];
9664
9665 static int
9666 api_sr_localsid_add_del (vat_main_t * vam)
9667 {
9668   unformat_input_t *i = vam->input;
9669   vl_api_sr_localsid_add_del_t *mp;
9670
9671   u8 is_del;
9672   ip6_address_t localsid;
9673   u8 end_psp = 0;
9674   u8 behavior = ~0;
9675   u32 sw_if_index;
9676   u32 fib_table = ~(u32) 0;
9677   ip6_address_t next_hop;
9678
9679   bool nexthop_set = 0;
9680
9681   int ret;
9682
9683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9684     {
9685       if (unformat (i, "del"))
9686         is_del = 1;
9687       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9688       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9689         nexthop_set = 1;
9690       else if (unformat (i, "behavior %u", &behavior));
9691       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9692       else if (unformat (i, "fib-table %u", &fib_table));
9693       else if (unformat (i, "end.psp %u", &behavior));
9694       else
9695         break;
9696     }
9697
9698   M (SR_LOCALSID_ADD_DEL, mp);
9699
9700   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9701   if (nexthop_set)
9702     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9703   mp->behavior = behavior;
9704   mp->sw_if_index = ntohl (sw_if_index);
9705   mp->fib_table = ntohl (fib_table);
9706   mp->end_psp = end_psp;
9707   mp->is_del = is_del;
9708
9709   S (mp);
9710   W (ret);
9711   return ret;
9712 }
9713
9714 static int
9715 api_ioam_enable (vat_main_t * vam)
9716 {
9717   unformat_input_t *input = vam->input;
9718   vl_api_ioam_enable_t *mp;
9719   u32 id = 0;
9720   int has_trace_option = 0;
9721   int has_pot_option = 0;
9722   int has_seqno_option = 0;
9723   int has_analyse_option = 0;
9724   int ret;
9725
9726   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9727     {
9728       if (unformat (input, "trace"))
9729         has_trace_option = 1;
9730       else if (unformat (input, "pot"))
9731         has_pot_option = 1;
9732       else if (unformat (input, "seqno"))
9733         has_seqno_option = 1;
9734       else if (unformat (input, "analyse"))
9735         has_analyse_option = 1;
9736       else
9737         break;
9738     }
9739   M (IOAM_ENABLE, mp);
9740   mp->id = htons (id);
9741   mp->seqno = has_seqno_option;
9742   mp->analyse = has_analyse_option;
9743   mp->pot_enable = has_pot_option;
9744   mp->trace_enable = has_trace_option;
9745
9746   S (mp);
9747   W (ret);
9748   return ret;
9749 }
9750
9751
9752 static int
9753 api_ioam_disable (vat_main_t * vam)
9754 {
9755   vl_api_ioam_disable_t *mp;
9756   int ret;
9757
9758   M (IOAM_DISABLE, mp);
9759   S (mp);
9760   W (ret);
9761   return ret;
9762 }
9763
9764 #define foreach_tcp_proto_field                 \
9765 _(src_port)                                     \
9766 _(dst_port)
9767
9768 #define foreach_udp_proto_field                 \
9769 _(src_port)                                     \
9770 _(dst_port)
9771
9772 #define foreach_ip4_proto_field                 \
9773 _(src_address)                                  \
9774 _(dst_address)                                  \
9775 _(tos)                                          \
9776 _(length)                                       \
9777 _(fragment_id)                                  \
9778 _(ttl)                                          \
9779 _(protocol)                                     \
9780 _(checksum)
9781
9782 typedef struct
9783 {
9784   u16 src_port, dst_port;
9785 } tcpudp_header_t;
9786
9787 #if VPP_API_TEST_BUILTIN == 0
9788 uword
9789 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9790 {
9791   u8 **maskp = va_arg (*args, u8 **);
9792   u8 *mask = 0;
9793   u8 found_something = 0;
9794   tcp_header_t *tcp;
9795
9796 #define _(a) u8 a=0;
9797   foreach_tcp_proto_field;
9798 #undef _
9799
9800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9801     {
9802       if (0);
9803 #define _(a) else if (unformat (input, #a)) a=1;
9804       foreach_tcp_proto_field
9805 #undef _
9806         else
9807         break;
9808     }
9809
9810 #define _(a) found_something += a;
9811   foreach_tcp_proto_field;
9812 #undef _
9813
9814   if (found_something == 0)
9815     return 0;
9816
9817   vec_validate (mask, sizeof (*tcp) - 1);
9818
9819   tcp = (tcp_header_t *) mask;
9820
9821 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9822   foreach_tcp_proto_field;
9823 #undef _
9824
9825   *maskp = mask;
9826   return 1;
9827 }
9828
9829 uword
9830 unformat_udp_mask (unformat_input_t * input, va_list * args)
9831 {
9832   u8 **maskp = va_arg (*args, u8 **);
9833   u8 *mask = 0;
9834   u8 found_something = 0;
9835   udp_header_t *udp;
9836
9837 #define _(a) u8 a=0;
9838   foreach_udp_proto_field;
9839 #undef _
9840
9841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9842     {
9843       if (0);
9844 #define _(a) else if (unformat (input, #a)) a=1;
9845       foreach_udp_proto_field
9846 #undef _
9847         else
9848         break;
9849     }
9850
9851 #define _(a) found_something += a;
9852   foreach_udp_proto_field;
9853 #undef _
9854
9855   if (found_something == 0)
9856     return 0;
9857
9858   vec_validate (mask, sizeof (*udp) - 1);
9859
9860   udp = (udp_header_t *) mask;
9861
9862 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9863   foreach_udp_proto_field;
9864 #undef _
9865
9866   *maskp = mask;
9867   return 1;
9868 }
9869
9870 uword
9871 unformat_l4_mask (unformat_input_t * input, va_list * args)
9872 {
9873   u8 **maskp = va_arg (*args, u8 **);
9874   u16 src_port = 0, dst_port = 0;
9875   tcpudp_header_t *tcpudp;
9876
9877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9878     {
9879       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9880         return 1;
9881       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9882         return 1;
9883       else if (unformat (input, "src_port"))
9884         src_port = 0xFFFF;
9885       else if (unformat (input, "dst_port"))
9886         dst_port = 0xFFFF;
9887       else
9888         return 0;
9889     }
9890
9891   if (!src_port && !dst_port)
9892     return 0;
9893
9894   u8 *mask = 0;
9895   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9896
9897   tcpudp = (tcpudp_header_t *) mask;
9898   tcpudp->src_port = src_port;
9899   tcpudp->dst_port = dst_port;
9900
9901   *maskp = mask;
9902
9903   return 1;
9904 }
9905
9906 uword
9907 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9908 {
9909   u8 **maskp = va_arg (*args, u8 **);
9910   u8 *mask = 0;
9911   u8 found_something = 0;
9912   ip4_header_t *ip;
9913
9914 #define _(a) u8 a=0;
9915   foreach_ip4_proto_field;
9916 #undef _
9917   u8 version = 0;
9918   u8 hdr_length = 0;
9919
9920
9921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9922     {
9923       if (unformat (input, "version"))
9924         version = 1;
9925       else if (unformat (input, "hdr_length"))
9926         hdr_length = 1;
9927       else if (unformat (input, "src"))
9928         src_address = 1;
9929       else if (unformat (input, "dst"))
9930         dst_address = 1;
9931       else if (unformat (input, "proto"))
9932         protocol = 1;
9933
9934 #define _(a) else if (unformat (input, #a)) a=1;
9935       foreach_ip4_proto_field
9936 #undef _
9937         else
9938         break;
9939     }
9940
9941 #define _(a) found_something += a;
9942   foreach_ip4_proto_field;
9943 #undef _
9944
9945   if (found_something == 0)
9946     return 0;
9947
9948   vec_validate (mask, sizeof (*ip) - 1);
9949
9950   ip = (ip4_header_t *) mask;
9951
9952 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9953   foreach_ip4_proto_field;
9954 #undef _
9955
9956   ip->ip_version_and_header_length = 0;
9957
9958   if (version)
9959     ip->ip_version_and_header_length |= 0xF0;
9960
9961   if (hdr_length)
9962     ip->ip_version_and_header_length |= 0x0F;
9963
9964   *maskp = mask;
9965   return 1;
9966 }
9967
9968 #define foreach_ip6_proto_field                 \
9969 _(src_address)                                  \
9970 _(dst_address)                                  \
9971 _(payload_length)                               \
9972 _(hop_limit)                                    \
9973 _(protocol)
9974
9975 uword
9976 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9977 {
9978   u8 **maskp = va_arg (*args, u8 **);
9979   u8 *mask = 0;
9980   u8 found_something = 0;
9981   ip6_header_t *ip;
9982   u32 ip_version_traffic_class_and_flow_label;
9983
9984 #define _(a) u8 a=0;
9985   foreach_ip6_proto_field;
9986 #undef _
9987   u8 version = 0;
9988   u8 traffic_class = 0;
9989   u8 flow_label = 0;
9990
9991   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9992     {
9993       if (unformat (input, "version"))
9994         version = 1;
9995       else if (unformat (input, "traffic-class"))
9996         traffic_class = 1;
9997       else if (unformat (input, "flow-label"))
9998         flow_label = 1;
9999       else if (unformat (input, "src"))
10000         src_address = 1;
10001       else if (unformat (input, "dst"))
10002         dst_address = 1;
10003       else if (unformat (input, "proto"))
10004         protocol = 1;
10005
10006 #define _(a) else if (unformat (input, #a)) a=1;
10007       foreach_ip6_proto_field
10008 #undef _
10009         else
10010         break;
10011     }
10012
10013 #define _(a) found_something += a;
10014   foreach_ip6_proto_field;
10015 #undef _
10016
10017   if (found_something == 0)
10018     return 0;
10019
10020   vec_validate (mask, sizeof (*ip) - 1);
10021
10022   ip = (ip6_header_t *) mask;
10023
10024 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10025   foreach_ip6_proto_field;
10026 #undef _
10027
10028   ip_version_traffic_class_and_flow_label = 0;
10029
10030   if (version)
10031     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10032
10033   if (traffic_class)
10034     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10035
10036   if (flow_label)
10037     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10038
10039   ip->ip_version_traffic_class_and_flow_label =
10040     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10041
10042   *maskp = mask;
10043   return 1;
10044 }
10045
10046 uword
10047 unformat_l3_mask (unformat_input_t * input, va_list * args)
10048 {
10049   u8 **maskp = va_arg (*args, u8 **);
10050
10051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10052     {
10053       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10054         return 1;
10055       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10056         return 1;
10057       else
10058         break;
10059     }
10060   return 0;
10061 }
10062
10063 uword
10064 unformat_l2_mask (unformat_input_t * input, va_list * args)
10065 {
10066   u8 **maskp = va_arg (*args, u8 **);
10067   u8 *mask = 0;
10068   u8 src = 0;
10069   u8 dst = 0;
10070   u8 proto = 0;
10071   u8 tag1 = 0;
10072   u8 tag2 = 0;
10073   u8 ignore_tag1 = 0;
10074   u8 ignore_tag2 = 0;
10075   u8 cos1 = 0;
10076   u8 cos2 = 0;
10077   u8 dot1q = 0;
10078   u8 dot1ad = 0;
10079   int len = 14;
10080
10081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10082     {
10083       if (unformat (input, "src"))
10084         src = 1;
10085       else if (unformat (input, "dst"))
10086         dst = 1;
10087       else if (unformat (input, "proto"))
10088         proto = 1;
10089       else if (unformat (input, "tag1"))
10090         tag1 = 1;
10091       else if (unformat (input, "tag2"))
10092         tag2 = 1;
10093       else if (unformat (input, "ignore-tag1"))
10094         ignore_tag1 = 1;
10095       else if (unformat (input, "ignore-tag2"))
10096         ignore_tag2 = 1;
10097       else if (unformat (input, "cos1"))
10098         cos1 = 1;
10099       else if (unformat (input, "cos2"))
10100         cos2 = 1;
10101       else if (unformat (input, "dot1q"))
10102         dot1q = 1;
10103       else if (unformat (input, "dot1ad"))
10104         dot1ad = 1;
10105       else
10106         break;
10107     }
10108   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10109        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10110     return 0;
10111
10112   if (tag1 || ignore_tag1 || cos1 || dot1q)
10113     len = 18;
10114   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10115     len = 22;
10116
10117   vec_validate (mask, len - 1);
10118
10119   if (dst)
10120     memset (mask, 0xff, 6);
10121
10122   if (src)
10123     memset (mask + 6, 0xff, 6);
10124
10125   if (tag2 || dot1ad)
10126     {
10127       /* inner vlan tag */
10128       if (tag2)
10129         {
10130           mask[19] = 0xff;
10131           mask[18] = 0x0f;
10132         }
10133       if (cos2)
10134         mask[18] |= 0xe0;
10135       if (proto)
10136         mask[21] = mask[20] = 0xff;
10137       if (tag1)
10138         {
10139           mask[15] = 0xff;
10140           mask[14] = 0x0f;
10141         }
10142       if (cos1)
10143         mask[14] |= 0xe0;
10144       *maskp = mask;
10145       return 1;
10146     }
10147   if (tag1 | dot1q)
10148     {
10149       if (tag1)
10150         {
10151           mask[15] = 0xff;
10152           mask[14] = 0x0f;
10153         }
10154       if (cos1)
10155         mask[14] |= 0xe0;
10156       if (proto)
10157         mask[16] = mask[17] = 0xff;
10158
10159       *maskp = mask;
10160       return 1;
10161     }
10162   if (cos2)
10163     mask[18] |= 0xe0;
10164   if (cos1)
10165     mask[14] |= 0xe0;
10166   if (proto)
10167     mask[12] = mask[13] = 0xff;
10168
10169   *maskp = mask;
10170   return 1;
10171 }
10172
10173 uword
10174 unformat_classify_mask (unformat_input_t * input, va_list * args)
10175 {
10176   u8 **maskp = va_arg (*args, u8 **);
10177   u32 *skipp = va_arg (*args, u32 *);
10178   u32 *matchp = va_arg (*args, u32 *);
10179   u32 match;
10180   u8 *mask = 0;
10181   u8 *l2 = 0;
10182   u8 *l3 = 0;
10183   u8 *l4 = 0;
10184   int i;
10185
10186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10187     {
10188       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10189         ;
10190       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10191         ;
10192       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10193         ;
10194       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10195         ;
10196       else
10197         break;
10198     }
10199
10200   if (l4 && !l3)
10201     {
10202       vec_free (mask);
10203       vec_free (l2);
10204       vec_free (l4);
10205       return 0;
10206     }
10207
10208   if (mask || l2 || l3 || l4)
10209     {
10210       if (l2 || l3 || l4)
10211         {
10212           /* "With a free Ethernet header in every package" */
10213           if (l2 == 0)
10214             vec_validate (l2, 13);
10215           mask = l2;
10216           if (vec_len (l3))
10217             {
10218               vec_append (mask, l3);
10219               vec_free (l3);
10220             }
10221           if (vec_len (l4))
10222             {
10223               vec_append (mask, l4);
10224               vec_free (l4);
10225             }
10226         }
10227
10228       /* Scan forward looking for the first significant mask octet */
10229       for (i = 0; i < vec_len (mask); i++)
10230         if (mask[i])
10231           break;
10232
10233       /* compute (skip, match) params */
10234       *skipp = i / sizeof (u32x4);
10235       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10236
10237       /* Pad mask to an even multiple of the vector size */
10238       while (vec_len (mask) % sizeof (u32x4))
10239         vec_add1 (mask, 0);
10240
10241       match = vec_len (mask) / sizeof (u32x4);
10242
10243       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10244         {
10245           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10246           if (*tmp || *(tmp + 1))
10247             break;
10248           match--;
10249         }
10250       if (match == 0)
10251         clib_warning ("BUG: match 0");
10252
10253       _vec_len (mask) = match * sizeof (u32x4);
10254
10255       *matchp = match;
10256       *maskp = mask;
10257
10258       return 1;
10259     }
10260
10261   return 0;
10262 }
10263 #endif /* VPP_API_TEST_BUILTIN */
10264
10265 #define foreach_l2_next                         \
10266 _(drop, DROP)                                   \
10267 _(ethernet, ETHERNET_INPUT)                     \
10268 _(ip4, IP4_INPUT)                               \
10269 _(ip6, IP6_INPUT)
10270
10271 uword
10272 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10273 {
10274   u32 *miss_next_indexp = va_arg (*args, u32 *);
10275   u32 next_index = 0;
10276   u32 tmp;
10277
10278 #define _(n,N) \
10279   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10280   foreach_l2_next;
10281 #undef _
10282
10283   if (unformat (input, "%d", &tmp))
10284     {
10285       next_index = tmp;
10286       goto out;
10287     }
10288
10289   return 0;
10290
10291 out:
10292   *miss_next_indexp = next_index;
10293   return 1;
10294 }
10295
10296 #define foreach_ip_next                         \
10297 _(drop, DROP)                                   \
10298 _(local, LOCAL)                                 \
10299 _(rewrite, REWRITE)
10300
10301 uword
10302 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10303 {
10304   u32 *miss_next_indexp = va_arg (*args, u32 *);
10305   u32 next_index = 0;
10306   u32 tmp;
10307
10308 #define _(n,N) \
10309   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10310   foreach_ip_next;
10311 #undef _
10312
10313   if (unformat (input, "%d", &tmp))
10314     {
10315       next_index = tmp;
10316       goto out;
10317     }
10318
10319   return 0;
10320
10321 out:
10322   *miss_next_indexp = next_index;
10323   return 1;
10324 }
10325
10326 #define foreach_acl_next                        \
10327 _(deny, DENY)
10328
10329 uword
10330 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10331 {
10332   u32 *miss_next_indexp = va_arg (*args, u32 *);
10333   u32 next_index = 0;
10334   u32 tmp;
10335
10336 #define _(n,N) \
10337   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10338   foreach_acl_next;
10339 #undef _
10340
10341   if (unformat (input, "permit"))
10342     {
10343       next_index = ~0;
10344       goto out;
10345     }
10346   else if (unformat (input, "%d", &tmp))
10347     {
10348       next_index = tmp;
10349       goto out;
10350     }
10351
10352   return 0;
10353
10354 out:
10355   *miss_next_indexp = next_index;
10356   return 1;
10357 }
10358
10359 uword
10360 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10361 {
10362   u32 *r = va_arg (*args, u32 *);
10363
10364   if (unformat (input, "conform-color"))
10365     *r = POLICE_CONFORM;
10366   else if (unformat (input, "exceed-color"))
10367     *r = POLICE_EXCEED;
10368   else
10369     return 0;
10370
10371   return 1;
10372 }
10373
10374 static int
10375 api_classify_add_del_table (vat_main_t * vam)
10376 {
10377   unformat_input_t *i = vam->input;
10378   vl_api_classify_add_del_table_t *mp;
10379
10380   u32 nbuckets = 2;
10381   u32 skip = ~0;
10382   u32 match = ~0;
10383   int is_add = 1;
10384   int del_chain = 0;
10385   u32 table_index = ~0;
10386   u32 next_table_index = ~0;
10387   u32 miss_next_index = ~0;
10388   u32 memory_size = 32 << 20;
10389   u8 *mask = 0;
10390   u32 current_data_flag = 0;
10391   int current_data_offset = 0;
10392   int ret;
10393
10394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10395     {
10396       if (unformat (i, "del"))
10397         is_add = 0;
10398       else if (unformat (i, "del-chain"))
10399         {
10400           is_add = 0;
10401           del_chain = 1;
10402         }
10403       else if (unformat (i, "buckets %d", &nbuckets))
10404         ;
10405       else if (unformat (i, "memory_size %d", &memory_size))
10406         ;
10407       else if (unformat (i, "skip %d", &skip))
10408         ;
10409       else if (unformat (i, "match %d", &match))
10410         ;
10411       else if (unformat (i, "table %d", &table_index))
10412         ;
10413       else if (unformat (i, "mask %U", unformat_classify_mask,
10414                          &mask, &skip, &match))
10415         ;
10416       else if (unformat (i, "next-table %d", &next_table_index))
10417         ;
10418       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10419                          &miss_next_index))
10420         ;
10421       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10422                          &miss_next_index))
10423         ;
10424       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10425                          &miss_next_index))
10426         ;
10427       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10428         ;
10429       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10430         ;
10431       else
10432         break;
10433     }
10434
10435   if (is_add && mask == 0)
10436     {
10437       errmsg ("Mask required");
10438       return -99;
10439     }
10440
10441   if (is_add && skip == ~0)
10442     {
10443       errmsg ("skip count required");
10444       return -99;
10445     }
10446
10447   if (is_add && match == ~0)
10448     {
10449       errmsg ("match count required");
10450       return -99;
10451     }
10452
10453   if (!is_add && table_index == ~0)
10454     {
10455       errmsg ("table index required for delete");
10456       return -99;
10457     }
10458
10459   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10460
10461   mp->is_add = is_add;
10462   mp->del_chain = del_chain;
10463   mp->table_index = ntohl (table_index);
10464   mp->nbuckets = ntohl (nbuckets);
10465   mp->memory_size = ntohl (memory_size);
10466   mp->skip_n_vectors = ntohl (skip);
10467   mp->match_n_vectors = ntohl (match);
10468   mp->next_table_index = ntohl (next_table_index);
10469   mp->miss_next_index = ntohl (miss_next_index);
10470   mp->current_data_flag = ntohl (current_data_flag);
10471   mp->current_data_offset = ntohl (current_data_offset);
10472   clib_memcpy (mp->mask, mask, vec_len (mask));
10473
10474   vec_free (mask);
10475
10476   S (mp);
10477   W (ret);
10478   return ret;
10479 }
10480
10481 #if VPP_API_TEST_BUILTIN == 0
10482 uword
10483 unformat_l4_match (unformat_input_t * input, va_list * args)
10484 {
10485   u8 **matchp = va_arg (*args, u8 **);
10486
10487   u8 *proto_header = 0;
10488   int src_port = 0;
10489   int dst_port = 0;
10490
10491   tcpudp_header_t h;
10492
10493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10494     {
10495       if (unformat (input, "src_port %d", &src_port))
10496         ;
10497       else if (unformat (input, "dst_port %d", &dst_port))
10498         ;
10499       else
10500         return 0;
10501     }
10502
10503   h.src_port = clib_host_to_net_u16 (src_port);
10504   h.dst_port = clib_host_to_net_u16 (dst_port);
10505   vec_validate (proto_header, sizeof (h) - 1);
10506   memcpy (proto_header, &h, sizeof (h));
10507
10508   *matchp = proto_header;
10509
10510   return 1;
10511 }
10512
10513 uword
10514 unformat_ip4_match (unformat_input_t * input, va_list * args)
10515 {
10516   u8 **matchp = va_arg (*args, u8 **);
10517   u8 *match = 0;
10518   ip4_header_t *ip;
10519   int version = 0;
10520   u32 version_val;
10521   int hdr_length = 0;
10522   u32 hdr_length_val;
10523   int src = 0, dst = 0;
10524   ip4_address_t src_val, dst_val;
10525   int proto = 0;
10526   u32 proto_val;
10527   int tos = 0;
10528   u32 tos_val;
10529   int length = 0;
10530   u32 length_val;
10531   int fragment_id = 0;
10532   u32 fragment_id_val;
10533   int ttl = 0;
10534   int ttl_val;
10535   int checksum = 0;
10536   u32 checksum_val;
10537
10538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10539     {
10540       if (unformat (input, "version %d", &version_val))
10541         version = 1;
10542       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10543         hdr_length = 1;
10544       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10545         src = 1;
10546       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10547         dst = 1;
10548       else if (unformat (input, "proto %d", &proto_val))
10549         proto = 1;
10550       else if (unformat (input, "tos %d", &tos_val))
10551         tos = 1;
10552       else if (unformat (input, "length %d", &length_val))
10553         length = 1;
10554       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10555         fragment_id = 1;
10556       else if (unformat (input, "ttl %d", &ttl_val))
10557         ttl = 1;
10558       else if (unformat (input, "checksum %d", &checksum_val))
10559         checksum = 1;
10560       else
10561         break;
10562     }
10563
10564   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10565       + ttl + checksum == 0)
10566     return 0;
10567
10568   /*
10569    * Aligned because we use the real comparison functions
10570    */
10571   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10572
10573   ip = (ip4_header_t *) match;
10574
10575   /* These are realistically matched in practice */
10576   if (src)
10577     ip->src_address.as_u32 = src_val.as_u32;
10578
10579   if (dst)
10580     ip->dst_address.as_u32 = dst_val.as_u32;
10581
10582   if (proto)
10583     ip->protocol = proto_val;
10584
10585
10586   /* These are not, but they're included for completeness */
10587   if (version)
10588     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10589
10590   if (hdr_length)
10591     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10592
10593   if (tos)
10594     ip->tos = tos_val;
10595
10596   if (length)
10597     ip->length = clib_host_to_net_u16 (length_val);
10598
10599   if (ttl)
10600     ip->ttl = ttl_val;
10601
10602   if (checksum)
10603     ip->checksum = clib_host_to_net_u16 (checksum_val);
10604
10605   *matchp = match;
10606   return 1;
10607 }
10608
10609 uword
10610 unformat_ip6_match (unformat_input_t * input, va_list * args)
10611 {
10612   u8 **matchp = va_arg (*args, u8 **);
10613   u8 *match = 0;
10614   ip6_header_t *ip;
10615   int version = 0;
10616   u32 version_val;
10617   u8 traffic_class = 0;
10618   u32 traffic_class_val = 0;
10619   u8 flow_label = 0;
10620   u8 flow_label_val;
10621   int src = 0, dst = 0;
10622   ip6_address_t src_val, dst_val;
10623   int proto = 0;
10624   u32 proto_val;
10625   int payload_length = 0;
10626   u32 payload_length_val;
10627   int hop_limit = 0;
10628   int hop_limit_val;
10629   u32 ip_version_traffic_class_and_flow_label;
10630
10631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10632     {
10633       if (unformat (input, "version %d", &version_val))
10634         version = 1;
10635       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10636         traffic_class = 1;
10637       else if (unformat (input, "flow_label %d", &flow_label_val))
10638         flow_label = 1;
10639       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10640         src = 1;
10641       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10642         dst = 1;
10643       else if (unformat (input, "proto %d", &proto_val))
10644         proto = 1;
10645       else if (unformat (input, "payload_length %d", &payload_length_val))
10646         payload_length = 1;
10647       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10648         hop_limit = 1;
10649       else
10650         break;
10651     }
10652
10653   if (version + traffic_class + flow_label + src + dst + proto +
10654       payload_length + hop_limit == 0)
10655     return 0;
10656
10657   /*
10658    * Aligned because we use the real comparison functions
10659    */
10660   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10661
10662   ip = (ip6_header_t *) match;
10663
10664   if (src)
10665     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10666
10667   if (dst)
10668     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10669
10670   if (proto)
10671     ip->protocol = proto_val;
10672
10673   ip_version_traffic_class_and_flow_label = 0;
10674
10675   if (version)
10676     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10677
10678   if (traffic_class)
10679     ip_version_traffic_class_and_flow_label |=
10680       (traffic_class_val & 0xFF) << 20;
10681
10682   if (flow_label)
10683     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10684
10685   ip->ip_version_traffic_class_and_flow_label =
10686     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10687
10688   if (payload_length)
10689     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10690
10691   if (hop_limit)
10692     ip->hop_limit = hop_limit_val;
10693
10694   *matchp = match;
10695   return 1;
10696 }
10697
10698 uword
10699 unformat_l3_match (unformat_input_t * input, va_list * args)
10700 {
10701   u8 **matchp = va_arg (*args, u8 **);
10702
10703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10704     {
10705       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10706         return 1;
10707       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10708         return 1;
10709       else
10710         break;
10711     }
10712   return 0;
10713 }
10714
10715 uword
10716 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10717 {
10718   u8 *tagp = va_arg (*args, u8 *);
10719   u32 tag;
10720
10721   if (unformat (input, "%d", &tag))
10722     {
10723       tagp[0] = (tag >> 8) & 0x0F;
10724       tagp[1] = tag & 0xFF;
10725       return 1;
10726     }
10727
10728   return 0;
10729 }
10730
10731 uword
10732 unformat_l2_match (unformat_input_t * input, va_list * args)
10733 {
10734   u8 **matchp = va_arg (*args, u8 **);
10735   u8 *match = 0;
10736   u8 src = 0;
10737   u8 src_val[6];
10738   u8 dst = 0;
10739   u8 dst_val[6];
10740   u8 proto = 0;
10741   u16 proto_val;
10742   u8 tag1 = 0;
10743   u8 tag1_val[2];
10744   u8 tag2 = 0;
10745   u8 tag2_val[2];
10746   int len = 14;
10747   u8 ignore_tag1 = 0;
10748   u8 ignore_tag2 = 0;
10749   u8 cos1 = 0;
10750   u8 cos2 = 0;
10751   u32 cos1_val = 0;
10752   u32 cos2_val = 0;
10753
10754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10755     {
10756       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10757         src = 1;
10758       else
10759         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10760         dst = 1;
10761       else if (unformat (input, "proto %U",
10762                          unformat_ethernet_type_host_byte_order, &proto_val))
10763         proto = 1;
10764       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10765         tag1 = 1;
10766       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10767         tag2 = 1;
10768       else if (unformat (input, "ignore-tag1"))
10769         ignore_tag1 = 1;
10770       else if (unformat (input, "ignore-tag2"))
10771         ignore_tag2 = 1;
10772       else if (unformat (input, "cos1 %d", &cos1_val))
10773         cos1 = 1;
10774       else if (unformat (input, "cos2 %d", &cos2_val))
10775         cos2 = 1;
10776       else
10777         break;
10778     }
10779   if ((src + dst + proto + tag1 + tag2 +
10780        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10781     return 0;
10782
10783   if (tag1 || ignore_tag1 || cos1)
10784     len = 18;
10785   if (tag2 || ignore_tag2 || cos2)
10786     len = 22;
10787
10788   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10789
10790   if (dst)
10791     clib_memcpy (match, dst_val, 6);
10792
10793   if (src)
10794     clib_memcpy (match + 6, src_val, 6);
10795
10796   if (tag2)
10797     {
10798       /* inner vlan tag */
10799       match[19] = tag2_val[1];
10800       match[18] = tag2_val[0];
10801       if (cos2)
10802         match[18] |= (cos2_val & 0x7) << 5;
10803       if (proto)
10804         {
10805           match[21] = proto_val & 0xff;
10806           match[20] = proto_val >> 8;
10807         }
10808       if (tag1)
10809         {
10810           match[15] = tag1_val[1];
10811           match[14] = tag1_val[0];
10812         }
10813       if (cos1)
10814         match[14] |= (cos1_val & 0x7) << 5;
10815       *matchp = match;
10816       return 1;
10817     }
10818   if (tag1)
10819     {
10820       match[15] = tag1_val[1];
10821       match[14] = tag1_val[0];
10822       if (proto)
10823         {
10824           match[17] = proto_val & 0xff;
10825           match[16] = proto_val >> 8;
10826         }
10827       if (cos1)
10828         match[14] |= (cos1_val & 0x7) << 5;
10829
10830       *matchp = match;
10831       return 1;
10832     }
10833   if (cos2)
10834     match[18] |= (cos2_val & 0x7) << 5;
10835   if (cos1)
10836     match[14] |= (cos1_val & 0x7) << 5;
10837   if (proto)
10838     {
10839       match[13] = proto_val & 0xff;
10840       match[12] = proto_val >> 8;
10841     }
10842
10843   *matchp = match;
10844   return 1;
10845 }
10846 #endif
10847
10848 uword
10849 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10850 {
10851   u8 **matchp = va_arg (*args, u8 **);
10852   u32 skip_n_vectors = va_arg (*args, u32);
10853   u32 match_n_vectors = va_arg (*args, u32);
10854
10855   u8 *match = 0;
10856   u8 *l2 = 0;
10857   u8 *l3 = 0;
10858   u8 *l4 = 0;
10859
10860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10861     {
10862       if (unformat (input, "hex %U", unformat_hex_string, &match))
10863         ;
10864       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10865         ;
10866       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10867         ;
10868       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10869         ;
10870       else
10871         break;
10872     }
10873
10874   if (l4 && !l3)
10875     {
10876       vec_free (match);
10877       vec_free (l2);
10878       vec_free (l4);
10879       return 0;
10880     }
10881
10882   if (match || l2 || l3 || l4)
10883     {
10884       if (l2 || l3 || l4)
10885         {
10886           /* "Win a free Ethernet header in every packet" */
10887           if (l2 == 0)
10888             vec_validate_aligned (l2, 13, sizeof (u32x4));
10889           match = l2;
10890           if (vec_len (l3))
10891             {
10892               vec_append_aligned (match, l3, sizeof (u32x4));
10893               vec_free (l3);
10894             }
10895           if (vec_len (l4))
10896             {
10897               vec_append_aligned (match, l4, sizeof (u32x4));
10898               vec_free (l4);
10899             }
10900         }
10901
10902       /* Make sure the vector is big enough even if key is all 0's */
10903       vec_validate_aligned
10904         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10905          sizeof (u32x4));
10906
10907       /* Set size, include skipped vectors */
10908       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10909
10910       *matchp = match;
10911
10912       return 1;
10913     }
10914
10915   return 0;
10916 }
10917
10918 static int
10919 api_classify_add_del_session (vat_main_t * vam)
10920 {
10921   unformat_input_t *i = vam->input;
10922   vl_api_classify_add_del_session_t *mp;
10923   int is_add = 1;
10924   u32 table_index = ~0;
10925   u32 hit_next_index = ~0;
10926   u32 opaque_index = ~0;
10927   u8 *match = 0;
10928   i32 advance = 0;
10929   u32 skip_n_vectors = 0;
10930   u32 match_n_vectors = 0;
10931   u32 action = 0;
10932   u32 metadata = 0;
10933   int ret;
10934
10935   /*
10936    * Warning: you have to supply skip_n and match_n
10937    * because the API client cant simply look at the classify
10938    * table object.
10939    */
10940
10941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10942     {
10943       if (unformat (i, "del"))
10944         is_add = 0;
10945       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10946                          &hit_next_index))
10947         ;
10948       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10949                          &hit_next_index))
10950         ;
10951       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10952                          &hit_next_index))
10953         ;
10954       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10955         ;
10956       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10957         ;
10958       else if (unformat (i, "opaque-index %d", &opaque_index))
10959         ;
10960       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10961         ;
10962       else if (unformat (i, "match_n %d", &match_n_vectors))
10963         ;
10964       else if (unformat (i, "match %U", api_unformat_classify_match,
10965                          &match, skip_n_vectors, match_n_vectors))
10966         ;
10967       else if (unformat (i, "advance %d", &advance))
10968         ;
10969       else if (unformat (i, "table-index %d", &table_index))
10970         ;
10971       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10972         action = 1;
10973       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10974         action = 2;
10975       else if (unformat (i, "action %d", &action))
10976         ;
10977       else if (unformat (i, "metadata %d", &metadata))
10978         ;
10979       else
10980         break;
10981     }
10982
10983   if (table_index == ~0)
10984     {
10985       errmsg ("Table index required");
10986       return -99;
10987     }
10988
10989   if (is_add && match == 0)
10990     {
10991       errmsg ("Match value required");
10992       return -99;
10993     }
10994
10995   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10996
10997   mp->is_add = is_add;
10998   mp->table_index = ntohl (table_index);
10999   mp->hit_next_index = ntohl (hit_next_index);
11000   mp->opaque_index = ntohl (opaque_index);
11001   mp->advance = ntohl (advance);
11002   mp->action = action;
11003   mp->metadata = ntohl (metadata);
11004   clib_memcpy (mp->match, match, vec_len (match));
11005   vec_free (match);
11006
11007   S (mp);
11008   W (ret);
11009   return ret;
11010 }
11011
11012 static int
11013 api_classify_set_interface_ip_table (vat_main_t * vam)
11014 {
11015   unformat_input_t *i = vam->input;
11016   vl_api_classify_set_interface_ip_table_t *mp;
11017   u32 sw_if_index;
11018   int sw_if_index_set;
11019   u32 table_index = ~0;
11020   u8 is_ipv6 = 0;
11021   int ret;
11022
11023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11024     {
11025       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11026         sw_if_index_set = 1;
11027       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11028         sw_if_index_set = 1;
11029       else if (unformat (i, "table %d", &table_index))
11030         ;
11031       else
11032         {
11033           clib_warning ("parse error '%U'", format_unformat_error, i);
11034           return -99;
11035         }
11036     }
11037
11038   if (sw_if_index_set == 0)
11039     {
11040       errmsg ("missing interface name or sw_if_index");
11041       return -99;
11042     }
11043
11044
11045   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11046
11047   mp->sw_if_index = ntohl (sw_if_index);
11048   mp->table_index = ntohl (table_index);
11049   mp->is_ipv6 = is_ipv6;
11050
11051   S (mp);
11052   W (ret);
11053   return ret;
11054 }
11055
11056 static int
11057 api_classify_set_interface_l2_tables (vat_main_t * vam)
11058 {
11059   unformat_input_t *i = vam->input;
11060   vl_api_classify_set_interface_l2_tables_t *mp;
11061   u32 sw_if_index;
11062   int sw_if_index_set;
11063   u32 ip4_table_index = ~0;
11064   u32 ip6_table_index = ~0;
11065   u32 other_table_index = ~0;
11066   u32 is_input = 1;
11067   int ret;
11068
11069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11070     {
11071       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11072         sw_if_index_set = 1;
11073       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11074         sw_if_index_set = 1;
11075       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11076         ;
11077       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11078         ;
11079       else if (unformat (i, "other-table %d", &other_table_index))
11080         ;
11081       else if (unformat (i, "is-input %d", &is_input))
11082         ;
11083       else
11084         {
11085           clib_warning ("parse error '%U'", format_unformat_error, i);
11086           return -99;
11087         }
11088     }
11089
11090   if (sw_if_index_set == 0)
11091     {
11092       errmsg ("missing interface name or sw_if_index");
11093       return -99;
11094     }
11095
11096
11097   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11098
11099   mp->sw_if_index = ntohl (sw_if_index);
11100   mp->ip4_table_index = ntohl (ip4_table_index);
11101   mp->ip6_table_index = ntohl (ip6_table_index);
11102   mp->other_table_index = ntohl (other_table_index);
11103   mp->is_input = (u8) is_input;
11104
11105   S (mp);
11106   W (ret);
11107   return ret;
11108 }
11109
11110 static int
11111 api_set_ipfix_exporter (vat_main_t * vam)
11112 {
11113   unformat_input_t *i = vam->input;
11114   vl_api_set_ipfix_exporter_t *mp;
11115   ip4_address_t collector_address;
11116   u8 collector_address_set = 0;
11117   u32 collector_port = ~0;
11118   ip4_address_t src_address;
11119   u8 src_address_set = 0;
11120   u32 vrf_id = ~0;
11121   u32 path_mtu = ~0;
11122   u32 template_interval = ~0;
11123   u8 udp_checksum = 0;
11124   int ret;
11125
11126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11127     {
11128       if (unformat (i, "collector_address %U", unformat_ip4_address,
11129                     &collector_address))
11130         collector_address_set = 1;
11131       else if (unformat (i, "collector_port %d", &collector_port))
11132         ;
11133       else if (unformat (i, "src_address %U", unformat_ip4_address,
11134                          &src_address))
11135         src_address_set = 1;
11136       else if (unformat (i, "vrf_id %d", &vrf_id))
11137         ;
11138       else if (unformat (i, "path_mtu %d", &path_mtu))
11139         ;
11140       else if (unformat (i, "template_interval %d", &template_interval))
11141         ;
11142       else if (unformat (i, "udp_checksum"))
11143         udp_checksum = 1;
11144       else
11145         break;
11146     }
11147
11148   if (collector_address_set == 0)
11149     {
11150       errmsg ("collector_address required");
11151       return -99;
11152     }
11153
11154   if (src_address_set == 0)
11155     {
11156       errmsg ("src_address required");
11157       return -99;
11158     }
11159
11160   M (SET_IPFIX_EXPORTER, mp);
11161
11162   memcpy (mp->collector_address, collector_address.data,
11163           sizeof (collector_address.data));
11164   mp->collector_port = htons ((u16) collector_port);
11165   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11166   mp->vrf_id = htonl (vrf_id);
11167   mp->path_mtu = htonl (path_mtu);
11168   mp->template_interval = htonl (template_interval);
11169   mp->udp_checksum = udp_checksum;
11170
11171   S (mp);
11172   W (ret);
11173   return ret;
11174 }
11175
11176 static int
11177 api_set_ipfix_classify_stream (vat_main_t * vam)
11178 {
11179   unformat_input_t *i = vam->input;
11180   vl_api_set_ipfix_classify_stream_t *mp;
11181   u32 domain_id = 0;
11182   u32 src_port = UDP_DST_PORT_ipfix;
11183   int ret;
11184
11185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11186     {
11187       if (unformat (i, "domain %d", &domain_id))
11188         ;
11189       else if (unformat (i, "src_port %d", &src_port))
11190         ;
11191       else
11192         {
11193           errmsg ("unknown input `%U'", format_unformat_error, i);
11194           return -99;
11195         }
11196     }
11197
11198   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11199
11200   mp->domain_id = htonl (domain_id);
11201   mp->src_port = htons ((u16) src_port);
11202
11203   S (mp);
11204   W (ret);
11205   return ret;
11206 }
11207
11208 static int
11209 api_ipfix_classify_table_add_del (vat_main_t * vam)
11210 {
11211   unformat_input_t *i = vam->input;
11212   vl_api_ipfix_classify_table_add_del_t *mp;
11213   int is_add = -1;
11214   u32 classify_table_index = ~0;
11215   u8 ip_version = 0;
11216   u8 transport_protocol = 255;
11217   int ret;
11218
11219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11220     {
11221       if (unformat (i, "add"))
11222         is_add = 1;
11223       else if (unformat (i, "del"))
11224         is_add = 0;
11225       else if (unformat (i, "table %d", &classify_table_index))
11226         ;
11227       else if (unformat (i, "ip4"))
11228         ip_version = 4;
11229       else if (unformat (i, "ip6"))
11230         ip_version = 6;
11231       else if (unformat (i, "tcp"))
11232         transport_protocol = 6;
11233       else if (unformat (i, "udp"))
11234         transport_protocol = 17;
11235       else
11236         {
11237           errmsg ("unknown input `%U'", format_unformat_error, i);
11238           return -99;
11239         }
11240     }
11241
11242   if (is_add == -1)
11243     {
11244       errmsg ("expecting: add|del");
11245       return -99;
11246     }
11247   if (classify_table_index == ~0)
11248     {
11249       errmsg ("classifier table not specified");
11250       return -99;
11251     }
11252   if (ip_version == 0)
11253     {
11254       errmsg ("IP version not specified");
11255       return -99;
11256     }
11257
11258   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11259
11260   mp->is_add = is_add;
11261   mp->table_id = htonl (classify_table_index);
11262   mp->ip_version = ip_version;
11263   mp->transport_protocol = transport_protocol;
11264
11265   S (mp);
11266   W (ret);
11267   return ret;
11268 }
11269
11270 static int
11271 api_get_node_index (vat_main_t * vam)
11272 {
11273   unformat_input_t *i = vam->input;
11274   vl_api_get_node_index_t *mp;
11275   u8 *name = 0;
11276   int ret;
11277
11278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11279     {
11280       if (unformat (i, "node %s", &name))
11281         ;
11282       else
11283         break;
11284     }
11285   if (name == 0)
11286     {
11287       errmsg ("node name required");
11288       return -99;
11289     }
11290   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11291     {
11292       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11293       return -99;
11294     }
11295
11296   M (GET_NODE_INDEX, mp);
11297   clib_memcpy (mp->node_name, name, vec_len (name));
11298   vec_free (name);
11299
11300   S (mp);
11301   W (ret);
11302   return ret;
11303 }
11304
11305 static int
11306 api_get_next_index (vat_main_t * vam)
11307 {
11308   unformat_input_t *i = vam->input;
11309   vl_api_get_next_index_t *mp;
11310   u8 *node_name = 0, *next_node_name = 0;
11311   int ret;
11312
11313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11314     {
11315       if (unformat (i, "node-name %s", &node_name))
11316         ;
11317       else if (unformat (i, "next-node-name %s", &next_node_name))
11318         break;
11319     }
11320
11321   if (node_name == 0)
11322     {
11323       errmsg ("node name required");
11324       return -99;
11325     }
11326   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11327     {
11328       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11329       return -99;
11330     }
11331
11332   if (next_node_name == 0)
11333     {
11334       errmsg ("next node name required");
11335       return -99;
11336     }
11337   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11338     {
11339       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11340       return -99;
11341     }
11342
11343   M (GET_NEXT_INDEX, mp);
11344   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11345   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11346   vec_free (node_name);
11347   vec_free (next_node_name);
11348
11349   S (mp);
11350   W (ret);
11351   return ret;
11352 }
11353
11354 static int
11355 api_add_node_next (vat_main_t * vam)
11356 {
11357   unformat_input_t *i = vam->input;
11358   vl_api_add_node_next_t *mp;
11359   u8 *name = 0;
11360   u8 *next = 0;
11361   int ret;
11362
11363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11364     {
11365       if (unformat (i, "node %s", &name))
11366         ;
11367       else if (unformat (i, "next %s", &next))
11368         ;
11369       else
11370         break;
11371     }
11372   if (name == 0)
11373     {
11374       errmsg ("node name required");
11375       return -99;
11376     }
11377   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11378     {
11379       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11380       return -99;
11381     }
11382   if (next == 0)
11383     {
11384       errmsg ("next node required");
11385       return -99;
11386     }
11387   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11388     {
11389       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11390       return -99;
11391     }
11392
11393   M (ADD_NODE_NEXT, mp);
11394   clib_memcpy (mp->node_name, name, vec_len (name));
11395   clib_memcpy (mp->next_name, next, vec_len (next));
11396   vec_free (name);
11397   vec_free (next);
11398
11399   S (mp);
11400   W (ret);
11401   return ret;
11402 }
11403
11404 static int
11405 api_l2tpv3_create_tunnel (vat_main_t * vam)
11406 {
11407   unformat_input_t *i = vam->input;
11408   ip6_address_t client_address, our_address;
11409   int client_address_set = 0;
11410   int our_address_set = 0;
11411   u32 local_session_id = 0;
11412   u32 remote_session_id = 0;
11413   u64 local_cookie = 0;
11414   u64 remote_cookie = 0;
11415   u8 l2_sublayer_present = 0;
11416   vl_api_l2tpv3_create_tunnel_t *mp;
11417   int ret;
11418
11419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11420     {
11421       if (unformat (i, "client_address %U", unformat_ip6_address,
11422                     &client_address))
11423         client_address_set = 1;
11424       else if (unformat (i, "our_address %U", unformat_ip6_address,
11425                          &our_address))
11426         our_address_set = 1;
11427       else if (unformat (i, "local_session_id %d", &local_session_id))
11428         ;
11429       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11430         ;
11431       else if (unformat (i, "local_cookie %lld", &local_cookie))
11432         ;
11433       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11434         ;
11435       else if (unformat (i, "l2-sublayer-present"))
11436         l2_sublayer_present = 1;
11437       else
11438         break;
11439     }
11440
11441   if (client_address_set == 0)
11442     {
11443       errmsg ("client_address required");
11444       return -99;
11445     }
11446
11447   if (our_address_set == 0)
11448     {
11449       errmsg ("our_address required");
11450       return -99;
11451     }
11452
11453   M (L2TPV3_CREATE_TUNNEL, mp);
11454
11455   clib_memcpy (mp->client_address, client_address.as_u8,
11456                sizeof (mp->client_address));
11457
11458   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11459
11460   mp->local_session_id = ntohl (local_session_id);
11461   mp->remote_session_id = ntohl (remote_session_id);
11462   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11463   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11464   mp->l2_sublayer_present = l2_sublayer_present;
11465   mp->is_ipv6 = 1;
11466
11467   S (mp);
11468   W (ret);
11469   return ret;
11470 }
11471
11472 static int
11473 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11474 {
11475   unformat_input_t *i = vam->input;
11476   u32 sw_if_index;
11477   u8 sw_if_index_set = 0;
11478   u64 new_local_cookie = 0;
11479   u64 new_remote_cookie = 0;
11480   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11481   int ret;
11482
11483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11486         sw_if_index_set = 1;
11487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11488         sw_if_index_set = 1;
11489       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11490         ;
11491       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11492         ;
11493       else
11494         break;
11495     }
11496
11497   if (sw_if_index_set == 0)
11498     {
11499       errmsg ("missing interface name or sw_if_index");
11500       return -99;
11501     }
11502
11503   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11504
11505   mp->sw_if_index = ntohl (sw_if_index);
11506   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11507   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11508
11509   S (mp);
11510   W (ret);
11511   return ret;
11512 }
11513
11514 static int
11515 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11516 {
11517   unformat_input_t *i = vam->input;
11518   vl_api_l2tpv3_interface_enable_disable_t *mp;
11519   u32 sw_if_index;
11520   u8 sw_if_index_set = 0;
11521   u8 enable_disable = 1;
11522   int ret;
11523
11524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11525     {
11526       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11527         sw_if_index_set = 1;
11528       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11529         sw_if_index_set = 1;
11530       else if (unformat (i, "enable"))
11531         enable_disable = 1;
11532       else if (unformat (i, "disable"))
11533         enable_disable = 0;
11534       else
11535         break;
11536     }
11537
11538   if (sw_if_index_set == 0)
11539     {
11540       errmsg ("missing interface name or sw_if_index");
11541       return -99;
11542     }
11543
11544   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11545
11546   mp->sw_if_index = ntohl (sw_if_index);
11547   mp->enable_disable = enable_disable;
11548
11549   S (mp);
11550   W (ret);
11551   return ret;
11552 }
11553
11554 static int
11555 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11556 {
11557   unformat_input_t *i = vam->input;
11558   vl_api_l2tpv3_set_lookup_key_t *mp;
11559   u8 key = ~0;
11560   int ret;
11561
11562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11563     {
11564       if (unformat (i, "lookup_v6_src"))
11565         key = L2T_LOOKUP_SRC_ADDRESS;
11566       else if (unformat (i, "lookup_v6_dst"))
11567         key = L2T_LOOKUP_DST_ADDRESS;
11568       else if (unformat (i, "lookup_session_id"))
11569         key = L2T_LOOKUP_SESSION_ID;
11570       else
11571         break;
11572     }
11573
11574   if (key == (u8) ~ 0)
11575     {
11576       errmsg ("l2tp session lookup key unset");
11577       return -99;
11578     }
11579
11580   M (L2TPV3_SET_LOOKUP_KEY, mp);
11581
11582   mp->key = key;
11583
11584   S (mp);
11585   W (ret);
11586   return ret;
11587 }
11588
11589 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11590   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11591 {
11592   vat_main_t *vam = &vat_main;
11593
11594   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11595          format_ip6_address, mp->our_address,
11596          format_ip6_address, mp->client_address,
11597          clib_net_to_host_u32 (mp->sw_if_index));
11598
11599   print (vam->ofp,
11600          "   local cookies %016llx %016llx remote cookie %016llx",
11601          clib_net_to_host_u64 (mp->local_cookie[0]),
11602          clib_net_to_host_u64 (mp->local_cookie[1]),
11603          clib_net_to_host_u64 (mp->remote_cookie));
11604
11605   print (vam->ofp, "   local session-id %d remote session-id %d",
11606          clib_net_to_host_u32 (mp->local_session_id),
11607          clib_net_to_host_u32 (mp->remote_session_id));
11608
11609   print (vam->ofp, "   l2 specific sublayer %s\n",
11610          mp->l2_sublayer_present ? "preset" : "absent");
11611
11612 }
11613
11614 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11615   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11616 {
11617   vat_main_t *vam = &vat_main;
11618   vat_json_node_t *node = NULL;
11619   struct in6_addr addr;
11620
11621   if (VAT_JSON_ARRAY != vam->json_tree.type)
11622     {
11623       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11624       vat_json_init_array (&vam->json_tree);
11625     }
11626   node = vat_json_array_add (&vam->json_tree);
11627
11628   vat_json_init_object (node);
11629
11630   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11631   vat_json_object_add_ip6 (node, "our_address", addr);
11632   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11633   vat_json_object_add_ip6 (node, "client_address", addr);
11634
11635   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11636   vat_json_init_array (lc);
11637   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11638   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11639   vat_json_object_add_uint (node, "remote_cookie",
11640                             clib_net_to_host_u64 (mp->remote_cookie));
11641
11642   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11643   vat_json_object_add_uint (node, "local_session_id",
11644                             clib_net_to_host_u32 (mp->local_session_id));
11645   vat_json_object_add_uint (node, "remote_session_id",
11646                             clib_net_to_host_u32 (mp->remote_session_id));
11647   vat_json_object_add_string_copy (node, "l2_sublayer",
11648                                    mp->l2_sublayer_present ? (u8 *) "present"
11649                                    : (u8 *) "absent");
11650 }
11651
11652 static int
11653 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11654 {
11655   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11656   vl_api_control_ping_t *mp_ping;
11657   int ret;
11658
11659   /* Get list of l2tpv3-tunnel interfaces */
11660   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11661   S (mp);
11662
11663   /* Use a control ping for synchronization */
11664   MPING (CONTROL_PING, mp_ping);
11665   S (mp_ping);
11666
11667   W (ret);
11668   return ret;
11669 }
11670
11671
11672 static void vl_api_sw_interface_tap_details_t_handler
11673   (vl_api_sw_interface_tap_details_t * mp)
11674 {
11675   vat_main_t *vam = &vat_main;
11676
11677   print (vam->ofp, "%-16s %d",
11678          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11679 }
11680
11681 static void vl_api_sw_interface_tap_details_t_handler_json
11682   (vl_api_sw_interface_tap_details_t * mp)
11683 {
11684   vat_main_t *vam = &vat_main;
11685   vat_json_node_t *node = NULL;
11686
11687   if (VAT_JSON_ARRAY != vam->json_tree.type)
11688     {
11689       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11690       vat_json_init_array (&vam->json_tree);
11691     }
11692   node = vat_json_array_add (&vam->json_tree);
11693
11694   vat_json_init_object (node);
11695   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11696   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11697 }
11698
11699 static int
11700 api_sw_interface_tap_dump (vat_main_t * vam)
11701 {
11702   vl_api_sw_interface_tap_dump_t *mp;
11703   vl_api_control_ping_t *mp_ping;
11704   int ret;
11705
11706   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11707   /* Get list of tap interfaces */
11708   M (SW_INTERFACE_TAP_DUMP, mp);
11709   S (mp);
11710
11711   /* Use a control ping for synchronization */
11712   MPING (CONTROL_PING, mp_ping);
11713   S (mp_ping);
11714
11715   W (ret);
11716   return ret;
11717 }
11718
11719 static uword unformat_vxlan_decap_next
11720   (unformat_input_t * input, va_list * args)
11721 {
11722   u32 *result = va_arg (*args, u32 *);
11723   u32 tmp;
11724
11725   if (unformat (input, "l2"))
11726     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11727   else if (unformat (input, "%d", &tmp))
11728     *result = tmp;
11729   else
11730     return 0;
11731   return 1;
11732 }
11733
11734 static int
11735 api_vxlan_add_del_tunnel (vat_main_t * vam)
11736 {
11737   unformat_input_t *line_input = vam->input;
11738   vl_api_vxlan_add_del_tunnel_t *mp;
11739   ip46_address_t src, dst;
11740   u8 is_add = 1;
11741   u8 ipv4_set = 0, ipv6_set = 0;
11742   u8 src_set = 0;
11743   u8 dst_set = 0;
11744   u8 grp_set = 0;
11745   u32 mcast_sw_if_index = ~0;
11746   u32 encap_vrf_id = 0;
11747   u32 decap_next_index = ~0;
11748   u32 vni = 0;
11749   int ret;
11750
11751   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11752   memset (&src, 0, sizeof src);
11753   memset (&dst, 0, sizeof dst);
11754
11755   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11756     {
11757       if (unformat (line_input, "del"))
11758         is_add = 0;
11759       else
11760         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11761         {
11762           ipv4_set = 1;
11763           src_set = 1;
11764         }
11765       else
11766         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11767         {
11768           ipv4_set = 1;
11769           dst_set = 1;
11770         }
11771       else
11772         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11773         {
11774           ipv6_set = 1;
11775           src_set = 1;
11776         }
11777       else
11778         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11779         {
11780           ipv6_set = 1;
11781           dst_set = 1;
11782         }
11783       else if (unformat (line_input, "group %U %U",
11784                          unformat_ip4_address, &dst.ip4,
11785                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11786         {
11787           grp_set = dst_set = 1;
11788           ipv4_set = 1;
11789         }
11790       else if (unformat (line_input, "group %U",
11791                          unformat_ip4_address, &dst.ip4))
11792         {
11793           grp_set = dst_set = 1;
11794           ipv4_set = 1;
11795         }
11796       else if (unformat (line_input, "group %U %U",
11797                          unformat_ip6_address, &dst.ip6,
11798                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11799         {
11800           grp_set = dst_set = 1;
11801           ipv6_set = 1;
11802         }
11803       else if (unformat (line_input, "group %U",
11804                          unformat_ip6_address, &dst.ip6))
11805         {
11806           grp_set = dst_set = 1;
11807           ipv6_set = 1;
11808         }
11809       else
11810         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11811         ;
11812       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11813         ;
11814       else if (unformat (line_input, "decap-next %U",
11815                          unformat_vxlan_decap_next, &decap_next_index))
11816         ;
11817       else if (unformat (line_input, "vni %d", &vni))
11818         ;
11819       else
11820         {
11821           errmsg ("parse error '%U'", format_unformat_error, line_input);
11822           return -99;
11823         }
11824     }
11825
11826   if (src_set == 0)
11827     {
11828       errmsg ("tunnel src address not specified");
11829       return -99;
11830     }
11831   if (dst_set == 0)
11832     {
11833       errmsg ("tunnel dst address not specified");
11834       return -99;
11835     }
11836
11837   if (grp_set && !ip46_address_is_multicast (&dst))
11838     {
11839       errmsg ("tunnel group address not multicast");
11840       return -99;
11841     }
11842   if (grp_set && mcast_sw_if_index == ~0)
11843     {
11844       errmsg ("tunnel nonexistent multicast device");
11845       return -99;
11846     }
11847   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11848     {
11849       errmsg ("tunnel dst address must be unicast");
11850       return -99;
11851     }
11852
11853
11854   if (ipv4_set && ipv6_set)
11855     {
11856       errmsg ("both IPv4 and IPv6 addresses specified");
11857       return -99;
11858     }
11859
11860   if ((vni == 0) || (vni >> 24))
11861     {
11862       errmsg ("vni not specified or out of range");
11863       return -99;
11864     }
11865
11866   M (VXLAN_ADD_DEL_TUNNEL, mp);
11867
11868   if (ipv6_set)
11869     {
11870       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11871       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11872     }
11873   else
11874     {
11875       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11876       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11877     }
11878   mp->encap_vrf_id = ntohl (encap_vrf_id);
11879   mp->decap_next_index = ntohl (decap_next_index);
11880   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11881   mp->vni = ntohl (vni);
11882   mp->is_add = is_add;
11883   mp->is_ipv6 = ipv6_set;
11884
11885   S (mp);
11886   W (ret);
11887   return ret;
11888 }
11889
11890 static void vl_api_vxlan_tunnel_details_t_handler
11891   (vl_api_vxlan_tunnel_details_t * mp)
11892 {
11893   vat_main_t *vam = &vat_main;
11894   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11895   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11896
11897   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11898          ntohl (mp->sw_if_index),
11899          format_ip46_address, &src, IP46_TYPE_ANY,
11900          format_ip46_address, &dst, IP46_TYPE_ANY,
11901          ntohl (mp->encap_vrf_id),
11902          ntohl (mp->decap_next_index), ntohl (mp->vni),
11903          ntohl (mp->mcast_sw_if_index));
11904 }
11905
11906 static void vl_api_vxlan_tunnel_details_t_handler_json
11907   (vl_api_vxlan_tunnel_details_t * mp)
11908 {
11909   vat_main_t *vam = &vat_main;
11910   vat_json_node_t *node = NULL;
11911
11912   if (VAT_JSON_ARRAY != vam->json_tree.type)
11913     {
11914       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11915       vat_json_init_array (&vam->json_tree);
11916     }
11917   node = vat_json_array_add (&vam->json_tree);
11918
11919   vat_json_init_object (node);
11920   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11921   if (mp->is_ipv6)
11922     {
11923       struct in6_addr ip6;
11924
11925       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11926       vat_json_object_add_ip6 (node, "src_address", ip6);
11927       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11928       vat_json_object_add_ip6 (node, "dst_address", ip6);
11929     }
11930   else
11931     {
11932       struct in_addr ip4;
11933
11934       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11935       vat_json_object_add_ip4 (node, "src_address", ip4);
11936       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11937       vat_json_object_add_ip4 (node, "dst_address", ip4);
11938     }
11939   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11940   vat_json_object_add_uint (node, "decap_next_index",
11941                             ntohl (mp->decap_next_index));
11942   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11943   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11944   vat_json_object_add_uint (node, "mcast_sw_if_index",
11945                             ntohl (mp->mcast_sw_if_index));
11946 }
11947
11948 static int
11949 api_vxlan_tunnel_dump (vat_main_t * vam)
11950 {
11951   unformat_input_t *i = vam->input;
11952   vl_api_vxlan_tunnel_dump_t *mp;
11953   vl_api_control_ping_t *mp_ping;
11954   u32 sw_if_index;
11955   u8 sw_if_index_set = 0;
11956   int ret;
11957
11958   /* Parse args required to build the message */
11959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11960     {
11961       if (unformat (i, "sw_if_index %d", &sw_if_index))
11962         sw_if_index_set = 1;
11963       else
11964         break;
11965     }
11966
11967   if (sw_if_index_set == 0)
11968     {
11969       sw_if_index = ~0;
11970     }
11971
11972   if (!vam->json_output)
11973     {
11974       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11975              "sw_if_index", "src_address", "dst_address",
11976              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11977     }
11978
11979   /* Get list of vxlan-tunnel interfaces */
11980   M (VXLAN_TUNNEL_DUMP, mp);
11981
11982   mp->sw_if_index = htonl (sw_if_index);
11983
11984   S (mp);
11985
11986   /* Use a control ping for synchronization */
11987   MPING (CONTROL_PING, mp_ping);
11988   S (mp_ping);
11989
11990   W (ret);
11991   return ret;
11992 }
11993
11994 static int
11995 api_gre_add_del_tunnel (vat_main_t * vam)
11996 {
11997   unformat_input_t *line_input = vam->input;
11998   vl_api_gre_add_del_tunnel_t *mp;
11999   ip4_address_t src4, dst4;
12000   ip6_address_t src6, dst6;
12001   u8 is_add = 1;
12002   u8 ipv4_set = 0;
12003   u8 ipv6_set = 0;
12004   u8 teb = 0;
12005   u8 src_set = 0;
12006   u8 dst_set = 0;
12007   u32 outer_fib_id = 0;
12008   int ret;
12009
12010   memset (&src4, 0, sizeof src4);
12011   memset (&dst4, 0, sizeof dst4);
12012   memset (&src6, 0, sizeof src6);
12013   memset (&dst6, 0, sizeof dst6);
12014
12015   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12016     {
12017       if (unformat (line_input, "del"))
12018         is_add = 0;
12019       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12020         {
12021           src_set = 1;
12022           ipv4_set = 1;
12023         }
12024       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12025         {
12026           dst_set = 1;
12027           ipv4_set = 1;
12028         }
12029       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12030         {
12031           src_set = 1;
12032           ipv6_set = 1;
12033         }
12034       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12035         {
12036           dst_set = 1;
12037           ipv6_set = 1;
12038         }
12039       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12040         ;
12041       else if (unformat (line_input, "teb"))
12042         teb = 1;
12043       else
12044         {
12045           errmsg ("parse error '%U'", format_unformat_error, line_input);
12046           return -99;
12047         }
12048     }
12049
12050   if (src_set == 0)
12051     {
12052       errmsg ("tunnel src address not specified");
12053       return -99;
12054     }
12055   if (dst_set == 0)
12056     {
12057       errmsg ("tunnel dst address not specified");
12058       return -99;
12059     }
12060   if (ipv4_set && ipv6_set)
12061     {
12062       errmsg ("both IPv4 and IPv6 addresses specified");
12063       return -99;
12064     }
12065
12066
12067   M (GRE_ADD_DEL_TUNNEL, mp);
12068
12069   if (ipv4_set)
12070     {
12071       clib_memcpy (&mp->src_address, &src4, 4);
12072       clib_memcpy (&mp->dst_address, &dst4, 4);
12073     }
12074   else
12075     {
12076       clib_memcpy (&mp->src_address, &src6, 16);
12077       clib_memcpy (&mp->dst_address, &dst6, 16);
12078     }
12079   mp->outer_fib_id = ntohl (outer_fib_id);
12080   mp->is_add = is_add;
12081   mp->teb = teb;
12082   mp->is_ipv6 = ipv6_set;
12083
12084   S (mp);
12085   W (ret);
12086   return ret;
12087 }
12088
12089 static void vl_api_gre_tunnel_details_t_handler
12090   (vl_api_gre_tunnel_details_t * mp)
12091 {
12092   vat_main_t *vam = &vat_main;
12093   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12094   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12095
12096   print (vam->ofp, "%11d%24U%24U%6d%14d",
12097          ntohl (mp->sw_if_index),
12098          format_ip46_address, &src, IP46_TYPE_ANY,
12099          format_ip46_address, &dst, IP46_TYPE_ANY,
12100          mp->teb, ntohl (mp->outer_fib_id));
12101 }
12102
12103 static void vl_api_gre_tunnel_details_t_handler_json
12104   (vl_api_gre_tunnel_details_t * mp)
12105 {
12106   vat_main_t *vam = &vat_main;
12107   vat_json_node_t *node = NULL;
12108   struct in_addr ip4;
12109   struct in6_addr ip6;
12110
12111   if (VAT_JSON_ARRAY != vam->json_tree.type)
12112     {
12113       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12114       vat_json_init_array (&vam->json_tree);
12115     }
12116   node = vat_json_array_add (&vam->json_tree);
12117
12118   vat_json_init_object (node);
12119   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12120   if (!mp->is_ipv6)
12121     {
12122       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12123       vat_json_object_add_ip4 (node, "src_address", ip4);
12124       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12125       vat_json_object_add_ip4 (node, "dst_address", ip4);
12126     }
12127   else
12128     {
12129       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12130       vat_json_object_add_ip6 (node, "src_address", ip6);
12131       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12132       vat_json_object_add_ip6 (node, "dst_address", ip6);
12133     }
12134   vat_json_object_add_uint (node, "teb", mp->teb);
12135   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12136   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12137 }
12138
12139 static int
12140 api_gre_tunnel_dump (vat_main_t * vam)
12141 {
12142   unformat_input_t *i = vam->input;
12143   vl_api_gre_tunnel_dump_t *mp;
12144   vl_api_control_ping_t *mp_ping;
12145   u32 sw_if_index;
12146   u8 sw_if_index_set = 0;
12147   int ret;
12148
12149   /* Parse args required to build the message */
12150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12151     {
12152       if (unformat (i, "sw_if_index %d", &sw_if_index))
12153         sw_if_index_set = 1;
12154       else
12155         break;
12156     }
12157
12158   if (sw_if_index_set == 0)
12159     {
12160       sw_if_index = ~0;
12161     }
12162
12163   if (!vam->json_output)
12164     {
12165       print (vam->ofp, "%11s%24s%24s%6s%14s",
12166              "sw_if_index", "src_address", "dst_address", "teb",
12167              "outer_fib_id");
12168     }
12169
12170   /* Get list of gre-tunnel interfaces */
12171   M (GRE_TUNNEL_DUMP, mp);
12172
12173   mp->sw_if_index = htonl (sw_if_index);
12174
12175   S (mp);
12176
12177   /* Use a control ping for synchronization */
12178   MPING (CONTROL_PING, mp_ping);
12179   S (mp_ping);
12180
12181   W (ret);
12182   return ret;
12183 }
12184
12185 static int
12186 api_l2_fib_clear_table (vat_main_t * vam)
12187 {
12188 //  unformat_input_t * i = vam->input;
12189   vl_api_l2_fib_clear_table_t *mp;
12190   int ret;
12191
12192   M (L2_FIB_CLEAR_TABLE, mp);
12193
12194   S (mp);
12195   W (ret);
12196   return ret;
12197 }
12198
12199 static int
12200 api_l2_interface_efp_filter (vat_main_t * vam)
12201 {
12202   unformat_input_t *i = vam->input;
12203   vl_api_l2_interface_efp_filter_t *mp;
12204   u32 sw_if_index;
12205   u8 enable = 1;
12206   u8 sw_if_index_set = 0;
12207   int ret;
12208
12209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12210     {
12211       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12212         sw_if_index_set = 1;
12213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12214         sw_if_index_set = 1;
12215       else if (unformat (i, "enable"))
12216         enable = 1;
12217       else if (unformat (i, "disable"))
12218         enable = 0;
12219       else
12220         {
12221           clib_warning ("parse error '%U'", format_unformat_error, i);
12222           return -99;
12223         }
12224     }
12225
12226   if (sw_if_index_set == 0)
12227     {
12228       errmsg ("missing sw_if_index");
12229       return -99;
12230     }
12231
12232   M (L2_INTERFACE_EFP_FILTER, mp);
12233
12234   mp->sw_if_index = ntohl (sw_if_index);
12235   mp->enable_disable = enable;
12236
12237   S (mp);
12238   W (ret);
12239   return ret;
12240 }
12241
12242 #define foreach_vtr_op                          \
12243 _("disable",  L2_VTR_DISABLED)                  \
12244 _("push-1",  L2_VTR_PUSH_1)                     \
12245 _("push-2",  L2_VTR_PUSH_2)                     \
12246 _("pop-1",  L2_VTR_POP_1)                       \
12247 _("pop-2",  L2_VTR_POP_2)                       \
12248 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12249 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12250 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12251 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12252
12253 static int
12254 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12255 {
12256   unformat_input_t *i = vam->input;
12257   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12258   u32 sw_if_index;
12259   u8 sw_if_index_set = 0;
12260   u8 vtr_op_set = 0;
12261   u32 vtr_op = 0;
12262   u32 push_dot1q = 1;
12263   u32 tag1 = ~0;
12264   u32 tag2 = ~0;
12265   int ret;
12266
12267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12268     {
12269       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12270         sw_if_index_set = 1;
12271       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12272         sw_if_index_set = 1;
12273       else if (unformat (i, "vtr_op %d", &vtr_op))
12274         vtr_op_set = 1;
12275 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12276       foreach_vtr_op
12277 #undef _
12278         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12279         ;
12280       else if (unformat (i, "tag1 %d", &tag1))
12281         ;
12282       else if (unformat (i, "tag2 %d", &tag2))
12283         ;
12284       else
12285         {
12286           clib_warning ("parse error '%U'", format_unformat_error, i);
12287           return -99;
12288         }
12289     }
12290
12291   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12292     {
12293       errmsg ("missing vtr operation or sw_if_index");
12294       return -99;
12295     }
12296
12297   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12298   mp->sw_if_index = ntohl (sw_if_index);
12299   mp->vtr_op = ntohl (vtr_op);
12300   mp->push_dot1q = ntohl (push_dot1q);
12301   mp->tag1 = ntohl (tag1);
12302   mp->tag2 = ntohl (tag2);
12303
12304   S (mp);
12305   W (ret);
12306   return ret;
12307 }
12308
12309 static int
12310 api_create_vhost_user_if (vat_main_t * vam)
12311 {
12312   unformat_input_t *i = vam->input;
12313   vl_api_create_vhost_user_if_t *mp;
12314   u8 *file_name;
12315   u8 is_server = 0;
12316   u8 file_name_set = 0;
12317   u32 custom_dev_instance = ~0;
12318   u8 hwaddr[6];
12319   u8 use_custom_mac = 0;
12320   u8 *tag = 0;
12321   int ret;
12322
12323   /* Shut up coverity */
12324   memset (hwaddr, 0, sizeof (hwaddr));
12325
12326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12327     {
12328       if (unformat (i, "socket %s", &file_name))
12329         {
12330           file_name_set = 1;
12331         }
12332       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12333         ;
12334       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12335         use_custom_mac = 1;
12336       else if (unformat (i, "server"))
12337         is_server = 1;
12338       else if (unformat (i, "tag %s", &tag))
12339         ;
12340       else
12341         break;
12342     }
12343
12344   if (file_name_set == 0)
12345     {
12346       errmsg ("missing socket file name");
12347       return -99;
12348     }
12349
12350   if (vec_len (file_name) > 255)
12351     {
12352       errmsg ("socket file name too long");
12353       return -99;
12354     }
12355   vec_add1 (file_name, 0);
12356
12357   M (CREATE_VHOST_USER_IF, mp);
12358
12359   mp->is_server = is_server;
12360   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12361   vec_free (file_name);
12362   if (custom_dev_instance != ~0)
12363     {
12364       mp->renumber = 1;
12365       mp->custom_dev_instance = ntohl (custom_dev_instance);
12366     }
12367   mp->use_custom_mac = use_custom_mac;
12368   clib_memcpy (mp->mac_address, hwaddr, 6);
12369   if (tag)
12370     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12371   vec_free (tag);
12372
12373   S (mp);
12374   W (ret);
12375   return ret;
12376 }
12377
12378 static int
12379 api_modify_vhost_user_if (vat_main_t * vam)
12380 {
12381   unformat_input_t *i = vam->input;
12382   vl_api_modify_vhost_user_if_t *mp;
12383   u8 *file_name;
12384   u8 is_server = 0;
12385   u8 file_name_set = 0;
12386   u32 custom_dev_instance = ~0;
12387   u8 sw_if_index_set = 0;
12388   u32 sw_if_index = (u32) ~ 0;
12389   int ret;
12390
12391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12392     {
12393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12394         sw_if_index_set = 1;
12395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12396         sw_if_index_set = 1;
12397       else if (unformat (i, "socket %s", &file_name))
12398         {
12399           file_name_set = 1;
12400         }
12401       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12402         ;
12403       else if (unformat (i, "server"))
12404         is_server = 1;
12405       else
12406         break;
12407     }
12408
12409   if (sw_if_index_set == 0)
12410     {
12411       errmsg ("missing sw_if_index or interface name");
12412       return -99;
12413     }
12414
12415   if (file_name_set == 0)
12416     {
12417       errmsg ("missing socket file name");
12418       return -99;
12419     }
12420
12421   if (vec_len (file_name) > 255)
12422     {
12423       errmsg ("socket file name too long");
12424       return -99;
12425     }
12426   vec_add1 (file_name, 0);
12427
12428   M (MODIFY_VHOST_USER_IF, mp);
12429
12430   mp->sw_if_index = ntohl (sw_if_index);
12431   mp->is_server = is_server;
12432   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12433   vec_free (file_name);
12434   if (custom_dev_instance != ~0)
12435     {
12436       mp->renumber = 1;
12437       mp->custom_dev_instance = ntohl (custom_dev_instance);
12438     }
12439
12440   S (mp);
12441   W (ret);
12442   return ret;
12443 }
12444
12445 static int
12446 api_delete_vhost_user_if (vat_main_t * vam)
12447 {
12448   unformat_input_t *i = vam->input;
12449   vl_api_delete_vhost_user_if_t *mp;
12450   u32 sw_if_index = ~0;
12451   u8 sw_if_index_set = 0;
12452   int ret;
12453
12454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12455     {
12456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12457         sw_if_index_set = 1;
12458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12459         sw_if_index_set = 1;
12460       else
12461         break;
12462     }
12463
12464   if (sw_if_index_set == 0)
12465     {
12466       errmsg ("missing sw_if_index or interface name");
12467       return -99;
12468     }
12469
12470
12471   M (DELETE_VHOST_USER_IF, mp);
12472
12473   mp->sw_if_index = ntohl (sw_if_index);
12474
12475   S (mp);
12476   W (ret);
12477   return ret;
12478 }
12479
12480 static void vl_api_sw_interface_vhost_user_details_t_handler
12481   (vl_api_sw_interface_vhost_user_details_t * mp)
12482 {
12483   vat_main_t *vam = &vat_main;
12484
12485   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12486          (char *) mp->interface_name,
12487          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12488          clib_net_to_host_u64 (mp->features), mp->is_server,
12489          ntohl (mp->num_regions), (char *) mp->sock_filename);
12490   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12491 }
12492
12493 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12494   (vl_api_sw_interface_vhost_user_details_t * mp)
12495 {
12496   vat_main_t *vam = &vat_main;
12497   vat_json_node_t *node = NULL;
12498
12499   if (VAT_JSON_ARRAY != vam->json_tree.type)
12500     {
12501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12502       vat_json_init_array (&vam->json_tree);
12503     }
12504   node = vat_json_array_add (&vam->json_tree);
12505
12506   vat_json_init_object (node);
12507   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12508   vat_json_object_add_string_copy (node, "interface_name",
12509                                    mp->interface_name);
12510   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12511                             ntohl (mp->virtio_net_hdr_sz));
12512   vat_json_object_add_uint (node, "features",
12513                             clib_net_to_host_u64 (mp->features));
12514   vat_json_object_add_uint (node, "is_server", mp->is_server);
12515   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12516   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12517   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12518 }
12519
12520 static int
12521 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12522 {
12523   vl_api_sw_interface_vhost_user_dump_t *mp;
12524   vl_api_control_ping_t *mp_ping;
12525   int ret;
12526   print (vam->ofp,
12527          "Interface name            idx hdr_sz features server regions filename");
12528
12529   /* Get list of vhost-user interfaces */
12530   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12531   S (mp);
12532
12533   /* Use a control ping for synchronization */
12534   MPING (CONTROL_PING, mp_ping);
12535   S (mp_ping);
12536
12537   W (ret);
12538   return ret;
12539 }
12540
12541 static int
12542 api_show_version (vat_main_t * vam)
12543 {
12544   vl_api_show_version_t *mp;
12545   int ret;
12546
12547   M (SHOW_VERSION, mp);
12548
12549   S (mp);
12550   W (ret);
12551   return ret;
12552 }
12553
12554
12555 static int
12556 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12557 {
12558   unformat_input_t *line_input = vam->input;
12559   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12560   ip4_address_t local4, remote4;
12561   ip6_address_t local6, remote6;
12562   u8 is_add = 1;
12563   u8 ipv4_set = 0, ipv6_set = 0;
12564   u8 local_set = 0;
12565   u8 remote_set = 0;
12566   u8 grp_set = 0;
12567   u32 mcast_sw_if_index = ~0;
12568   u32 encap_vrf_id = 0;
12569   u32 decap_vrf_id = 0;
12570   u8 protocol = ~0;
12571   u32 vni;
12572   u8 vni_set = 0;
12573   int ret;
12574
12575   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12576   memset (&local4, 0, sizeof local4);
12577   memset (&remote4, 0, sizeof remote4);
12578   memset (&local6, 0, sizeof local6);
12579   memset (&remote6, 0, sizeof remote6);
12580
12581   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12582     {
12583       if (unformat (line_input, "del"))
12584         is_add = 0;
12585       else if (unformat (line_input, "local %U",
12586                          unformat_ip4_address, &local4))
12587         {
12588           local_set = 1;
12589           ipv4_set = 1;
12590         }
12591       else if (unformat (line_input, "remote %U",
12592                          unformat_ip4_address, &remote4))
12593         {
12594           remote_set = 1;
12595           ipv4_set = 1;
12596         }
12597       else if (unformat (line_input, "local %U",
12598                          unformat_ip6_address, &local6))
12599         {
12600           local_set = 1;
12601           ipv6_set = 1;
12602         }
12603       else if (unformat (line_input, "remote %U",
12604                          unformat_ip6_address, &remote6))
12605         {
12606           remote_set = 1;
12607           ipv6_set = 1;
12608         }
12609       else if (unformat (line_input, "group %U %U",
12610                          unformat_ip4_address, &remote4,
12611                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12612         {
12613           grp_set = remote_set = 1;
12614           ipv4_set = 1;
12615         }
12616       else if (unformat (line_input, "group %U",
12617                          unformat_ip4_address, &remote4))
12618         {
12619           grp_set = remote_set = 1;
12620           ipv4_set = 1;
12621         }
12622       else if (unformat (line_input, "group %U %U",
12623                          unformat_ip6_address, &remote6,
12624                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12625         {
12626           grp_set = remote_set = 1;
12627           ipv6_set = 1;
12628         }
12629       else if (unformat (line_input, "group %U",
12630                          unformat_ip6_address, &remote6))
12631         {
12632           grp_set = remote_set = 1;
12633           ipv6_set = 1;
12634         }
12635       else
12636         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12637         ;
12638       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12639         ;
12640       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12641         ;
12642       else if (unformat (line_input, "vni %d", &vni))
12643         vni_set = 1;
12644       else if (unformat (line_input, "next-ip4"))
12645         protocol = 1;
12646       else if (unformat (line_input, "next-ip6"))
12647         protocol = 2;
12648       else if (unformat (line_input, "next-ethernet"))
12649         protocol = 3;
12650       else if (unformat (line_input, "next-nsh"))
12651         protocol = 4;
12652       else
12653         {
12654           errmsg ("parse error '%U'", format_unformat_error, line_input);
12655           return -99;
12656         }
12657     }
12658
12659   if (local_set == 0)
12660     {
12661       errmsg ("tunnel local address not specified");
12662       return -99;
12663     }
12664   if (remote_set == 0)
12665     {
12666       errmsg ("tunnel remote address not specified");
12667       return -99;
12668     }
12669   if (grp_set && mcast_sw_if_index == ~0)
12670     {
12671       errmsg ("tunnel nonexistent multicast device");
12672       return -99;
12673     }
12674   if (ipv4_set && ipv6_set)
12675     {
12676       errmsg ("both IPv4 and IPv6 addresses specified");
12677       return -99;
12678     }
12679
12680   if (vni_set == 0)
12681     {
12682       errmsg ("vni not specified");
12683       return -99;
12684     }
12685
12686   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12687
12688
12689   if (ipv6_set)
12690     {
12691       clib_memcpy (&mp->local, &local6, sizeof (local6));
12692       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12693     }
12694   else
12695     {
12696       clib_memcpy (&mp->local, &local4, sizeof (local4));
12697       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12698     }
12699
12700   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12701   mp->encap_vrf_id = ntohl (encap_vrf_id);
12702   mp->decap_vrf_id = ntohl (decap_vrf_id);
12703   mp->protocol = protocol;
12704   mp->vni = ntohl (vni);
12705   mp->is_add = is_add;
12706   mp->is_ipv6 = ipv6_set;
12707
12708   S (mp);
12709   W (ret);
12710   return ret;
12711 }
12712
12713 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12714   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12715 {
12716   vat_main_t *vam = &vat_main;
12717   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12718   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12719
12720   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12721          ntohl (mp->sw_if_index),
12722          format_ip46_address, &local, IP46_TYPE_ANY,
12723          format_ip46_address, &remote, IP46_TYPE_ANY,
12724          ntohl (mp->vni), mp->protocol,
12725          ntohl (mp->mcast_sw_if_index),
12726          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12727 }
12728
12729
12730 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12731   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12732 {
12733   vat_main_t *vam = &vat_main;
12734   vat_json_node_t *node = NULL;
12735   struct in_addr ip4;
12736   struct in6_addr ip6;
12737
12738   if (VAT_JSON_ARRAY != vam->json_tree.type)
12739     {
12740       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12741       vat_json_init_array (&vam->json_tree);
12742     }
12743   node = vat_json_array_add (&vam->json_tree);
12744
12745   vat_json_init_object (node);
12746   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12747   if (mp->is_ipv6)
12748     {
12749       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12750       vat_json_object_add_ip6 (node, "local", ip6);
12751       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12752       vat_json_object_add_ip6 (node, "remote", ip6);
12753     }
12754   else
12755     {
12756       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12757       vat_json_object_add_ip4 (node, "local", ip4);
12758       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12759       vat_json_object_add_ip4 (node, "remote", ip4);
12760     }
12761   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12762   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12763   vat_json_object_add_uint (node, "mcast_sw_if_index",
12764                             ntohl (mp->mcast_sw_if_index));
12765   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12766   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12767   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12768 }
12769
12770 static int
12771 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12772 {
12773   unformat_input_t *i = vam->input;
12774   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12775   vl_api_control_ping_t *mp_ping;
12776   u32 sw_if_index;
12777   u8 sw_if_index_set = 0;
12778   int ret;
12779
12780   /* Parse args required to build the message */
12781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12782     {
12783       if (unformat (i, "sw_if_index %d", &sw_if_index))
12784         sw_if_index_set = 1;
12785       else
12786         break;
12787     }
12788
12789   if (sw_if_index_set == 0)
12790     {
12791       sw_if_index = ~0;
12792     }
12793
12794   if (!vam->json_output)
12795     {
12796       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12797              "sw_if_index", "local", "remote", "vni",
12798              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12799     }
12800
12801   /* Get list of vxlan-tunnel interfaces */
12802   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12803
12804   mp->sw_if_index = htonl (sw_if_index);
12805
12806   S (mp);
12807
12808   /* Use a control ping for synchronization */
12809   MPING (CONTROL_PING, mp_ping);
12810   S (mp_ping);
12811
12812   W (ret);
12813   return ret;
12814 }
12815
12816
12817 u8 *
12818 format_l2_fib_mac_address (u8 * s, va_list * args)
12819 {
12820   u8 *a = va_arg (*args, u8 *);
12821
12822   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12823                  a[2], a[3], a[4], a[5], a[6], a[7]);
12824 }
12825
12826 static void vl_api_l2_fib_table_details_t_handler
12827   (vl_api_l2_fib_table_details_t * mp)
12828 {
12829   vat_main_t *vam = &vat_main;
12830
12831   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12832          "       %d       %d     %d",
12833          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12834          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12835          mp->bvi_mac);
12836 }
12837
12838 static void vl_api_l2_fib_table_details_t_handler_json
12839   (vl_api_l2_fib_table_details_t * mp)
12840 {
12841   vat_main_t *vam = &vat_main;
12842   vat_json_node_t *node = NULL;
12843
12844   if (VAT_JSON_ARRAY != vam->json_tree.type)
12845     {
12846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12847       vat_json_init_array (&vam->json_tree);
12848     }
12849   node = vat_json_array_add (&vam->json_tree);
12850
12851   vat_json_init_object (node);
12852   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12853   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12854   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12855   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12856   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12857   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12858 }
12859
12860 static int
12861 api_l2_fib_table_dump (vat_main_t * vam)
12862 {
12863   unformat_input_t *i = vam->input;
12864   vl_api_l2_fib_table_dump_t *mp;
12865   vl_api_control_ping_t *mp_ping;
12866   u32 bd_id;
12867   u8 bd_id_set = 0;
12868   int ret;
12869
12870   /* Parse args required to build the message */
12871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12872     {
12873       if (unformat (i, "bd_id %d", &bd_id))
12874         bd_id_set = 1;
12875       else
12876         break;
12877     }
12878
12879   if (bd_id_set == 0)
12880     {
12881       errmsg ("missing bridge domain");
12882       return -99;
12883     }
12884
12885   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12886
12887   /* Get list of l2 fib entries */
12888   M (L2_FIB_TABLE_DUMP, mp);
12889
12890   mp->bd_id = ntohl (bd_id);
12891   S (mp);
12892
12893   /* Use a control ping for synchronization */
12894   MPING (CONTROL_PING, mp_ping);
12895   S (mp_ping);
12896
12897   W (ret);
12898   return ret;
12899 }
12900
12901
12902 static int
12903 api_interface_name_renumber (vat_main_t * vam)
12904 {
12905   unformat_input_t *line_input = vam->input;
12906   vl_api_interface_name_renumber_t *mp;
12907   u32 sw_if_index = ~0;
12908   u32 new_show_dev_instance = ~0;
12909   int ret;
12910
12911   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12912     {
12913       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12914                     &sw_if_index))
12915         ;
12916       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12917         ;
12918       else if (unformat (line_input, "new_show_dev_instance %d",
12919                          &new_show_dev_instance))
12920         ;
12921       else
12922         break;
12923     }
12924
12925   if (sw_if_index == ~0)
12926     {
12927       errmsg ("missing interface name or sw_if_index");
12928       return -99;
12929     }
12930
12931   if (new_show_dev_instance == ~0)
12932     {
12933       errmsg ("missing new_show_dev_instance");
12934       return -99;
12935     }
12936
12937   M (INTERFACE_NAME_RENUMBER, mp);
12938
12939   mp->sw_if_index = ntohl (sw_if_index);
12940   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12941
12942   S (mp);
12943   W (ret);
12944   return ret;
12945 }
12946
12947 static int
12948 api_want_ip4_arp_events (vat_main_t * vam)
12949 {
12950   unformat_input_t *line_input = vam->input;
12951   vl_api_want_ip4_arp_events_t *mp;
12952   ip4_address_t address;
12953   int address_set = 0;
12954   u32 enable_disable = 1;
12955   int ret;
12956
12957   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12958     {
12959       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12960         address_set = 1;
12961       else if (unformat (line_input, "del"))
12962         enable_disable = 0;
12963       else
12964         break;
12965     }
12966
12967   if (address_set == 0)
12968     {
12969       errmsg ("missing addresses");
12970       return -99;
12971     }
12972
12973   M (WANT_IP4_ARP_EVENTS, mp);
12974   mp->enable_disable = enable_disable;
12975   mp->pid = htonl (getpid ());
12976   mp->address = address.as_u32;
12977
12978   S (mp);
12979   W (ret);
12980   return ret;
12981 }
12982
12983 static int
12984 api_want_ip6_nd_events (vat_main_t * vam)
12985 {
12986   unformat_input_t *line_input = vam->input;
12987   vl_api_want_ip6_nd_events_t *mp;
12988   ip6_address_t address;
12989   int address_set = 0;
12990   u32 enable_disable = 1;
12991   int ret;
12992
12993   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12994     {
12995       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12996         address_set = 1;
12997       else if (unformat (line_input, "del"))
12998         enable_disable = 0;
12999       else
13000         break;
13001     }
13002
13003   if (address_set == 0)
13004     {
13005       errmsg ("missing addresses");
13006       return -99;
13007     }
13008
13009   M (WANT_IP6_ND_EVENTS, mp);
13010   mp->enable_disable = enable_disable;
13011   mp->pid = htonl (getpid ());
13012   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13013
13014   S (mp);
13015   W (ret);
13016   return ret;
13017 }
13018
13019 static int
13020 api_want_l2_macs_events (vat_main_t * vam)
13021 {
13022   unformat_input_t *line_input = vam->input;
13023   vl_api_want_l2_macs_events_t *mp;
13024   u8 enable_disable = 1;
13025   u32 scan_delay = 0;
13026   u32 max_macs_in_event = 0;
13027   u32 learn_limit = 0;
13028   int ret;
13029
13030   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13031     {
13032       if (unformat (line_input, "learn-limit %d", &learn_limit))
13033         ;
13034       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13035         ;
13036       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13037         ;
13038       else if (unformat (line_input, "disable"))
13039         enable_disable = 0;
13040       else
13041         break;
13042     }
13043
13044   M (WANT_L2_MACS_EVENTS, mp);
13045   mp->enable_disable = enable_disable;
13046   mp->pid = htonl (getpid ());
13047   mp->learn_limit = htonl (learn_limit);
13048   mp->scan_delay = (u8) scan_delay;
13049   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13050   S (mp);
13051   W (ret);
13052   return ret;
13053 }
13054
13055 static int
13056 api_input_acl_set_interface (vat_main_t * vam)
13057 {
13058   unformat_input_t *i = vam->input;
13059   vl_api_input_acl_set_interface_t *mp;
13060   u32 sw_if_index;
13061   int sw_if_index_set;
13062   u32 ip4_table_index = ~0;
13063   u32 ip6_table_index = ~0;
13064   u32 l2_table_index = ~0;
13065   u8 is_add = 1;
13066   int ret;
13067
13068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13069     {
13070       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13071         sw_if_index_set = 1;
13072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13073         sw_if_index_set = 1;
13074       else if (unformat (i, "del"))
13075         is_add = 0;
13076       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13077         ;
13078       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13079         ;
13080       else if (unformat (i, "l2-table %d", &l2_table_index))
13081         ;
13082       else
13083         {
13084           clib_warning ("parse error '%U'", format_unformat_error, i);
13085           return -99;
13086         }
13087     }
13088
13089   if (sw_if_index_set == 0)
13090     {
13091       errmsg ("missing interface name or sw_if_index");
13092       return -99;
13093     }
13094
13095   M (INPUT_ACL_SET_INTERFACE, mp);
13096
13097   mp->sw_if_index = ntohl (sw_if_index);
13098   mp->ip4_table_index = ntohl (ip4_table_index);
13099   mp->ip6_table_index = ntohl (ip6_table_index);
13100   mp->l2_table_index = ntohl (l2_table_index);
13101   mp->is_add = is_add;
13102
13103   S (mp);
13104   W (ret);
13105   return ret;
13106 }
13107
13108 static int
13109 api_ip_address_dump (vat_main_t * vam)
13110 {
13111   unformat_input_t *i = vam->input;
13112   vl_api_ip_address_dump_t *mp;
13113   vl_api_control_ping_t *mp_ping;
13114   u32 sw_if_index = ~0;
13115   u8 sw_if_index_set = 0;
13116   u8 ipv4_set = 0;
13117   u8 ipv6_set = 0;
13118   int ret;
13119
13120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13121     {
13122       if (unformat (i, "sw_if_index %d", &sw_if_index))
13123         sw_if_index_set = 1;
13124       else
13125         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13126         sw_if_index_set = 1;
13127       else if (unformat (i, "ipv4"))
13128         ipv4_set = 1;
13129       else if (unformat (i, "ipv6"))
13130         ipv6_set = 1;
13131       else
13132         break;
13133     }
13134
13135   if (ipv4_set && ipv6_set)
13136     {
13137       errmsg ("ipv4 and ipv6 flags cannot be both set");
13138       return -99;
13139     }
13140
13141   if ((!ipv4_set) && (!ipv6_set))
13142     {
13143       errmsg ("no ipv4 nor ipv6 flag set");
13144       return -99;
13145     }
13146
13147   if (sw_if_index_set == 0)
13148     {
13149       errmsg ("missing interface name or sw_if_index");
13150       return -99;
13151     }
13152
13153   vam->current_sw_if_index = sw_if_index;
13154   vam->is_ipv6 = ipv6_set;
13155
13156   M (IP_ADDRESS_DUMP, mp);
13157   mp->sw_if_index = ntohl (sw_if_index);
13158   mp->is_ipv6 = ipv6_set;
13159   S (mp);
13160
13161   /* Use a control ping for synchronization */
13162   MPING (CONTROL_PING, mp_ping);
13163   S (mp_ping);
13164
13165   W (ret);
13166   return ret;
13167 }
13168
13169 static int
13170 api_ip_dump (vat_main_t * vam)
13171 {
13172   vl_api_ip_dump_t *mp;
13173   vl_api_control_ping_t *mp_ping;
13174   unformat_input_t *in = vam->input;
13175   int ipv4_set = 0;
13176   int ipv6_set = 0;
13177   int is_ipv6;
13178   int i;
13179   int ret;
13180
13181   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13182     {
13183       if (unformat (in, "ipv4"))
13184         ipv4_set = 1;
13185       else if (unformat (in, "ipv6"))
13186         ipv6_set = 1;
13187       else
13188         break;
13189     }
13190
13191   if (ipv4_set && ipv6_set)
13192     {
13193       errmsg ("ipv4 and ipv6 flags cannot be both set");
13194       return -99;
13195     }
13196
13197   if ((!ipv4_set) && (!ipv6_set))
13198     {
13199       errmsg ("no ipv4 nor ipv6 flag set");
13200       return -99;
13201     }
13202
13203   is_ipv6 = ipv6_set;
13204   vam->is_ipv6 = is_ipv6;
13205
13206   /* free old data */
13207   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13208     {
13209       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13210     }
13211   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13212
13213   M (IP_DUMP, mp);
13214   mp->is_ipv6 = ipv6_set;
13215   S (mp);
13216
13217   /* Use a control ping for synchronization */
13218   MPING (CONTROL_PING, mp_ping);
13219   S (mp_ping);
13220
13221   W (ret);
13222   return ret;
13223 }
13224
13225 static int
13226 api_ipsec_spd_add_del (vat_main_t * vam)
13227 {
13228   unformat_input_t *i = vam->input;
13229   vl_api_ipsec_spd_add_del_t *mp;
13230   u32 spd_id = ~0;
13231   u8 is_add = 1;
13232   int ret;
13233
13234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13235     {
13236       if (unformat (i, "spd_id %d", &spd_id))
13237         ;
13238       else if (unformat (i, "del"))
13239         is_add = 0;
13240       else
13241         {
13242           clib_warning ("parse error '%U'", format_unformat_error, i);
13243           return -99;
13244         }
13245     }
13246   if (spd_id == ~0)
13247     {
13248       errmsg ("spd_id must be set");
13249       return -99;
13250     }
13251
13252   M (IPSEC_SPD_ADD_DEL, mp);
13253
13254   mp->spd_id = ntohl (spd_id);
13255   mp->is_add = is_add;
13256
13257   S (mp);
13258   W (ret);
13259   return ret;
13260 }
13261
13262 static int
13263 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13264 {
13265   unformat_input_t *i = vam->input;
13266   vl_api_ipsec_interface_add_del_spd_t *mp;
13267   u32 sw_if_index;
13268   u8 sw_if_index_set = 0;
13269   u32 spd_id = (u32) ~ 0;
13270   u8 is_add = 1;
13271   int ret;
13272
13273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13274     {
13275       if (unformat (i, "del"))
13276         is_add = 0;
13277       else if (unformat (i, "spd_id %d", &spd_id))
13278         ;
13279       else
13280         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13281         sw_if_index_set = 1;
13282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13283         sw_if_index_set = 1;
13284       else
13285         {
13286           clib_warning ("parse error '%U'", format_unformat_error, i);
13287           return -99;
13288         }
13289
13290     }
13291
13292   if (spd_id == (u32) ~ 0)
13293     {
13294       errmsg ("spd_id must be set");
13295       return -99;
13296     }
13297
13298   if (sw_if_index_set == 0)
13299     {
13300       errmsg ("missing interface name or sw_if_index");
13301       return -99;
13302     }
13303
13304   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13305
13306   mp->spd_id = ntohl (spd_id);
13307   mp->sw_if_index = ntohl (sw_if_index);
13308   mp->is_add = is_add;
13309
13310   S (mp);
13311   W (ret);
13312   return ret;
13313 }
13314
13315 static int
13316 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13317 {
13318   unformat_input_t *i = vam->input;
13319   vl_api_ipsec_spd_add_del_entry_t *mp;
13320   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13321   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13322   i32 priority = 0;
13323   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13324   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13325   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13326   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13327   int ret;
13328
13329   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13330   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13331   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13332   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13333   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13334   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13335
13336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13337     {
13338       if (unformat (i, "del"))
13339         is_add = 0;
13340       if (unformat (i, "outbound"))
13341         is_outbound = 1;
13342       if (unformat (i, "inbound"))
13343         is_outbound = 0;
13344       else if (unformat (i, "spd_id %d", &spd_id))
13345         ;
13346       else if (unformat (i, "sa_id %d", &sa_id))
13347         ;
13348       else if (unformat (i, "priority %d", &priority))
13349         ;
13350       else if (unformat (i, "protocol %d", &protocol))
13351         ;
13352       else if (unformat (i, "lport_start %d", &lport_start))
13353         ;
13354       else if (unformat (i, "lport_stop %d", &lport_stop))
13355         ;
13356       else if (unformat (i, "rport_start %d", &rport_start))
13357         ;
13358       else if (unformat (i, "rport_stop %d", &rport_stop))
13359         ;
13360       else
13361         if (unformat
13362             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13363         {
13364           is_ipv6 = 0;
13365           is_ip_any = 0;
13366         }
13367       else
13368         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13369         {
13370           is_ipv6 = 0;
13371           is_ip_any = 0;
13372         }
13373       else
13374         if (unformat
13375             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13376         {
13377           is_ipv6 = 0;
13378           is_ip_any = 0;
13379         }
13380       else
13381         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13382         {
13383           is_ipv6 = 0;
13384           is_ip_any = 0;
13385         }
13386       else
13387         if (unformat
13388             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13389         {
13390           is_ipv6 = 1;
13391           is_ip_any = 0;
13392         }
13393       else
13394         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13395         {
13396           is_ipv6 = 1;
13397           is_ip_any = 0;
13398         }
13399       else
13400         if (unformat
13401             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13402         {
13403           is_ipv6 = 1;
13404           is_ip_any = 0;
13405         }
13406       else
13407         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13408         {
13409           is_ipv6 = 1;
13410           is_ip_any = 0;
13411         }
13412       else
13413         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13414         {
13415           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13416             {
13417               clib_warning ("unsupported action: 'resolve'");
13418               return -99;
13419             }
13420         }
13421       else
13422         {
13423           clib_warning ("parse error '%U'", format_unformat_error, i);
13424           return -99;
13425         }
13426
13427     }
13428
13429   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13430
13431   mp->spd_id = ntohl (spd_id);
13432   mp->priority = ntohl (priority);
13433   mp->is_outbound = is_outbound;
13434
13435   mp->is_ipv6 = is_ipv6;
13436   if (is_ipv6 || is_ip_any)
13437     {
13438       clib_memcpy (mp->remote_address_start, &raddr6_start,
13439                    sizeof (ip6_address_t));
13440       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13441                    sizeof (ip6_address_t));
13442       clib_memcpy (mp->local_address_start, &laddr6_start,
13443                    sizeof (ip6_address_t));
13444       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13445                    sizeof (ip6_address_t));
13446     }
13447   else
13448     {
13449       clib_memcpy (mp->remote_address_start, &raddr4_start,
13450                    sizeof (ip4_address_t));
13451       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13452                    sizeof (ip4_address_t));
13453       clib_memcpy (mp->local_address_start, &laddr4_start,
13454                    sizeof (ip4_address_t));
13455       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13456                    sizeof (ip4_address_t));
13457     }
13458   mp->protocol = (u8) protocol;
13459   mp->local_port_start = ntohs ((u16) lport_start);
13460   mp->local_port_stop = ntohs ((u16) lport_stop);
13461   mp->remote_port_start = ntohs ((u16) rport_start);
13462   mp->remote_port_stop = ntohs ((u16) rport_stop);
13463   mp->policy = (u8) policy;
13464   mp->sa_id = ntohl (sa_id);
13465   mp->is_add = is_add;
13466   mp->is_ip_any = is_ip_any;
13467   S (mp);
13468   W (ret);
13469   return ret;
13470 }
13471
13472 static int
13473 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13474 {
13475   unformat_input_t *i = vam->input;
13476   vl_api_ipsec_sad_add_del_entry_t *mp;
13477   u32 sad_id = 0, spi = 0;
13478   u8 *ck = 0, *ik = 0;
13479   u8 is_add = 1;
13480
13481   u8 protocol = IPSEC_PROTOCOL_AH;
13482   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13483   u32 crypto_alg = 0, integ_alg = 0;
13484   ip4_address_t tun_src4;
13485   ip4_address_t tun_dst4;
13486   ip6_address_t tun_src6;
13487   ip6_address_t tun_dst6;
13488   int ret;
13489
13490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13491     {
13492       if (unformat (i, "del"))
13493         is_add = 0;
13494       else if (unformat (i, "sad_id %d", &sad_id))
13495         ;
13496       else if (unformat (i, "spi %d", &spi))
13497         ;
13498       else if (unformat (i, "esp"))
13499         protocol = IPSEC_PROTOCOL_ESP;
13500       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13501         {
13502           is_tunnel = 1;
13503           is_tunnel_ipv6 = 0;
13504         }
13505       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13506         {
13507           is_tunnel = 1;
13508           is_tunnel_ipv6 = 0;
13509         }
13510       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13511         {
13512           is_tunnel = 1;
13513           is_tunnel_ipv6 = 1;
13514         }
13515       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13516         {
13517           is_tunnel = 1;
13518           is_tunnel_ipv6 = 1;
13519         }
13520       else
13521         if (unformat
13522             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13523         {
13524           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13525               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13526             {
13527               clib_warning ("unsupported crypto-alg: '%U'",
13528                             format_ipsec_crypto_alg, crypto_alg);
13529               return -99;
13530             }
13531         }
13532       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13533         ;
13534       else
13535         if (unformat
13536             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13537         {
13538           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13539               integ_alg >= IPSEC_INTEG_N_ALG)
13540             {
13541               clib_warning ("unsupported integ-alg: '%U'",
13542                             format_ipsec_integ_alg, integ_alg);
13543               return -99;
13544             }
13545         }
13546       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13547         ;
13548       else
13549         {
13550           clib_warning ("parse error '%U'", format_unformat_error, i);
13551           return -99;
13552         }
13553
13554     }
13555
13556   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13557
13558   mp->sad_id = ntohl (sad_id);
13559   mp->is_add = is_add;
13560   mp->protocol = protocol;
13561   mp->spi = ntohl (spi);
13562   mp->is_tunnel = is_tunnel;
13563   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13564   mp->crypto_algorithm = crypto_alg;
13565   mp->integrity_algorithm = integ_alg;
13566   mp->crypto_key_length = vec_len (ck);
13567   mp->integrity_key_length = vec_len (ik);
13568
13569   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13570     mp->crypto_key_length = sizeof (mp->crypto_key);
13571
13572   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13573     mp->integrity_key_length = sizeof (mp->integrity_key);
13574
13575   if (ck)
13576     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13577   if (ik)
13578     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13579
13580   if (is_tunnel)
13581     {
13582       if (is_tunnel_ipv6)
13583         {
13584           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13585                        sizeof (ip6_address_t));
13586           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13587                        sizeof (ip6_address_t));
13588         }
13589       else
13590         {
13591           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13592                        sizeof (ip4_address_t));
13593           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13594                        sizeof (ip4_address_t));
13595         }
13596     }
13597
13598   S (mp);
13599   W (ret);
13600   return ret;
13601 }
13602
13603 static int
13604 api_ipsec_sa_set_key (vat_main_t * vam)
13605 {
13606   unformat_input_t *i = vam->input;
13607   vl_api_ipsec_sa_set_key_t *mp;
13608   u32 sa_id;
13609   u8 *ck = 0, *ik = 0;
13610   int ret;
13611
13612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13613     {
13614       if (unformat (i, "sa_id %d", &sa_id))
13615         ;
13616       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13617         ;
13618       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13619         ;
13620       else
13621         {
13622           clib_warning ("parse error '%U'", format_unformat_error, i);
13623           return -99;
13624         }
13625     }
13626
13627   M (IPSEC_SA_SET_KEY, mp);
13628
13629   mp->sa_id = ntohl (sa_id);
13630   mp->crypto_key_length = vec_len (ck);
13631   mp->integrity_key_length = vec_len (ik);
13632
13633   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13634     mp->crypto_key_length = sizeof (mp->crypto_key);
13635
13636   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13637     mp->integrity_key_length = sizeof (mp->integrity_key);
13638
13639   if (ck)
13640     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13641   if (ik)
13642     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13643
13644   S (mp);
13645   W (ret);
13646   return ret;
13647 }
13648
13649 static int
13650 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13651 {
13652   unformat_input_t *i = vam->input;
13653   vl_api_ipsec_tunnel_if_add_del_t *mp;
13654   u32 local_spi = 0, remote_spi = 0;
13655   u32 crypto_alg = 0, integ_alg = 0;
13656   u8 *lck = NULL, *rck = NULL;
13657   u8 *lik = NULL, *rik = NULL;
13658   ip4_address_t local_ip = { {0} };
13659   ip4_address_t remote_ip = { {0} };
13660   u8 is_add = 1;
13661   u8 esn = 0;
13662   u8 anti_replay = 0;
13663   int ret;
13664
13665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13666     {
13667       if (unformat (i, "del"))
13668         is_add = 0;
13669       else if (unformat (i, "esn"))
13670         esn = 1;
13671       else if (unformat (i, "anti_replay"))
13672         anti_replay = 1;
13673       else if (unformat (i, "local_spi %d", &local_spi))
13674         ;
13675       else if (unformat (i, "remote_spi %d", &remote_spi))
13676         ;
13677       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13678         ;
13679       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13680         ;
13681       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13682         ;
13683       else
13684         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13685         ;
13686       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13687         ;
13688       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13689         ;
13690       else
13691         if (unformat
13692             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13693         {
13694           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13695               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13696             {
13697               errmsg ("unsupported crypto-alg: '%U'\n",
13698                       format_ipsec_crypto_alg, crypto_alg);
13699               return -99;
13700             }
13701         }
13702       else
13703         if (unformat
13704             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13705         {
13706           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13707               integ_alg >= IPSEC_INTEG_N_ALG)
13708             {
13709               errmsg ("unsupported integ-alg: '%U'\n",
13710                       format_ipsec_integ_alg, integ_alg);
13711               return -99;
13712             }
13713         }
13714       else
13715         {
13716           errmsg ("parse error '%U'\n", format_unformat_error, i);
13717           return -99;
13718         }
13719     }
13720
13721   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13722
13723   mp->is_add = is_add;
13724   mp->esn = esn;
13725   mp->anti_replay = anti_replay;
13726
13727   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13728   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13729
13730   mp->local_spi = htonl (local_spi);
13731   mp->remote_spi = htonl (remote_spi);
13732   mp->crypto_alg = (u8) crypto_alg;
13733
13734   mp->local_crypto_key_len = 0;
13735   if (lck)
13736     {
13737       mp->local_crypto_key_len = vec_len (lck);
13738       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13739         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13740       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13741     }
13742
13743   mp->remote_crypto_key_len = 0;
13744   if (rck)
13745     {
13746       mp->remote_crypto_key_len = vec_len (rck);
13747       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13748         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13749       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13750     }
13751
13752   mp->integ_alg = (u8) integ_alg;
13753
13754   mp->local_integ_key_len = 0;
13755   if (lik)
13756     {
13757       mp->local_integ_key_len = vec_len (lik);
13758       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13759         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13760       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13761     }
13762
13763   mp->remote_integ_key_len = 0;
13764   if (rik)
13765     {
13766       mp->remote_integ_key_len = vec_len (rik);
13767       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13768         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13769       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13770     }
13771
13772   S (mp);
13773   W (ret);
13774   return ret;
13775 }
13776
13777 static int
13778 api_ikev2_profile_add_del (vat_main_t * vam)
13779 {
13780   unformat_input_t *i = vam->input;
13781   vl_api_ikev2_profile_add_del_t *mp;
13782   u8 is_add = 1;
13783   u8 *name = 0;
13784   int ret;
13785
13786   const char *valid_chars = "a-zA-Z0-9_";
13787
13788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13789     {
13790       if (unformat (i, "del"))
13791         is_add = 0;
13792       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13793         vec_add1 (name, 0);
13794       else
13795         {
13796           errmsg ("parse error '%U'", format_unformat_error, i);
13797           return -99;
13798         }
13799     }
13800
13801   if (!vec_len (name))
13802     {
13803       errmsg ("profile name must be specified");
13804       return -99;
13805     }
13806
13807   if (vec_len (name) > 64)
13808     {
13809       errmsg ("profile name too long");
13810       return -99;
13811     }
13812
13813   M (IKEV2_PROFILE_ADD_DEL, mp);
13814
13815   clib_memcpy (mp->name, name, vec_len (name));
13816   mp->is_add = is_add;
13817   vec_free (name);
13818
13819   S (mp);
13820   W (ret);
13821   return ret;
13822 }
13823
13824 static int
13825 api_ikev2_profile_set_auth (vat_main_t * vam)
13826 {
13827   unformat_input_t *i = vam->input;
13828   vl_api_ikev2_profile_set_auth_t *mp;
13829   u8 *name = 0;
13830   u8 *data = 0;
13831   u32 auth_method = 0;
13832   u8 is_hex = 0;
13833   int ret;
13834
13835   const char *valid_chars = "a-zA-Z0-9_";
13836
13837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13838     {
13839       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13840         vec_add1 (name, 0);
13841       else if (unformat (i, "auth_method %U",
13842                          unformat_ikev2_auth_method, &auth_method))
13843         ;
13844       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13845         is_hex = 1;
13846       else if (unformat (i, "auth_data %v", &data))
13847         ;
13848       else
13849         {
13850           errmsg ("parse error '%U'", format_unformat_error, i);
13851           return -99;
13852         }
13853     }
13854
13855   if (!vec_len (name))
13856     {
13857       errmsg ("profile name must be specified");
13858       return -99;
13859     }
13860
13861   if (vec_len (name) > 64)
13862     {
13863       errmsg ("profile name too long");
13864       return -99;
13865     }
13866
13867   if (!vec_len (data))
13868     {
13869       errmsg ("auth_data must be specified");
13870       return -99;
13871     }
13872
13873   if (!auth_method)
13874     {
13875       errmsg ("auth_method must be specified");
13876       return -99;
13877     }
13878
13879   M (IKEV2_PROFILE_SET_AUTH, mp);
13880
13881   mp->is_hex = is_hex;
13882   mp->auth_method = (u8) auth_method;
13883   mp->data_len = vec_len (data);
13884   clib_memcpy (mp->name, name, vec_len (name));
13885   clib_memcpy (mp->data, data, vec_len (data));
13886   vec_free (name);
13887   vec_free (data);
13888
13889   S (mp);
13890   W (ret);
13891   return ret;
13892 }
13893
13894 static int
13895 api_ikev2_profile_set_id (vat_main_t * vam)
13896 {
13897   unformat_input_t *i = vam->input;
13898   vl_api_ikev2_profile_set_id_t *mp;
13899   u8 *name = 0;
13900   u8 *data = 0;
13901   u8 is_local = 0;
13902   u32 id_type = 0;
13903   ip4_address_t ip4;
13904   int ret;
13905
13906   const char *valid_chars = "a-zA-Z0-9_";
13907
13908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13909     {
13910       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13911         vec_add1 (name, 0);
13912       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13913         ;
13914       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13915         {
13916           data = vec_new (u8, 4);
13917           clib_memcpy (data, ip4.as_u8, 4);
13918         }
13919       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13920         ;
13921       else if (unformat (i, "id_data %v", &data))
13922         ;
13923       else if (unformat (i, "local"))
13924         is_local = 1;
13925       else if (unformat (i, "remote"))
13926         is_local = 0;
13927       else
13928         {
13929           errmsg ("parse error '%U'", format_unformat_error, i);
13930           return -99;
13931         }
13932     }
13933
13934   if (!vec_len (name))
13935     {
13936       errmsg ("profile name must be specified");
13937       return -99;
13938     }
13939
13940   if (vec_len (name) > 64)
13941     {
13942       errmsg ("profile name too long");
13943       return -99;
13944     }
13945
13946   if (!vec_len (data))
13947     {
13948       errmsg ("id_data must be specified");
13949       return -99;
13950     }
13951
13952   if (!id_type)
13953     {
13954       errmsg ("id_type must be specified");
13955       return -99;
13956     }
13957
13958   M (IKEV2_PROFILE_SET_ID, mp);
13959
13960   mp->is_local = is_local;
13961   mp->id_type = (u8) id_type;
13962   mp->data_len = vec_len (data);
13963   clib_memcpy (mp->name, name, vec_len (name));
13964   clib_memcpy (mp->data, data, vec_len (data));
13965   vec_free (name);
13966   vec_free (data);
13967
13968   S (mp);
13969   W (ret);
13970   return ret;
13971 }
13972
13973 static int
13974 api_ikev2_profile_set_ts (vat_main_t * vam)
13975 {
13976   unformat_input_t *i = vam->input;
13977   vl_api_ikev2_profile_set_ts_t *mp;
13978   u8 *name = 0;
13979   u8 is_local = 0;
13980   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13981   ip4_address_t start_addr, end_addr;
13982
13983   const char *valid_chars = "a-zA-Z0-9_";
13984   int ret;
13985
13986   start_addr.as_u32 = 0;
13987   end_addr.as_u32 = (u32) ~ 0;
13988
13989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13990     {
13991       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13992         vec_add1 (name, 0);
13993       else if (unformat (i, "protocol %d", &proto))
13994         ;
13995       else if (unformat (i, "start_port %d", &start_port))
13996         ;
13997       else if (unformat (i, "end_port %d", &end_port))
13998         ;
13999       else
14000         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14001         ;
14002       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14003         ;
14004       else if (unformat (i, "local"))
14005         is_local = 1;
14006       else if (unformat (i, "remote"))
14007         is_local = 0;
14008       else
14009         {
14010           errmsg ("parse error '%U'", format_unformat_error, i);
14011           return -99;
14012         }
14013     }
14014
14015   if (!vec_len (name))
14016     {
14017       errmsg ("profile name must be specified");
14018       return -99;
14019     }
14020
14021   if (vec_len (name) > 64)
14022     {
14023       errmsg ("profile name too long");
14024       return -99;
14025     }
14026
14027   M (IKEV2_PROFILE_SET_TS, mp);
14028
14029   mp->is_local = is_local;
14030   mp->proto = (u8) proto;
14031   mp->start_port = (u16) start_port;
14032   mp->end_port = (u16) end_port;
14033   mp->start_addr = start_addr.as_u32;
14034   mp->end_addr = end_addr.as_u32;
14035   clib_memcpy (mp->name, name, vec_len (name));
14036   vec_free (name);
14037
14038   S (mp);
14039   W (ret);
14040   return ret;
14041 }
14042
14043 static int
14044 api_ikev2_set_local_key (vat_main_t * vam)
14045 {
14046   unformat_input_t *i = vam->input;
14047   vl_api_ikev2_set_local_key_t *mp;
14048   u8 *file = 0;
14049   int ret;
14050
14051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14052     {
14053       if (unformat (i, "file %v", &file))
14054         vec_add1 (file, 0);
14055       else
14056         {
14057           errmsg ("parse error '%U'", format_unformat_error, i);
14058           return -99;
14059         }
14060     }
14061
14062   if (!vec_len (file))
14063     {
14064       errmsg ("RSA key file must be specified");
14065       return -99;
14066     }
14067
14068   if (vec_len (file) > 256)
14069     {
14070       errmsg ("file name too long");
14071       return -99;
14072     }
14073
14074   M (IKEV2_SET_LOCAL_KEY, mp);
14075
14076   clib_memcpy (mp->key_file, file, vec_len (file));
14077   vec_free (file);
14078
14079   S (mp);
14080   W (ret);
14081   return ret;
14082 }
14083
14084 static int
14085 api_ikev2_set_responder (vat_main_t * vam)
14086 {
14087   unformat_input_t *i = vam->input;
14088   vl_api_ikev2_set_responder_t *mp;
14089   int ret;
14090   u8 *name = 0;
14091   u32 sw_if_index = ~0;
14092   ip4_address_t address;
14093
14094   const char *valid_chars = "a-zA-Z0-9_";
14095
14096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14097     {
14098       if (unformat
14099           (i, "%U interface %d address %U", unformat_token, valid_chars,
14100            &name, &sw_if_index, unformat_ip4_address, &address))
14101         vec_add1 (name, 0);
14102       else
14103         {
14104           errmsg ("parse error '%U'", format_unformat_error, i);
14105           return -99;
14106         }
14107     }
14108
14109   if (!vec_len (name))
14110     {
14111       errmsg ("profile name must be specified");
14112       return -99;
14113     }
14114
14115   if (vec_len (name) > 64)
14116     {
14117       errmsg ("profile name too long");
14118       return -99;
14119     }
14120
14121   M (IKEV2_SET_RESPONDER, mp);
14122
14123   clib_memcpy (mp->name, name, vec_len (name));
14124   vec_free (name);
14125
14126   mp->sw_if_index = sw_if_index;
14127   clib_memcpy (mp->address, &address, sizeof (address));
14128
14129   S (mp);
14130   W (ret);
14131   return ret;
14132 }
14133
14134 static int
14135 api_ikev2_set_ike_transforms (vat_main_t * vam)
14136 {
14137   unformat_input_t *i = vam->input;
14138   vl_api_ikev2_set_ike_transforms_t *mp;
14139   int ret;
14140   u8 *name = 0;
14141   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14142
14143   const char *valid_chars = "a-zA-Z0-9_";
14144
14145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14146     {
14147       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14148                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14149         vec_add1 (name, 0);
14150       else
14151         {
14152           errmsg ("parse error '%U'", format_unformat_error, i);
14153           return -99;
14154         }
14155     }
14156
14157   if (!vec_len (name))
14158     {
14159       errmsg ("profile name must be specified");
14160       return -99;
14161     }
14162
14163   if (vec_len (name) > 64)
14164     {
14165       errmsg ("profile name too long");
14166       return -99;
14167     }
14168
14169   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14170
14171   clib_memcpy (mp->name, name, vec_len (name));
14172   vec_free (name);
14173   mp->crypto_alg = crypto_alg;
14174   mp->crypto_key_size = crypto_key_size;
14175   mp->integ_alg = integ_alg;
14176   mp->dh_group = dh_group;
14177
14178   S (mp);
14179   W (ret);
14180   return ret;
14181 }
14182
14183
14184 static int
14185 api_ikev2_set_esp_transforms (vat_main_t * vam)
14186 {
14187   unformat_input_t *i = vam->input;
14188   vl_api_ikev2_set_esp_transforms_t *mp;
14189   int ret;
14190   u8 *name = 0;
14191   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14192
14193   const char *valid_chars = "a-zA-Z0-9_";
14194
14195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14196     {
14197       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14198                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14199         vec_add1 (name, 0);
14200       else
14201         {
14202           errmsg ("parse error '%U'", format_unformat_error, i);
14203           return -99;
14204         }
14205     }
14206
14207   if (!vec_len (name))
14208     {
14209       errmsg ("profile name must be specified");
14210       return -99;
14211     }
14212
14213   if (vec_len (name) > 64)
14214     {
14215       errmsg ("profile name too long");
14216       return -99;
14217     }
14218
14219   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14220
14221   clib_memcpy (mp->name, name, vec_len (name));
14222   vec_free (name);
14223   mp->crypto_alg = crypto_alg;
14224   mp->crypto_key_size = crypto_key_size;
14225   mp->integ_alg = integ_alg;
14226   mp->dh_group = dh_group;
14227
14228   S (mp);
14229   W (ret);
14230   return ret;
14231 }
14232
14233 static int
14234 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14235 {
14236   unformat_input_t *i = vam->input;
14237   vl_api_ikev2_set_sa_lifetime_t *mp;
14238   int ret;
14239   u8 *name = 0;
14240   u64 lifetime, lifetime_maxdata;
14241   u32 lifetime_jitter, handover;
14242
14243   const char *valid_chars = "a-zA-Z0-9_";
14244
14245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14246     {
14247       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14248                     &lifetime, &lifetime_jitter, &handover,
14249                     &lifetime_maxdata))
14250         vec_add1 (name, 0);
14251       else
14252         {
14253           errmsg ("parse error '%U'", format_unformat_error, i);
14254           return -99;
14255         }
14256     }
14257
14258   if (!vec_len (name))
14259     {
14260       errmsg ("profile name must be specified");
14261       return -99;
14262     }
14263
14264   if (vec_len (name) > 64)
14265     {
14266       errmsg ("profile name too long");
14267       return -99;
14268     }
14269
14270   M (IKEV2_SET_SA_LIFETIME, mp);
14271
14272   clib_memcpy (mp->name, name, vec_len (name));
14273   vec_free (name);
14274   mp->lifetime = lifetime;
14275   mp->lifetime_jitter = lifetime_jitter;
14276   mp->handover = handover;
14277   mp->lifetime_maxdata = lifetime_maxdata;
14278
14279   S (mp);
14280   W (ret);
14281   return ret;
14282 }
14283
14284 static int
14285 api_ikev2_initiate_sa_init (vat_main_t * vam)
14286 {
14287   unformat_input_t *i = vam->input;
14288   vl_api_ikev2_initiate_sa_init_t *mp;
14289   int ret;
14290   u8 *name = 0;
14291
14292   const char *valid_chars = "a-zA-Z0-9_";
14293
14294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14295     {
14296       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14297         vec_add1 (name, 0);
14298       else
14299         {
14300           errmsg ("parse error '%U'", format_unformat_error, i);
14301           return -99;
14302         }
14303     }
14304
14305   if (!vec_len (name))
14306     {
14307       errmsg ("profile name must be specified");
14308       return -99;
14309     }
14310
14311   if (vec_len (name) > 64)
14312     {
14313       errmsg ("profile name too long");
14314       return -99;
14315     }
14316
14317   M (IKEV2_INITIATE_SA_INIT, mp);
14318
14319   clib_memcpy (mp->name, name, vec_len (name));
14320   vec_free (name);
14321
14322   S (mp);
14323   W (ret);
14324   return ret;
14325 }
14326
14327 static int
14328 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14329 {
14330   unformat_input_t *i = vam->input;
14331   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14332   int ret;
14333   u64 ispi;
14334
14335
14336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14337     {
14338       if (unformat (i, "%lx", &ispi))
14339         ;
14340       else
14341         {
14342           errmsg ("parse error '%U'", format_unformat_error, i);
14343           return -99;
14344         }
14345     }
14346
14347   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14348
14349   mp->ispi = ispi;
14350
14351   S (mp);
14352   W (ret);
14353   return ret;
14354 }
14355
14356 static int
14357 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14358 {
14359   unformat_input_t *i = vam->input;
14360   vl_api_ikev2_initiate_del_child_sa_t *mp;
14361   int ret;
14362   u32 ispi;
14363
14364
14365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14366     {
14367       if (unformat (i, "%x", &ispi))
14368         ;
14369       else
14370         {
14371           errmsg ("parse error '%U'", format_unformat_error, i);
14372           return -99;
14373         }
14374     }
14375
14376   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14377
14378   mp->ispi = ispi;
14379
14380   S (mp);
14381   W (ret);
14382   return ret;
14383 }
14384
14385 static int
14386 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14387 {
14388   unformat_input_t *i = vam->input;
14389   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14390   int ret;
14391   u32 ispi;
14392
14393
14394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14395     {
14396       if (unformat (i, "%x", &ispi))
14397         ;
14398       else
14399         {
14400           errmsg ("parse error '%U'", format_unformat_error, i);
14401           return -99;
14402         }
14403     }
14404
14405   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14406
14407   mp->ispi = ispi;
14408
14409   S (mp);
14410   W (ret);
14411   return ret;
14412 }
14413
14414 /*
14415  * MAP
14416  */
14417 static int
14418 api_map_add_domain (vat_main_t * vam)
14419 {
14420   unformat_input_t *i = vam->input;
14421   vl_api_map_add_domain_t *mp;
14422
14423   ip4_address_t ip4_prefix;
14424   ip6_address_t ip6_prefix;
14425   ip6_address_t ip6_src;
14426   u32 num_m_args = 0;
14427   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14428     0, psid_length = 0;
14429   u8 is_translation = 0;
14430   u32 mtu = 0;
14431   u32 ip6_src_len = 128;
14432   int ret;
14433
14434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14435     {
14436       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14437                     &ip4_prefix, &ip4_prefix_len))
14438         num_m_args++;
14439       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14440                          &ip6_prefix, &ip6_prefix_len))
14441         num_m_args++;
14442       else
14443         if (unformat
14444             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14445              &ip6_src_len))
14446         num_m_args++;
14447       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14448         num_m_args++;
14449       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14450         num_m_args++;
14451       else if (unformat (i, "psid-offset %d", &psid_offset))
14452         num_m_args++;
14453       else if (unformat (i, "psid-len %d", &psid_length))
14454         num_m_args++;
14455       else if (unformat (i, "mtu %d", &mtu))
14456         num_m_args++;
14457       else if (unformat (i, "map-t"))
14458         is_translation = 1;
14459       else
14460         {
14461           clib_warning ("parse error '%U'", format_unformat_error, i);
14462           return -99;
14463         }
14464     }
14465
14466   if (num_m_args < 3)
14467     {
14468       errmsg ("mandatory argument(s) missing");
14469       return -99;
14470     }
14471
14472   /* Construct the API message */
14473   M (MAP_ADD_DOMAIN, mp);
14474
14475   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14476   mp->ip4_prefix_len = ip4_prefix_len;
14477
14478   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14479   mp->ip6_prefix_len = ip6_prefix_len;
14480
14481   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14482   mp->ip6_src_prefix_len = ip6_src_len;
14483
14484   mp->ea_bits_len = ea_bits_len;
14485   mp->psid_offset = psid_offset;
14486   mp->psid_length = psid_length;
14487   mp->is_translation = is_translation;
14488   mp->mtu = htons (mtu);
14489
14490   /* send it... */
14491   S (mp);
14492
14493   /* Wait for a reply, return good/bad news  */
14494   W (ret);
14495   return ret;
14496 }
14497
14498 static int
14499 api_map_del_domain (vat_main_t * vam)
14500 {
14501   unformat_input_t *i = vam->input;
14502   vl_api_map_del_domain_t *mp;
14503
14504   u32 num_m_args = 0;
14505   u32 index;
14506   int ret;
14507
14508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14509     {
14510       if (unformat (i, "index %d", &index))
14511         num_m_args++;
14512       else
14513         {
14514           clib_warning ("parse error '%U'", format_unformat_error, i);
14515           return -99;
14516         }
14517     }
14518
14519   if (num_m_args != 1)
14520     {
14521       errmsg ("mandatory argument(s) missing");
14522       return -99;
14523     }
14524
14525   /* Construct the API message */
14526   M (MAP_DEL_DOMAIN, mp);
14527
14528   mp->index = ntohl (index);
14529
14530   /* send it... */
14531   S (mp);
14532
14533   /* Wait for a reply, return good/bad news  */
14534   W (ret);
14535   return ret;
14536 }
14537
14538 static int
14539 api_map_add_del_rule (vat_main_t * vam)
14540 {
14541   unformat_input_t *i = vam->input;
14542   vl_api_map_add_del_rule_t *mp;
14543   u8 is_add = 1;
14544   ip6_address_t ip6_dst;
14545   u32 num_m_args = 0, index, psid = 0;
14546   int ret;
14547
14548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14549     {
14550       if (unformat (i, "index %d", &index))
14551         num_m_args++;
14552       else if (unformat (i, "psid %d", &psid))
14553         num_m_args++;
14554       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14555         num_m_args++;
14556       else if (unformat (i, "del"))
14557         {
14558           is_add = 0;
14559         }
14560       else
14561         {
14562           clib_warning ("parse error '%U'", format_unformat_error, i);
14563           return -99;
14564         }
14565     }
14566
14567   /* Construct the API message */
14568   M (MAP_ADD_DEL_RULE, mp);
14569
14570   mp->index = ntohl (index);
14571   mp->is_add = is_add;
14572   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14573   mp->psid = ntohs (psid);
14574
14575   /* send it... */
14576   S (mp);
14577
14578   /* Wait for a reply, return good/bad news  */
14579   W (ret);
14580   return ret;
14581 }
14582
14583 static int
14584 api_map_domain_dump (vat_main_t * vam)
14585 {
14586   vl_api_map_domain_dump_t *mp;
14587   vl_api_control_ping_t *mp_ping;
14588   int ret;
14589
14590   /* Construct the API message */
14591   M (MAP_DOMAIN_DUMP, mp);
14592
14593   /* send it... */
14594   S (mp);
14595
14596   /* Use a control ping for synchronization */
14597   MPING (CONTROL_PING, mp_ping);
14598   S (mp_ping);
14599
14600   W (ret);
14601   return ret;
14602 }
14603
14604 static int
14605 api_map_rule_dump (vat_main_t * vam)
14606 {
14607   unformat_input_t *i = vam->input;
14608   vl_api_map_rule_dump_t *mp;
14609   vl_api_control_ping_t *mp_ping;
14610   u32 domain_index = ~0;
14611   int ret;
14612
14613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14614     {
14615       if (unformat (i, "index %u", &domain_index))
14616         ;
14617       else
14618         break;
14619     }
14620
14621   if (domain_index == ~0)
14622     {
14623       clib_warning ("parse error: domain index expected");
14624       return -99;
14625     }
14626
14627   /* Construct the API message */
14628   M (MAP_RULE_DUMP, mp);
14629
14630   mp->domain_index = htonl (domain_index);
14631
14632   /* send it... */
14633   S (mp);
14634
14635   /* Use a control ping for synchronization */
14636   MPING (CONTROL_PING, mp_ping);
14637   S (mp_ping);
14638
14639   W (ret);
14640   return ret;
14641 }
14642
14643 static void vl_api_map_add_domain_reply_t_handler
14644   (vl_api_map_add_domain_reply_t * mp)
14645 {
14646   vat_main_t *vam = &vat_main;
14647   i32 retval = ntohl (mp->retval);
14648
14649   if (vam->async_mode)
14650     {
14651       vam->async_errors += (retval < 0);
14652     }
14653   else
14654     {
14655       vam->retval = retval;
14656       vam->result_ready = 1;
14657     }
14658 }
14659
14660 static void vl_api_map_add_domain_reply_t_handler_json
14661   (vl_api_map_add_domain_reply_t * mp)
14662 {
14663   vat_main_t *vam = &vat_main;
14664   vat_json_node_t node;
14665
14666   vat_json_init_object (&node);
14667   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14668   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14669
14670   vat_json_print (vam->ofp, &node);
14671   vat_json_free (&node);
14672
14673   vam->retval = ntohl (mp->retval);
14674   vam->result_ready = 1;
14675 }
14676
14677 static int
14678 api_get_first_msg_id (vat_main_t * vam)
14679 {
14680   vl_api_get_first_msg_id_t *mp;
14681   unformat_input_t *i = vam->input;
14682   u8 *name;
14683   u8 name_set = 0;
14684   int ret;
14685
14686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14687     {
14688       if (unformat (i, "client %s", &name))
14689         name_set = 1;
14690       else
14691         break;
14692     }
14693
14694   if (name_set == 0)
14695     {
14696       errmsg ("missing client name");
14697       return -99;
14698     }
14699   vec_add1 (name, 0);
14700
14701   if (vec_len (name) > 63)
14702     {
14703       errmsg ("client name too long");
14704       return -99;
14705     }
14706
14707   M (GET_FIRST_MSG_ID, mp);
14708   clib_memcpy (mp->name, name, vec_len (name));
14709   S (mp);
14710   W (ret);
14711   return ret;
14712 }
14713
14714 static int
14715 api_cop_interface_enable_disable (vat_main_t * vam)
14716 {
14717   unformat_input_t *line_input = vam->input;
14718   vl_api_cop_interface_enable_disable_t *mp;
14719   u32 sw_if_index = ~0;
14720   u8 enable_disable = 1;
14721   int ret;
14722
14723   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat (line_input, "disable"))
14726         enable_disable = 0;
14727       if (unformat (line_input, "enable"))
14728         enable_disable = 1;
14729       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14730                          vam, &sw_if_index))
14731         ;
14732       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14733         ;
14734       else
14735         break;
14736     }
14737
14738   if (sw_if_index == ~0)
14739     {
14740       errmsg ("missing interface name or sw_if_index");
14741       return -99;
14742     }
14743
14744   /* Construct the API message */
14745   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14746   mp->sw_if_index = ntohl (sw_if_index);
14747   mp->enable_disable = enable_disable;
14748
14749   /* send it... */
14750   S (mp);
14751   /* Wait for the reply */
14752   W (ret);
14753   return ret;
14754 }
14755
14756 static int
14757 api_cop_whitelist_enable_disable (vat_main_t * vam)
14758 {
14759   unformat_input_t *line_input = vam->input;
14760   vl_api_cop_whitelist_enable_disable_t *mp;
14761   u32 sw_if_index = ~0;
14762   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14763   u32 fib_id = 0;
14764   int ret;
14765
14766   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14767     {
14768       if (unformat (line_input, "ip4"))
14769         ip4 = 1;
14770       else if (unformat (line_input, "ip6"))
14771         ip6 = 1;
14772       else if (unformat (line_input, "default"))
14773         default_cop = 1;
14774       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14775                          vam, &sw_if_index))
14776         ;
14777       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14778         ;
14779       else if (unformat (line_input, "fib-id %d", &fib_id))
14780         ;
14781       else
14782         break;
14783     }
14784
14785   if (sw_if_index == ~0)
14786     {
14787       errmsg ("missing interface name or sw_if_index");
14788       return -99;
14789     }
14790
14791   /* Construct the API message */
14792   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14793   mp->sw_if_index = ntohl (sw_if_index);
14794   mp->fib_id = ntohl (fib_id);
14795   mp->ip4 = ip4;
14796   mp->ip6 = ip6;
14797   mp->default_cop = default_cop;
14798
14799   /* send it... */
14800   S (mp);
14801   /* Wait for the reply */
14802   W (ret);
14803   return ret;
14804 }
14805
14806 static int
14807 api_get_node_graph (vat_main_t * vam)
14808 {
14809   vl_api_get_node_graph_t *mp;
14810   int ret;
14811
14812   M (GET_NODE_GRAPH, mp);
14813
14814   /* send it... */
14815   S (mp);
14816   /* Wait for the reply */
14817   W (ret);
14818   return ret;
14819 }
14820
14821 /* *INDENT-OFF* */
14822 /** Used for parsing LISP eids */
14823 typedef CLIB_PACKED(struct{
14824   u8 addr[16];   /**< eid address */
14825   u32 len;       /**< prefix length if IP */
14826   u8 type;      /**< type of eid */
14827 }) lisp_eid_vat_t;
14828 /* *INDENT-ON* */
14829
14830 static uword
14831 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14832 {
14833   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14834
14835   memset (a, 0, sizeof (a[0]));
14836
14837   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14838     {
14839       a->type = 0;              /* ipv4 type */
14840     }
14841   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14842     {
14843       a->type = 1;              /* ipv6 type */
14844     }
14845   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14846     {
14847       a->type = 2;              /* mac type */
14848     }
14849   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14850     {
14851       a->type = 3;              /* NSH type */
14852       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14853       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14854     }
14855   else
14856     {
14857       return 0;
14858     }
14859
14860   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14861     {
14862       return 0;
14863     }
14864
14865   return 1;
14866 }
14867
14868 static int
14869 lisp_eid_size_vat (u8 type)
14870 {
14871   switch (type)
14872     {
14873     case 0:
14874       return 4;
14875     case 1:
14876       return 16;
14877     case 2:
14878       return 6;
14879     case 3:
14880       return 5;
14881     }
14882   return 0;
14883 }
14884
14885 static void
14886 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14887 {
14888   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14889 }
14890
14891 static int
14892 api_one_add_del_locator_set (vat_main_t * vam)
14893 {
14894   unformat_input_t *input = vam->input;
14895   vl_api_one_add_del_locator_set_t *mp;
14896   u8 is_add = 1;
14897   u8 *locator_set_name = NULL;
14898   u8 locator_set_name_set = 0;
14899   vl_api_local_locator_t locator, *locators = 0;
14900   u32 sw_if_index, priority, weight;
14901   u32 data_len = 0;
14902
14903   int ret;
14904   /* Parse args required to build the message */
14905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14906     {
14907       if (unformat (input, "del"))
14908         {
14909           is_add = 0;
14910         }
14911       else if (unformat (input, "locator-set %s", &locator_set_name))
14912         {
14913           locator_set_name_set = 1;
14914         }
14915       else if (unformat (input, "sw_if_index %u p %u w %u",
14916                          &sw_if_index, &priority, &weight))
14917         {
14918           locator.sw_if_index = htonl (sw_if_index);
14919           locator.priority = priority;
14920           locator.weight = weight;
14921           vec_add1 (locators, locator);
14922         }
14923       else
14924         if (unformat
14925             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14926              &sw_if_index, &priority, &weight))
14927         {
14928           locator.sw_if_index = htonl (sw_if_index);
14929           locator.priority = priority;
14930           locator.weight = weight;
14931           vec_add1 (locators, locator);
14932         }
14933       else
14934         break;
14935     }
14936
14937   if (locator_set_name_set == 0)
14938     {
14939       errmsg ("missing locator-set name");
14940       vec_free (locators);
14941       return -99;
14942     }
14943
14944   if (vec_len (locator_set_name) > 64)
14945     {
14946       errmsg ("locator-set name too long");
14947       vec_free (locator_set_name);
14948       vec_free (locators);
14949       return -99;
14950     }
14951   vec_add1 (locator_set_name, 0);
14952
14953   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14954
14955   /* Construct the API message */
14956   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14957
14958   mp->is_add = is_add;
14959   clib_memcpy (mp->locator_set_name, locator_set_name,
14960                vec_len (locator_set_name));
14961   vec_free (locator_set_name);
14962
14963   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14964   if (locators)
14965     clib_memcpy (mp->locators, locators, data_len);
14966   vec_free (locators);
14967
14968   /* send it... */
14969   S (mp);
14970
14971   /* Wait for a reply... */
14972   W (ret);
14973   return ret;
14974 }
14975
14976 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14977
14978 static int
14979 api_one_add_del_locator (vat_main_t * vam)
14980 {
14981   unformat_input_t *input = vam->input;
14982   vl_api_one_add_del_locator_t *mp;
14983   u32 tmp_if_index = ~0;
14984   u32 sw_if_index = ~0;
14985   u8 sw_if_index_set = 0;
14986   u8 sw_if_index_if_name_set = 0;
14987   u32 priority = ~0;
14988   u8 priority_set = 0;
14989   u32 weight = ~0;
14990   u8 weight_set = 0;
14991   u8 is_add = 1;
14992   u8 *locator_set_name = NULL;
14993   u8 locator_set_name_set = 0;
14994   int ret;
14995
14996   /* Parse args required to build the message */
14997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14998     {
14999       if (unformat (input, "del"))
15000         {
15001           is_add = 0;
15002         }
15003       else if (unformat (input, "locator-set %s", &locator_set_name))
15004         {
15005           locator_set_name_set = 1;
15006         }
15007       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15008                          &tmp_if_index))
15009         {
15010           sw_if_index_if_name_set = 1;
15011           sw_if_index = tmp_if_index;
15012         }
15013       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15014         {
15015           sw_if_index_set = 1;
15016           sw_if_index = tmp_if_index;
15017         }
15018       else if (unformat (input, "p %d", &priority))
15019         {
15020           priority_set = 1;
15021         }
15022       else if (unformat (input, "w %d", &weight))
15023         {
15024           weight_set = 1;
15025         }
15026       else
15027         break;
15028     }
15029
15030   if (locator_set_name_set == 0)
15031     {
15032       errmsg ("missing locator-set name");
15033       return -99;
15034     }
15035
15036   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15037     {
15038       errmsg ("missing sw_if_index");
15039       vec_free (locator_set_name);
15040       return -99;
15041     }
15042
15043   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15044     {
15045       errmsg ("cannot use both params interface name and sw_if_index");
15046       vec_free (locator_set_name);
15047       return -99;
15048     }
15049
15050   if (priority_set == 0)
15051     {
15052       errmsg ("missing locator-set priority");
15053       vec_free (locator_set_name);
15054       return -99;
15055     }
15056
15057   if (weight_set == 0)
15058     {
15059       errmsg ("missing locator-set weight");
15060       vec_free (locator_set_name);
15061       return -99;
15062     }
15063
15064   if (vec_len (locator_set_name) > 64)
15065     {
15066       errmsg ("locator-set name too long");
15067       vec_free (locator_set_name);
15068       return -99;
15069     }
15070   vec_add1 (locator_set_name, 0);
15071
15072   /* Construct the API message */
15073   M (ONE_ADD_DEL_LOCATOR, mp);
15074
15075   mp->is_add = is_add;
15076   mp->sw_if_index = ntohl (sw_if_index);
15077   mp->priority = priority;
15078   mp->weight = weight;
15079   clib_memcpy (mp->locator_set_name, locator_set_name,
15080                vec_len (locator_set_name));
15081   vec_free (locator_set_name);
15082
15083   /* send it... */
15084   S (mp);
15085
15086   /* Wait for a reply... */
15087   W (ret);
15088   return ret;
15089 }
15090
15091 #define api_lisp_add_del_locator api_one_add_del_locator
15092
15093 uword
15094 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15095 {
15096   u32 *key_id = va_arg (*args, u32 *);
15097   u8 *s = 0;
15098
15099   if (unformat (input, "%s", &s))
15100     {
15101       if (!strcmp ((char *) s, "sha1"))
15102         key_id[0] = HMAC_SHA_1_96;
15103       else if (!strcmp ((char *) s, "sha256"))
15104         key_id[0] = HMAC_SHA_256_128;
15105       else
15106         {
15107           clib_warning ("invalid key_id: '%s'", s);
15108           key_id[0] = HMAC_NO_KEY;
15109         }
15110     }
15111   else
15112     return 0;
15113
15114   vec_free (s);
15115   return 1;
15116 }
15117
15118 static int
15119 api_one_add_del_local_eid (vat_main_t * vam)
15120 {
15121   unformat_input_t *input = vam->input;
15122   vl_api_one_add_del_local_eid_t *mp;
15123   u8 is_add = 1;
15124   u8 eid_set = 0;
15125   lisp_eid_vat_t _eid, *eid = &_eid;
15126   u8 *locator_set_name = 0;
15127   u8 locator_set_name_set = 0;
15128   u32 vni = 0;
15129   u16 key_id = 0;
15130   u8 *key = 0;
15131   int ret;
15132
15133   /* Parse args required to build the message */
15134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15135     {
15136       if (unformat (input, "del"))
15137         {
15138           is_add = 0;
15139         }
15140       else if (unformat (input, "vni %d", &vni))
15141         {
15142           ;
15143         }
15144       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15145         {
15146           eid_set = 1;
15147         }
15148       else if (unformat (input, "locator-set %s", &locator_set_name))
15149         {
15150           locator_set_name_set = 1;
15151         }
15152       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15153         ;
15154       else if (unformat (input, "secret-key %_%v%_", &key))
15155         ;
15156       else
15157         break;
15158     }
15159
15160   if (locator_set_name_set == 0)
15161     {
15162       errmsg ("missing locator-set name");
15163       return -99;
15164     }
15165
15166   if (0 == eid_set)
15167     {
15168       errmsg ("EID address not set!");
15169       vec_free (locator_set_name);
15170       return -99;
15171     }
15172
15173   if (key && (0 == key_id))
15174     {
15175       errmsg ("invalid key_id!");
15176       return -99;
15177     }
15178
15179   if (vec_len (key) > 64)
15180     {
15181       errmsg ("key too long");
15182       vec_free (key);
15183       return -99;
15184     }
15185
15186   if (vec_len (locator_set_name) > 64)
15187     {
15188       errmsg ("locator-set name too long");
15189       vec_free (locator_set_name);
15190       return -99;
15191     }
15192   vec_add1 (locator_set_name, 0);
15193
15194   /* Construct the API message */
15195   M (ONE_ADD_DEL_LOCAL_EID, mp);
15196
15197   mp->is_add = is_add;
15198   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15199   mp->eid_type = eid->type;
15200   mp->prefix_len = eid->len;
15201   mp->vni = clib_host_to_net_u32 (vni);
15202   mp->key_id = clib_host_to_net_u16 (key_id);
15203   clib_memcpy (mp->locator_set_name, locator_set_name,
15204                vec_len (locator_set_name));
15205   clib_memcpy (mp->key, key, vec_len (key));
15206
15207   vec_free (locator_set_name);
15208   vec_free (key);
15209
15210   /* send it... */
15211   S (mp);
15212
15213   /* Wait for a reply... */
15214   W (ret);
15215   return ret;
15216 }
15217
15218 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15219
15220 static int
15221 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15222 {
15223   u32 dp_table = 0, vni = 0;;
15224   unformat_input_t *input = vam->input;
15225   vl_api_gpe_add_del_fwd_entry_t *mp;
15226   u8 is_add = 1;
15227   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15228   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15229   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15230   u32 action = ~0, w;
15231   ip4_address_t rmt_rloc4, lcl_rloc4;
15232   ip6_address_t rmt_rloc6, lcl_rloc6;
15233   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15234   int ret;
15235
15236   memset (&rloc, 0, sizeof (rloc));
15237
15238   /* Parse args required to build the message */
15239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15240     {
15241       if (unformat (input, "del"))
15242         is_add = 0;
15243       else if (unformat (input, "add"))
15244         is_add = 1;
15245       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15246         {
15247           rmt_eid_set = 1;
15248         }
15249       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15250         {
15251           lcl_eid_set = 1;
15252         }
15253       else if (unformat (input, "vrf %d", &dp_table))
15254         ;
15255       else if (unformat (input, "bd %d", &dp_table))
15256         ;
15257       else if (unformat (input, "vni %d", &vni))
15258         ;
15259       else if (unformat (input, "w %d", &w))
15260         {
15261           if (!curr_rloc)
15262             {
15263               errmsg ("No RLOC configured for setting priority/weight!");
15264               return -99;
15265             }
15266           curr_rloc->weight = w;
15267         }
15268       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15269                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15270         {
15271           rloc.is_ip4 = 1;
15272
15273           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15274           rloc.weight = 0;
15275           vec_add1 (lcl_locs, rloc);
15276
15277           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15278           vec_add1 (rmt_locs, rloc);
15279           /* weight saved in rmt loc */
15280           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15281         }
15282       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15283                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15284         {
15285           rloc.is_ip4 = 0;
15286           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15287           rloc.weight = 0;
15288           vec_add1 (lcl_locs, rloc);
15289
15290           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15291           vec_add1 (rmt_locs, rloc);
15292           /* weight saved in rmt loc */
15293           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15294         }
15295       else if (unformat (input, "action %d", &action))
15296         {
15297           ;
15298         }
15299       else
15300         {
15301           clib_warning ("parse error '%U'", format_unformat_error, input);
15302           return -99;
15303         }
15304     }
15305
15306   if (!rmt_eid_set)
15307     {
15308       errmsg ("remote eid addresses not set");
15309       return -99;
15310     }
15311
15312   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15313     {
15314       errmsg ("eid types don't match");
15315       return -99;
15316     }
15317
15318   if (0 == rmt_locs && (u32) ~ 0 == action)
15319     {
15320       errmsg ("action not set for negative mapping");
15321       return -99;
15322     }
15323
15324   /* Construct the API message */
15325   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15326       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15327
15328   mp->is_add = is_add;
15329   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15330   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15331   mp->eid_type = rmt_eid->type;
15332   mp->dp_table = clib_host_to_net_u32 (dp_table);
15333   mp->vni = clib_host_to_net_u32 (vni);
15334   mp->rmt_len = rmt_eid->len;
15335   mp->lcl_len = lcl_eid->len;
15336   mp->action = action;
15337
15338   if (0 != rmt_locs && 0 != lcl_locs)
15339     {
15340       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15341       clib_memcpy (mp->locs, lcl_locs,
15342                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15343
15344       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15345       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15346                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15347     }
15348   vec_free (lcl_locs);
15349   vec_free (rmt_locs);
15350
15351   /* send it... */
15352   S (mp);
15353
15354   /* Wait for a reply... */
15355   W (ret);
15356   return ret;
15357 }
15358
15359 static int
15360 api_one_add_del_map_server (vat_main_t * vam)
15361 {
15362   unformat_input_t *input = vam->input;
15363   vl_api_one_add_del_map_server_t *mp;
15364   u8 is_add = 1;
15365   u8 ipv4_set = 0;
15366   u8 ipv6_set = 0;
15367   ip4_address_t ipv4;
15368   ip6_address_t ipv6;
15369   int ret;
15370
15371   /* Parse args required to build the message */
15372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15373     {
15374       if (unformat (input, "del"))
15375         {
15376           is_add = 0;
15377         }
15378       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15379         {
15380           ipv4_set = 1;
15381         }
15382       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15383         {
15384           ipv6_set = 1;
15385         }
15386       else
15387         break;
15388     }
15389
15390   if (ipv4_set && ipv6_set)
15391     {
15392       errmsg ("both eid v4 and v6 addresses set");
15393       return -99;
15394     }
15395
15396   if (!ipv4_set && !ipv6_set)
15397     {
15398       errmsg ("eid addresses not set");
15399       return -99;
15400     }
15401
15402   /* Construct the API message */
15403   M (ONE_ADD_DEL_MAP_SERVER, mp);
15404
15405   mp->is_add = is_add;
15406   if (ipv6_set)
15407     {
15408       mp->is_ipv6 = 1;
15409       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15410     }
15411   else
15412     {
15413       mp->is_ipv6 = 0;
15414       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15415     }
15416
15417   /* send it... */
15418   S (mp);
15419
15420   /* Wait for a reply... */
15421   W (ret);
15422   return ret;
15423 }
15424
15425 #define api_lisp_add_del_map_server api_one_add_del_map_server
15426
15427 static int
15428 api_one_add_del_map_resolver (vat_main_t * vam)
15429 {
15430   unformat_input_t *input = vam->input;
15431   vl_api_one_add_del_map_resolver_t *mp;
15432   u8 is_add = 1;
15433   u8 ipv4_set = 0;
15434   u8 ipv6_set = 0;
15435   ip4_address_t ipv4;
15436   ip6_address_t ipv6;
15437   int ret;
15438
15439   /* Parse args required to build the message */
15440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15441     {
15442       if (unformat (input, "del"))
15443         {
15444           is_add = 0;
15445         }
15446       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15447         {
15448           ipv4_set = 1;
15449         }
15450       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15451         {
15452           ipv6_set = 1;
15453         }
15454       else
15455         break;
15456     }
15457
15458   if (ipv4_set && ipv6_set)
15459     {
15460       errmsg ("both eid v4 and v6 addresses set");
15461       return -99;
15462     }
15463
15464   if (!ipv4_set && !ipv6_set)
15465     {
15466       errmsg ("eid addresses not set");
15467       return -99;
15468     }
15469
15470   /* Construct the API message */
15471   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15472
15473   mp->is_add = is_add;
15474   if (ipv6_set)
15475     {
15476       mp->is_ipv6 = 1;
15477       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15478     }
15479   else
15480     {
15481       mp->is_ipv6 = 0;
15482       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15483     }
15484
15485   /* send it... */
15486   S (mp);
15487
15488   /* Wait for a reply... */
15489   W (ret);
15490   return ret;
15491 }
15492
15493 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15494
15495 static int
15496 api_lisp_gpe_enable_disable (vat_main_t * vam)
15497 {
15498   unformat_input_t *input = vam->input;
15499   vl_api_gpe_enable_disable_t *mp;
15500   u8 is_set = 0;
15501   u8 is_en = 1;
15502   int ret;
15503
15504   /* Parse args required to build the message */
15505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15506     {
15507       if (unformat (input, "enable"))
15508         {
15509           is_set = 1;
15510           is_en = 1;
15511         }
15512       else if (unformat (input, "disable"))
15513         {
15514           is_set = 1;
15515           is_en = 0;
15516         }
15517       else
15518         break;
15519     }
15520
15521   if (is_set == 0)
15522     {
15523       errmsg ("Value not set");
15524       return -99;
15525     }
15526
15527   /* Construct the API message */
15528   M (GPE_ENABLE_DISABLE, mp);
15529
15530   mp->is_en = is_en;
15531
15532   /* send it... */
15533   S (mp);
15534
15535   /* Wait for a reply... */
15536   W (ret);
15537   return ret;
15538 }
15539
15540 static int
15541 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15542 {
15543   unformat_input_t *input = vam->input;
15544   vl_api_one_rloc_probe_enable_disable_t *mp;
15545   u8 is_set = 0;
15546   u8 is_en = 0;
15547   int ret;
15548
15549   /* Parse args required to build the message */
15550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15551     {
15552       if (unformat (input, "enable"))
15553         {
15554           is_set = 1;
15555           is_en = 1;
15556         }
15557       else if (unformat (input, "disable"))
15558         is_set = 1;
15559       else
15560         break;
15561     }
15562
15563   if (!is_set)
15564     {
15565       errmsg ("Value not set");
15566       return -99;
15567     }
15568
15569   /* Construct the API message */
15570   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15571
15572   mp->is_enabled = is_en;
15573
15574   /* send it... */
15575   S (mp);
15576
15577   /* Wait for a reply... */
15578   W (ret);
15579   return ret;
15580 }
15581
15582 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15583
15584 static int
15585 api_one_map_register_enable_disable (vat_main_t * vam)
15586 {
15587   unformat_input_t *input = vam->input;
15588   vl_api_one_map_register_enable_disable_t *mp;
15589   u8 is_set = 0;
15590   u8 is_en = 0;
15591   int ret;
15592
15593   /* Parse args required to build the message */
15594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15595     {
15596       if (unformat (input, "enable"))
15597         {
15598           is_set = 1;
15599           is_en = 1;
15600         }
15601       else if (unformat (input, "disable"))
15602         is_set = 1;
15603       else
15604         break;
15605     }
15606
15607   if (!is_set)
15608     {
15609       errmsg ("Value not set");
15610       return -99;
15611     }
15612
15613   /* Construct the API message */
15614   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15615
15616   mp->is_enabled = is_en;
15617
15618   /* send it... */
15619   S (mp);
15620
15621   /* Wait for a reply... */
15622   W (ret);
15623   return ret;
15624 }
15625
15626 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15627
15628 static int
15629 api_one_enable_disable (vat_main_t * vam)
15630 {
15631   unformat_input_t *input = vam->input;
15632   vl_api_one_enable_disable_t *mp;
15633   u8 is_set = 0;
15634   u8 is_en = 0;
15635   int ret;
15636
15637   /* Parse args required to build the message */
15638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15639     {
15640       if (unformat (input, "enable"))
15641         {
15642           is_set = 1;
15643           is_en = 1;
15644         }
15645       else if (unformat (input, "disable"))
15646         {
15647           is_set = 1;
15648         }
15649       else
15650         break;
15651     }
15652
15653   if (!is_set)
15654     {
15655       errmsg ("Value not set");
15656       return -99;
15657     }
15658
15659   /* Construct the API message */
15660   M (ONE_ENABLE_DISABLE, mp);
15661
15662   mp->is_en = is_en;
15663
15664   /* send it... */
15665   S (mp);
15666
15667   /* Wait for a reply... */
15668   W (ret);
15669   return ret;
15670 }
15671
15672 #define api_lisp_enable_disable api_one_enable_disable
15673
15674 static int
15675 api_show_one_map_register_state (vat_main_t * vam)
15676 {
15677   vl_api_show_one_map_register_state_t *mp;
15678   int ret;
15679
15680   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15681
15682   /* send */
15683   S (mp);
15684
15685   /* wait for reply */
15686   W (ret);
15687   return ret;
15688 }
15689
15690 #define api_show_lisp_map_register_state api_show_one_map_register_state
15691
15692 static int
15693 api_show_one_rloc_probe_state (vat_main_t * vam)
15694 {
15695   vl_api_show_one_rloc_probe_state_t *mp;
15696   int ret;
15697
15698   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15699
15700   /* send */
15701   S (mp);
15702
15703   /* wait for reply */
15704   W (ret);
15705   return ret;
15706 }
15707
15708 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15709
15710 static int
15711 api_one_add_del_ndp_entry (vat_main_t * vam)
15712 {
15713   vl_api_one_add_del_ndp_entry_t *mp;
15714   unformat_input_t *input = vam->input;
15715   u8 is_add = 1;
15716   u8 mac_set = 0;
15717   u8 bd_set = 0;
15718   u8 ip_set = 0;
15719   u8 mac[6] = { 0, };
15720   u8 ip6[16] = { 0, };
15721   u32 bd = ~0;
15722   int ret;
15723
15724   /* Parse args required to build the message */
15725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15726     {
15727       if (unformat (input, "del"))
15728         is_add = 0;
15729       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15730         mac_set = 1;
15731       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15732         ip_set = 1;
15733       else if (unformat (input, "bd %d", &bd))
15734         bd_set = 1;
15735       else
15736         {
15737           errmsg ("parse error '%U'", format_unformat_error, input);
15738           return -99;
15739         }
15740     }
15741
15742   if (!bd_set || !ip_set || (!mac_set && is_add))
15743     {
15744       errmsg ("Missing BD, IP or MAC!");
15745       return -99;
15746     }
15747
15748   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15749   mp->is_add = is_add;
15750   clib_memcpy (mp->mac, mac, 6);
15751   mp->bd = clib_host_to_net_u32 (bd);
15752   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15753
15754   /* send */
15755   S (mp);
15756
15757   /* wait for reply */
15758   W (ret);
15759   return ret;
15760 }
15761
15762 static int
15763 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15764 {
15765   vl_api_one_add_del_l2_arp_entry_t *mp;
15766   unformat_input_t *input = vam->input;
15767   u8 is_add = 1;
15768   u8 mac_set = 0;
15769   u8 bd_set = 0;
15770   u8 ip_set = 0;
15771   u8 mac[6] = { 0, };
15772   u32 ip4 = 0, bd = ~0;
15773   int ret;
15774
15775   /* Parse args required to build the message */
15776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15777     {
15778       if (unformat (input, "del"))
15779         is_add = 0;
15780       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15781         mac_set = 1;
15782       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15783         ip_set = 1;
15784       else if (unformat (input, "bd %d", &bd))
15785         bd_set = 1;
15786       else
15787         {
15788           errmsg ("parse error '%U'", format_unformat_error, input);
15789           return -99;
15790         }
15791     }
15792
15793   if (!bd_set || !ip_set || (!mac_set && is_add))
15794     {
15795       errmsg ("Missing BD, IP or MAC!");
15796       return -99;
15797     }
15798
15799   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15800   mp->is_add = is_add;
15801   clib_memcpy (mp->mac, mac, 6);
15802   mp->bd = clib_host_to_net_u32 (bd);
15803   mp->ip4 = ip4;
15804
15805   /* send */
15806   S (mp);
15807
15808   /* wait for reply */
15809   W (ret);
15810   return ret;
15811 }
15812
15813 static int
15814 api_one_ndp_bd_get (vat_main_t * vam)
15815 {
15816   vl_api_one_ndp_bd_get_t *mp;
15817   int ret;
15818
15819   M (ONE_NDP_BD_GET, mp);
15820
15821   /* send */
15822   S (mp);
15823
15824   /* wait for reply */
15825   W (ret);
15826   return ret;
15827 }
15828
15829 static int
15830 api_one_ndp_entries_get (vat_main_t * vam)
15831 {
15832   vl_api_one_ndp_entries_get_t *mp;
15833   unformat_input_t *input = vam->input;
15834   u8 bd_set = 0;
15835   u32 bd = ~0;
15836   int ret;
15837
15838   /* Parse args required to build the message */
15839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15840     {
15841       if (unformat (input, "bd %d", &bd))
15842         bd_set = 1;
15843       else
15844         {
15845           errmsg ("parse error '%U'", format_unformat_error, input);
15846           return -99;
15847         }
15848     }
15849
15850   if (!bd_set)
15851     {
15852       errmsg ("Expected bridge domain!");
15853       return -99;
15854     }
15855
15856   M (ONE_NDP_ENTRIES_GET, mp);
15857   mp->bd = clib_host_to_net_u32 (bd);
15858
15859   /* send */
15860   S (mp);
15861
15862   /* wait for reply */
15863   W (ret);
15864   return ret;
15865 }
15866
15867 static int
15868 api_one_l2_arp_bd_get (vat_main_t * vam)
15869 {
15870   vl_api_one_l2_arp_bd_get_t *mp;
15871   int ret;
15872
15873   M (ONE_L2_ARP_BD_GET, mp);
15874
15875   /* send */
15876   S (mp);
15877
15878   /* wait for reply */
15879   W (ret);
15880   return ret;
15881 }
15882
15883 static int
15884 api_one_l2_arp_entries_get (vat_main_t * vam)
15885 {
15886   vl_api_one_l2_arp_entries_get_t *mp;
15887   unformat_input_t *input = vam->input;
15888   u8 bd_set = 0;
15889   u32 bd = ~0;
15890   int ret;
15891
15892   /* Parse args required to build the message */
15893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15894     {
15895       if (unformat (input, "bd %d", &bd))
15896         bd_set = 1;
15897       else
15898         {
15899           errmsg ("parse error '%U'", format_unformat_error, input);
15900           return -99;
15901         }
15902     }
15903
15904   if (!bd_set)
15905     {
15906       errmsg ("Expected bridge domain!");
15907       return -99;
15908     }
15909
15910   M (ONE_L2_ARP_ENTRIES_GET, mp);
15911   mp->bd = clib_host_to_net_u32 (bd);
15912
15913   /* send */
15914   S (mp);
15915
15916   /* wait for reply */
15917   W (ret);
15918   return ret;
15919 }
15920
15921 static int
15922 api_one_stats_enable_disable (vat_main_t * vam)
15923 {
15924   vl_api_one_stats_enable_disable_t *mp;
15925   unformat_input_t *input = vam->input;
15926   u8 is_set = 0;
15927   u8 is_en = 0;
15928   int ret;
15929
15930   /* Parse args required to build the message */
15931   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15932     {
15933       if (unformat (input, "enable"))
15934         {
15935           is_set = 1;
15936           is_en = 1;
15937         }
15938       else if (unformat (input, "disable"))
15939         {
15940           is_set = 1;
15941         }
15942       else
15943         break;
15944     }
15945
15946   if (!is_set)
15947     {
15948       errmsg ("Value not set");
15949       return -99;
15950     }
15951
15952   M (ONE_STATS_ENABLE_DISABLE, mp);
15953   mp->is_en = is_en;
15954
15955   /* send */
15956   S (mp);
15957
15958   /* wait for reply */
15959   W (ret);
15960   return ret;
15961 }
15962
15963 static int
15964 api_show_one_stats_enable_disable (vat_main_t * vam)
15965 {
15966   vl_api_show_one_stats_enable_disable_t *mp;
15967   int ret;
15968
15969   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15970
15971   /* send */
15972   S (mp);
15973
15974   /* wait for reply */
15975   W (ret);
15976   return ret;
15977 }
15978
15979 static int
15980 api_show_one_map_request_mode (vat_main_t * vam)
15981 {
15982   vl_api_show_one_map_request_mode_t *mp;
15983   int ret;
15984
15985   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15986
15987   /* send */
15988   S (mp);
15989
15990   /* wait for reply */
15991   W (ret);
15992   return ret;
15993 }
15994
15995 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15996
15997 static int
15998 api_one_map_request_mode (vat_main_t * vam)
15999 {
16000   unformat_input_t *input = vam->input;
16001   vl_api_one_map_request_mode_t *mp;
16002   u8 mode = 0;
16003   int ret;
16004
16005   /* Parse args required to build the message */
16006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16007     {
16008       if (unformat (input, "dst-only"))
16009         mode = 0;
16010       else if (unformat (input, "src-dst"))
16011         mode = 1;
16012       else
16013         {
16014           errmsg ("parse error '%U'", format_unformat_error, input);
16015           return -99;
16016         }
16017     }
16018
16019   M (ONE_MAP_REQUEST_MODE, mp);
16020
16021   mp->mode = mode;
16022
16023   /* send */
16024   S (mp);
16025
16026   /* wait for reply */
16027   W (ret);
16028   return ret;
16029 }
16030
16031 #define api_lisp_map_request_mode api_one_map_request_mode
16032
16033 /**
16034  * Enable/disable ONE proxy ITR.
16035  *
16036  * @param vam vpp API test context
16037  * @return return code
16038  */
16039 static int
16040 api_one_pitr_set_locator_set (vat_main_t * vam)
16041 {
16042   u8 ls_name_set = 0;
16043   unformat_input_t *input = vam->input;
16044   vl_api_one_pitr_set_locator_set_t *mp;
16045   u8 is_add = 1;
16046   u8 *ls_name = 0;
16047   int ret;
16048
16049   /* Parse args required to build the message */
16050   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16051     {
16052       if (unformat (input, "del"))
16053         is_add = 0;
16054       else if (unformat (input, "locator-set %s", &ls_name))
16055         ls_name_set = 1;
16056       else
16057         {
16058           errmsg ("parse error '%U'", format_unformat_error, input);
16059           return -99;
16060         }
16061     }
16062
16063   if (!ls_name_set)
16064     {
16065       errmsg ("locator-set name not set!");
16066       return -99;
16067     }
16068
16069   M (ONE_PITR_SET_LOCATOR_SET, mp);
16070
16071   mp->is_add = is_add;
16072   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16073   vec_free (ls_name);
16074
16075   /* send */
16076   S (mp);
16077
16078   /* wait for reply */
16079   W (ret);
16080   return ret;
16081 }
16082
16083 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16084
16085 static int
16086 api_one_nsh_set_locator_set (vat_main_t * vam)
16087 {
16088   u8 ls_name_set = 0;
16089   unformat_input_t *input = vam->input;
16090   vl_api_one_nsh_set_locator_set_t *mp;
16091   u8 is_add = 1;
16092   u8 *ls_name = 0;
16093   int ret;
16094
16095   /* Parse args required to build the message */
16096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16097     {
16098       if (unformat (input, "del"))
16099         is_add = 0;
16100       else if (unformat (input, "ls %s", &ls_name))
16101         ls_name_set = 1;
16102       else
16103         {
16104           errmsg ("parse error '%U'", format_unformat_error, input);
16105           return -99;
16106         }
16107     }
16108
16109   if (!ls_name_set && is_add)
16110     {
16111       errmsg ("locator-set name not set!");
16112       return -99;
16113     }
16114
16115   M (ONE_NSH_SET_LOCATOR_SET, mp);
16116
16117   mp->is_add = is_add;
16118   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16119   vec_free (ls_name);
16120
16121   /* send */
16122   S (mp);
16123
16124   /* wait for reply */
16125   W (ret);
16126   return ret;
16127 }
16128
16129 static int
16130 api_show_one_pitr (vat_main_t * vam)
16131 {
16132   vl_api_show_one_pitr_t *mp;
16133   int ret;
16134
16135   if (!vam->json_output)
16136     {
16137       print (vam->ofp, "%=20s", "lisp status:");
16138     }
16139
16140   M (SHOW_ONE_PITR, mp);
16141   /* send it... */
16142   S (mp);
16143
16144   /* Wait for a reply... */
16145   W (ret);
16146   return ret;
16147 }
16148
16149 #define api_show_lisp_pitr api_show_one_pitr
16150
16151 static int
16152 api_one_use_petr (vat_main_t * vam)
16153 {
16154   unformat_input_t *input = vam->input;
16155   vl_api_one_use_petr_t *mp;
16156   u8 is_add = 0;
16157   ip_address_t ip;
16158   int ret;
16159
16160   memset (&ip, 0, sizeof (ip));
16161
16162   /* Parse args required to build the message */
16163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16164     {
16165       if (unformat (input, "disable"))
16166         is_add = 0;
16167       else
16168         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16169         {
16170           is_add = 1;
16171           ip_addr_version (&ip) = IP4;
16172         }
16173       else
16174         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16175         {
16176           is_add = 1;
16177           ip_addr_version (&ip) = IP6;
16178         }
16179       else
16180         {
16181           errmsg ("parse error '%U'", format_unformat_error, input);
16182           return -99;
16183         }
16184     }
16185
16186   M (ONE_USE_PETR, mp);
16187
16188   mp->is_add = is_add;
16189   if (is_add)
16190     {
16191       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16192       if (mp->is_ip4)
16193         clib_memcpy (mp->address, &ip, 4);
16194       else
16195         clib_memcpy (mp->address, &ip, 16);
16196     }
16197
16198   /* send */
16199   S (mp);
16200
16201   /* wait for reply */
16202   W (ret);
16203   return ret;
16204 }
16205
16206 #define api_lisp_use_petr api_one_use_petr
16207
16208 static int
16209 api_show_one_nsh_mapping (vat_main_t * vam)
16210 {
16211   vl_api_show_one_use_petr_t *mp;
16212   int ret;
16213
16214   if (!vam->json_output)
16215     {
16216       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16217     }
16218
16219   M (SHOW_ONE_NSH_MAPPING, mp);
16220   /* send it... */
16221   S (mp);
16222
16223   /* Wait for a reply... */
16224   W (ret);
16225   return ret;
16226 }
16227
16228 static int
16229 api_show_one_use_petr (vat_main_t * vam)
16230 {
16231   vl_api_show_one_use_petr_t *mp;
16232   int ret;
16233
16234   if (!vam->json_output)
16235     {
16236       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16237     }
16238
16239   M (SHOW_ONE_USE_PETR, mp);
16240   /* send it... */
16241   S (mp);
16242
16243   /* Wait for a reply... */
16244   W (ret);
16245   return ret;
16246 }
16247
16248 #define api_show_lisp_use_petr api_show_one_use_petr
16249
16250 /**
16251  * Add/delete mapping between vni and vrf
16252  */
16253 static int
16254 api_one_eid_table_add_del_map (vat_main_t * vam)
16255 {
16256   unformat_input_t *input = vam->input;
16257   vl_api_one_eid_table_add_del_map_t *mp;
16258   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16259   u32 vni, vrf, bd_index;
16260   int ret;
16261
16262   /* Parse args required to build the message */
16263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16264     {
16265       if (unformat (input, "del"))
16266         is_add = 0;
16267       else if (unformat (input, "vrf %d", &vrf))
16268         vrf_set = 1;
16269       else if (unformat (input, "bd_index %d", &bd_index))
16270         bd_index_set = 1;
16271       else if (unformat (input, "vni %d", &vni))
16272         vni_set = 1;
16273       else
16274         break;
16275     }
16276
16277   if (!vni_set || (!vrf_set && !bd_index_set))
16278     {
16279       errmsg ("missing arguments!");
16280       return -99;
16281     }
16282
16283   if (vrf_set && bd_index_set)
16284     {
16285       errmsg ("error: both vrf and bd entered!");
16286       return -99;
16287     }
16288
16289   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16290
16291   mp->is_add = is_add;
16292   mp->vni = htonl (vni);
16293   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16294   mp->is_l2 = bd_index_set;
16295
16296   /* send */
16297   S (mp);
16298
16299   /* wait for reply */
16300   W (ret);
16301   return ret;
16302 }
16303
16304 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16305
16306 uword
16307 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16308 {
16309   u32 *action = va_arg (*args, u32 *);
16310   u8 *s = 0;
16311
16312   if (unformat (input, "%s", &s))
16313     {
16314       if (!strcmp ((char *) s, "no-action"))
16315         action[0] = 0;
16316       else if (!strcmp ((char *) s, "natively-forward"))
16317         action[0] = 1;
16318       else if (!strcmp ((char *) s, "send-map-request"))
16319         action[0] = 2;
16320       else if (!strcmp ((char *) s, "drop"))
16321         action[0] = 3;
16322       else
16323         {
16324           clib_warning ("invalid action: '%s'", s);
16325           action[0] = 3;
16326         }
16327     }
16328   else
16329     return 0;
16330
16331   vec_free (s);
16332   return 1;
16333 }
16334
16335 /**
16336  * Add/del remote mapping to/from ONE control plane
16337  *
16338  * @param vam vpp API test context
16339  * @return return code
16340  */
16341 static int
16342 api_one_add_del_remote_mapping (vat_main_t * vam)
16343 {
16344   unformat_input_t *input = vam->input;
16345   vl_api_one_add_del_remote_mapping_t *mp;
16346   u32 vni = 0;
16347   lisp_eid_vat_t _eid, *eid = &_eid;
16348   lisp_eid_vat_t _seid, *seid = &_seid;
16349   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16350   u32 action = ~0, p, w, data_len;
16351   ip4_address_t rloc4;
16352   ip6_address_t rloc6;
16353   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16354   int ret;
16355
16356   memset (&rloc, 0, sizeof (rloc));
16357
16358   /* Parse args required to build the message */
16359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16360     {
16361       if (unformat (input, "del-all"))
16362         {
16363           del_all = 1;
16364         }
16365       else if (unformat (input, "del"))
16366         {
16367           is_add = 0;
16368         }
16369       else if (unformat (input, "add"))
16370         {
16371           is_add = 1;
16372         }
16373       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16374         {
16375           eid_set = 1;
16376         }
16377       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16378         {
16379           seid_set = 1;
16380         }
16381       else if (unformat (input, "vni %d", &vni))
16382         {
16383           ;
16384         }
16385       else if (unformat (input, "p %d w %d", &p, &w))
16386         {
16387           if (!curr_rloc)
16388             {
16389               errmsg ("No RLOC configured for setting priority/weight!");
16390               return -99;
16391             }
16392           curr_rloc->priority = p;
16393           curr_rloc->weight = w;
16394         }
16395       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16396         {
16397           rloc.is_ip4 = 1;
16398           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16399           vec_add1 (rlocs, rloc);
16400           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16401         }
16402       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16403         {
16404           rloc.is_ip4 = 0;
16405           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16406           vec_add1 (rlocs, rloc);
16407           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16408         }
16409       else if (unformat (input, "action %U",
16410                          unformat_negative_mapping_action, &action))
16411         {
16412           ;
16413         }
16414       else
16415         {
16416           clib_warning ("parse error '%U'", format_unformat_error, input);
16417           return -99;
16418         }
16419     }
16420
16421   if (0 == eid_set)
16422     {
16423       errmsg ("missing params!");
16424       return -99;
16425     }
16426
16427   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16428     {
16429       errmsg ("no action set for negative map-reply!");
16430       return -99;
16431     }
16432
16433   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16434
16435   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16436   mp->is_add = is_add;
16437   mp->vni = htonl (vni);
16438   mp->action = (u8) action;
16439   mp->is_src_dst = seid_set;
16440   mp->eid_len = eid->len;
16441   mp->seid_len = seid->len;
16442   mp->del_all = del_all;
16443   mp->eid_type = eid->type;
16444   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16445   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16446
16447   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16448   clib_memcpy (mp->rlocs, rlocs, data_len);
16449   vec_free (rlocs);
16450
16451   /* send it... */
16452   S (mp);
16453
16454   /* Wait for a reply... */
16455   W (ret);
16456   return ret;
16457 }
16458
16459 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16460
16461 /**
16462  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16463  * forwarding entries in data-plane accordingly.
16464  *
16465  * @param vam vpp API test context
16466  * @return return code
16467  */
16468 static int
16469 api_one_add_del_adjacency (vat_main_t * vam)
16470 {
16471   unformat_input_t *input = vam->input;
16472   vl_api_one_add_del_adjacency_t *mp;
16473   u32 vni = 0;
16474   ip4_address_t leid4, reid4;
16475   ip6_address_t leid6, reid6;
16476   u8 reid_mac[6] = { 0 };
16477   u8 leid_mac[6] = { 0 };
16478   u8 reid_type, leid_type;
16479   u32 leid_len = 0, reid_len = 0, len;
16480   u8 is_add = 1;
16481   int ret;
16482
16483   leid_type = reid_type = (u8) ~ 0;
16484
16485   /* Parse args required to build the message */
16486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16487     {
16488       if (unformat (input, "del"))
16489         {
16490           is_add = 0;
16491         }
16492       else if (unformat (input, "add"))
16493         {
16494           is_add = 1;
16495         }
16496       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16497                          &reid4, &len))
16498         {
16499           reid_type = 0;        /* ipv4 */
16500           reid_len = len;
16501         }
16502       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16503                          &reid6, &len))
16504         {
16505           reid_type = 1;        /* ipv6 */
16506           reid_len = len;
16507         }
16508       else if (unformat (input, "reid %U", unformat_ethernet_address,
16509                          reid_mac))
16510         {
16511           reid_type = 2;        /* mac */
16512         }
16513       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16514                          &leid4, &len))
16515         {
16516           leid_type = 0;        /* ipv4 */
16517           leid_len = len;
16518         }
16519       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16520                          &leid6, &len))
16521         {
16522           leid_type = 1;        /* ipv6 */
16523           leid_len = len;
16524         }
16525       else if (unformat (input, "leid %U", unformat_ethernet_address,
16526                          leid_mac))
16527         {
16528           leid_type = 2;        /* mac */
16529         }
16530       else if (unformat (input, "vni %d", &vni))
16531         {
16532           ;
16533         }
16534       else
16535         {
16536           errmsg ("parse error '%U'", format_unformat_error, input);
16537           return -99;
16538         }
16539     }
16540
16541   if ((u8) ~ 0 == reid_type)
16542     {
16543       errmsg ("missing params!");
16544       return -99;
16545     }
16546
16547   if (leid_type != reid_type)
16548     {
16549       errmsg ("remote and local EIDs are of different types!");
16550       return -99;
16551     }
16552
16553   M (ONE_ADD_DEL_ADJACENCY, mp);
16554   mp->is_add = is_add;
16555   mp->vni = htonl (vni);
16556   mp->leid_len = leid_len;
16557   mp->reid_len = reid_len;
16558   mp->eid_type = reid_type;
16559
16560   switch (mp->eid_type)
16561     {
16562     case 0:
16563       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16564       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16565       break;
16566     case 1:
16567       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16568       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16569       break;
16570     case 2:
16571       clib_memcpy (mp->leid, leid_mac, 6);
16572       clib_memcpy (mp->reid, reid_mac, 6);
16573       break;
16574     default:
16575       errmsg ("unknown EID type %d!", mp->eid_type);
16576       return 0;
16577     }
16578
16579   /* send it... */
16580   S (mp);
16581
16582   /* Wait for a reply... */
16583   W (ret);
16584   return ret;
16585 }
16586
16587 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16588
16589 uword
16590 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16591 {
16592   u32 *mode = va_arg (*args, u32 *);
16593
16594   if (unformat (input, "lisp"))
16595     *mode = 0;
16596   else if (unformat (input, "vxlan"))
16597     *mode = 1;
16598   else
16599     return 0;
16600
16601   return 1;
16602 }
16603
16604 static int
16605 api_gpe_get_encap_mode (vat_main_t * vam)
16606 {
16607   vl_api_gpe_get_encap_mode_t *mp;
16608   int ret;
16609
16610   /* Construct the API message */
16611   M (GPE_GET_ENCAP_MODE, mp);
16612
16613   /* send it... */
16614   S (mp);
16615
16616   /* Wait for a reply... */
16617   W (ret);
16618   return ret;
16619 }
16620
16621 static int
16622 api_gpe_set_encap_mode (vat_main_t * vam)
16623 {
16624   unformat_input_t *input = vam->input;
16625   vl_api_gpe_set_encap_mode_t *mp;
16626   int ret;
16627   u32 mode = 0;
16628
16629   /* Parse args required to build the message */
16630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16631     {
16632       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16633         ;
16634       else
16635         break;
16636     }
16637
16638   /* Construct the API message */
16639   M (GPE_SET_ENCAP_MODE, mp);
16640
16641   mp->mode = mode;
16642
16643   /* send it... */
16644   S (mp);
16645
16646   /* Wait for a reply... */
16647   W (ret);
16648   return ret;
16649 }
16650
16651 static int
16652 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16653 {
16654   unformat_input_t *input = vam->input;
16655   vl_api_gpe_add_del_iface_t *mp;
16656   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16657   u32 dp_table = 0, vni = 0;
16658   int ret;
16659
16660   /* Parse args required to build the message */
16661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16662     {
16663       if (unformat (input, "up"))
16664         {
16665           action_set = 1;
16666           is_add = 1;
16667         }
16668       else if (unformat (input, "down"))
16669         {
16670           action_set = 1;
16671           is_add = 0;
16672         }
16673       else if (unformat (input, "table_id %d", &dp_table))
16674         {
16675           dp_table_set = 1;
16676         }
16677       else if (unformat (input, "bd_id %d", &dp_table))
16678         {
16679           dp_table_set = 1;
16680           is_l2 = 1;
16681         }
16682       else if (unformat (input, "vni %d", &vni))
16683         {
16684           vni_set = 1;
16685         }
16686       else
16687         break;
16688     }
16689
16690   if (action_set == 0)
16691     {
16692       errmsg ("Action not set");
16693       return -99;
16694     }
16695   if (dp_table_set == 0 || vni_set == 0)
16696     {
16697       errmsg ("vni and dp_table must be set");
16698       return -99;
16699     }
16700
16701   /* Construct the API message */
16702   M (GPE_ADD_DEL_IFACE, mp);
16703
16704   mp->is_add = is_add;
16705   mp->dp_table = clib_host_to_net_u32 (dp_table);
16706   mp->is_l2 = is_l2;
16707   mp->vni = clib_host_to_net_u32 (vni);
16708
16709   /* send it... */
16710   S (mp);
16711
16712   /* Wait for a reply... */
16713   W (ret);
16714   return ret;
16715 }
16716
16717 static int
16718 api_one_map_register_fallback_threshold (vat_main_t * vam)
16719 {
16720   unformat_input_t *input = vam->input;
16721   vl_api_one_map_register_fallback_threshold_t *mp;
16722   u32 value = 0;
16723   u8 is_set = 0;
16724   int ret;
16725
16726   /* Parse args required to build the message */
16727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16728     {
16729       if (unformat (input, "%u", &value))
16730         is_set = 1;
16731       else
16732         {
16733           clib_warning ("parse error '%U'", format_unformat_error, input);
16734           return -99;
16735         }
16736     }
16737
16738   if (!is_set)
16739     {
16740       errmsg ("fallback threshold value is missing!");
16741       return -99;
16742     }
16743
16744   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16745   mp->value = clib_host_to_net_u32 (value);
16746
16747   /* send it... */
16748   S (mp);
16749
16750   /* Wait for a reply... */
16751   W (ret);
16752   return ret;
16753 }
16754
16755 static int
16756 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16757 {
16758   vl_api_show_one_map_register_fallback_threshold_t *mp;
16759   int ret;
16760
16761   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16762
16763   /* send it... */
16764   S (mp);
16765
16766   /* Wait for a reply... */
16767   W (ret);
16768   return ret;
16769 }
16770
16771 uword
16772 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16773 {
16774   u32 *proto = va_arg (*args, u32 *);
16775
16776   if (unformat (input, "udp"))
16777     *proto = 1;
16778   else if (unformat (input, "api"))
16779     *proto = 2;
16780   else
16781     return 0;
16782
16783   return 1;
16784 }
16785
16786 static int
16787 api_one_set_transport_protocol (vat_main_t * vam)
16788 {
16789   unformat_input_t *input = vam->input;
16790   vl_api_one_set_transport_protocol_t *mp;
16791   u8 is_set = 0;
16792   u32 protocol = 0;
16793   int ret;
16794
16795   /* Parse args required to build the message */
16796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16797     {
16798       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16799         is_set = 1;
16800       else
16801         {
16802           clib_warning ("parse error '%U'", format_unformat_error, input);
16803           return -99;
16804         }
16805     }
16806
16807   if (!is_set)
16808     {
16809       errmsg ("Transport protocol missing!");
16810       return -99;
16811     }
16812
16813   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16814   mp->protocol = (u8) protocol;
16815
16816   /* send it... */
16817   S (mp);
16818
16819   /* Wait for a reply... */
16820   W (ret);
16821   return ret;
16822 }
16823
16824 static int
16825 api_one_get_transport_protocol (vat_main_t * vam)
16826 {
16827   vl_api_one_get_transport_protocol_t *mp;
16828   int ret;
16829
16830   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16831
16832   /* send it... */
16833   S (mp);
16834
16835   /* Wait for a reply... */
16836   W (ret);
16837   return ret;
16838 }
16839
16840 static int
16841 api_one_map_register_set_ttl (vat_main_t * vam)
16842 {
16843   unformat_input_t *input = vam->input;
16844   vl_api_one_map_register_set_ttl_t *mp;
16845   u32 ttl = 0;
16846   u8 is_set = 0;
16847   int ret;
16848
16849   /* Parse args required to build the message */
16850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16851     {
16852       if (unformat (input, "%u", &ttl))
16853         is_set = 1;
16854       else
16855         {
16856           clib_warning ("parse error '%U'", format_unformat_error, input);
16857           return -99;
16858         }
16859     }
16860
16861   if (!is_set)
16862     {
16863       errmsg ("TTL value missing!");
16864       return -99;
16865     }
16866
16867   M (ONE_MAP_REGISTER_SET_TTL, mp);
16868   mp->ttl = clib_host_to_net_u32 (ttl);
16869
16870   /* send it... */
16871   S (mp);
16872
16873   /* Wait for a reply... */
16874   W (ret);
16875   return ret;
16876 }
16877
16878 static int
16879 api_show_one_map_register_ttl (vat_main_t * vam)
16880 {
16881   vl_api_show_one_map_register_ttl_t *mp;
16882   int ret;
16883
16884   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16885
16886   /* send it... */
16887   S (mp);
16888
16889   /* Wait for a reply... */
16890   W (ret);
16891   return ret;
16892 }
16893
16894 /**
16895  * Add/del map request itr rlocs from ONE control plane and updates
16896  *
16897  * @param vam vpp API test context
16898  * @return return code
16899  */
16900 static int
16901 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16902 {
16903   unformat_input_t *input = vam->input;
16904   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16905   u8 *locator_set_name = 0;
16906   u8 locator_set_name_set = 0;
16907   u8 is_add = 1;
16908   int ret;
16909
16910   /* Parse args required to build the message */
16911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16912     {
16913       if (unformat (input, "del"))
16914         {
16915           is_add = 0;
16916         }
16917       else if (unformat (input, "%_%v%_", &locator_set_name))
16918         {
16919           locator_set_name_set = 1;
16920         }
16921       else
16922         {
16923           clib_warning ("parse error '%U'", format_unformat_error, input);
16924           return -99;
16925         }
16926     }
16927
16928   if (is_add && !locator_set_name_set)
16929     {
16930       errmsg ("itr-rloc is not set!");
16931       return -99;
16932     }
16933
16934   if (is_add && vec_len (locator_set_name) > 64)
16935     {
16936       errmsg ("itr-rloc locator-set name too long");
16937       vec_free (locator_set_name);
16938       return -99;
16939     }
16940
16941   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16942   mp->is_add = is_add;
16943   if (is_add)
16944     {
16945       clib_memcpy (mp->locator_set_name, locator_set_name,
16946                    vec_len (locator_set_name));
16947     }
16948   else
16949     {
16950       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16951     }
16952   vec_free (locator_set_name);
16953
16954   /* send it... */
16955   S (mp);
16956
16957   /* Wait for a reply... */
16958   W (ret);
16959   return ret;
16960 }
16961
16962 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16963
16964 static int
16965 api_one_locator_dump (vat_main_t * vam)
16966 {
16967   unformat_input_t *input = vam->input;
16968   vl_api_one_locator_dump_t *mp;
16969   vl_api_control_ping_t *mp_ping;
16970   u8 is_index_set = 0, is_name_set = 0;
16971   u8 *ls_name = 0;
16972   u32 ls_index = ~0;
16973   int ret;
16974
16975   /* Parse args required to build the message */
16976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16977     {
16978       if (unformat (input, "ls_name %_%v%_", &ls_name))
16979         {
16980           is_name_set = 1;
16981         }
16982       else if (unformat (input, "ls_index %d", &ls_index))
16983         {
16984           is_index_set = 1;
16985         }
16986       else
16987         {
16988           errmsg ("parse error '%U'", format_unformat_error, input);
16989           return -99;
16990         }
16991     }
16992
16993   if (!is_index_set && !is_name_set)
16994     {
16995       errmsg ("error: expected one of index or name!");
16996       return -99;
16997     }
16998
16999   if (is_index_set && is_name_set)
17000     {
17001       errmsg ("error: only one param expected!");
17002       return -99;
17003     }
17004
17005   if (vec_len (ls_name) > 62)
17006     {
17007       errmsg ("error: locator set name too long!");
17008       return -99;
17009     }
17010
17011   if (!vam->json_output)
17012     {
17013       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17014     }
17015
17016   M (ONE_LOCATOR_DUMP, mp);
17017   mp->is_index_set = is_index_set;
17018
17019   if (is_index_set)
17020     mp->ls_index = clib_host_to_net_u32 (ls_index);
17021   else
17022     {
17023       vec_add1 (ls_name, 0);
17024       strncpy ((char *) mp->ls_name, (char *) ls_name,
17025                sizeof (mp->ls_name) - 1);
17026     }
17027
17028   /* send it... */
17029   S (mp);
17030
17031   /* Use a control ping for synchronization */
17032   MPING (CONTROL_PING, mp_ping);
17033   S (mp_ping);
17034
17035   /* Wait for a reply... */
17036   W (ret);
17037   return ret;
17038 }
17039
17040 #define api_lisp_locator_dump api_one_locator_dump
17041
17042 static int
17043 api_one_locator_set_dump (vat_main_t * vam)
17044 {
17045   vl_api_one_locator_set_dump_t *mp;
17046   vl_api_control_ping_t *mp_ping;
17047   unformat_input_t *input = vam->input;
17048   u8 filter = 0;
17049   int ret;
17050
17051   /* Parse args required to build the message */
17052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17053     {
17054       if (unformat (input, "local"))
17055         {
17056           filter = 1;
17057         }
17058       else if (unformat (input, "remote"))
17059         {
17060           filter = 2;
17061         }
17062       else
17063         {
17064           errmsg ("parse error '%U'", format_unformat_error, input);
17065           return -99;
17066         }
17067     }
17068
17069   if (!vam->json_output)
17070     {
17071       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17072     }
17073
17074   M (ONE_LOCATOR_SET_DUMP, mp);
17075
17076   mp->filter = filter;
17077
17078   /* send it... */
17079   S (mp);
17080
17081   /* Use a control ping for synchronization */
17082   MPING (CONTROL_PING, mp_ping);
17083   S (mp_ping);
17084
17085   /* Wait for a reply... */
17086   W (ret);
17087   return ret;
17088 }
17089
17090 #define api_lisp_locator_set_dump api_one_locator_set_dump
17091
17092 static int
17093 api_one_eid_table_map_dump (vat_main_t * vam)
17094 {
17095   u8 is_l2 = 0;
17096   u8 mode_set = 0;
17097   unformat_input_t *input = vam->input;
17098   vl_api_one_eid_table_map_dump_t *mp;
17099   vl_api_control_ping_t *mp_ping;
17100   int ret;
17101
17102   /* Parse args required to build the message */
17103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17104     {
17105       if (unformat (input, "l2"))
17106         {
17107           is_l2 = 1;
17108           mode_set = 1;
17109         }
17110       else if (unformat (input, "l3"))
17111         {
17112           is_l2 = 0;
17113           mode_set = 1;
17114         }
17115       else
17116         {
17117           errmsg ("parse error '%U'", format_unformat_error, input);
17118           return -99;
17119         }
17120     }
17121
17122   if (!mode_set)
17123     {
17124       errmsg ("expected one of 'l2' or 'l3' parameter!");
17125       return -99;
17126     }
17127
17128   if (!vam->json_output)
17129     {
17130       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17131     }
17132
17133   M (ONE_EID_TABLE_MAP_DUMP, mp);
17134   mp->is_l2 = is_l2;
17135
17136   /* send it... */
17137   S (mp);
17138
17139   /* Use a control ping for synchronization */
17140   MPING (CONTROL_PING, mp_ping);
17141   S (mp_ping);
17142
17143   /* Wait for a reply... */
17144   W (ret);
17145   return ret;
17146 }
17147
17148 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17149
17150 static int
17151 api_one_eid_table_vni_dump (vat_main_t * vam)
17152 {
17153   vl_api_one_eid_table_vni_dump_t *mp;
17154   vl_api_control_ping_t *mp_ping;
17155   int ret;
17156
17157   if (!vam->json_output)
17158     {
17159       print (vam->ofp, "VNI");
17160     }
17161
17162   M (ONE_EID_TABLE_VNI_DUMP, mp);
17163
17164   /* send it... */
17165   S (mp);
17166
17167   /* Use a control ping for synchronization */
17168   MPING (CONTROL_PING, mp_ping);
17169   S (mp_ping);
17170
17171   /* Wait for a reply... */
17172   W (ret);
17173   return ret;
17174 }
17175
17176 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17177
17178 static int
17179 api_one_eid_table_dump (vat_main_t * vam)
17180 {
17181   unformat_input_t *i = vam->input;
17182   vl_api_one_eid_table_dump_t *mp;
17183   vl_api_control_ping_t *mp_ping;
17184   struct in_addr ip4;
17185   struct in6_addr ip6;
17186   u8 mac[6];
17187   u8 eid_type = ~0, eid_set = 0;
17188   u32 prefix_length = ~0, t, vni = 0;
17189   u8 filter = 0;
17190   int ret;
17191   lisp_nsh_api_t nsh;
17192
17193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17194     {
17195       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17196         {
17197           eid_set = 1;
17198           eid_type = 0;
17199           prefix_length = t;
17200         }
17201       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17202         {
17203           eid_set = 1;
17204           eid_type = 1;
17205           prefix_length = t;
17206         }
17207       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17208         {
17209           eid_set = 1;
17210           eid_type = 2;
17211         }
17212       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17213         {
17214           eid_set = 1;
17215           eid_type = 3;
17216         }
17217       else if (unformat (i, "vni %d", &t))
17218         {
17219           vni = t;
17220         }
17221       else if (unformat (i, "local"))
17222         {
17223           filter = 1;
17224         }
17225       else if (unformat (i, "remote"))
17226         {
17227           filter = 2;
17228         }
17229       else
17230         {
17231           errmsg ("parse error '%U'", format_unformat_error, i);
17232           return -99;
17233         }
17234     }
17235
17236   if (!vam->json_output)
17237     {
17238       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17239              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17240     }
17241
17242   M (ONE_EID_TABLE_DUMP, mp);
17243
17244   mp->filter = filter;
17245   if (eid_set)
17246     {
17247       mp->eid_set = 1;
17248       mp->vni = htonl (vni);
17249       mp->eid_type = eid_type;
17250       switch (eid_type)
17251         {
17252         case 0:
17253           mp->prefix_length = prefix_length;
17254           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17255           break;
17256         case 1:
17257           mp->prefix_length = prefix_length;
17258           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17259           break;
17260         case 2:
17261           clib_memcpy (mp->eid, mac, sizeof (mac));
17262           break;
17263         case 3:
17264           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17265           break;
17266         default:
17267           errmsg ("unknown EID type %d!", eid_type);
17268           return -99;
17269         }
17270     }
17271
17272   /* send it... */
17273   S (mp);
17274
17275   /* Use a control ping for synchronization */
17276   MPING (CONTROL_PING, mp_ping);
17277   S (mp_ping);
17278
17279   /* Wait for a reply... */
17280   W (ret);
17281   return ret;
17282 }
17283
17284 #define api_lisp_eid_table_dump api_one_eid_table_dump
17285
17286 static int
17287 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17288 {
17289   unformat_input_t *i = vam->input;
17290   vl_api_gpe_fwd_entries_get_t *mp;
17291   u8 vni_set = 0;
17292   u32 vni = ~0;
17293   int ret;
17294
17295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17296     {
17297       if (unformat (i, "vni %d", &vni))
17298         {
17299           vni_set = 1;
17300         }
17301       else
17302         {
17303           errmsg ("parse error '%U'", format_unformat_error, i);
17304           return -99;
17305         }
17306     }
17307
17308   if (!vni_set)
17309     {
17310       errmsg ("vni not set!");
17311       return -99;
17312     }
17313
17314   if (!vam->json_output)
17315     {
17316       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17317              "leid", "reid");
17318     }
17319
17320   M (GPE_FWD_ENTRIES_GET, mp);
17321   mp->vni = clib_host_to_net_u32 (vni);
17322
17323   /* send it... */
17324   S (mp);
17325
17326   /* Wait for a reply... */
17327   W (ret);
17328   return ret;
17329 }
17330
17331 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17332 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17333 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17334 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17335 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17336 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17337 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17338 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17339
17340 static int
17341 api_one_adjacencies_get (vat_main_t * vam)
17342 {
17343   unformat_input_t *i = vam->input;
17344   vl_api_one_adjacencies_get_t *mp;
17345   u8 vni_set = 0;
17346   u32 vni = ~0;
17347   int ret;
17348
17349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17350     {
17351       if (unformat (i, "vni %d", &vni))
17352         {
17353           vni_set = 1;
17354         }
17355       else
17356         {
17357           errmsg ("parse error '%U'", format_unformat_error, i);
17358           return -99;
17359         }
17360     }
17361
17362   if (!vni_set)
17363     {
17364       errmsg ("vni not set!");
17365       return -99;
17366     }
17367
17368   if (!vam->json_output)
17369     {
17370       print (vam->ofp, "%s %40s", "leid", "reid");
17371     }
17372
17373   M (ONE_ADJACENCIES_GET, mp);
17374   mp->vni = clib_host_to_net_u32 (vni);
17375
17376   /* send it... */
17377   S (mp);
17378
17379   /* Wait for a reply... */
17380   W (ret);
17381   return ret;
17382 }
17383
17384 #define api_lisp_adjacencies_get api_one_adjacencies_get
17385
17386 static int
17387 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17388 {
17389   unformat_input_t *i = vam->input;
17390   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17391   int ret;
17392   u8 ip_family_set = 0, is_ip4 = 1;
17393
17394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17395     {
17396       if (unformat (i, "ip4"))
17397         {
17398           ip_family_set = 1;
17399           is_ip4 = 1;
17400         }
17401       else if (unformat (i, "ip6"))
17402         {
17403           ip_family_set = 1;
17404           is_ip4 = 0;
17405         }
17406       else
17407         {
17408           errmsg ("parse error '%U'", format_unformat_error, i);
17409           return -99;
17410         }
17411     }
17412
17413   if (!ip_family_set)
17414     {
17415       errmsg ("ip family not set!");
17416       return -99;
17417     }
17418
17419   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17420   mp->is_ip4 = is_ip4;
17421
17422   /* send it... */
17423   S (mp);
17424
17425   /* Wait for a reply... */
17426   W (ret);
17427   return ret;
17428 }
17429
17430 static int
17431 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17432 {
17433   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17434   int ret;
17435
17436   if (!vam->json_output)
17437     {
17438       print (vam->ofp, "VNIs");
17439     }
17440
17441   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17442
17443   /* send it... */
17444   S (mp);
17445
17446   /* Wait for a reply... */
17447   W (ret);
17448   return ret;
17449 }
17450
17451 static int
17452 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17453 {
17454   unformat_input_t *i = vam->input;
17455   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17456   int ret = 0;
17457   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17458   struct in_addr ip4;
17459   struct in6_addr ip6;
17460   u32 table_id = 0, nh_sw_if_index = ~0;
17461
17462   memset (&ip4, 0, sizeof (ip4));
17463   memset (&ip6, 0, sizeof (ip6));
17464
17465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17466     {
17467       if (unformat (i, "del"))
17468         is_add = 0;
17469       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17470                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17471         {
17472           ip_set = 1;
17473           is_ip4 = 1;
17474         }
17475       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17476                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17477         {
17478           ip_set = 1;
17479           is_ip4 = 0;
17480         }
17481       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17482         {
17483           ip_set = 1;
17484           is_ip4 = 1;
17485           nh_sw_if_index = ~0;
17486         }
17487       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17488         {
17489           ip_set = 1;
17490           is_ip4 = 0;
17491           nh_sw_if_index = ~0;
17492         }
17493       else if (unformat (i, "table %d", &table_id))
17494         ;
17495       else
17496         {
17497           errmsg ("parse error '%U'", format_unformat_error, i);
17498           return -99;
17499         }
17500     }
17501
17502   if (!ip_set)
17503     {
17504       errmsg ("nh addr not set!");
17505       return -99;
17506     }
17507
17508   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17509   mp->is_add = is_add;
17510   mp->table_id = clib_host_to_net_u32 (table_id);
17511   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17512   mp->is_ip4 = is_ip4;
17513   if (is_ip4)
17514     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17515   else
17516     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17517
17518   /* send it... */
17519   S (mp);
17520
17521   /* Wait for a reply... */
17522   W (ret);
17523   return ret;
17524 }
17525
17526 static int
17527 api_one_map_server_dump (vat_main_t * vam)
17528 {
17529   vl_api_one_map_server_dump_t *mp;
17530   vl_api_control_ping_t *mp_ping;
17531   int ret;
17532
17533   if (!vam->json_output)
17534     {
17535       print (vam->ofp, "%=20s", "Map server");
17536     }
17537
17538   M (ONE_MAP_SERVER_DUMP, mp);
17539   /* send it... */
17540   S (mp);
17541
17542   /* Use a control ping for synchronization */
17543   MPING (CONTROL_PING, mp_ping);
17544   S (mp_ping);
17545
17546   /* Wait for a reply... */
17547   W (ret);
17548   return ret;
17549 }
17550
17551 #define api_lisp_map_server_dump api_one_map_server_dump
17552
17553 static int
17554 api_one_map_resolver_dump (vat_main_t * vam)
17555 {
17556   vl_api_one_map_resolver_dump_t *mp;
17557   vl_api_control_ping_t *mp_ping;
17558   int ret;
17559
17560   if (!vam->json_output)
17561     {
17562       print (vam->ofp, "%=20s", "Map resolver");
17563     }
17564
17565   M (ONE_MAP_RESOLVER_DUMP, mp);
17566   /* send it... */
17567   S (mp);
17568
17569   /* Use a control ping for synchronization */
17570   MPING (CONTROL_PING, mp_ping);
17571   S (mp_ping);
17572
17573   /* Wait for a reply... */
17574   W (ret);
17575   return ret;
17576 }
17577
17578 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17579
17580 static int
17581 api_one_stats_flush (vat_main_t * vam)
17582 {
17583   vl_api_one_stats_flush_t *mp;
17584   int ret = 0;
17585
17586   M (ONE_STATS_FLUSH, mp);
17587   S (mp);
17588   W (ret);
17589   return ret;
17590 }
17591
17592 static int
17593 api_one_stats_dump (vat_main_t * vam)
17594 {
17595   vl_api_one_stats_dump_t *mp;
17596   vl_api_control_ping_t *mp_ping;
17597   int ret;
17598
17599   M (ONE_STATS_DUMP, mp);
17600   /* send it... */
17601   S (mp);
17602
17603   /* Use a control ping for synchronization */
17604   MPING (CONTROL_PING, mp_ping);
17605   S (mp_ping);
17606
17607   /* Wait for a reply... */
17608   W (ret);
17609   return ret;
17610 }
17611
17612 static int
17613 api_show_one_status (vat_main_t * vam)
17614 {
17615   vl_api_show_one_status_t *mp;
17616   int ret;
17617
17618   if (!vam->json_output)
17619     {
17620       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17621     }
17622
17623   M (SHOW_ONE_STATUS, mp);
17624   /* send it... */
17625   S (mp);
17626   /* Wait for a reply... */
17627   W (ret);
17628   return ret;
17629 }
17630
17631 #define api_show_lisp_status api_show_one_status
17632
17633 static int
17634 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17635 {
17636   vl_api_gpe_fwd_entry_path_dump_t *mp;
17637   vl_api_control_ping_t *mp_ping;
17638   unformat_input_t *i = vam->input;
17639   u32 fwd_entry_index = ~0;
17640   int ret;
17641
17642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17643     {
17644       if (unformat (i, "index %d", &fwd_entry_index))
17645         ;
17646       else
17647         break;
17648     }
17649
17650   if (~0 == fwd_entry_index)
17651     {
17652       errmsg ("no index specified!");
17653       return -99;
17654     }
17655
17656   if (!vam->json_output)
17657     {
17658       print (vam->ofp, "first line");
17659     }
17660
17661   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17662
17663   /* send it... */
17664   S (mp);
17665   /* Use a control ping for synchronization */
17666   MPING (CONTROL_PING, mp_ping);
17667   S (mp_ping);
17668
17669   /* Wait for a reply... */
17670   W (ret);
17671   return ret;
17672 }
17673
17674 static int
17675 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17676 {
17677   vl_api_one_get_map_request_itr_rlocs_t *mp;
17678   int ret;
17679
17680   if (!vam->json_output)
17681     {
17682       print (vam->ofp, "%=20s", "itr-rlocs:");
17683     }
17684
17685   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17686   /* send it... */
17687   S (mp);
17688   /* Wait for a reply... */
17689   W (ret);
17690   return ret;
17691 }
17692
17693 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17694
17695 static int
17696 api_af_packet_create (vat_main_t * vam)
17697 {
17698   unformat_input_t *i = vam->input;
17699   vl_api_af_packet_create_t *mp;
17700   u8 *host_if_name = 0;
17701   u8 hw_addr[6];
17702   u8 random_hw_addr = 1;
17703   int ret;
17704
17705   memset (hw_addr, 0, sizeof (hw_addr));
17706
17707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17708     {
17709       if (unformat (i, "name %s", &host_if_name))
17710         vec_add1 (host_if_name, 0);
17711       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17712         random_hw_addr = 0;
17713       else
17714         break;
17715     }
17716
17717   if (!vec_len (host_if_name))
17718     {
17719       errmsg ("host-interface name must be specified");
17720       return -99;
17721     }
17722
17723   if (vec_len (host_if_name) > 64)
17724     {
17725       errmsg ("host-interface name too long");
17726       return -99;
17727     }
17728
17729   M (AF_PACKET_CREATE, mp);
17730
17731   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17732   clib_memcpy (mp->hw_addr, hw_addr, 6);
17733   mp->use_random_hw_addr = random_hw_addr;
17734   vec_free (host_if_name);
17735
17736   S (mp);
17737
17738   /* *INDENT-OFF* */
17739   W2 (ret,
17740       ({
17741         if (ret == 0)
17742           fprintf (vam->ofp ? vam->ofp : stderr,
17743                    " new sw_if_index = %d\n", vam->sw_if_index);
17744       }));
17745   /* *INDENT-ON* */
17746   return ret;
17747 }
17748
17749 static int
17750 api_af_packet_delete (vat_main_t * vam)
17751 {
17752   unformat_input_t *i = vam->input;
17753   vl_api_af_packet_delete_t *mp;
17754   u8 *host_if_name = 0;
17755   int ret;
17756
17757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17758     {
17759       if (unformat (i, "name %s", &host_if_name))
17760         vec_add1 (host_if_name, 0);
17761       else
17762         break;
17763     }
17764
17765   if (!vec_len (host_if_name))
17766     {
17767       errmsg ("host-interface name must be specified");
17768       return -99;
17769     }
17770
17771   if (vec_len (host_if_name) > 64)
17772     {
17773       errmsg ("host-interface name too long");
17774       return -99;
17775     }
17776
17777   M (AF_PACKET_DELETE, mp);
17778
17779   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17780   vec_free (host_if_name);
17781
17782   S (mp);
17783   W (ret);
17784   return ret;
17785 }
17786
17787 static int
17788 api_policer_add_del (vat_main_t * vam)
17789 {
17790   unformat_input_t *i = vam->input;
17791   vl_api_policer_add_del_t *mp;
17792   u8 is_add = 1;
17793   u8 *name = 0;
17794   u32 cir = 0;
17795   u32 eir = 0;
17796   u64 cb = 0;
17797   u64 eb = 0;
17798   u8 rate_type = 0;
17799   u8 round_type = 0;
17800   u8 type = 0;
17801   u8 color_aware = 0;
17802   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17803   int ret;
17804
17805   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17806   conform_action.dscp = 0;
17807   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17808   exceed_action.dscp = 0;
17809   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17810   violate_action.dscp = 0;
17811
17812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17813     {
17814       if (unformat (i, "del"))
17815         is_add = 0;
17816       else if (unformat (i, "name %s", &name))
17817         vec_add1 (name, 0);
17818       else if (unformat (i, "cir %u", &cir))
17819         ;
17820       else if (unformat (i, "eir %u", &eir))
17821         ;
17822       else if (unformat (i, "cb %u", &cb))
17823         ;
17824       else if (unformat (i, "eb %u", &eb))
17825         ;
17826       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17827                          &rate_type))
17828         ;
17829       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17830                          &round_type))
17831         ;
17832       else if (unformat (i, "type %U", unformat_policer_type, &type))
17833         ;
17834       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17835                          &conform_action))
17836         ;
17837       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17838                          &exceed_action))
17839         ;
17840       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17841                          &violate_action))
17842         ;
17843       else if (unformat (i, "color-aware"))
17844         color_aware = 1;
17845       else
17846         break;
17847     }
17848
17849   if (!vec_len (name))
17850     {
17851       errmsg ("policer name must be specified");
17852       return -99;
17853     }
17854
17855   if (vec_len (name) > 64)
17856     {
17857       errmsg ("policer name too long");
17858       return -99;
17859     }
17860
17861   M (POLICER_ADD_DEL, mp);
17862
17863   clib_memcpy (mp->name, name, vec_len (name));
17864   vec_free (name);
17865   mp->is_add = is_add;
17866   mp->cir = cir;
17867   mp->eir = eir;
17868   mp->cb = cb;
17869   mp->eb = eb;
17870   mp->rate_type = rate_type;
17871   mp->round_type = round_type;
17872   mp->type = type;
17873   mp->conform_action_type = conform_action.action_type;
17874   mp->conform_dscp = conform_action.dscp;
17875   mp->exceed_action_type = exceed_action.action_type;
17876   mp->exceed_dscp = exceed_action.dscp;
17877   mp->violate_action_type = violate_action.action_type;
17878   mp->violate_dscp = violate_action.dscp;
17879   mp->color_aware = color_aware;
17880
17881   S (mp);
17882   W (ret);
17883   return ret;
17884 }
17885
17886 static int
17887 api_policer_dump (vat_main_t * vam)
17888 {
17889   unformat_input_t *i = vam->input;
17890   vl_api_policer_dump_t *mp;
17891   vl_api_control_ping_t *mp_ping;
17892   u8 *match_name = 0;
17893   u8 match_name_valid = 0;
17894   int ret;
17895
17896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17897     {
17898       if (unformat (i, "name %s", &match_name))
17899         {
17900           vec_add1 (match_name, 0);
17901           match_name_valid = 1;
17902         }
17903       else
17904         break;
17905     }
17906
17907   M (POLICER_DUMP, mp);
17908   mp->match_name_valid = match_name_valid;
17909   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17910   vec_free (match_name);
17911   /* send it... */
17912   S (mp);
17913
17914   /* Use a control ping for synchronization */
17915   MPING (CONTROL_PING, mp_ping);
17916   S (mp_ping);
17917
17918   /* Wait for a reply... */
17919   W (ret);
17920   return ret;
17921 }
17922
17923 static int
17924 api_policer_classify_set_interface (vat_main_t * vam)
17925 {
17926   unformat_input_t *i = vam->input;
17927   vl_api_policer_classify_set_interface_t *mp;
17928   u32 sw_if_index;
17929   int sw_if_index_set;
17930   u32 ip4_table_index = ~0;
17931   u32 ip6_table_index = ~0;
17932   u32 l2_table_index = ~0;
17933   u8 is_add = 1;
17934   int ret;
17935
17936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17937     {
17938       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17939         sw_if_index_set = 1;
17940       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17941         sw_if_index_set = 1;
17942       else if (unformat (i, "del"))
17943         is_add = 0;
17944       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17945         ;
17946       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17947         ;
17948       else if (unformat (i, "l2-table %d", &l2_table_index))
17949         ;
17950       else
17951         {
17952           clib_warning ("parse error '%U'", format_unformat_error, i);
17953           return -99;
17954         }
17955     }
17956
17957   if (sw_if_index_set == 0)
17958     {
17959       errmsg ("missing interface name or sw_if_index");
17960       return -99;
17961     }
17962
17963   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17964
17965   mp->sw_if_index = ntohl (sw_if_index);
17966   mp->ip4_table_index = ntohl (ip4_table_index);
17967   mp->ip6_table_index = ntohl (ip6_table_index);
17968   mp->l2_table_index = ntohl (l2_table_index);
17969   mp->is_add = is_add;
17970
17971   S (mp);
17972   W (ret);
17973   return ret;
17974 }
17975
17976 static int
17977 api_policer_classify_dump (vat_main_t * vam)
17978 {
17979   unformat_input_t *i = vam->input;
17980   vl_api_policer_classify_dump_t *mp;
17981   vl_api_control_ping_t *mp_ping;
17982   u8 type = POLICER_CLASSIFY_N_TABLES;
17983   int ret;
17984
17985   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17986     ;
17987   else
17988     {
17989       errmsg ("classify table type must be specified");
17990       return -99;
17991     }
17992
17993   if (!vam->json_output)
17994     {
17995       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17996     }
17997
17998   M (POLICER_CLASSIFY_DUMP, mp);
17999   mp->type = type;
18000   /* send it... */
18001   S (mp);
18002
18003   /* Use a control ping for synchronization */
18004   MPING (CONTROL_PING, mp_ping);
18005   S (mp_ping);
18006
18007   /* Wait for a reply... */
18008   W (ret);
18009   return ret;
18010 }
18011
18012 static int
18013 api_netmap_create (vat_main_t * vam)
18014 {
18015   unformat_input_t *i = vam->input;
18016   vl_api_netmap_create_t *mp;
18017   u8 *if_name = 0;
18018   u8 hw_addr[6];
18019   u8 random_hw_addr = 1;
18020   u8 is_pipe = 0;
18021   u8 is_master = 0;
18022   int ret;
18023
18024   memset (hw_addr, 0, sizeof (hw_addr));
18025
18026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18027     {
18028       if (unformat (i, "name %s", &if_name))
18029         vec_add1 (if_name, 0);
18030       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18031         random_hw_addr = 0;
18032       else if (unformat (i, "pipe"))
18033         is_pipe = 1;
18034       else if (unformat (i, "master"))
18035         is_master = 1;
18036       else if (unformat (i, "slave"))
18037         is_master = 0;
18038       else
18039         break;
18040     }
18041
18042   if (!vec_len (if_name))
18043     {
18044       errmsg ("interface name must be specified");
18045       return -99;
18046     }
18047
18048   if (vec_len (if_name) > 64)
18049     {
18050       errmsg ("interface name too long");
18051       return -99;
18052     }
18053
18054   M (NETMAP_CREATE, mp);
18055
18056   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18057   clib_memcpy (mp->hw_addr, hw_addr, 6);
18058   mp->use_random_hw_addr = random_hw_addr;
18059   mp->is_pipe = is_pipe;
18060   mp->is_master = is_master;
18061   vec_free (if_name);
18062
18063   S (mp);
18064   W (ret);
18065   return ret;
18066 }
18067
18068 static int
18069 api_netmap_delete (vat_main_t * vam)
18070 {
18071   unformat_input_t *i = vam->input;
18072   vl_api_netmap_delete_t *mp;
18073   u8 *if_name = 0;
18074   int ret;
18075
18076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18077     {
18078       if (unformat (i, "name %s", &if_name))
18079         vec_add1 (if_name, 0);
18080       else
18081         break;
18082     }
18083
18084   if (!vec_len (if_name))
18085     {
18086       errmsg ("interface name must be specified");
18087       return -99;
18088     }
18089
18090   if (vec_len (if_name) > 64)
18091     {
18092       errmsg ("interface name too long");
18093       return -99;
18094     }
18095
18096   M (NETMAP_DELETE, mp);
18097
18098   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18099   vec_free (if_name);
18100
18101   S (mp);
18102   W (ret);
18103   return ret;
18104 }
18105
18106 static void
18107 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18108 {
18109   if (fp->afi == IP46_TYPE_IP6)
18110     print (vam->ofp,
18111            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18112            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18113            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18114            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18115            format_ip6_address, fp->next_hop);
18116   else if (fp->afi == IP46_TYPE_IP4)
18117     print (vam->ofp,
18118            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18119            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18120            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18121            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18122            format_ip4_address, fp->next_hop);
18123 }
18124
18125 static void
18126 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18127                                  vl_api_fib_path2_t * fp)
18128 {
18129   struct in_addr ip4;
18130   struct in6_addr ip6;
18131
18132   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18133   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18134   vat_json_object_add_uint (node, "is_local", fp->is_local);
18135   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18136   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18137   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18138   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18139   if (fp->afi == IP46_TYPE_IP4)
18140     {
18141       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18142       vat_json_object_add_ip4 (node, "next_hop", ip4);
18143     }
18144   else if (fp->afi == IP46_TYPE_IP6)
18145     {
18146       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18147       vat_json_object_add_ip6 (node, "next_hop", ip6);
18148     }
18149 }
18150
18151 static void
18152 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18153 {
18154   vat_main_t *vam = &vat_main;
18155   int count = ntohl (mp->mt_count);
18156   vl_api_fib_path2_t *fp;
18157   i32 i;
18158
18159   print (vam->ofp, "[%d]: sw_if_index %d via:",
18160          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18161   fp = mp->mt_paths;
18162   for (i = 0; i < count; i++)
18163     {
18164       vl_api_mpls_fib_path_print (vam, fp);
18165       fp++;
18166     }
18167
18168   print (vam->ofp, "");
18169 }
18170
18171 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18172 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18173
18174 static void
18175 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18176 {
18177   vat_main_t *vam = &vat_main;
18178   vat_json_node_t *node = NULL;
18179   int count = ntohl (mp->mt_count);
18180   vl_api_fib_path2_t *fp;
18181   i32 i;
18182
18183   if (VAT_JSON_ARRAY != vam->json_tree.type)
18184     {
18185       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18186       vat_json_init_array (&vam->json_tree);
18187     }
18188   node = vat_json_array_add (&vam->json_tree);
18189
18190   vat_json_init_object (node);
18191   vat_json_object_add_uint (node, "tunnel_index",
18192                             ntohl (mp->mt_tunnel_index));
18193   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18194
18195   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18196
18197   fp = mp->mt_paths;
18198   for (i = 0; i < count; i++)
18199     {
18200       vl_api_mpls_fib_path_json_print (node, fp);
18201       fp++;
18202     }
18203 }
18204
18205 static int
18206 api_mpls_tunnel_dump (vat_main_t * vam)
18207 {
18208   vl_api_mpls_tunnel_dump_t *mp;
18209   vl_api_control_ping_t *mp_ping;
18210   i32 index = -1;
18211   int ret;
18212
18213   /* Parse args required to build the message */
18214   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18215     {
18216       if (!unformat (vam->input, "tunnel_index %d", &index))
18217         {
18218           index = -1;
18219           break;
18220         }
18221     }
18222
18223   print (vam->ofp, "  tunnel_index %d", index);
18224
18225   M (MPLS_TUNNEL_DUMP, mp);
18226   mp->tunnel_index = htonl (index);
18227   S (mp);
18228
18229   /* Use a control ping for synchronization */
18230   MPING (CONTROL_PING, mp_ping);
18231   S (mp_ping);
18232
18233   W (ret);
18234   return ret;
18235 }
18236
18237 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18238 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18239
18240
18241 static void
18242 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18243 {
18244   vat_main_t *vam = &vat_main;
18245   int count = ntohl (mp->count);
18246   vl_api_fib_path2_t *fp;
18247   int i;
18248
18249   print (vam->ofp,
18250          "table-id %d, label %u, ess_bit %u",
18251          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18252   fp = mp->path;
18253   for (i = 0; i < count; i++)
18254     {
18255       vl_api_mpls_fib_path_print (vam, fp);
18256       fp++;
18257     }
18258 }
18259
18260 static void vl_api_mpls_fib_details_t_handler_json
18261   (vl_api_mpls_fib_details_t * mp)
18262 {
18263   vat_main_t *vam = &vat_main;
18264   int count = ntohl (mp->count);
18265   vat_json_node_t *node = NULL;
18266   vl_api_fib_path2_t *fp;
18267   int i;
18268
18269   if (VAT_JSON_ARRAY != vam->json_tree.type)
18270     {
18271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18272       vat_json_init_array (&vam->json_tree);
18273     }
18274   node = vat_json_array_add (&vam->json_tree);
18275
18276   vat_json_init_object (node);
18277   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18278   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18279   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18280   vat_json_object_add_uint (node, "path_count", count);
18281   fp = mp->path;
18282   for (i = 0; i < count; i++)
18283     {
18284       vl_api_mpls_fib_path_json_print (node, fp);
18285       fp++;
18286     }
18287 }
18288
18289 static int
18290 api_mpls_fib_dump (vat_main_t * vam)
18291 {
18292   vl_api_mpls_fib_dump_t *mp;
18293   vl_api_control_ping_t *mp_ping;
18294   int ret;
18295
18296   M (MPLS_FIB_DUMP, mp);
18297   S (mp);
18298
18299   /* Use a control ping for synchronization */
18300   MPING (CONTROL_PING, mp_ping);
18301   S (mp_ping);
18302
18303   W (ret);
18304   return ret;
18305 }
18306
18307 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18308 #define vl_api_ip_fib_details_t_print vl_noop_handler
18309
18310 static void
18311 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18312 {
18313   vat_main_t *vam = &vat_main;
18314   int count = ntohl (mp->count);
18315   vl_api_fib_path_t *fp;
18316   int i;
18317
18318   print (vam->ofp,
18319          "table-id %d, prefix %U/%d",
18320          ntohl (mp->table_id), format_ip4_address, mp->address,
18321          mp->address_length);
18322   fp = mp->path;
18323   for (i = 0; i < count; i++)
18324     {
18325       if (fp->afi == IP46_TYPE_IP6)
18326         print (vam->ofp,
18327                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18328                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18329                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18330                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18331                format_ip6_address, fp->next_hop);
18332       else if (fp->afi == IP46_TYPE_IP4)
18333         print (vam->ofp,
18334                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18335                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18336                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18337                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18338                format_ip4_address, fp->next_hop);
18339       fp++;
18340     }
18341 }
18342
18343 static void vl_api_ip_fib_details_t_handler_json
18344   (vl_api_ip_fib_details_t * mp)
18345 {
18346   vat_main_t *vam = &vat_main;
18347   int count = ntohl (mp->count);
18348   vat_json_node_t *node = NULL;
18349   struct in_addr ip4;
18350   struct in6_addr ip6;
18351   vl_api_fib_path_t *fp;
18352   int i;
18353
18354   if (VAT_JSON_ARRAY != vam->json_tree.type)
18355     {
18356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18357       vat_json_init_array (&vam->json_tree);
18358     }
18359   node = vat_json_array_add (&vam->json_tree);
18360
18361   vat_json_init_object (node);
18362   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18363   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18364   vat_json_object_add_ip4 (node, "prefix", ip4);
18365   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18366   vat_json_object_add_uint (node, "path_count", count);
18367   fp = mp->path;
18368   for (i = 0; i < count; i++)
18369     {
18370       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18371       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18372       vat_json_object_add_uint (node, "is_local", fp->is_local);
18373       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18374       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18375       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18376       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18377       if (fp->afi == IP46_TYPE_IP4)
18378         {
18379           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18380           vat_json_object_add_ip4 (node, "next_hop", ip4);
18381         }
18382       else if (fp->afi == IP46_TYPE_IP6)
18383         {
18384           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18385           vat_json_object_add_ip6 (node, "next_hop", ip6);
18386         }
18387     }
18388 }
18389
18390 static int
18391 api_ip_fib_dump (vat_main_t * vam)
18392 {
18393   vl_api_ip_fib_dump_t *mp;
18394   vl_api_control_ping_t *mp_ping;
18395   int ret;
18396
18397   M (IP_FIB_DUMP, mp);
18398   S (mp);
18399
18400   /* Use a control ping for synchronization */
18401   MPING (CONTROL_PING, mp_ping);
18402   S (mp_ping);
18403
18404   W (ret);
18405   return ret;
18406 }
18407
18408 static int
18409 api_ip_mfib_dump (vat_main_t * vam)
18410 {
18411   vl_api_ip_mfib_dump_t *mp;
18412   vl_api_control_ping_t *mp_ping;
18413   int ret;
18414
18415   M (IP_MFIB_DUMP, mp);
18416   S (mp);
18417
18418   /* Use a control ping for synchronization */
18419   MPING (CONTROL_PING, mp_ping);
18420   S (mp_ping);
18421
18422   W (ret);
18423   return ret;
18424 }
18425
18426 static void vl_api_ip_neighbor_details_t_handler
18427   (vl_api_ip_neighbor_details_t * mp)
18428 {
18429   vat_main_t *vam = &vat_main;
18430
18431   print (vam->ofp, "%c %U %U",
18432          (mp->is_static) ? 'S' : 'D',
18433          format_ethernet_address, &mp->mac_address,
18434          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
18435          &mp->ip_address);
18436 }
18437
18438 static void vl_api_ip_neighbor_details_t_handler_json
18439   (vl_api_ip_neighbor_details_t * mp)
18440 {
18441
18442   vat_main_t *vam = &vat_main;
18443   vat_json_node_t *node;
18444   struct in_addr ip4;
18445   struct in6_addr ip6;
18446
18447   if (VAT_JSON_ARRAY != vam->json_tree.type)
18448     {
18449       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18450       vat_json_init_array (&vam->json_tree);
18451     }
18452   node = vat_json_array_add (&vam->json_tree);
18453
18454   vat_json_init_object (node);
18455   vat_json_object_add_string_copy (node, "flag",
18456                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
18457                                    "dynamic");
18458
18459   vat_json_object_add_string_copy (node, "link_layer",
18460                                    format (0, "%U", format_ethernet_address,
18461                                            &mp->mac_address));
18462
18463   if (mp->is_ipv6)
18464     {
18465       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
18466       vat_json_object_add_ip6 (node, "ip_address", ip6);
18467     }
18468   else
18469     {
18470       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
18471       vat_json_object_add_ip4 (node, "ip_address", ip4);
18472     }
18473 }
18474
18475 static int
18476 api_ip_neighbor_dump (vat_main_t * vam)
18477 {
18478   unformat_input_t *i = vam->input;
18479   vl_api_ip_neighbor_dump_t *mp;
18480   vl_api_control_ping_t *mp_ping;
18481   u8 is_ipv6 = 0;
18482   u32 sw_if_index = ~0;
18483   int ret;
18484
18485   /* Parse args required to build the message */
18486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18487     {
18488       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18489         ;
18490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18491         ;
18492       else if (unformat (i, "ip6"))
18493         is_ipv6 = 1;
18494       else
18495         break;
18496     }
18497
18498   if (sw_if_index == ~0)
18499     {
18500       errmsg ("missing interface name or sw_if_index");
18501       return -99;
18502     }
18503
18504   M (IP_NEIGHBOR_DUMP, mp);
18505   mp->is_ipv6 = (u8) is_ipv6;
18506   mp->sw_if_index = ntohl (sw_if_index);
18507   S (mp);
18508
18509   /* Use a control ping for synchronization */
18510   MPING (CONTROL_PING, mp_ping);
18511   S (mp_ping);
18512
18513   W (ret);
18514   return ret;
18515 }
18516
18517 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
18518 #define vl_api_ip6_fib_details_t_print vl_noop_handler
18519
18520 static void
18521 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
18522 {
18523   vat_main_t *vam = &vat_main;
18524   int count = ntohl (mp->count);
18525   vl_api_fib_path_t *fp;
18526   int i;
18527
18528   print (vam->ofp,
18529          "table-id %d, prefix %U/%d",
18530          ntohl (mp->table_id), format_ip6_address, mp->address,
18531          mp->address_length);
18532   fp = mp->path;
18533   for (i = 0; i < count; i++)
18534     {
18535       if (fp->afi == IP46_TYPE_IP6)
18536         print (vam->ofp,
18537                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18538                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18539                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18540                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18541                format_ip6_address, fp->next_hop);
18542       else if (fp->afi == IP46_TYPE_IP4)
18543         print (vam->ofp,
18544                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18545                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18546                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18547                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18548                format_ip4_address, fp->next_hop);
18549       fp++;
18550     }
18551 }
18552
18553 static void vl_api_ip6_fib_details_t_handler_json
18554   (vl_api_ip6_fib_details_t * mp)
18555 {
18556   vat_main_t *vam = &vat_main;
18557   int count = ntohl (mp->count);
18558   vat_json_node_t *node = NULL;
18559   struct in_addr ip4;
18560   struct in6_addr ip6;
18561   vl_api_fib_path_t *fp;
18562   int i;
18563
18564   if (VAT_JSON_ARRAY != vam->json_tree.type)
18565     {
18566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18567       vat_json_init_array (&vam->json_tree);
18568     }
18569   node = vat_json_array_add (&vam->json_tree);
18570
18571   vat_json_init_object (node);
18572   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18573   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
18574   vat_json_object_add_ip6 (node, "prefix", ip6);
18575   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18576   vat_json_object_add_uint (node, "path_count", count);
18577   fp = mp->path;
18578   for (i = 0; i < count; i++)
18579     {
18580       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18581       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18582       vat_json_object_add_uint (node, "is_local", fp->is_local);
18583       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18584       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18585       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18586       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18587       if (fp->afi == IP46_TYPE_IP4)
18588         {
18589           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18590           vat_json_object_add_ip4 (node, "next_hop", ip4);
18591         }
18592       else if (fp->afi == IP46_TYPE_IP6)
18593         {
18594           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18595           vat_json_object_add_ip6 (node, "next_hop", ip6);
18596         }
18597     }
18598 }
18599
18600 static int
18601 api_ip6_fib_dump (vat_main_t * vam)
18602 {
18603   vl_api_ip6_fib_dump_t *mp;
18604   vl_api_control_ping_t *mp_ping;
18605   int ret;
18606
18607   M (IP6_FIB_DUMP, mp);
18608   S (mp);
18609
18610   /* Use a control ping for synchronization */
18611   MPING (CONTROL_PING, mp_ping);
18612   S (mp_ping);
18613
18614   W (ret);
18615   return ret;
18616 }
18617
18618 static int
18619 api_ip6_mfib_dump (vat_main_t * vam)
18620 {
18621   vl_api_ip6_mfib_dump_t *mp;
18622   vl_api_control_ping_t *mp_ping;
18623   int ret;
18624
18625   M (IP6_MFIB_DUMP, mp);
18626   S (mp);
18627
18628   /* Use a control ping for synchronization */
18629   MPING (CONTROL_PING, mp_ping);
18630   S (mp_ping);
18631
18632   W (ret);
18633   return ret;
18634 }
18635
18636 int
18637 api_classify_table_ids (vat_main_t * vam)
18638 {
18639   vl_api_classify_table_ids_t *mp;
18640   int ret;
18641
18642   /* Construct the API message */
18643   M (CLASSIFY_TABLE_IDS, mp);
18644   mp->context = 0;
18645
18646   S (mp);
18647   W (ret);
18648   return ret;
18649 }
18650
18651 int
18652 api_classify_table_by_interface (vat_main_t * vam)
18653 {
18654   unformat_input_t *input = vam->input;
18655   vl_api_classify_table_by_interface_t *mp;
18656
18657   u32 sw_if_index = ~0;
18658   int ret;
18659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18660     {
18661       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18662         ;
18663       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18664         ;
18665       else
18666         break;
18667     }
18668   if (sw_if_index == ~0)
18669     {
18670       errmsg ("missing interface name or sw_if_index");
18671       return -99;
18672     }
18673
18674   /* Construct the API message */
18675   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18676   mp->context = 0;
18677   mp->sw_if_index = ntohl (sw_if_index);
18678
18679   S (mp);
18680   W (ret);
18681   return ret;
18682 }
18683
18684 int
18685 api_classify_table_info (vat_main_t * vam)
18686 {
18687   unformat_input_t *input = vam->input;
18688   vl_api_classify_table_info_t *mp;
18689
18690   u32 table_id = ~0;
18691   int ret;
18692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18693     {
18694       if (unformat (input, "table_id %d", &table_id))
18695         ;
18696       else
18697         break;
18698     }
18699   if (table_id == ~0)
18700     {
18701       errmsg ("missing table id");
18702       return -99;
18703     }
18704
18705   /* Construct the API message */
18706   M (CLASSIFY_TABLE_INFO, mp);
18707   mp->context = 0;
18708   mp->table_id = ntohl (table_id);
18709
18710   S (mp);
18711   W (ret);
18712   return ret;
18713 }
18714
18715 int
18716 api_classify_session_dump (vat_main_t * vam)
18717 {
18718   unformat_input_t *input = vam->input;
18719   vl_api_classify_session_dump_t *mp;
18720   vl_api_control_ping_t *mp_ping;
18721
18722   u32 table_id = ~0;
18723   int ret;
18724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18725     {
18726       if (unformat (input, "table_id %d", &table_id))
18727         ;
18728       else
18729         break;
18730     }
18731   if (table_id == ~0)
18732     {
18733       errmsg ("missing table id");
18734       return -99;
18735     }
18736
18737   /* Construct the API message */
18738   M (CLASSIFY_SESSION_DUMP, mp);
18739   mp->context = 0;
18740   mp->table_id = ntohl (table_id);
18741   S (mp);
18742
18743   /* Use a control ping for synchronization */
18744   MPING (CONTROL_PING, mp_ping);
18745   S (mp_ping);
18746
18747   W (ret);
18748   return ret;
18749 }
18750
18751 static void
18752 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18753 {
18754   vat_main_t *vam = &vat_main;
18755
18756   print (vam->ofp, "collector_address %U, collector_port %d, "
18757          "src_address %U, vrf_id %d, path_mtu %u, "
18758          "template_interval %u, udp_checksum %d",
18759          format_ip4_address, mp->collector_address,
18760          ntohs (mp->collector_port),
18761          format_ip4_address, mp->src_address,
18762          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18763          ntohl (mp->template_interval), mp->udp_checksum);
18764
18765   vam->retval = 0;
18766   vam->result_ready = 1;
18767 }
18768
18769 static void
18770   vl_api_ipfix_exporter_details_t_handler_json
18771   (vl_api_ipfix_exporter_details_t * mp)
18772 {
18773   vat_main_t *vam = &vat_main;
18774   vat_json_node_t node;
18775   struct in_addr collector_address;
18776   struct in_addr src_address;
18777
18778   vat_json_init_object (&node);
18779   clib_memcpy (&collector_address, &mp->collector_address,
18780                sizeof (collector_address));
18781   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18782   vat_json_object_add_uint (&node, "collector_port",
18783                             ntohs (mp->collector_port));
18784   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18785   vat_json_object_add_ip4 (&node, "src_address", src_address);
18786   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18787   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18788   vat_json_object_add_uint (&node, "template_interval",
18789                             ntohl (mp->template_interval));
18790   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18791
18792   vat_json_print (vam->ofp, &node);
18793   vat_json_free (&node);
18794   vam->retval = 0;
18795   vam->result_ready = 1;
18796 }
18797
18798 int
18799 api_ipfix_exporter_dump (vat_main_t * vam)
18800 {
18801   vl_api_ipfix_exporter_dump_t *mp;
18802   int ret;
18803
18804   /* Construct the API message */
18805   M (IPFIX_EXPORTER_DUMP, mp);
18806   mp->context = 0;
18807
18808   S (mp);
18809   W (ret);
18810   return ret;
18811 }
18812
18813 static int
18814 api_ipfix_classify_stream_dump (vat_main_t * vam)
18815 {
18816   vl_api_ipfix_classify_stream_dump_t *mp;
18817   int ret;
18818
18819   /* Construct the API message */
18820   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18821   mp->context = 0;
18822
18823   S (mp);
18824   W (ret);
18825   return ret;
18826   /* NOTREACHED */
18827   return 0;
18828 }
18829
18830 static void
18831   vl_api_ipfix_classify_stream_details_t_handler
18832   (vl_api_ipfix_classify_stream_details_t * mp)
18833 {
18834   vat_main_t *vam = &vat_main;
18835   print (vam->ofp, "domain_id %d, src_port %d",
18836          ntohl (mp->domain_id), ntohs (mp->src_port));
18837   vam->retval = 0;
18838   vam->result_ready = 1;
18839 }
18840
18841 static void
18842   vl_api_ipfix_classify_stream_details_t_handler_json
18843   (vl_api_ipfix_classify_stream_details_t * mp)
18844 {
18845   vat_main_t *vam = &vat_main;
18846   vat_json_node_t node;
18847
18848   vat_json_init_object (&node);
18849   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18850   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18851
18852   vat_json_print (vam->ofp, &node);
18853   vat_json_free (&node);
18854   vam->retval = 0;
18855   vam->result_ready = 1;
18856 }
18857
18858 static int
18859 api_ipfix_classify_table_dump (vat_main_t * vam)
18860 {
18861   vl_api_ipfix_classify_table_dump_t *mp;
18862   vl_api_control_ping_t *mp_ping;
18863   int ret;
18864
18865   if (!vam->json_output)
18866     {
18867       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18868              "transport_protocol");
18869     }
18870
18871   /* Construct the API message */
18872   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18873
18874   /* send it... */
18875   S (mp);
18876
18877   /* Use a control ping for synchronization */
18878   MPING (CONTROL_PING, mp_ping);
18879   S (mp_ping);
18880
18881   W (ret);
18882   return ret;
18883 }
18884
18885 static void
18886   vl_api_ipfix_classify_table_details_t_handler
18887   (vl_api_ipfix_classify_table_details_t * mp)
18888 {
18889   vat_main_t *vam = &vat_main;
18890   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18891          mp->transport_protocol);
18892 }
18893
18894 static void
18895   vl_api_ipfix_classify_table_details_t_handler_json
18896   (vl_api_ipfix_classify_table_details_t * mp)
18897 {
18898   vat_json_node_t *node = NULL;
18899   vat_main_t *vam = &vat_main;
18900
18901   if (VAT_JSON_ARRAY != vam->json_tree.type)
18902     {
18903       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18904       vat_json_init_array (&vam->json_tree);
18905     }
18906
18907   node = vat_json_array_add (&vam->json_tree);
18908   vat_json_init_object (node);
18909
18910   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18911   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18912   vat_json_object_add_uint (node, "transport_protocol",
18913                             mp->transport_protocol);
18914 }
18915
18916 static int
18917 api_sw_interface_span_enable_disable (vat_main_t * vam)
18918 {
18919   unformat_input_t *i = vam->input;
18920   vl_api_sw_interface_span_enable_disable_t *mp;
18921   u32 src_sw_if_index = ~0;
18922   u32 dst_sw_if_index = ~0;
18923   u8 state = 3;
18924   int ret;
18925   u8 is_l2 = 0;
18926
18927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18928     {
18929       if (unformat
18930           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18931         ;
18932       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18933         ;
18934       else
18935         if (unformat
18936             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18937         ;
18938       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18939         ;
18940       else if (unformat (i, "disable"))
18941         state = 0;
18942       else if (unformat (i, "rx"))
18943         state = 1;
18944       else if (unformat (i, "tx"))
18945         state = 2;
18946       else if (unformat (i, "both"))
18947         state = 3;
18948       else if (unformat (i, "l2"))
18949         is_l2 = 1;
18950       else
18951         break;
18952     }
18953
18954   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18955
18956   mp->sw_if_index_from = htonl (src_sw_if_index);
18957   mp->sw_if_index_to = htonl (dst_sw_if_index);
18958   mp->state = state;
18959   mp->is_l2 = is_l2;
18960
18961   S (mp);
18962   W (ret);
18963   return ret;
18964 }
18965
18966 static void
18967 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18968                                             * mp)
18969 {
18970   vat_main_t *vam = &vat_main;
18971   u8 *sw_if_from_name = 0;
18972   u8 *sw_if_to_name = 0;
18973   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18974   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18975   char *states[] = { "none", "rx", "tx", "both" };
18976   hash_pair_t *p;
18977
18978   /* *INDENT-OFF* */
18979   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18980   ({
18981     if ((u32) p->value[0] == sw_if_index_from)
18982       {
18983         sw_if_from_name = (u8 *)(p->key);
18984         if (sw_if_to_name)
18985           break;
18986       }
18987     if ((u32) p->value[0] == sw_if_index_to)
18988       {
18989         sw_if_to_name = (u8 *)(p->key);
18990         if (sw_if_from_name)
18991           break;
18992       }
18993   }));
18994   /* *INDENT-ON* */
18995   print (vam->ofp, "%20s => %20s (%s)",
18996          sw_if_from_name, sw_if_to_name, states[mp->state]);
18997 }
18998
18999 static void
19000   vl_api_sw_interface_span_details_t_handler_json
19001   (vl_api_sw_interface_span_details_t * mp)
19002 {
19003   vat_main_t *vam = &vat_main;
19004   vat_json_node_t *node = NULL;
19005   u8 *sw_if_from_name = 0;
19006   u8 *sw_if_to_name = 0;
19007   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19008   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19009   hash_pair_t *p;
19010
19011   /* *INDENT-OFF* */
19012   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19013   ({
19014     if ((u32) p->value[0] == sw_if_index_from)
19015       {
19016         sw_if_from_name = (u8 *)(p->key);
19017         if (sw_if_to_name)
19018           break;
19019       }
19020     if ((u32) p->value[0] == sw_if_index_to)
19021       {
19022         sw_if_to_name = (u8 *)(p->key);
19023         if (sw_if_from_name)
19024           break;
19025       }
19026   }));
19027   /* *INDENT-ON* */
19028
19029   if (VAT_JSON_ARRAY != vam->json_tree.type)
19030     {
19031       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19032       vat_json_init_array (&vam->json_tree);
19033     }
19034   node = vat_json_array_add (&vam->json_tree);
19035
19036   vat_json_init_object (node);
19037   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19038   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19039   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19040   if (0 != sw_if_to_name)
19041     {
19042       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19043     }
19044   vat_json_object_add_uint (node, "state", mp->state);
19045 }
19046
19047 static int
19048 api_sw_interface_span_dump (vat_main_t * vam)
19049 {
19050   unformat_input_t *input = vam->input;
19051   vl_api_sw_interface_span_dump_t *mp;
19052   vl_api_control_ping_t *mp_ping;
19053   u8 is_l2 = 0;
19054   int ret;
19055
19056   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19057     {
19058       if (unformat (input, "l2"))
19059         is_l2 = 1;
19060       else
19061         break;
19062     }
19063
19064   M (SW_INTERFACE_SPAN_DUMP, mp);
19065   mp->is_l2 = is_l2;
19066   S (mp);
19067
19068   /* Use a control ping for synchronization */
19069   MPING (CONTROL_PING, mp_ping);
19070   S (mp_ping);
19071
19072   W (ret);
19073   return ret;
19074 }
19075
19076 int
19077 api_pg_create_interface (vat_main_t * vam)
19078 {
19079   unformat_input_t *input = vam->input;
19080   vl_api_pg_create_interface_t *mp;
19081
19082   u32 if_id = ~0;
19083   int ret;
19084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19085     {
19086       if (unformat (input, "if_id %d", &if_id))
19087         ;
19088       else
19089         break;
19090     }
19091   if (if_id == ~0)
19092     {
19093       errmsg ("missing pg interface index");
19094       return -99;
19095     }
19096
19097   /* Construct the API message */
19098   M (PG_CREATE_INTERFACE, mp);
19099   mp->context = 0;
19100   mp->interface_id = ntohl (if_id);
19101
19102   S (mp);
19103   W (ret);
19104   return ret;
19105 }
19106
19107 int
19108 api_pg_capture (vat_main_t * vam)
19109 {
19110   unformat_input_t *input = vam->input;
19111   vl_api_pg_capture_t *mp;
19112
19113   u32 if_id = ~0;
19114   u8 enable = 1;
19115   u32 count = 1;
19116   u8 pcap_file_set = 0;
19117   u8 *pcap_file = 0;
19118   int ret;
19119   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19120     {
19121       if (unformat (input, "if_id %d", &if_id))
19122         ;
19123       else if (unformat (input, "pcap %s", &pcap_file))
19124         pcap_file_set = 1;
19125       else if (unformat (input, "count %d", &count))
19126         ;
19127       else if (unformat (input, "disable"))
19128         enable = 0;
19129       else
19130         break;
19131     }
19132   if (if_id == ~0)
19133     {
19134       errmsg ("missing pg interface index");
19135       return -99;
19136     }
19137   if (pcap_file_set > 0)
19138     {
19139       if (vec_len (pcap_file) > 255)
19140         {
19141           errmsg ("pcap file name is too long");
19142           return -99;
19143         }
19144     }
19145
19146   u32 name_len = vec_len (pcap_file);
19147   /* Construct the API message */
19148   M (PG_CAPTURE, mp);
19149   mp->context = 0;
19150   mp->interface_id = ntohl (if_id);
19151   mp->is_enabled = enable;
19152   mp->count = ntohl (count);
19153   mp->pcap_name_length = ntohl (name_len);
19154   if (pcap_file_set != 0)
19155     {
19156       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19157     }
19158   vec_free (pcap_file);
19159
19160   S (mp);
19161   W (ret);
19162   return ret;
19163 }
19164
19165 int
19166 api_pg_enable_disable (vat_main_t * vam)
19167 {
19168   unformat_input_t *input = vam->input;
19169   vl_api_pg_enable_disable_t *mp;
19170
19171   u8 enable = 1;
19172   u8 stream_name_set = 0;
19173   u8 *stream_name = 0;
19174   int ret;
19175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19176     {
19177       if (unformat (input, "stream %s", &stream_name))
19178         stream_name_set = 1;
19179       else if (unformat (input, "disable"))
19180         enable = 0;
19181       else
19182         break;
19183     }
19184
19185   if (stream_name_set > 0)
19186     {
19187       if (vec_len (stream_name) > 255)
19188         {
19189           errmsg ("stream name too long");
19190           return -99;
19191         }
19192     }
19193
19194   u32 name_len = vec_len (stream_name);
19195   /* Construct the API message */
19196   M (PG_ENABLE_DISABLE, mp);
19197   mp->context = 0;
19198   mp->is_enabled = enable;
19199   if (stream_name_set != 0)
19200     {
19201       mp->stream_name_length = ntohl (name_len);
19202       clib_memcpy (mp->stream_name, stream_name, name_len);
19203     }
19204   vec_free (stream_name);
19205
19206   S (mp);
19207   W (ret);
19208   return ret;
19209 }
19210
19211 int
19212 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19213 {
19214   unformat_input_t *input = vam->input;
19215   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19216
19217   u16 *low_ports = 0;
19218   u16 *high_ports = 0;
19219   u16 this_low;
19220   u16 this_hi;
19221   ip4_address_t ip4_addr;
19222   ip6_address_t ip6_addr;
19223   u32 length;
19224   u32 tmp, tmp2;
19225   u8 prefix_set = 0;
19226   u32 vrf_id = ~0;
19227   u8 is_add = 1;
19228   u8 is_ipv6 = 0;
19229   int ret;
19230
19231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19232     {
19233       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19234         {
19235           prefix_set = 1;
19236         }
19237       else
19238         if (unformat
19239             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19240         {
19241           prefix_set = 1;
19242           is_ipv6 = 1;
19243         }
19244       else if (unformat (input, "vrf %d", &vrf_id))
19245         ;
19246       else if (unformat (input, "del"))
19247         is_add = 0;
19248       else if (unformat (input, "port %d", &tmp))
19249         {
19250           if (tmp == 0 || tmp > 65535)
19251             {
19252               errmsg ("port %d out of range", tmp);
19253               return -99;
19254             }
19255           this_low = tmp;
19256           this_hi = this_low + 1;
19257           vec_add1 (low_ports, this_low);
19258           vec_add1 (high_ports, this_hi);
19259         }
19260       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19261         {
19262           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19263             {
19264               errmsg ("incorrect range parameters");
19265               return -99;
19266             }
19267           this_low = tmp;
19268           /* Note: in debug CLI +1 is added to high before
19269              passing to real fn that does "the work"
19270              (ip_source_and_port_range_check_add_del).
19271              This fn is a wrapper around the binary API fn a
19272              control plane will call, which expects this increment
19273              to have occurred. Hence letting the binary API control
19274              plane fn do the increment for consistency between VAT
19275              and other control planes.
19276            */
19277           this_hi = tmp2;
19278           vec_add1 (low_ports, this_low);
19279           vec_add1 (high_ports, this_hi);
19280         }
19281       else
19282         break;
19283     }
19284
19285   if (prefix_set == 0)
19286     {
19287       errmsg ("<address>/<mask> not specified");
19288       return -99;
19289     }
19290
19291   if (vrf_id == ~0)
19292     {
19293       errmsg ("VRF ID required, not specified");
19294       return -99;
19295     }
19296
19297   if (vrf_id == 0)
19298     {
19299       errmsg
19300         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19301       return -99;
19302     }
19303
19304   if (vec_len (low_ports) == 0)
19305     {
19306       errmsg ("At least one port or port range required");
19307       return -99;
19308     }
19309
19310   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19311
19312   mp->is_add = is_add;
19313
19314   if (is_ipv6)
19315     {
19316       mp->is_ipv6 = 1;
19317       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19318     }
19319   else
19320     {
19321       mp->is_ipv6 = 0;
19322       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19323     }
19324
19325   mp->mask_length = length;
19326   mp->number_of_ranges = vec_len (low_ports);
19327
19328   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19329   vec_free (low_ports);
19330
19331   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19332   vec_free (high_ports);
19333
19334   mp->vrf_id = ntohl (vrf_id);
19335
19336   S (mp);
19337   W (ret);
19338   return ret;
19339 }
19340
19341 int
19342 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19343 {
19344   unformat_input_t *input = vam->input;
19345   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19346   u32 sw_if_index = ~0;
19347   int vrf_set = 0;
19348   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19349   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19350   u8 is_add = 1;
19351   int ret;
19352
19353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19354     {
19355       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19356         ;
19357       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19358         ;
19359       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19360         vrf_set = 1;
19361       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19362         vrf_set = 1;
19363       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19364         vrf_set = 1;
19365       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19366         vrf_set = 1;
19367       else if (unformat (input, "del"))
19368         is_add = 0;
19369       else
19370         break;
19371     }
19372
19373   if (sw_if_index == ~0)
19374     {
19375       errmsg ("Interface required but not specified");
19376       return -99;
19377     }
19378
19379   if (vrf_set == 0)
19380     {
19381       errmsg ("VRF ID required but not specified");
19382       return -99;
19383     }
19384
19385   if (tcp_out_vrf_id == 0
19386       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19387     {
19388       errmsg
19389         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19390       return -99;
19391     }
19392
19393   /* Construct the API message */
19394   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19395
19396   mp->sw_if_index = ntohl (sw_if_index);
19397   mp->is_add = is_add;
19398   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19399   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19400   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19401   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19402
19403   /* send it... */
19404   S (mp);
19405
19406   /* Wait for a reply... */
19407   W (ret);
19408   return ret;
19409 }
19410
19411 static int
19412 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
19413 {
19414   unformat_input_t *i = vam->input;
19415   vl_api_ipsec_gre_add_del_tunnel_t *mp;
19416   u32 local_sa_id = 0;
19417   u32 remote_sa_id = 0;
19418   ip4_address_t src_address;
19419   ip4_address_t dst_address;
19420   u8 is_add = 1;
19421   int ret;
19422
19423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19424     {
19425       if (unformat (i, "local_sa %d", &local_sa_id))
19426         ;
19427       else if (unformat (i, "remote_sa %d", &remote_sa_id))
19428         ;
19429       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
19430         ;
19431       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
19432         ;
19433       else if (unformat (i, "del"))
19434         is_add = 0;
19435       else
19436         {
19437           clib_warning ("parse error '%U'", format_unformat_error, i);
19438           return -99;
19439         }
19440     }
19441
19442   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
19443
19444   mp->local_sa_id = ntohl (local_sa_id);
19445   mp->remote_sa_id = ntohl (remote_sa_id);
19446   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
19447   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
19448   mp->is_add = is_add;
19449
19450   S (mp);
19451   W (ret);
19452   return ret;
19453 }
19454
19455 static int
19456 api_punt (vat_main_t * vam)
19457 {
19458   unformat_input_t *i = vam->input;
19459   vl_api_punt_t *mp;
19460   u32 ipv = ~0;
19461   u32 protocol = ~0;
19462   u32 port = ~0;
19463   int is_add = 1;
19464   int ret;
19465
19466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19467     {
19468       if (unformat (i, "ip %d", &ipv))
19469         ;
19470       else if (unformat (i, "protocol %d", &protocol))
19471         ;
19472       else if (unformat (i, "port %d", &port))
19473         ;
19474       else if (unformat (i, "del"))
19475         is_add = 0;
19476       else
19477         {
19478           clib_warning ("parse error '%U'", format_unformat_error, i);
19479           return -99;
19480         }
19481     }
19482
19483   M (PUNT, mp);
19484
19485   mp->is_add = (u8) is_add;
19486   mp->ipv = (u8) ipv;
19487   mp->l4_protocol = (u8) protocol;
19488   mp->l4_port = htons ((u16) port);
19489
19490   S (mp);
19491   W (ret);
19492   return ret;
19493 }
19494
19495 static void vl_api_ipsec_gre_tunnel_details_t_handler
19496   (vl_api_ipsec_gre_tunnel_details_t * mp)
19497 {
19498   vat_main_t *vam = &vat_main;
19499
19500   print (vam->ofp, "%11d%15U%15U%14d%14d",
19501          ntohl (mp->sw_if_index),
19502          format_ip4_address, &mp->src_address,
19503          format_ip4_address, &mp->dst_address,
19504          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
19505 }
19506
19507 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
19508   (vl_api_ipsec_gre_tunnel_details_t * mp)
19509 {
19510   vat_main_t *vam = &vat_main;
19511   vat_json_node_t *node = NULL;
19512   struct in_addr ip4;
19513
19514   if (VAT_JSON_ARRAY != vam->json_tree.type)
19515     {
19516       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19517       vat_json_init_array (&vam->json_tree);
19518     }
19519   node = vat_json_array_add (&vam->json_tree);
19520
19521   vat_json_init_object (node);
19522   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19523   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
19524   vat_json_object_add_ip4 (node, "src_address", ip4);
19525   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
19526   vat_json_object_add_ip4 (node, "dst_address", ip4);
19527   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
19528   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
19529 }
19530
19531 static int
19532 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
19533 {
19534   unformat_input_t *i = vam->input;
19535   vl_api_ipsec_gre_tunnel_dump_t *mp;
19536   vl_api_control_ping_t *mp_ping;
19537   u32 sw_if_index;
19538   u8 sw_if_index_set = 0;
19539   int ret;
19540
19541   /* Parse args required to build the message */
19542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19543     {
19544       if (unformat (i, "sw_if_index %d", &sw_if_index))
19545         sw_if_index_set = 1;
19546       else
19547         break;
19548     }
19549
19550   if (sw_if_index_set == 0)
19551     {
19552       sw_if_index = ~0;
19553     }
19554
19555   if (!vam->json_output)
19556     {
19557       print (vam->ofp, "%11s%15s%15s%14s%14s",
19558              "sw_if_index", "src_address", "dst_address",
19559              "local_sa_id", "remote_sa_id");
19560     }
19561
19562   /* Get list of gre-tunnel interfaces */
19563   M (IPSEC_GRE_TUNNEL_DUMP, mp);
19564
19565   mp->sw_if_index = htonl (sw_if_index);
19566
19567   S (mp);
19568
19569   /* Use a control ping for synchronization */
19570   MPING (CONTROL_PING, mp_ping);
19571   S (mp_ping);
19572
19573   W (ret);
19574   return ret;
19575 }
19576
19577 static int
19578 api_delete_subif (vat_main_t * vam)
19579 {
19580   unformat_input_t *i = vam->input;
19581   vl_api_delete_subif_t *mp;
19582   u32 sw_if_index = ~0;
19583   int ret;
19584
19585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19586     {
19587       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19588         ;
19589       if (unformat (i, "sw_if_index %d", &sw_if_index))
19590         ;
19591       else
19592         break;
19593     }
19594
19595   if (sw_if_index == ~0)
19596     {
19597       errmsg ("missing sw_if_index");
19598       return -99;
19599     }
19600
19601   /* Construct the API message */
19602   M (DELETE_SUBIF, mp);
19603   mp->sw_if_index = ntohl (sw_if_index);
19604
19605   S (mp);
19606   W (ret);
19607   return ret;
19608 }
19609
19610 #define foreach_pbb_vtr_op      \
19611 _("disable",  L2_VTR_DISABLED)  \
19612 _("pop",  L2_VTR_POP_2)         \
19613 _("push",  L2_VTR_PUSH_2)
19614
19615 static int
19616 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19617 {
19618   unformat_input_t *i = vam->input;
19619   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19620   u32 sw_if_index = ~0, vtr_op = ~0;
19621   u16 outer_tag = ~0;
19622   u8 dmac[6], smac[6];
19623   u8 dmac_set = 0, smac_set = 0;
19624   u16 vlanid = 0;
19625   u32 sid = ~0;
19626   u32 tmp;
19627   int ret;
19628
19629   /* Shut up coverity */
19630   memset (dmac, 0, sizeof (dmac));
19631   memset (smac, 0, sizeof (smac));
19632
19633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19634     {
19635       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19636         ;
19637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19638         ;
19639       else if (unformat (i, "vtr_op %d", &vtr_op))
19640         ;
19641 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19642       foreach_pbb_vtr_op
19643 #undef _
19644         else if (unformat (i, "translate_pbb_stag"))
19645         {
19646           if (unformat (i, "%d", &tmp))
19647             {
19648               vtr_op = L2_VTR_TRANSLATE_2_1;
19649               outer_tag = tmp;
19650             }
19651           else
19652             {
19653               errmsg
19654                 ("translate_pbb_stag operation requires outer tag definition");
19655               return -99;
19656             }
19657         }
19658       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19659         dmac_set++;
19660       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19661         smac_set++;
19662       else if (unformat (i, "sid %d", &sid))
19663         ;
19664       else if (unformat (i, "vlanid %d", &tmp))
19665         vlanid = tmp;
19666       else
19667         {
19668           clib_warning ("parse error '%U'", format_unformat_error, i);
19669           return -99;
19670         }
19671     }
19672
19673   if ((sw_if_index == ~0) || (vtr_op == ~0))
19674     {
19675       errmsg ("missing sw_if_index or vtr operation");
19676       return -99;
19677     }
19678   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19679       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19680     {
19681       errmsg
19682         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19683       return -99;
19684     }
19685
19686   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19687   mp->sw_if_index = ntohl (sw_if_index);
19688   mp->vtr_op = ntohl (vtr_op);
19689   mp->outer_tag = ntohs (outer_tag);
19690   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19691   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19692   mp->b_vlanid = ntohs (vlanid);
19693   mp->i_sid = ntohl (sid);
19694
19695   S (mp);
19696   W (ret);
19697   return ret;
19698 }
19699
19700 static int
19701 api_flow_classify_set_interface (vat_main_t * vam)
19702 {
19703   unformat_input_t *i = vam->input;
19704   vl_api_flow_classify_set_interface_t *mp;
19705   u32 sw_if_index;
19706   int sw_if_index_set;
19707   u32 ip4_table_index = ~0;
19708   u32 ip6_table_index = ~0;
19709   u8 is_add = 1;
19710   int ret;
19711
19712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19713     {
19714       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19715         sw_if_index_set = 1;
19716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19717         sw_if_index_set = 1;
19718       else if (unformat (i, "del"))
19719         is_add = 0;
19720       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19721         ;
19722       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19723         ;
19724       else
19725         {
19726           clib_warning ("parse error '%U'", format_unformat_error, i);
19727           return -99;
19728         }
19729     }
19730
19731   if (sw_if_index_set == 0)
19732     {
19733       errmsg ("missing interface name or sw_if_index");
19734       return -99;
19735     }
19736
19737   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19738
19739   mp->sw_if_index = ntohl (sw_if_index);
19740   mp->ip4_table_index = ntohl (ip4_table_index);
19741   mp->ip6_table_index = ntohl (ip6_table_index);
19742   mp->is_add = is_add;
19743
19744   S (mp);
19745   W (ret);
19746   return ret;
19747 }
19748
19749 static int
19750 api_flow_classify_dump (vat_main_t * vam)
19751 {
19752   unformat_input_t *i = vam->input;
19753   vl_api_flow_classify_dump_t *mp;
19754   vl_api_control_ping_t *mp_ping;
19755   u8 type = FLOW_CLASSIFY_N_TABLES;
19756   int ret;
19757
19758   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19759     ;
19760   else
19761     {
19762       errmsg ("classify table type must be specified");
19763       return -99;
19764     }
19765
19766   if (!vam->json_output)
19767     {
19768       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19769     }
19770
19771   M (FLOW_CLASSIFY_DUMP, mp);
19772   mp->type = type;
19773   /* send it... */
19774   S (mp);
19775
19776   /* Use a control ping for synchronization */
19777   MPING (CONTROL_PING, mp_ping);
19778   S (mp_ping);
19779
19780   /* Wait for a reply... */
19781   W (ret);
19782   return ret;
19783 }
19784
19785 static int
19786 api_feature_enable_disable (vat_main_t * vam)
19787 {
19788   unformat_input_t *i = vam->input;
19789   vl_api_feature_enable_disable_t *mp;
19790   u8 *arc_name = 0;
19791   u8 *feature_name = 0;
19792   u32 sw_if_index = ~0;
19793   u8 enable = 1;
19794   int ret;
19795
19796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19797     {
19798       if (unformat (i, "arc_name %s", &arc_name))
19799         ;
19800       else if (unformat (i, "feature_name %s", &feature_name))
19801         ;
19802       else
19803         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19804         ;
19805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19806         ;
19807       else if (unformat (i, "disable"))
19808         enable = 0;
19809       else
19810         break;
19811     }
19812
19813   if (arc_name == 0)
19814     {
19815       errmsg ("missing arc name");
19816       return -99;
19817     }
19818   if (vec_len (arc_name) > 63)
19819     {
19820       errmsg ("arc name too long");
19821     }
19822
19823   if (feature_name == 0)
19824     {
19825       errmsg ("missing feature name");
19826       return -99;
19827     }
19828   if (vec_len (feature_name) > 63)
19829     {
19830       errmsg ("feature name too long");
19831     }
19832
19833   if (sw_if_index == ~0)
19834     {
19835       errmsg ("missing interface name or sw_if_index");
19836       return -99;
19837     }
19838
19839   /* Construct the API message */
19840   M (FEATURE_ENABLE_DISABLE, mp);
19841   mp->sw_if_index = ntohl (sw_if_index);
19842   mp->enable = enable;
19843   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19844   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19845   vec_free (arc_name);
19846   vec_free (feature_name);
19847
19848   S (mp);
19849   W (ret);
19850   return ret;
19851 }
19852
19853 static int
19854 api_sw_interface_tag_add_del (vat_main_t * vam)
19855 {
19856   unformat_input_t *i = vam->input;
19857   vl_api_sw_interface_tag_add_del_t *mp;
19858   u32 sw_if_index = ~0;
19859   u8 *tag = 0;
19860   u8 enable = 1;
19861   int ret;
19862
19863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19864     {
19865       if (unformat (i, "tag %s", &tag))
19866         ;
19867       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19868         ;
19869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19870         ;
19871       else if (unformat (i, "del"))
19872         enable = 0;
19873       else
19874         break;
19875     }
19876
19877   if (sw_if_index == ~0)
19878     {
19879       errmsg ("missing interface name or sw_if_index");
19880       return -99;
19881     }
19882
19883   if (enable && (tag == 0))
19884     {
19885       errmsg ("no tag specified");
19886       return -99;
19887     }
19888
19889   /* Construct the API message */
19890   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19891   mp->sw_if_index = ntohl (sw_if_index);
19892   mp->is_add = enable;
19893   if (enable)
19894     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19895   vec_free (tag);
19896
19897   S (mp);
19898   W (ret);
19899   return ret;
19900 }
19901
19902 static void vl_api_l2_xconnect_details_t_handler
19903   (vl_api_l2_xconnect_details_t * mp)
19904 {
19905   vat_main_t *vam = &vat_main;
19906
19907   print (vam->ofp, "%15d%15d",
19908          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19909 }
19910
19911 static void vl_api_l2_xconnect_details_t_handler_json
19912   (vl_api_l2_xconnect_details_t * mp)
19913 {
19914   vat_main_t *vam = &vat_main;
19915   vat_json_node_t *node = NULL;
19916
19917   if (VAT_JSON_ARRAY != vam->json_tree.type)
19918     {
19919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19920       vat_json_init_array (&vam->json_tree);
19921     }
19922   node = vat_json_array_add (&vam->json_tree);
19923
19924   vat_json_init_object (node);
19925   vat_json_object_add_uint (node, "rx_sw_if_index",
19926                             ntohl (mp->rx_sw_if_index));
19927   vat_json_object_add_uint (node, "tx_sw_if_index",
19928                             ntohl (mp->tx_sw_if_index));
19929 }
19930
19931 static int
19932 api_l2_xconnect_dump (vat_main_t * vam)
19933 {
19934   vl_api_l2_xconnect_dump_t *mp;
19935   vl_api_control_ping_t *mp_ping;
19936   int ret;
19937
19938   if (!vam->json_output)
19939     {
19940       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19941     }
19942
19943   M (L2_XCONNECT_DUMP, mp);
19944
19945   S (mp);
19946
19947   /* Use a control ping for synchronization */
19948   MPING (CONTROL_PING, mp_ping);
19949   S (mp_ping);
19950
19951   W (ret);
19952   return ret;
19953 }
19954
19955 static int
19956 api_sw_interface_set_mtu (vat_main_t * vam)
19957 {
19958   unformat_input_t *i = vam->input;
19959   vl_api_sw_interface_set_mtu_t *mp;
19960   u32 sw_if_index = ~0;
19961   u32 mtu = 0;
19962   int ret;
19963
19964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19965     {
19966       if (unformat (i, "mtu %d", &mtu))
19967         ;
19968       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19969         ;
19970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19971         ;
19972       else
19973         break;
19974     }
19975
19976   if (sw_if_index == ~0)
19977     {
19978       errmsg ("missing interface name or sw_if_index");
19979       return -99;
19980     }
19981
19982   if (mtu == 0)
19983     {
19984       errmsg ("no mtu specified");
19985       return -99;
19986     }
19987
19988   /* Construct the API message */
19989   M (SW_INTERFACE_SET_MTU, mp);
19990   mp->sw_if_index = ntohl (sw_if_index);
19991   mp->mtu = ntohs ((u16) mtu);
19992
19993   S (mp);
19994   W (ret);
19995   return ret;
19996 }
19997
19998 static int
19999 api_p2p_ethernet_add (vat_main_t * vam)
20000 {
20001   unformat_input_t *i = vam->input;
20002   vl_api_p2p_ethernet_add_t *mp;
20003   u32 parent_if_index = ~0;
20004   u32 sub_id = ~0;
20005   u8 remote_mac[6];
20006   u8 mac_set = 0;
20007   int ret;
20008
20009   memset (remote_mac, 0, sizeof (remote_mac));
20010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20011     {
20012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20013         ;
20014       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20015         ;
20016       else
20017         if (unformat
20018             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20019         mac_set++;
20020       else if (unformat (i, "sub_id %d", &sub_id))
20021         ;
20022       else
20023         {
20024           clib_warning ("parse error '%U'", format_unformat_error, i);
20025           return -99;
20026         }
20027     }
20028
20029   if (parent_if_index == ~0)
20030     {
20031       errmsg ("missing interface name or sw_if_index");
20032       return -99;
20033     }
20034   if (mac_set == 0)
20035     {
20036       errmsg ("missing remote mac address");
20037       return -99;
20038     }
20039   if (sub_id == ~0)
20040     {
20041       errmsg ("missing sub-interface id");
20042       return -99;
20043     }
20044
20045   M (P2P_ETHERNET_ADD, mp);
20046   mp->parent_if_index = ntohl (parent_if_index);
20047   mp->subif_id = ntohl (sub_id);
20048   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20049
20050   S (mp);
20051   W (ret);
20052   return ret;
20053 }
20054
20055 static int
20056 api_p2p_ethernet_del (vat_main_t * vam)
20057 {
20058   unformat_input_t *i = vam->input;
20059   vl_api_p2p_ethernet_del_t *mp;
20060   u32 parent_if_index = ~0;
20061   u8 remote_mac[6];
20062   u8 mac_set = 0;
20063   int ret;
20064
20065   memset (remote_mac, 0, sizeof (remote_mac));
20066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20067     {
20068       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20069         ;
20070       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20071         ;
20072       else
20073         if (unformat
20074             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20075         mac_set++;
20076       else
20077         {
20078           clib_warning ("parse error '%U'", format_unformat_error, i);
20079           return -99;
20080         }
20081     }
20082
20083   if (parent_if_index == ~0)
20084     {
20085       errmsg ("missing interface name or sw_if_index");
20086       return -99;
20087     }
20088   if (mac_set == 0)
20089     {
20090       errmsg ("missing remote mac address");
20091       return -99;
20092     }
20093
20094   M (P2P_ETHERNET_DEL, mp);
20095   mp->parent_if_index = ntohl (parent_if_index);
20096   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20097
20098   S (mp);
20099   W (ret);
20100   return ret;
20101 }
20102
20103 static int
20104 api_lldp_config (vat_main_t * vam)
20105 {
20106   unformat_input_t *i = vam->input;
20107   vl_api_lldp_config_t *mp;
20108   int tx_hold = 0;
20109   int tx_interval = 0;
20110   u8 *sys_name = NULL;
20111   int ret;
20112
20113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20114     {
20115       if (unformat (i, "system-name %s", &sys_name))
20116         ;
20117       else if (unformat (i, "tx-hold %d", &tx_hold))
20118         ;
20119       else if (unformat (i, "tx-interval %d", &tx_interval))
20120         ;
20121       else
20122         {
20123           clib_warning ("parse error '%U'", format_unformat_error, i);
20124           return -99;
20125         }
20126     }
20127
20128   vec_add1 (sys_name, 0);
20129
20130   M (LLDP_CONFIG, mp);
20131   mp->tx_hold = htonl (tx_hold);
20132   mp->tx_interval = htonl (tx_interval);
20133   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20134   vec_free (sys_name);
20135
20136   S (mp);
20137   W (ret);
20138   return ret;
20139 }
20140
20141 static int
20142 api_sw_interface_set_lldp (vat_main_t * vam)
20143 {
20144   unformat_input_t *i = vam->input;
20145   vl_api_sw_interface_set_lldp_t *mp;
20146   u32 sw_if_index = ~0;
20147   u32 enable = 1;
20148   u8 *port_desc = NULL;
20149   int ret;
20150
20151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20152     {
20153       if (unformat (i, "disable"))
20154         enable = 0;
20155       else
20156         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20157         ;
20158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20159         ;
20160       else if (unformat (i, "port-desc %s", &port_desc))
20161         ;
20162       else
20163         break;
20164     }
20165
20166   if (sw_if_index == ~0)
20167     {
20168       errmsg ("missing interface name or sw_if_index");
20169       return -99;
20170     }
20171
20172   /* Construct the API message */
20173   vec_add1 (port_desc, 0);
20174   M (SW_INTERFACE_SET_LLDP, mp);
20175   mp->sw_if_index = ntohl (sw_if_index);
20176   mp->enable = enable;
20177   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20178   vec_free (port_desc);
20179
20180   S (mp);
20181   W (ret);
20182   return ret;
20183 }
20184
20185 static int
20186 api_tcp_configure_src_addresses (vat_main_t * vam)
20187 {
20188   vl_api_tcp_configure_src_addresses_t *mp;
20189   unformat_input_t *i = vam->input;
20190   ip4_address_t v4first, v4last;
20191   ip6_address_t v6first, v6last;
20192   u8 range_set = 0;
20193   u32 vrf_id = 0;
20194   int ret;
20195
20196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20197     {
20198       if (unformat (i, "%U - %U",
20199                     unformat_ip4_address, &v4first,
20200                     unformat_ip4_address, &v4last))
20201         {
20202           if (range_set)
20203             {
20204               errmsg ("one range per message (range already set)");
20205               return -99;
20206             }
20207           range_set = 1;
20208         }
20209       else if (unformat (i, "%U - %U",
20210                          unformat_ip6_address, &v6first,
20211                          unformat_ip6_address, &v6last))
20212         {
20213           if (range_set)
20214             {
20215               errmsg ("one range per message (range already set)");
20216               return -99;
20217             }
20218           range_set = 2;
20219         }
20220       else if (unformat (i, "vrf %d", &vrf_id))
20221         ;
20222       else
20223         break;
20224     }
20225
20226   if (range_set == 0)
20227     {
20228       errmsg ("address range not set");
20229       return -99;
20230     }
20231
20232   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20233   mp->vrf_id = ntohl (vrf_id);
20234   /* ipv6? */
20235   if (range_set == 2)
20236     {
20237       mp->is_ipv6 = 1;
20238       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20239       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20240     }
20241   else
20242     {
20243       mp->is_ipv6 = 0;
20244       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20245       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20246     }
20247   S (mp);
20248   W (ret);
20249   return ret;
20250 }
20251
20252 static int
20253 api_memfd_segment_create (vat_main_t * vam)
20254 {
20255   unformat_input_t *i = vam->input;
20256   vl_api_memfd_segment_create_t *mp;
20257   u64 size = 64 << 20;
20258   int ret;
20259
20260 #if VPP_API_TEST_BUILTIN == 1
20261   errmsg ("memfd_segment_create (builtin) not supported");
20262   return -99;
20263 #endif
20264
20265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20266     {
20267       if (unformat (i, "size %U", unformat_memory_size, &size))
20268         ;
20269       else
20270         break;
20271     }
20272
20273   M (MEMFD_SEGMENT_CREATE, mp);
20274   mp->requested_size = size;
20275   S (mp);
20276   W (ret);
20277   return ret;
20278 }
20279
20280 static int
20281 q_or_quit (vat_main_t * vam)
20282 {
20283 #if VPP_API_TEST_BUILTIN == 0
20284   longjmp (vam->jump_buf, 1);
20285 #endif
20286   return 0;                     /* not so much */
20287 }
20288
20289 static int
20290 q (vat_main_t * vam)
20291 {
20292   return q_or_quit (vam);
20293 }
20294
20295 static int
20296 quit (vat_main_t * vam)
20297 {
20298   return q_or_quit (vam);
20299 }
20300
20301 static int
20302 comment (vat_main_t * vam)
20303 {
20304   return 0;
20305 }
20306
20307 static int
20308 cmd_cmp (void *a1, void *a2)
20309 {
20310   u8 **c1 = a1;
20311   u8 **c2 = a2;
20312
20313   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20314 }
20315
20316 static int
20317 help (vat_main_t * vam)
20318 {
20319   u8 **cmds = 0;
20320   u8 *name = 0;
20321   hash_pair_t *p;
20322   unformat_input_t *i = vam->input;
20323   int j;
20324
20325   if (unformat (i, "%s", &name))
20326     {
20327       uword *hs;
20328
20329       vec_add1 (name, 0);
20330
20331       hs = hash_get_mem (vam->help_by_name, name);
20332       if (hs)
20333         print (vam->ofp, "usage: %s %s", name, hs[0]);
20334       else
20335         print (vam->ofp, "No such msg / command '%s'", name);
20336       vec_free (name);
20337       return 0;
20338     }
20339
20340   print (vam->ofp, "Help is available for the following:");
20341
20342     /* *INDENT-OFF* */
20343     hash_foreach_pair (p, vam->function_by_name,
20344     ({
20345       vec_add1 (cmds, (u8 *)(p->key));
20346     }));
20347     /* *INDENT-ON* */
20348
20349   vec_sort_with_function (cmds, cmd_cmp);
20350
20351   for (j = 0; j < vec_len (cmds); j++)
20352     print (vam->ofp, "%s", cmds[j]);
20353
20354   vec_free (cmds);
20355   return 0;
20356 }
20357
20358 static int
20359 set (vat_main_t * vam)
20360 {
20361   u8 *name = 0, *value = 0;
20362   unformat_input_t *i = vam->input;
20363
20364   if (unformat (i, "%s", &name))
20365     {
20366       /* The input buffer is a vector, not a string. */
20367       value = vec_dup (i->buffer);
20368       vec_delete (value, i->index, 0);
20369       /* Almost certainly has a trailing newline */
20370       if (value[vec_len (value) - 1] == '\n')
20371         value[vec_len (value) - 1] = 0;
20372       /* Make sure it's a proper string, one way or the other */
20373       vec_add1 (value, 0);
20374       (void) clib_macro_set_value (&vam->macro_main,
20375                                    (char *) name, (char *) value);
20376     }
20377   else
20378     errmsg ("usage: set <name> <value>");
20379
20380   vec_free (name);
20381   vec_free (value);
20382   return 0;
20383 }
20384
20385 static int
20386 unset (vat_main_t * vam)
20387 {
20388   u8 *name = 0;
20389
20390   if (unformat (vam->input, "%s", &name))
20391     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20392       errmsg ("unset: %s wasn't set", name);
20393   vec_free (name);
20394   return 0;
20395 }
20396
20397 typedef struct
20398 {
20399   u8 *name;
20400   u8 *value;
20401 } macro_sort_t;
20402
20403
20404 static int
20405 macro_sort_cmp (void *a1, void *a2)
20406 {
20407   macro_sort_t *s1 = a1;
20408   macro_sort_t *s2 = a2;
20409
20410   return strcmp ((char *) (s1->name), (char *) (s2->name));
20411 }
20412
20413 static int
20414 dump_macro_table (vat_main_t * vam)
20415 {
20416   macro_sort_t *sort_me = 0, *sm;
20417   int i;
20418   hash_pair_t *p;
20419
20420     /* *INDENT-OFF* */
20421     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20422     ({
20423       vec_add2 (sort_me, sm, 1);
20424       sm->name = (u8 *)(p->key);
20425       sm->value = (u8 *) (p->value[0]);
20426     }));
20427     /* *INDENT-ON* */
20428
20429   vec_sort_with_function (sort_me, macro_sort_cmp);
20430
20431   if (vec_len (sort_me))
20432     print (vam->ofp, "%-15s%s", "Name", "Value");
20433   else
20434     print (vam->ofp, "The macro table is empty...");
20435
20436   for (i = 0; i < vec_len (sort_me); i++)
20437     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20438   return 0;
20439 }
20440
20441 static int
20442 dump_node_table (vat_main_t * vam)
20443 {
20444   int i, j;
20445   vlib_node_t *node, *next_node;
20446
20447   if (vec_len (vam->graph_nodes) == 0)
20448     {
20449       print (vam->ofp, "Node table empty, issue get_node_graph...");
20450       return 0;
20451     }
20452
20453   for (i = 0; i < vec_len (vam->graph_nodes); i++)
20454     {
20455       node = vam->graph_nodes[i];
20456       print (vam->ofp, "[%d] %s", i, node->name);
20457       for (j = 0; j < vec_len (node->next_nodes); j++)
20458         {
20459           if (node->next_nodes[j] != ~0)
20460             {
20461               next_node = vam->graph_nodes[node->next_nodes[j]];
20462               print (vam->ofp, "  [%d] %s", j, next_node->name);
20463             }
20464         }
20465     }
20466   return 0;
20467 }
20468
20469 static int
20470 value_sort_cmp (void *a1, void *a2)
20471 {
20472   name_sort_t *n1 = a1;
20473   name_sort_t *n2 = a2;
20474
20475   if (n1->value < n2->value)
20476     return -1;
20477   if (n1->value > n2->value)
20478     return 1;
20479   return 0;
20480 }
20481
20482
20483 static int
20484 dump_msg_api_table (vat_main_t * vam)
20485 {
20486   api_main_t *am = &api_main;
20487   name_sort_t *nses = 0, *ns;
20488   hash_pair_t *hp;
20489   int i;
20490
20491   /* *INDENT-OFF* */
20492   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20493   ({
20494     vec_add2 (nses, ns, 1);
20495     ns->name = (u8 *)(hp->key);
20496     ns->value = (u32) hp->value[0];
20497   }));
20498   /* *INDENT-ON* */
20499
20500   vec_sort_with_function (nses, value_sort_cmp);
20501
20502   for (i = 0; i < vec_len (nses); i++)
20503     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20504   vec_free (nses);
20505   return 0;
20506 }
20507
20508 static int
20509 get_msg_id (vat_main_t * vam)
20510 {
20511   u8 *name_and_crc;
20512   u32 message_index;
20513
20514   if (unformat (vam->input, "%s", &name_and_crc))
20515     {
20516       message_index = vl_api_get_msg_index (name_and_crc);
20517       if (message_index == ~0)
20518         {
20519           print (vam->ofp, " '%s' not found", name_and_crc);
20520           return 0;
20521         }
20522       print (vam->ofp, " '%s' has message index %d",
20523              name_and_crc, message_index);
20524       return 0;
20525     }
20526   errmsg ("name_and_crc required...");
20527   return 0;
20528 }
20529
20530 static int
20531 search_node_table (vat_main_t * vam)
20532 {
20533   unformat_input_t *line_input = vam->input;
20534   u8 *node_to_find;
20535   int j;
20536   vlib_node_t *node, *next_node;
20537   uword *p;
20538
20539   if (vam->graph_node_index_by_name == 0)
20540     {
20541       print (vam->ofp, "Node table empty, issue get_node_graph...");
20542       return 0;
20543     }
20544
20545   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20546     {
20547       if (unformat (line_input, "%s", &node_to_find))
20548         {
20549           vec_add1 (node_to_find, 0);
20550           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20551           if (p == 0)
20552             {
20553               print (vam->ofp, "%s not found...", node_to_find);
20554               goto out;
20555             }
20556           node = vam->graph_nodes[p[0]];
20557           print (vam->ofp, "[%d] %s", p[0], node->name);
20558           for (j = 0; j < vec_len (node->next_nodes); j++)
20559             {
20560               if (node->next_nodes[j] != ~0)
20561                 {
20562                   next_node = vam->graph_nodes[node->next_nodes[j]];
20563                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20564                 }
20565             }
20566         }
20567
20568       else
20569         {
20570           clib_warning ("parse error '%U'", format_unformat_error,
20571                         line_input);
20572           return -99;
20573         }
20574
20575     out:
20576       vec_free (node_to_find);
20577
20578     }
20579
20580   return 0;
20581 }
20582
20583
20584 static int
20585 script (vat_main_t * vam)
20586 {
20587 #if (VPP_API_TEST_BUILTIN==0)
20588   u8 *s = 0;
20589   char *save_current_file;
20590   unformat_input_t save_input;
20591   jmp_buf save_jump_buf;
20592   u32 save_line_number;
20593
20594   FILE *new_fp, *save_ifp;
20595
20596   if (unformat (vam->input, "%s", &s))
20597     {
20598       new_fp = fopen ((char *) s, "r");
20599       if (new_fp == 0)
20600         {
20601           errmsg ("Couldn't open script file %s", s);
20602           vec_free (s);
20603           return -99;
20604         }
20605     }
20606   else
20607     {
20608       errmsg ("Missing script name");
20609       return -99;
20610     }
20611
20612   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20613   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20614   save_ifp = vam->ifp;
20615   save_line_number = vam->input_line_number;
20616   save_current_file = (char *) vam->current_file;
20617
20618   vam->input_line_number = 0;
20619   vam->ifp = new_fp;
20620   vam->current_file = s;
20621   do_one_file (vam);
20622
20623   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
20624   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20625   vam->ifp = save_ifp;
20626   vam->input_line_number = save_line_number;
20627   vam->current_file = (u8 *) save_current_file;
20628   vec_free (s);
20629
20630   return 0;
20631 #else
20632   clib_warning ("use the exec command...");
20633   return -99;
20634 #endif
20635 }
20636
20637 static int
20638 echo (vat_main_t * vam)
20639 {
20640   print (vam->ofp, "%v", vam->input->buffer);
20641   return 0;
20642 }
20643
20644 /* List of API message constructors, CLI names map to api_xxx */
20645 #define foreach_vpe_api_msg                                             \
20646 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20647 _(sw_interface_dump,"")                                                 \
20648 _(sw_interface_set_flags,                                               \
20649   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20650 _(sw_interface_add_del_address,                                         \
20651   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20652 _(sw_interface_set_table,                                               \
20653   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20654 _(sw_interface_set_mpls_enable,                                         \
20655   "<intfc> | sw_if_index [disable | dis]")                              \
20656 _(sw_interface_set_vpath,                                               \
20657   "<intfc> | sw_if_index <id> enable | disable")                        \
20658 _(sw_interface_set_vxlan_bypass,                                        \
20659   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20660 _(sw_interface_set_l2_xconnect,                                         \
20661   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20662   "enable | disable")                                                   \
20663 _(sw_interface_set_l2_bridge,                                           \
20664   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20665   "[shg <split-horizon-group>] [bvi]\n"                                 \
20666   "enable | disable")                                                   \
20667 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20668 _(bridge_domain_add_del,                                                \
20669   "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") \
20670 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20671 _(l2fib_add_del,                                                        \
20672   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20673 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20674 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20675 _(l2_flags,                                                             \
20676   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20677 _(bridge_flags,                                                         \
20678   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20679 _(tap_connect,                                                          \
20680   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
20681 _(tap_modify,                                                           \
20682   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
20683 _(tap_delete,                                                           \
20684   "<vpp-if-name> | sw_if_index <id>")                                   \
20685 _(sw_interface_tap_dump, "")                                            \
20686 _(ip_table_add_del,                                                     \
20687   "table-id <n> [ipv6]\n")                                              \
20688 _(ip_add_del_route,                                                     \
20689   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
20690   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20691   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20692   "[multipath] [count <n>]")                                            \
20693 _(ip_mroute_add_del,                                                    \
20694   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20695   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20696 _(mpls_table_add_del,                                                   \
20697   "table-id <n>\n")                                                     \
20698 _(mpls_route_add_del,                                                   \
20699   "<label> <eos> via <addr> [table-id <n>]\n"                           \
20700   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20701   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20702   "[multipath] [count <n>]")                                            \
20703 _(mpls_ip_bind_unbind,                                                  \
20704   "<label> <addr/len>")                                                 \
20705 _(mpls_tunnel_add_del,                                                  \
20706   " via <addr> [table-id <n>]\n"                                        \
20707   "sw_if_index <id>] [l2]  [del]")                                      \
20708 _(proxy_arp_add_del,                                                    \
20709   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
20710 _(proxy_arp_intfc_enable_disable,                                       \
20711   "<intfc> | sw_if_index <id> enable | disable")                        \
20712 _(sw_interface_set_unnumbered,                                          \
20713   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20714 _(ip_neighbor_add_del,                                                  \
20715   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
20716   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
20717 _(reset_vrf, "vrf <id> [ipv6]")                                         \
20718 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20719 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20720   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20721   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20722   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20723 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
20724 _(reset_fib, "vrf <n> [ipv6]")                                          \
20725 _(dhcp_proxy_config,                                                    \
20726   "svr <v46-address> src <v46-address>\n"                               \
20727    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
20728 _(dhcp_proxy_set_vss,                                                   \
20729   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
20730 _(dhcp_proxy_dump, "ip6")                                               \
20731 _(dhcp_client_config,                                                   \
20732   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
20733 _(set_ip_flow_hash,                                                     \
20734   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20735 _(sw_interface_ip6_enable_disable,                                      \
20736   "<intfc> | sw_if_index <id> enable | disable")                        \
20737 _(sw_interface_ip6_set_link_local_address,                              \
20738   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
20739 _(ip6nd_proxy_add_del,                                                  \
20740   "<intfc> | sw_if_index <id> <ip6-address>")                           \
20741 _(ip6nd_proxy_dump, "")                                                 \
20742 _(sw_interface_ip6nd_ra_prefix,                                         \
20743   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
20744   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
20745   "[nolink] [isno]")                                                    \
20746 _(sw_interface_ip6nd_ra_config,                                         \
20747   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
20748   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
20749   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
20750 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
20751 _(l2_patch_add_del,                                                     \
20752   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20753   "enable | disable")                                                   \
20754 _(sr_localsid_add_del,                                                  \
20755   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20756   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20757 _(classify_add_del_table,                                               \
20758   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20759   " [del] [del-chain] mask <mask-value>\n"                              \
20760   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20761   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20762 _(classify_add_del_session,                                             \
20763   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20764   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20765   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20766   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20767 _(classify_set_interface_ip_table,                                      \
20768   "<intfc> | sw_if_index <nn> table <nn>")                              \
20769 _(classify_set_interface_l2_tables,                                     \
20770   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20771   "  [other-table <nn>]")                                               \
20772 _(get_node_index, "node <node-name")                                    \
20773 _(add_node_next, "node <node-name> next <next-node-name>")              \
20774 _(l2tpv3_create_tunnel,                                                 \
20775   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20776   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20777   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20778 _(l2tpv3_set_tunnel_cookies,                                            \
20779   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20780   "[new_remote_cookie <nn>]\n")                                         \
20781 _(l2tpv3_interface_enable_disable,                                      \
20782   "<intfc> | sw_if_index <nn> enable | disable")                        \
20783 _(l2tpv3_set_lookup_key,                                                \
20784   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20785 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20786 _(vxlan_add_del_tunnel,                                                 \
20787   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20788   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20789   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20790 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20791 _(gre_add_del_tunnel,                                                   \
20792   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20793 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20794 _(l2_fib_clear_table, "")                                               \
20795 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20796 _(l2_interface_vlan_tag_rewrite,                                        \
20797   "<intfc> | sw_if_index <nn> \n"                                       \
20798   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20799   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20800 _(create_vhost_user_if,                                                 \
20801         "socket <filename> [server] [renumber <dev_instance>] "         \
20802         "[mac <mac_address>]")                                          \
20803 _(modify_vhost_user_if,                                                 \
20804         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20805         "[server] [renumber <dev_instance>]")                           \
20806 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20807 _(sw_interface_vhost_user_dump, "")                                     \
20808 _(show_version, "")                                                     \
20809 _(vxlan_gpe_add_del_tunnel,                                             \
20810   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20811   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20812   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20813   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20814 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20815 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20816 _(interface_name_renumber,                                              \
20817   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20818 _(input_acl_set_interface,                                              \
20819   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20820   "  [l2-table <nn>] [del]")                                            \
20821 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20822 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20823 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20824 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20825 _(ip_dump, "ipv4 | ipv6")                                               \
20826 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20827 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20828   "  spid_id <n> ")                                                     \
20829 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20830   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20831   "  integ_alg <alg> integ_key <hex>")                                  \
20832 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20833   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20834   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20835   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20836 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20837 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20838   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20839   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20840   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20841 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20842 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20843   "(auth_data 0x<data> | auth_data <data>)")                            \
20844 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20845   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20846 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20847   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20848   "(local|remote)")                                                     \
20849 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20850 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20851 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20852 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20853 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20854 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20855 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20856 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20857 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20858 _(delete_loopback,"sw_if_index <nn>")                                   \
20859 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20860 _(map_add_domain,                                                       \
20861   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20862   "ip6-src <ip6addr> "                                                  \
20863   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20864 _(map_del_domain, "index <n>")                                          \
20865 _(map_add_del_rule,                                                     \
20866   "index <n> psid <n> dst <ip6addr> [del]")                             \
20867 _(map_domain_dump, "")                                                  \
20868 _(map_rule_dump, "index <map-domain>")                                  \
20869 _(want_interface_events,  "enable|disable")                             \
20870 _(want_stats,"enable|disable")                                          \
20871 _(get_first_msg_id, "client <name>")                                    \
20872 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20873 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20874   "fib-id <nn> [ip4][ip6][default]")                                    \
20875 _(get_node_graph, " ")                                                  \
20876 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20877 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20878 _(ioam_disable, "")                                                     \
20879 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20880                             " sw_if_index <sw_if_index> p <priority> "  \
20881                             "w <weight>] [del]")                        \
20882 _(one_add_del_locator, "locator-set <locator_name> "                    \
20883                         "iface <intf> | sw_if_index <sw_if_index> "     \
20884                         "p <priority> w <weight> [del]")                \
20885 _(one_add_del_local_eid,"vni <vni> eid "                                \
20886                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20887                          "locator-set <locator_name> [del]"             \
20888                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20889 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20890 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20891 _(one_enable_disable, "enable|disable")                                 \
20892 _(one_map_register_enable_disable, "enable|disable")                    \
20893 _(one_map_register_fallback_threshold, "<value>")                       \
20894 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20895 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20896                                "[seid <seid>] "                         \
20897                                "rloc <locator> p <prio> "               \
20898                                "w <weight> [rloc <loc> ... ] "          \
20899                                "action <action> [del-all]")             \
20900 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20901                           "<local-eid>")                                \
20902 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20903 _(one_use_petr, "ip-address> | disable")                                \
20904 _(one_map_request_mode, "src-dst|dst-only")                             \
20905 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20906 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20907 _(one_locator_set_dump, "[local | remote]")                             \
20908 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20909 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20910                        "[local] | [remote]")                            \
20911 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20912 _(one_ndp_bd_get, "")                                                   \
20913 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20914 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20915 _(one_l2_arp_bd_get, "")                                                \
20916 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20917 _(one_stats_enable_disable, "enable|disalbe")                           \
20918 _(show_one_stats_enable_disable, "")                                    \
20919 _(one_eid_table_vni_dump, "")                                           \
20920 _(one_eid_table_map_dump, "l2|l3")                                      \
20921 _(one_map_resolver_dump, "")                                            \
20922 _(one_map_server_dump, "")                                              \
20923 _(one_adjacencies_get, "vni <vni>")                                     \
20924 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20925 _(show_one_rloc_probe_state, "")                                        \
20926 _(show_one_map_register_state, "")                                      \
20927 _(show_one_status, "")                                                  \
20928 _(one_stats_dump, "")                                                   \
20929 _(one_stats_flush, "")                                                  \
20930 _(one_get_map_request_itr_rlocs, "")                                    \
20931 _(one_map_register_set_ttl, "<ttl>")                                    \
20932 _(one_set_transport_protocol, "udp|api")                                \
20933 _(one_get_transport_protocol, "")                                       \
20934 _(show_one_nsh_mapping, "")                                             \
20935 _(show_one_pitr, "")                                                    \
20936 _(show_one_use_petr, "")                                                \
20937 _(show_one_map_request_mode, "")                                        \
20938 _(show_one_map_register_ttl, "")                                        \
20939 _(show_one_map_register_fallback_threshold, "")                         \
20940 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20941                             " sw_if_index <sw_if_index> p <priority> "  \
20942                             "w <weight>] [del]")                        \
20943 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20944                         "iface <intf> | sw_if_index <sw_if_index> "     \
20945                         "p <priority> w <weight> [del]")                \
20946 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20947                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20948                          "locator-set <locator_name> [del]"             \
20949                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20950 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20951 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20952 _(lisp_enable_disable, "enable|disable")                                \
20953 _(lisp_map_register_enable_disable, "enable|disable")                   \
20954 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20955 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20956                                "[seid <seid>] "                         \
20957                                "rloc <locator> p <prio> "               \
20958                                "w <weight> [rloc <loc> ... ] "          \
20959                                "action <action> [del-all]")             \
20960 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20961                           "<local-eid>")                                \
20962 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20963 _(lisp_use_petr, "<ip-address> | disable")                              \
20964 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20965 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20966 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20967 _(lisp_locator_set_dump, "[local | remote]")                            \
20968 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20969 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20970                        "[local] | [remote]")                            \
20971 _(lisp_eid_table_vni_dump, "")                                          \
20972 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20973 _(lisp_map_resolver_dump, "")                                           \
20974 _(lisp_map_server_dump, "")                                             \
20975 _(lisp_adjacencies_get, "vni <vni>")                                    \
20976 _(gpe_fwd_entry_vnis_get, "")                                           \
20977 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20978 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20979                                 "[table <table-id>]")                   \
20980 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20981 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20982 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20983 _(gpe_get_encap_mode, "")                                               \
20984 _(lisp_gpe_add_del_iface, "up|down")                                    \
20985 _(lisp_gpe_enable_disable, "enable|disable")                            \
20986 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20987   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20988 _(show_lisp_rloc_probe_state, "")                                       \
20989 _(show_lisp_map_register_state, "")                                     \
20990 _(show_lisp_status, "")                                                 \
20991 _(lisp_get_map_request_itr_rlocs, "")                                   \
20992 _(show_lisp_pitr, "")                                                   \
20993 _(show_lisp_use_petr, "")                                               \
20994 _(show_lisp_map_request_mode, "")                                       \
20995 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20996 _(af_packet_delete, "name <host interface name>")                       \
20997 _(policer_add_del, "name <policer name> <params> [del]")                \
20998 _(policer_dump, "[name <policer name>]")                                \
20999 _(policer_classify_set_interface,                                       \
21000   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21001   "  [l2-table <nn>] [del]")                                            \
21002 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21003 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21004     "[master|slave]")                                                   \
21005 _(netmap_delete, "name <interface name>")                               \
21006 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21007 _(mpls_fib_dump, "")                                                    \
21008 _(classify_table_ids, "")                                               \
21009 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21010 _(classify_table_info, "table_id <nn>")                                 \
21011 _(classify_session_dump, "table_id <nn>")                               \
21012 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21013     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21014     "[template_interval <nn>] [udp_checksum]")                          \
21015 _(ipfix_exporter_dump, "")                                              \
21016 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21017 _(ipfix_classify_stream_dump, "")                                       \
21018 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21019 _(ipfix_classify_table_dump, "")                                        \
21020 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21021 _(sw_interface_span_dump, "[l2]")                                           \
21022 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21023 _(pg_create_interface, "if_id <nn>")                                    \
21024 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21025 _(pg_enable_disable, "[stream <id>] disable")                           \
21026 _(ip_source_and_port_range_check_add_del,                               \
21027   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21028 _(ip_source_and_port_range_check_interface_add_del,                     \
21029   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21030   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21031 _(ipsec_gre_add_del_tunnel,                                             \
21032   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21033 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21034 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21035 _(l2_interface_pbb_tag_rewrite,                                         \
21036   "<intfc> | sw_if_index <nn> \n"                                       \
21037   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21038   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21039 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21040 _(flow_classify_set_interface,                                          \
21041   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21042 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21043 _(ip_fib_dump, "")                                                      \
21044 _(ip_mfib_dump, "")                                                     \
21045 _(ip6_fib_dump, "")                                                     \
21046 _(ip6_mfib_dump, "")                                                    \
21047 _(feature_enable_disable, "arc_name <arc_name> "                        \
21048   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21049 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21050 "[disable]")                                                            \
21051 _(l2_xconnect_dump, "")                                                 \
21052 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21053 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21054 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21055 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21056 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21057 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21058 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]") \
21059 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21060 _(memfd_segment_create,"size <nnn>")
21061
21062 /* List of command functions, CLI names map directly to functions */
21063 #define foreach_cli_function                                    \
21064 _(comment, "usage: comment <ignore-rest-of-line>")              \
21065 _(dump_interface_table, "usage: dump_interface_table")          \
21066 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21067 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21068 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21069 _(dump_stats_table, "usage: dump_stats_table")                  \
21070 _(dump_macro_table, "usage: dump_macro_table ")                 \
21071 _(dump_node_table, "usage: dump_node_table")                    \
21072 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21073 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21074 _(echo, "usage: echo <message>")                                \
21075 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21076 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21077 _(help, "usage: help")                                          \
21078 _(q, "usage: quit")                                             \
21079 _(quit, "usage: quit")                                          \
21080 _(search_node_table, "usage: search_node_table <name>...")      \
21081 _(set, "usage: set <variable-name> <value>")                    \
21082 _(script, "usage: script <file-name>")                          \
21083 _(unset, "usage: unset <variable-name>")
21084 #define _(N,n)                                  \
21085     static void vl_api_##n##_t_handler_uni      \
21086     (vl_api_##n##_t * mp)                       \
21087     {                                           \
21088         vat_main_t * vam = &vat_main;           \
21089         if (vam->json_output) {                 \
21090             vl_api_##n##_t_handler_json(mp);    \
21091         } else {                                \
21092             vl_api_##n##_t_handler(mp);         \
21093         }                                       \
21094     }
21095 foreach_vpe_api_reply_msg;
21096 #if VPP_API_TEST_BUILTIN == 0
21097 foreach_standalone_reply_msg;
21098 #endif
21099 #undef _
21100
21101 void
21102 vat_api_hookup (vat_main_t * vam)
21103 {
21104 #define _(N,n)                                                  \
21105     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21106                            vl_api_##n##_t_handler_uni,          \
21107                            vl_noop_handler,                     \
21108                            vl_api_##n##_t_endian,               \
21109                            vl_api_##n##_t_print,                \
21110                            sizeof(vl_api_##n##_t), 1);
21111   foreach_vpe_api_reply_msg;
21112 #if VPP_API_TEST_BUILTIN == 0
21113   foreach_standalone_reply_msg;
21114 #endif
21115 #undef _
21116
21117 #if (VPP_API_TEST_BUILTIN==0)
21118   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21119
21120   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21121
21122   vam->function_by_name = hash_create_string (0, sizeof (uword));
21123
21124   vam->help_by_name = hash_create_string (0, sizeof (uword));
21125 #endif
21126
21127   /* API messages we can send */
21128 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21129   foreach_vpe_api_msg;
21130 #undef _
21131
21132   /* Help strings */
21133 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21134   foreach_vpe_api_msg;
21135 #undef _
21136
21137   /* CLI functions */
21138 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21139   foreach_cli_function;
21140 #undef _
21141
21142   /* Help strings */
21143 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21144   foreach_cli_function;
21145 #undef _
21146 }
21147
21148 #if VPP_API_TEST_BUILTIN
21149 static clib_error_t *
21150 vat_api_hookup_shim (vlib_main_t * vm)
21151 {
21152   vat_api_hookup (&vat_main);
21153   return 0;
21154 }
21155
21156 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21157 #endif
21158
21159 /*
21160  * fd.io coding-style-patch-verification: ON
21161  *
21162  * Local Variables:
21163  * eval: (c-set-style "gnu")
21164  * End:
21165  */