Add GPE CLI/API for setting encap mode
[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 <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.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 f64
78 vat_time_now (vat_main_t * vam)
79 {
80 #if VPP_API_TEST_BUILTIN
81   return vlib_time_now (vam->vlib_main);
82 #else
83   return clib_time_now (&vam->clib_time);
84 #endif
85 }
86
87 void
88 errmsg (char *fmt, ...)
89 {
90   vat_main_t *vam = &vat_main;
91   va_list va;
92   u8 *s;
93
94   va_start (va, fmt);
95   s = va_format (0, fmt, &va);
96   va_end (va);
97
98   vec_add1 (s, 0);
99
100 #if VPP_API_TEST_BUILTIN
101   vlib_cli_output (vam->vlib_main, (char *) s);
102 #else
103   {
104     if (vam->ifp != stdin)
105       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
106                vam->input_line_number);
107     fformat (vam->ofp, (char *) s);
108     fflush (vam->ofp);
109   }
110 #endif
111
112   vec_free (s);
113 }
114
115 #if VPP_API_TEST_BUILTIN == 0
116 static uword
117 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
118 {
119   vat_main_t *vam = va_arg (*args, vat_main_t *);
120   u32 *result = va_arg (*args, u32 *);
121   u8 *if_name;
122   uword *p;
123
124   if (!unformat (input, "%s", &if_name))
125     return 0;
126
127   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
128   if (p == 0)
129     return 0;
130   *result = p[0];
131   return 1;
132 }
133
134 /* Parse an IP4 address %d.%d.%d.%d. */
135 uword
136 unformat_ip4_address (unformat_input_t * input, va_list * args)
137 {
138   u8 *result = va_arg (*args, u8 *);
139   unsigned a[4];
140
141   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
142     return 0;
143
144   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
145     return 0;
146
147   result[0] = a[0];
148   result[1] = a[1];
149   result[2] = a[2];
150   result[3] = a[3];
151
152   return 1;
153 }
154
155 uword
156 unformat_ethernet_address (unformat_input_t * input, va_list * args)
157 {
158   u8 *result = va_arg (*args, u8 *);
159   u32 i, a[6];
160
161   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
162                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
163     return 0;
164
165   /* Check range. */
166   for (i = 0; i < 6; i++)
167     if (a[i] >= (1 << 8))
168       return 0;
169
170   for (i = 0; i < 6; i++)
171     result[i] = a[i];
172
173   return 1;
174 }
175
176 /* Returns ethernet type as an int in host byte order. */
177 uword
178 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
179                                         va_list * args)
180 {
181   u16 *result = va_arg (*args, u16 *);
182   int type;
183
184   /* Numeric type. */
185   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
186     {
187       if (type >= (1 << 16))
188         return 0;
189       *result = type;
190       return 1;
191     }
192   return 0;
193 }
194
195 /* Parse an IP6 address. */
196 uword
197 unformat_ip6_address (unformat_input_t * input, va_list * args)
198 {
199   ip6_address_t *result = va_arg (*args, ip6_address_t *);
200   u16 hex_quads[8];
201   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
202   uword c, n_colon, double_colon_index;
203
204   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
205   double_colon_index = ARRAY_LEN (hex_quads);
206   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
207     {
208       hex_digit = 16;
209       if (c >= '0' && c <= '9')
210         hex_digit = c - '0';
211       else if (c >= 'a' && c <= 'f')
212         hex_digit = c + 10 - 'a';
213       else if (c >= 'A' && c <= 'F')
214         hex_digit = c + 10 - 'A';
215       else if (c == ':' && n_colon < 2)
216         n_colon++;
217       else
218         {
219           unformat_put_input (input);
220           break;
221         }
222
223       /* Too many hex quads. */
224       if (n_hex_quads >= ARRAY_LEN (hex_quads))
225         return 0;
226
227       if (hex_digit < 16)
228         {
229           hex_quad = (hex_quad << 4) | hex_digit;
230
231           /* Hex quad must fit in 16 bits. */
232           if (n_hex_digits >= 4)
233             return 0;
234
235           n_colon = 0;
236           n_hex_digits++;
237         }
238
239       /* Save position of :: */
240       if (n_colon == 2)
241         {
242           /* More than one :: ? */
243           if (double_colon_index < ARRAY_LEN (hex_quads))
244             return 0;
245           double_colon_index = n_hex_quads;
246         }
247
248       if (n_colon > 0 && n_hex_digits > 0)
249         {
250           hex_quads[n_hex_quads++] = hex_quad;
251           hex_quad = 0;
252           n_hex_digits = 0;
253         }
254     }
255
256   if (n_hex_digits > 0)
257     hex_quads[n_hex_quads++] = hex_quad;
258
259   {
260     word i;
261
262     /* Expand :: to appropriate number of zero hex quads. */
263     if (double_colon_index < ARRAY_LEN (hex_quads))
264       {
265         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
266
267         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
268           hex_quads[n_zero + i] = hex_quads[i];
269
270         for (i = 0; i < n_zero; i++)
271           hex_quads[double_colon_index + i] = 0;
272
273         n_hex_quads = ARRAY_LEN (hex_quads);
274       }
275
276     /* Too few hex quads given. */
277     if (n_hex_quads < ARRAY_LEN (hex_quads))
278       return 0;
279
280     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
281       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
282
283     return 1;
284   }
285 }
286
287 uword
288 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
289 {
290   u32 *r = va_arg (*args, u32 *);
291
292   if (0);
293 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
294   foreach_ipsec_policy_action
295 #undef _
296     else
297     return 0;
298   return 1;
299 }
300
301 uword
302 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
303 {
304   u32 *r = va_arg (*args, u32 *);
305
306   if (0);
307 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
308   foreach_ipsec_crypto_alg
309 #undef _
310     else
311     return 0;
312   return 1;
313 }
314
315 u8 *
316 format_ipsec_crypto_alg (u8 * s, va_list * args)
317 {
318   u32 i = va_arg (*args, u32);
319   u8 *t = 0;
320
321   switch (i)
322     {
323 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
324       foreach_ipsec_crypto_alg
325 #undef _
326     default:
327       return format (s, "unknown");
328     }
329   return format (s, "%s", t);
330 }
331
332 uword
333 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
339   foreach_ipsec_integ_alg
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 u8 *
347 format_ipsec_integ_alg (u8 * s, va_list * args)
348 {
349   u32 i = va_arg (*args, u32);
350   u8 *t = 0;
351
352   switch (i)
353     {
354 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
355       foreach_ipsec_integ_alg
356 #undef _
357     default:
358       return format (s, "unknown");
359     }
360   return format (s, "%s", t);
361 }
362
363 uword
364 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
370   foreach_ikev2_auth_method
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 uword
378 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
379 {
380   u32 *r = va_arg (*args, u32 *);
381
382   if (0);
383 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
384   foreach_ikev2_id_type
385 #undef _
386     else
387     return 0;
388   return 1;
389 }
390 #else /* VPP_API_TEST_BUILTIN == 1 */
391 static uword
392 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
393 {
394   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
395   vnet_main_t *vnm = vnet_get_main ();
396   u32 *result = va_arg (*args, u32 *);
397   u32 sw_if_index;
398
399   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
400     return 0;
401
402   *result = sw_if_index;
403   return 1;
404 }
405 #endif /* VPP_API_TEST_BUILTIN */
406
407 static uword
408 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "kbps"))
413     *r = SSE2_QOS_RATE_KBPS;
414   else if (unformat (input, "pps"))
415     *r = SSE2_QOS_RATE_PPS;
416   else
417     return 0;
418   return 1;
419 }
420
421 static uword
422 unformat_policer_round_type (unformat_input_t * input, va_list * args)
423 {
424   u8 *r = va_arg (*args, u8 *);
425
426   if (unformat (input, "closest"))
427     *r = SSE2_QOS_ROUND_TO_CLOSEST;
428   else if (unformat (input, "up"))
429     *r = SSE2_QOS_ROUND_TO_UP;
430   else if (unformat (input, "down"))
431     *r = SSE2_QOS_ROUND_TO_DOWN;
432   else
433     return 0;
434   return 1;
435 }
436
437 static uword
438 unformat_policer_type (unformat_input_t * input, va_list * args)
439 {
440   u8 *r = va_arg (*args, u8 *);
441
442   if (unformat (input, "1r2c"))
443     *r = SSE2_QOS_POLICER_TYPE_1R2C;
444   else if (unformat (input, "1r3c"))
445     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
446   else if (unformat (input, "2r3c-2698"))
447     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
448   else if (unformat (input, "2r3c-4115"))
449     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
450   else if (unformat (input, "2r3c-mef5cf1"))
451     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
452   else
453     return 0;
454   return 1;
455 }
456
457 static uword
458 unformat_dscp (unformat_input_t * input, va_list * va)
459 {
460   u8 *r = va_arg (*va, u8 *);
461
462   if (0);
463 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
464   foreach_vnet_dscp
465 #undef _
466     else
467     return 0;
468   return 1;
469 }
470
471 static uword
472 unformat_policer_action_type (unformat_input_t * input, va_list * va)
473 {
474   sse2_qos_pol_action_params_st *a
475     = va_arg (*va, sse2_qos_pol_action_params_st *);
476
477   if (unformat (input, "drop"))
478     a->action_type = SSE2_QOS_ACTION_DROP;
479   else if (unformat (input, "transmit"))
480     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
481   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
482     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
490 {
491   u32 *r = va_arg (*va, u32 *);
492   u32 tid;
493
494   if (unformat (input, "ip4"))
495     tid = POLICER_CLASSIFY_TABLE_IP4;
496   else if (unformat (input, "ip6"))
497     tid = POLICER_CLASSIFY_TABLE_IP6;
498   else if (unformat (input, "l2"))
499     tid = POLICER_CLASSIFY_TABLE_L2;
500   else
501     return 0;
502
503   *r = tid;
504   return 1;
505 }
506
507 static uword
508 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
509 {
510   u32 *r = va_arg (*va, u32 *);
511   u32 tid;
512
513   if (unformat (input, "ip4"))
514     tid = FLOW_CLASSIFY_TABLE_IP4;
515   else if (unformat (input, "ip6"))
516     tid = FLOW_CLASSIFY_TABLE_IP6;
517   else
518     return 0;
519
520   *r = tid;
521   return 1;
522 }
523
524 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
525 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
526 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
527 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
528
529 #if (VPP_API_TEST_BUILTIN==0)
530 uword
531 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
532 {
533   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
534   mfib_itf_attribute_t attr;
535
536   old = *iflags;
537   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
538   {
539     if (unformat (input, mfib_itf_flag_long_names[attr]))
540       *iflags |= (1 << attr);
541   }
542   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
543   {
544     if (unformat (input, mfib_itf_flag_names[attr]))
545       *iflags |= (1 << attr);
546   }
547
548   return (old == *iflags ? 0 : 1);
549 }
550
551 uword
552 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
553 {
554   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
555   mfib_entry_attribute_t attr;
556
557   old = *eflags;
558   FOR_EACH_MFIB_ATTRIBUTE (attr)
559   {
560     if (unformat (input, mfib_flag_long_names[attr]))
561       *eflags |= (1 << attr);
562   }
563   FOR_EACH_MFIB_ATTRIBUTE (attr)
564   {
565     if (unformat (input, mfib_flag_names[attr]))
566       *eflags |= (1 << attr);
567   }
568
569   return (old == *eflags ? 0 : 1);
570 }
571
572 u8 *
573 format_ip4_address (u8 * s, va_list * args)
574 {
575   u8 *a = va_arg (*args, u8 *);
576   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
577 }
578
579 u8 *
580 format_ip6_address (u8 * s, va_list * args)
581 {
582   ip6_address_t *a = va_arg (*args, ip6_address_t *);
583   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
584
585   i_max_n_zero = ARRAY_LEN (a->as_u16);
586   max_n_zeros = 0;
587   i_first_zero = i_max_n_zero;
588   n_zeros = 0;
589   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
590     {
591       u32 is_zero = a->as_u16[i] == 0;
592       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
593         {
594           i_first_zero = i;
595           n_zeros = 0;
596         }
597       n_zeros += is_zero;
598       if ((!is_zero && n_zeros > max_n_zeros)
599           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
600         {
601           i_max_n_zero = i_first_zero;
602           max_n_zeros = n_zeros;
603           i_first_zero = ARRAY_LEN (a->as_u16);
604           n_zeros = 0;
605         }
606     }
607
608   last_double_colon = 0;
609   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
610     {
611       if (i == i_max_n_zero && max_n_zeros > 1)
612         {
613           s = format (s, "::");
614           i += max_n_zeros - 1;
615           last_double_colon = 1;
616         }
617       else
618         {
619           s = format (s, "%s%x",
620                       (last_double_colon || i == 0) ? "" : ":",
621                       clib_net_to_host_u16 (a->as_u16[i]));
622           last_double_colon = 0;
623         }
624     }
625
626   return s;
627 }
628
629 /* Format an IP46 address. */
630 u8 *
631 format_ip46_address (u8 * s, va_list * args)
632 {
633   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
634   ip46_type_t type = va_arg (*args, ip46_type_t);
635   int is_ip4 = 1;
636
637   switch (type)
638     {
639     case IP46_TYPE_ANY:
640       is_ip4 = ip46_address_is_ip4 (ip46);
641       break;
642     case IP46_TYPE_IP4:
643       is_ip4 = 1;
644       break;
645     case IP46_TYPE_IP6:
646       is_ip4 = 0;
647       break;
648     }
649
650   return is_ip4 ?
651     format (s, "%U", format_ip4_address, &ip46->ip4) :
652     format (s, "%U", format_ip6_address, &ip46->ip6);
653 }
654
655 u8 *
656 format_ethernet_address (u8 * s, va_list * args)
657 {
658   u8 *a = va_arg (*args, u8 *);
659
660   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
661                  a[0], a[1], a[2], a[3], a[4], a[5]);
662 }
663 #endif
664
665 static void
666 increment_v4_address (ip4_address_t * a)
667 {
668   u32 v;
669
670   v = ntohl (a->as_u32) + 1;
671   a->as_u32 = ntohl (v);
672 }
673
674 static void
675 increment_v6_address (ip6_address_t * a)
676 {
677   u64 v0, v1;
678
679   v0 = clib_net_to_host_u64 (a->as_u64[0]);
680   v1 = clib_net_to_host_u64 (a->as_u64[1]);
681
682   v1 += 1;
683   if (v1 == 0)
684     v0 += 1;
685   a->as_u64[0] = clib_net_to_host_u64 (v0);
686   a->as_u64[1] = clib_net_to_host_u64 (v1);
687 }
688
689 static void
690 increment_mac_address (u64 * mac)
691 {
692   u64 tmp = *mac;
693
694   tmp = clib_net_to_host_u64 (tmp);
695   tmp += 1 << 16;               /* skip unused (least significant) octets */
696   tmp = clib_host_to_net_u64 (tmp);
697   *mac = tmp;
698 }
699
700 static void vl_api_create_loopback_reply_t_handler
701   (vl_api_create_loopback_reply_t * mp)
702 {
703   vat_main_t *vam = &vat_main;
704   i32 retval = ntohl (mp->retval);
705
706   vam->retval = retval;
707   vam->regenerate_interface_table = 1;
708   vam->sw_if_index = ntohl (mp->sw_if_index);
709   vam->result_ready = 1;
710 }
711
712 static void vl_api_create_loopback_reply_t_handler_json
713   (vl_api_create_loopback_reply_t * mp)
714 {
715   vat_main_t *vam = &vat_main;
716   vat_json_node_t node;
717
718   vat_json_init_object (&node);
719   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
720   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
721
722   vat_json_print (vam->ofp, &node);
723   vat_json_free (&node);
724   vam->retval = ntohl (mp->retval);
725   vam->result_ready = 1;
726 }
727
728 static void vl_api_af_packet_create_reply_t_handler
729   (vl_api_af_packet_create_reply_t * mp)
730 {
731   vat_main_t *vam = &vat_main;
732   i32 retval = ntohl (mp->retval);
733
734   vam->retval = retval;
735   vam->regenerate_interface_table = 1;
736   vam->sw_if_index = ntohl (mp->sw_if_index);
737   vam->result_ready = 1;
738 }
739
740 static void vl_api_af_packet_create_reply_t_handler_json
741   (vl_api_af_packet_create_reply_t * mp)
742 {
743   vat_main_t *vam = &vat_main;
744   vat_json_node_t node;
745
746   vat_json_init_object (&node);
747   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
748   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
749
750   vat_json_print (vam->ofp, &node);
751   vat_json_free (&node);
752
753   vam->retval = ntohl (mp->retval);
754   vam->result_ready = 1;
755 }
756
757 static void vl_api_create_vlan_subif_reply_t_handler
758   (vl_api_create_vlan_subif_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   i32 retval = ntohl (mp->retval);
762
763   vam->retval = retval;
764   vam->regenerate_interface_table = 1;
765   vam->sw_if_index = ntohl (mp->sw_if_index);
766   vam->result_ready = 1;
767 }
768
769 static void vl_api_create_vlan_subif_reply_t_handler_json
770   (vl_api_create_vlan_subif_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   vat_json_node_t node;
774
775   vat_json_init_object (&node);
776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
777   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
778
779   vat_json_print (vam->ofp, &node);
780   vat_json_free (&node);
781
782   vam->retval = ntohl (mp->retval);
783   vam->result_ready = 1;
784 }
785
786 static void vl_api_create_subif_reply_t_handler
787   (vl_api_create_subif_reply_t * mp)
788 {
789   vat_main_t *vam = &vat_main;
790   i32 retval = ntohl (mp->retval);
791
792   vam->retval = retval;
793   vam->regenerate_interface_table = 1;
794   vam->sw_if_index = ntohl (mp->sw_if_index);
795   vam->result_ready = 1;
796 }
797
798 static void vl_api_create_subif_reply_t_handler_json
799   (vl_api_create_subif_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_interface_name_renumber_reply_t_handler
816   (vl_api_interface_name_renumber_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->result_ready = 1;
824 }
825
826 static void vl_api_interface_name_renumber_reply_t_handler_json
827   (vl_api_interface_name_renumber_reply_t * mp)
828 {
829   vat_main_t *vam = &vat_main;
830   vat_json_node_t node;
831
832   vat_json_init_object (&node);
833   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 /*
843  * Special-case: build the interface table, maintain
844  * the next loopback sw_if_index vbl.
845  */
846 static void vl_api_sw_interface_details_t_handler
847   (vl_api_sw_interface_details_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   u8 *s = format (0, "%s%c", mp->interface_name, 0);
851
852   hash_set_mem (vam->sw_if_index_by_interface_name, s,
853                 ntohl (mp->sw_if_index));
854
855   /* In sub interface case, fill the sub interface table entry */
856   if (mp->sw_if_index != mp->sup_sw_if_index)
857     {
858       sw_interface_subif_t *sub = NULL;
859
860       vec_add2 (vam->sw_if_subif_table, sub, 1);
861
862       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
863       strncpy ((char *) sub->interface_name, (char *) s,
864                vec_len (sub->interface_name));
865       sub->sw_if_index = ntohl (mp->sw_if_index);
866       sub->sub_id = ntohl (mp->sub_id);
867
868       sub->sub_dot1ad = mp->sub_dot1ad;
869       sub->sub_number_of_tags = mp->sub_number_of_tags;
870       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
871       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
872       sub->sub_exact_match = mp->sub_exact_match;
873       sub->sub_default = mp->sub_default;
874       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
875       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
876
877       /* vlan tag rewrite */
878       sub->vtr_op = ntohl (mp->vtr_op);
879       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
880       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
881       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
882     }
883 }
884
885 static void vl_api_sw_interface_details_t_handler_json
886   (vl_api_sw_interface_details_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   vat_json_node_t *node = NULL;
890
891   if (VAT_JSON_ARRAY != vam->json_tree.type)
892     {
893       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
894       vat_json_init_array (&vam->json_tree);
895     }
896   node = vat_json_array_add (&vam->json_tree);
897
898   vat_json_init_object (node);
899   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
900   vat_json_object_add_uint (node, "sup_sw_if_index",
901                             ntohl (mp->sup_sw_if_index));
902   vat_json_object_add_uint (node, "l2_address_length",
903                             ntohl (mp->l2_address_length));
904   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
905                              sizeof (mp->l2_address));
906   vat_json_object_add_string_copy (node, "interface_name",
907                                    mp->interface_name);
908   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
909   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
910   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
911   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
912   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
913   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
914   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
915   vat_json_object_add_uint (node, "sub_number_of_tags",
916                             mp->sub_number_of_tags);
917   vat_json_object_add_uint (node, "sub_outer_vlan_id",
918                             ntohs (mp->sub_outer_vlan_id));
919   vat_json_object_add_uint (node, "sub_inner_vlan_id",
920                             ntohs (mp->sub_inner_vlan_id));
921   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
922   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
923   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
924                             mp->sub_outer_vlan_id_any);
925   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
926                             mp->sub_inner_vlan_id_any);
927   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
928   vat_json_object_add_uint (node, "vtr_push_dot1q",
929                             ntohl (mp->vtr_push_dot1q));
930   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
931   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
932   if (mp->sub_dot1ah)
933     {
934       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
935                                        format (0, "%U",
936                                                format_ethernet_address,
937                                                &mp->b_dmac));
938       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
939                                        format (0, "%U",
940                                                format_ethernet_address,
941                                                &mp->b_smac));
942       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
943       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
944     }
945 }
946
947 static void vl_api_sw_interface_set_flags_t_handler
948   (vl_api_sw_interface_set_flags_t * mp)
949 {
950   vat_main_t *vam = &vat_main;
951   if (vam->interface_event_display)
952     errmsg ("interface flags: sw_if_index %d %s %s",
953             ntohl (mp->sw_if_index),
954             mp->admin_up_down ? "admin-up" : "admin-down",
955             mp->link_up_down ? "link-up" : "link-down");
956 }
957
958 static void vl_api_sw_interface_set_flags_t_handler_json
959   (vl_api_sw_interface_set_flags_t * mp)
960 {
961   /* JSON output not supported */
962 }
963
964 static void
965 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
966 {
967   vat_main_t *vam = &vat_main;
968   i32 retval = ntohl (mp->retval);
969
970   vam->retval = retval;
971   vam->shmem_result = (u8 *) mp->reply_in_shmem;
972   vam->result_ready = 1;
973 }
974
975 static void
976 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   vat_json_node_t node;
980   api_main_t *am = &api_main;
981   void *oldheap;
982   u8 *reply;
983
984   vat_json_init_object (&node);
985   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
986   vat_json_object_add_uint (&node, "reply_in_shmem",
987                             ntohl (mp->reply_in_shmem));
988   /* Toss the shared-memory original... */
989   pthread_mutex_lock (&am->vlib_rp->mutex);
990   oldheap = svm_push_data_heap (am->vlib_rp);
991
992   reply = (u8 *) (mp->reply_in_shmem);
993   vec_free (reply);
994
995   svm_pop_heap (oldheap);
996   pthread_mutex_unlock (&am->vlib_rp->mutex);
997
998   vat_json_print (vam->ofp, &node);
999   vat_json_free (&node);
1000
1001   vam->retval = ntohl (mp->retval);
1002   vam->result_ready = 1;
1003 }
1004
1005 static void
1006 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   i32 retval = ntohl (mp->retval);
1010
1011   vam->retval = retval;
1012   vam->cmd_reply = mp->reply;
1013   vam->result_ready = 1;
1014 }
1015
1016 static void
1017 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1018 {
1019   vat_main_t *vam = &vat_main;
1020   vat_json_node_t node;
1021
1022   vat_json_init_object (&node);
1023   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1024   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1025
1026   vat_json_print (vam->ofp, &node);
1027   vat_json_free (&node);
1028
1029   vam->retval = ntohl (mp->retval);
1030   vam->result_ready = 1;
1031 }
1032
1033 static void vl_api_classify_add_del_table_reply_t_handler
1034   (vl_api_classify_add_del_table_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   i32 retval = ntohl (mp->retval);
1038   if (vam->async_mode)
1039     {
1040       vam->async_errors += (retval < 0);
1041     }
1042   else
1043     {
1044       vam->retval = retval;
1045       if (retval == 0 &&
1046           ((mp->new_table_index != 0xFFFFFFFF) ||
1047            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1048            (mp->match_n_vectors != 0xFFFFFFFF)))
1049         /*
1050          * Note: this is just barely thread-safe, depends on
1051          * the main thread spinning waiting for an answer...
1052          */
1053         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1054                 ntohl (mp->new_table_index),
1055                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1056       vam->result_ready = 1;
1057     }
1058 }
1059
1060 static void vl_api_classify_add_del_table_reply_t_handler_json
1061   (vl_api_classify_add_del_table_reply_t * mp)
1062 {
1063   vat_main_t *vam = &vat_main;
1064   vat_json_node_t node;
1065
1066   vat_json_init_object (&node);
1067   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1068   vat_json_object_add_uint (&node, "new_table_index",
1069                             ntohl (mp->new_table_index));
1070   vat_json_object_add_uint (&node, "skip_n_vectors",
1071                             ntohl (mp->skip_n_vectors));
1072   vat_json_object_add_uint (&node, "match_n_vectors",
1073                             ntohl (mp->match_n_vectors));
1074
1075   vat_json_print (vam->ofp, &node);
1076   vat_json_free (&node);
1077
1078   vam->retval = ntohl (mp->retval);
1079   vam->result_ready = 1;
1080 }
1081
1082 static void vl_api_get_node_index_reply_t_handler
1083   (vl_api_get_node_index_reply_t * mp)
1084 {
1085   vat_main_t *vam = &vat_main;
1086   i32 retval = ntohl (mp->retval);
1087   if (vam->async_mode)
1088     {
1089       vam->async_errors += (retval < 0);
1090     }
1091   else
1092     {
1093       vam->retval = retval;
1094       if (retval == 0)
1095         errmsg ("node index %d", ntohl (mp->node_index));
1096       vam->result_ready = 1;
1097     }
1098 }
1099
1100 static void vl_api_get_node_index_reply_t_handler_json
1101   (vl_api_get_node_index_reply_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   vat_json_node_t node;
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1109
1110   vat_json_print (vam->ofp, &node);
1111   vat_json_free (&node);
1112
1113   vam->retval = ntohl (mp->retval);
1114   vam->result_ready = 1;
1115 }
1116
1117 static void vl_api_get_next_index_reply_t_handler
1118   (vl_api_get_next_index_reply_t * mp)
1119 {
1120   vat_main_t *vam = &vat_main;
1121   i32 retval = ntohl (mp->retval);
1122   if (vam->async_mode)
1123     {
1124       vam->async_errors += (retval < 0);
1125     }
1126   else
1127     {
1128       vam->retval = retval;
1129       if (retval == 0)
1130         errmsg ("next node index %d", ntohl (mp->next_index));
1131       vam->result_ready = 1;
1132     }
1133 }
1134
1135 static void vl_api_get_next_index_reply_t_handler_json
1136   (vl_api_get_next_index_reply_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   vat_json_node_t node;
1140
1141   vat_json_init_object (&node);
1142   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1143   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
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_add_node_next_reply_t_handler
1153   (vl_api_add_node_next_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 ("next index %d", ntohl (mp->next_index));
1166       vam->result_ready = 1;
1167     }
1168 }
1169
1170 static void vl_api_add_node_next_reply_t_handler_json
1171   (vl_api_add_node_next_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, "next_index", ntohl (mp->next_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_show_version_reply_t_handler
1188   (vl_api_show_version_reply_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   i32 retval = ntohl (mp->retval);
1192
1193   if (retval >= 0)
1194     {
1195       errmsg ("        program: %s", mp->program);
1196       errmsg ("        version: %s", mp->version);
1197       errmsg ("     build date: %s", mp->build_date);
1198       errmsg ("build directory: %s", mp->build_directory);
1199     }
1200   vam->retval = retval;
1201   vam->result_ready = 1;
1202 }
1203
1204 static void vl_api_show_version_reply_t_handler_json
1205   (vl_api_show_version_reply_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t node;
1209
1210   vat_json_init_object (&node);
1211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1212   vat_json_object_add_string_copy (&node, "program", mp->program);
1213   vat_json_object_add_string_copy (&node, "version", mp->version);
1214   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1215   vat_json_object_add_string_copy (&node, "build_directory",
1216                                    mp->build_directory);
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void
1226 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1227 {
1228   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1229           mp->mac_ip ? "mac/ip binding" : "address resolution",
1230           format_ip4_address, &mp->address,
1231           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1232 }
1233
1234 static void
1235 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1236 {
1237   /* JSON output not supported */
1238 }
1239
1240 static void
1241 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1242 {
1243   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1244           mp->mac_ip ? "mac/ip binding" : "address resolution",
1245           format_ip6_address, mp->address,
1246           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1247 }
1248
1249 static void
1250 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1251 {
1252   /* JSON output not supported */
1253 }
1254
1255 /*
1256  * Special-case: build the bridge domain table, maintain
1257  * the next bd id vbl.
1258  */
1259 static void vl_api_bridge_domain_details_t_handler
1260   (vl_api_bridge_domain_details_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1264
1265   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1266          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1267
1268   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1269          ntohl (mp->bd_id), mp->learn, mp->forward,
1270          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1271
1272   if (n_sw_ifs)
1273     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1274 }
1275
1276 static void vl_api_bridge_domain_details_t_handler_json
1277   (vl_api_bridge_domain_details_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t *node, *array = NULL;
1281
1282   if (VAT_JSON_ARRAY != vam->json_tree.type)
1283     {
1284       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1285       vat_json_init_array (&vam->json_tree);
1286     }
1287   node = vat_json_array_add (&vam->json_tree);
1288
1289   vat_json_init_object (node);
1290   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1291   vat_json_object_add_uint (node, "flood", mp->flood);
1292   vat_json_object_add_uint (node, "forward", mp->forward);
1293   vat_json_object_add_uint (node, "learn", mp->learn);
1294   vat_json_object_add_uint (node, "bvi_sw_if_index",
1295                             ntohl (mp->bvi_sw_if_index));
1296   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1297   array = vat_json_object_add (node, "sw_if");
1298   vat_json_init_array (array);
1299 }
1300
1301 /*
1302  * Special-case: build the bridge domain sw if table.
1303  */
1304 static void vl_api_bridge_domain_sw_if_details_t_handler
1305   (vl_api_bridge_domain_sw_if_details_t * mp)
1306 {
1307   vat_main_t *vam = &vat_main;
1308   hash_pair_t *p;
1309   u8 *sw_if_name = 0;
1310   u32 sw_if_index;
1311
1312   sw_if_index = ntohl (mp->sw_if_index);
1313   /* *INDENT-OFF* */
1314   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1315   ({
1316     if ((u32) p->value[0] == sw_if_index)
1317       {
1318         sw_if_name = (u8 *)(p->key);
1319         break;
1320       }
1321   }));
1322   /* *INDENT-ON* */
1323
1324   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1325          mp->shg, sw_if_name ? (char *) sw_if_name :
1326          "sw_if_index not found!");
1327 }
1328
1329 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1330   (vl_api_bridge_domain_sw_if_details_t * mp)
1331 {
1332   vat_main_t *vam = &vat_main;
1333   vat_json_node_t *node = NULL;
1334   uword last_index = 0;
1335
1336   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1337   ASSERT (vec_len (vam->json_tree.array) >= 1);
1338   last_index = vec_len (vam->json_tree.array) - 1;
1339   node = &vam->json_tree.array[last_index];
1340   node = vat_json_object_get_element (node, "sw_if");
1341   ASSERT (NULL != node);
1342   node = vat_json_array_add (node);
1343
1344   vat_json_init_object (node);
1345   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1346   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1347   vat_json_object_add_uint (node, "shg", mp->shg);
1348 }
1349
1350 static void vl_api_control_ping_reply_t_handler
1351   (vl_api_control_ping_reply_t * mp)
1352 {
1353   vat_main_t *vam = &vat_main;
1354   i32 retval = ntohl (mp->retval);
1355   if (vam->async_mode)
1356     {
1357       vam->async_errors += (retval < 0);
1358     }
1359   else
1360     {
1361       vam->retval = retval;
1362       vam->result_ready = 1;
1363     }
1364 }
1365
1366 static void vl_api_control_ping_reply_t_handler_json
1367   (vl_api_control_ping_reply_t * mp)
1368 {
1369   vat_main_t *vam = &vat_main;
1370   i32 retval = ntohl (mp->retval);
1371
1372   if (VAT_JSON_NONE != vam->json_tree.type)
1373     {
1374       vat_json_print (vam->ofp, &vam->json_tree);
1375       vat_json_free (&vam->json_tree);
1376       vam->json_tree.type = VAT_JSON_NONE;
1377     }
1378   else
1379     {
1380       /* just print [] */
1381       vat_json_init_array (&vam->json_tree);
1382       vat_json_print (vam->ofp, &vam->json_tree);
1383       vam->json_tree.type = VAT_JSON_NONE;
1384     }
1385
1386   vam->retval = retval;
1387   vam->result_ready = 1;
1388 }
1389
1390 static void
1391 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1392 {
1393   vat_main_t *vam = &vat_main;
1394   i32 retval = ntohl (mp->retval);
1395   if (vam->async_mode)
1396     {
1397       vam->async_errors += (retval < 0);
1398     }
1399   else
1400     {
1401       vam->retval = retval;
1402       vam->result_ready = 1;
1403     }
1404 }
1405
1406 static void vl_api_l2_flags_reply_t_handler_json
1407   (vl_api_l2_flags_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1415                             ntohl (mp->resulting_feature_bitmap));
1416
1417   vat_json_print (vam->ofp, &node);
1418   vat_json_free (&node);
1419
1420   vam->retval = ntohl (mp->retval);
1421   vam->result_ready = 1;
1422 }
1423
1424 static void vl_api_bridge_flags_reply_t_handler
1425   (vl_api_bridge_flags_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   i32 retval = ntohl (mp->retval);
1429   if (vam->async_mode)
1430     {
1431       vam->async_errors += (retval < 0);
1432     }
1433   else
1434     {
1435       vam->retval = retval;
1436       vam->result_ready = 1;
1437     }
1438 }
1439
1440 static void vl_api_bridge_flags_reply_t_handler_json
1441   (vl_api_bridge_flags_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   vat_json_node_t node;
1445
1446   vat_json_init_object (&node);
1447   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1448   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1449                             ntohl (mp->resulting_feature_bitmap));
1450
1451   vat_json_print (vam->ofp, &node);
1452   vat_json_free (&node);
1453
1454   vam->retval = ntohl (mp->retval);
1455   vam->result_ready = 1;
1456 }
1457
1458 static void vl_api_tap_connect_reply_t_handler
1459   (vl_api_tap_connect_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   i32 retval = ntohl (mp->retval);
1463   if (vam->async_mode)
1464     {
1465       vam->async_errors += (retval < 0);
1466     }
1467   else
1468     {
1469       vam->retval = retval;
1470       vam->sw_if_index = ntohl (mp->sw_if_index);
1471       vam->result_ready = 1;
1472     }
1473
1474 }
1475
1476 static void vl_api_tap_connect_reply_t_handler_json
1477   (vl_api_tap_connect_reply_t * mp)
1478 {
1479   vat_main_t *vam = &vat_main;
1480   vat_json_node_t node;
1481
1482   vat_json_init_object (&node);
1483   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1484   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491
1492 }
1493
1494 static void
1495 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->sw_if_index = ntohl (mp->sw_if_index);
1507       vam->result_ready = 1;
1508     }
1509 }
1510
1511 static void vl_api_tap_modify_reply_t_handler_json
1512   (vl_api_tap_modify_reply_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t node;
1516
1517   vat_json_init_object (&node);
1518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1520
1521   vat_json_print (vam->ofp, &node);
1522   vat_json_free (&node);
1523
1524   vam->retval = ntohl (mp->retval);
1525   vam->result_ready = 1;
1526 }
1527
1528 static void
1529 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   i32 retval = ntohl (mp->retval);
1533   if (vam->async_mode)
1534     {
1535       vam->async_errors += (retval < 0);
1536     }
1537   else
1538     {
1539       vam->retval = retval;
1540       vam->result_ready = 1;
1541     }
1542 }
1543
1544 static void vl_api_tap_delete_reply_t_handler_json
1545   (vl_api_tap_delete_reply_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t node;
1549
1550   vat_json_init_object (&node);
1551   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1552
1553   vat_json_print (vam->ofp, &node);
1554   vat_json_free (&node);
1555
1556   vam->retval = ntohl (mp->retval);
1557   vam->result_ready = 1;
1558 }
1559
1560 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1561   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1562 {
1563   vat_main_t *vam = &vat_main;
1564   i32 retval = ntohl (mp->retval);
1565   if (vam->async_mode)
1566     {
1567       vam->async_errors += (retval < 0);
1568     }
1569   else
1570     {
1571       vam->retval = retval;
1572       vam->result_ready = 1;
1573     }
1574 }
1575
1576 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1577   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   vat_json_node_t node;
1581
1582   vat_json_init_object (&node);
1583   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1584   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1585                             ntohl (mp->sw_if_index));
1586
1587   vat_json_print (vam->ofp, &node);
1588   vat_json_free (&node);
1589
1590   vam->retval = ntohl (mp->retval);
1591   vam->result_ready = 1;
1592 }
1593
1594 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1595   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1596 {
1597   vat_main_t *vam = &vat_main;
1598   i32 retval = ntohl (mp->retval);
1599   if (vam->async_mode)
1600     {
1601       vam->async_errors += (retval < 0);
1602     }
1603   else
1604     {
1605       vam->retval = retval;
1606       vam->sw_if_index = ntohl (mp->sw_if_index);
1607       vam->result_ready = 1;
1608     }
1609 }
1610
1611 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1612   (vl_api_l2tpv3_create_tunnel_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 vl_api_one_add_del_locator_set_reply_t_handler
1630   (vl_api_one_add_del_locator_set_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->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1646   (vl_api_one_add_del_locator_set_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1654
1655   vat_json_print (vam->ofp, &node);
1656   vat_json_free (&node);
1657
1658   vam->retval = ntohl (mp->retval);
1659   vam->result_ready = 1;
1660 }
1661
1662 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1663   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1664 {
1665   vat_main_t *vam = &vat_main;
1666   i32 retval = ntohl (mp->retval);
1667   if (vam->async_mode)
1668     {
1669       vam->async_errors += (retval < 0);
1670     }
1671   else
1672     {
1673       vam->retval = retval;
1674       vam->sw_if_index = ntohl (mp->sw_if_index);
1675       vam->result_ready = 1;
1676     }
1677 }
1678
1679 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1680   (vl_api_vxlan_add_del_tunnel_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1688
1689   vat_json_print (vam->ofp, &node);
1690   vat_json_free (&node);
1691
1692   vam->retval = ntohl (mp->retval);
1693   vam->result_ready = 1;
1694 }
1695
1696 static void vl_api_gre_add_del_tunnel_reply_t_handler
1697   (vl_api_gre_add_del_tunnel_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   i32 retval = ntohl (mp->retval);
1701   if (vam->async_mode)
1702     {
1703       vam->async_errors += (retval < 0);
1704     }
1705   else
1706     {
1707       vam->retval = retval;
1708       vam->sw_if_index = ntohl (mp->sw_if_index);
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1714   (vl_api_gre_add_del_tunnel_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1722
1723   vat_json_print (vam->ofp, &node);
1724   vat_json_free (&node);
1725
1726   vam->retval = ntohl (mp->retval);
1727   vam->result_ready = 1;
1728 }
1729
1730 static void vl_api_create_vhost_user_if_reply_t_handler
1731   (vl_api_create_vhost_user_if_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   i32 retval = ntohl (mp->retval);
1735   if (vam->async_mode)
1736     {
1737       vam->async_errors += (retval < 0);
1738     }
1739   else
1740     {
1741       vam->retval = retval;
1742       vam->sw_if_index = ntohl (mp->sw_if_index);
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_create_vhost_user_if_reply_t_handler_json
1748   (vl_api_create_vhost_user_if_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_ip_address_details_t_handler
1765   (vl_api_ip_address_details_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   static ip_address_details_t empty_ip_address_details = { {0} };
1769   ip_address_details_t *address = NULL;
1770   ip_details_t *current_ip_details = NULL;
1771   ip_details_t *details = NULL;
1772
1773   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1774
1775   if (!details || vam->current_sw_if_index >= vec_len (details)
1776       || !details[vam->current_sw_if_index].present)
1777     {
1778       errmsg ("ip address details arrived but not stored");
1779       errmsg ("ip_dump should be called first");
1780       return;
1781     }
1782
1783   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1784
1785 #define addresses (current_ip_details->addr)
1786
1787   vec_validate_init_empty (addresses, vec_len (addresses),
1788                            empty_ip_address_details);
1789
1790   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1791
1792   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1793   address->prefix_length = mp->prefix_length;
1794 #undef addresses
1795 }
1796
1797 static void vl_api_ip_address_details_t_handler_json
1798   (vl_api_ip_address_details_t * mp)
1799 {
1800   vat_main_t *vam = &vat_main;
1801   vat_json_node_t *node = NULL;
1802   struct in6_addr ip6;
1803   struct in_addr ip4;
1804
1805   if (VAT_JSON_ARRAY != vam->json_tree.type)
1806     {
1807       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1808       vat_json_init_array (&vam->json_tree);
1809     }
1810   node = vat_json_array_add (&vam->json_tree);
1811
1812   vat_json_init_object (node);
1813   if (vam->is_ipv6)
1814     {
1815       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1816       vat_json_object_add_ip6 (node, "ip", ip6);
1817     }
1818   else
1819     {
1820       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1821       vat_json_object_add_ip4 (node, "ip", ip4);
1822     }
1823   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1824 }
1825
1826 static void
1827 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   static ip_details_t empty_ip_details = { 0 };
1831   ip_details_t *ip = NULL;
1832   u32 sw_if_index = ~0;
1833
1834   sw_if_index = ntohl (mp->sw_if_index);
1835
1836   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1837                            sw_if_index, empty_ip_details);
1838
1839   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1840                          sw_if_index);
1841
1842   ip->present = 1;
1843 }
1844
1845 static void
1846 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1847 {
1848   vat_main_t *vam = &vat_main;
1849
1850   if (VAT_JSON_ARRAY != vam->json_tree.type)
1851     {
1852       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1853       vat_json_init_array (&vam->json_tree);
1854     }
1855   vat_json_array_add_uint (&vam->json_tree,
1856                            clib_net_to_host_u32 (mp->sw_if_index));
1857 }
1858
1859 static void vl_api_map_domain_details_t_handler_json
1860   (vl_api_map_domain_details_t * mp)
1861 {
1862   vat_json_node_t *node = NULL;
1863   vat_main_t *vam = &vat_main;
1864   struct in6_addr ip6;
1865   struct in_addr ip4;
1866
1867   if (VAT_JSON_ARRAY != vam->json_tree.type)
1868     {
1869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1870       vat_json_init_array (&vam->json_tree);
1871     }
1872
1873   node = vat_json_array_add (&vam->json_tree);
1874   vat_json_init_object (node);
1875
1876   vat_json_object_add_uint (node, "domain_index",
1877                             clib_net_to_host_u32 (mp->domain_index));
1878   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1879   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1880   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1881   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1882   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1883   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1884   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1885   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1886   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1887   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1888   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1889   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1890   vat_json_object_add_uint (node, "flags", mp->flags);
1891   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1892   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1893 }
1894
1895 static void vl_api_map_domain_details_t_handler
1896   (vl_api_map_domain_details_t * mp)
1897 {
1898   vat_main_t *vam = &vat_main;
1899
1900   if (mp->is_translation)
1901     {
1902       print (vam->ofp,
1903              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1904              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1905              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1906              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1907              clib_net_to_host_u32 (mp->domain_index));
1908     }
1909   else
1910     {
1911       print (vam->ofp,
1912              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1913              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1914              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1915              format_ip6_address, mp->ip6_src,
1916              clib_net_to_host_u32 (mp->domain_index));
1917     }
1918   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1919          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1920          mp->is_translation ? "map-t" : "");
1921 }
1922
1923 static void vl_api_map_rule_details_t_handler_json
1924   (vl_api_map_rule_details_t * mp)
1925 {
1926   struct in6_addr ip6;
1927   vat_json_node_t *node = NULL;
1928   vat_main_t *vam = &vat_main;
1929
1930   if (VAT_JSON_ARRAY != vam->json_tree.type)
1931     {
1932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1933       vat_json_init_array (&vam->json_tree);
1934     }
1935
1936   node = vat_json_array_add (&vam->json_tree);
1937   vat_json_init_object (node);
1938
1939   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1940   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1941   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1942 }
1943
1944 static void
1945 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1946 {
1947   vat_main_t *vam = &vat_main;
1948   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1949          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1950 }
1951
1952 static void
1953 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1954 {
1955   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1956           "router_addr %U host_mac %U",
1957           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1958           format_ip4_address, &mp->host_address,
1959           format_ip4_address, &mp->router_address,
1960           format_ethernet_address, mp->host_mac);
1961 }
1962
1963 static void vl_api_dhcp_compl_event_t_handler_json
1964   (vl_api_dhcp_compl_event_t * mp)
1965 {
1966   /* JSON output not supported */
1967 }
1968
1969 static void
1970 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1971                               u32 counter)
1972 {
1973   vat_main_t *vam = &vat_main;
1974   static u64 default_counter = 0;
1975
1976   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1977                            NULL);
1978   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1979                            sw_if_index, default_counter);
1980   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1981 }
1982
1983 static void
1984 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1985                                 interface_counter_t counter)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   static interface_counter_t default_counter = { 0, };
1989
1990   vec_validate_init_empty (vam->combined_interface_counters,
1991                            vnet_counter_type, NULL);
1992   vec_validate_init_empty (vam->combined_interface_counters
1993                            [vnet_counter_type], sw_if_index, default_counter);
1994   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1995 }
1996
1997 static void vl_api_vnet_interface_counters_t_handler
1998   (vl_api_vnet_interface_counters_t * mp)
1999 {
2000   /* not supported */
2001 }
2002
2003 static void vl_api_vnet_interface_counters_t_handler_json
2004   (vl_api_vnet_interface_counters_t * mp)
2005 {
2006   interface_counter_t counter;
2007   vlib_counter_t *v;
2008   u64 *v_packets;
2009   u64 packets;
2010   u32 count;
2011   u32 first_sw_if_index;
2012   int i;
2013
2014   count = ntohl (mp->count);
2015   first_sw_if_index = ntohl (mp->first_sw_if_index);
2016
2017   if (!mp->is_combined)
2018     {
2019       v_packets = (u64 *) & mp->data;
2020       for (i = 0; i < count; i++)
2021         {
2022           packets =
2023             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2024           set_simple_interface_counter (mp->vnet_counter_type,
2025                                         first_sw_if_index + i, packets);
2026           v_packets++;
2027         }
2028     }
2029   else
2030     {
2031       v = (vlib_counter_t *) & mp->data;
2032       for (i = 0; i < count; i++)
2033         {
2034           counter.packets =
2035             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2036           counter.bytes =
2037             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2038           set_combined_interface_counter (mp->vnet_counter_type,
2039                                           first_sw_if_index + i, counter);
2040           v++;
2041         }
2042     }
2043 }
2044
2045 static u32
2046 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2047 {
2048   vat_main_t *vam = &vat_main;
2049   u32 i;
2050
2051   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2052     {
2053       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2054         {
2055           return i;
2056         }
2057     }
2058   return ~0;
2059 }
2060
2061 static u32
2062 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2063 {
2064   vat_main_t *vam = &vat_main;
2065   u32 i;
2066
2067   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2068     {
2069       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2070         {
2071           return i;
2072         }
2073     }
2074   return ~0;
2075 }
2076
2077 static void vl_api_vnet_ip4_fib_counters_t_handler
2078   (vl_api_vnet_ip4_fib_counters_t * mp)
2079 {
2080   /* not supported */
2081 }
2082
2083 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2084   (vl_api_vnet_ip4_fib_counters_t * mp)
2085 {
2086   vat_main_t *vam = &vat_main;
2087   vl_api_ip4_fib_counter_t *v;
2088   ip4_fib_counter_t *counter;
2089   struct in_addr ip4;
2090   u32 vrf_id;
2091   u32 vrf_index;
2092   u32 count;
2093   int i;
2094
2095   vrf_id = ntohl (mp->vrf_id);
2096   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2097   if (~0 == vrf_index)
2098     {
2099       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2100       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2101       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2102       vec_validate (vam->ip4_fib_counters, vrf_index);
2103       vam->ip4_fib_counters[vrf_index] = NULL;
2104     }
2105
2106   vec_free (vam->ip4_fib_counters[vrf_index]);
2107   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2108   count = ntohl (mp->count);
2109   for (i = 0; i < count; i++)
2110     {
2111       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2112       counter = &vam->ip4_fib_counters[vrf_index][i];
2113       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2114       counter->address = ip4;
2115       counter->address_length = v->address_length;
2116       counter->packets = clib_net_to_host_u64 (v->packets);
2117       counter->bytes = clib_net_to_host_u64 (v->bytes);
2118       v++;
2119     }
2120 }
2121
2122 static void vl_api_vnet_ip4_nbr_counters_t_handler
2123   (vl_api_vnet_ip4_nbr_counters_t * mp)
2124 {
2125   /* not supported */
2126 }
2127
2128 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2129   (vl_api_vnet_ip4_nbr_counters_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   vl_api_ip4_nbr_counter_t *v;
2133   ip4_nbr_counter_t *counter;
2134   u32 sw_if_index;
2135   u32 count;
2136   int i;
2137
2138   sw_if_index = ntohl (mp->sw_if_index);
2139   count = ntohl (mp->count);
2140   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2141
2142   if (mp->begin)
2143     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2144
2145   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2146   for (i = 0; i < count; i++)
2147     {
2148       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2149       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2150       counter->address.s_addr = v->address;
2151       counter->packets = clib_net_to_host_u64 (v->packets);
2152       counter->bytes = clib_net_to_host_u64 (v->bytes);
2153       counter->linkt = v->link_type;
2154       v++;
2155     }
2156 }
2157
2158 static void vl_api_vnet_ip6_fib_counters_t_handler
2159   (vl_api_vnet_ip6_fib_counters_t * mp)
2160 {
2161   /* not supported */
2162 }
2163
2164 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2165   (vl_api_vnet_ip6_fib_counters_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   vl_api_ip6_fib_counter_t *v;
2169   ip6_fib_counter_t *counter;
2170   struct in6_addr ip6;
2171   u32 vrf_id;
2172   u32 vrf_index;
2173   u32 count;
2174   int i;
2175
2176   vrf_id = ntohl (mp->vrf_id);
2177   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2178   if (~0 == vrf_index)
2179     {
2180       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2181       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2182       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2183       vec_validate (vam->ip6_fib_counters, vrf_index);
2184       vam->ip6_fib_counters[vrf_index] = NULL;
2185     }
2186
2187   vec_free (vam->ip6_fib_counters[vrf_index]);
2188   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2189   count = ntohl (mp->count);
2190   for (i = 0; i < count; i++)
2191     {
2192       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2193       counter = &vam->ip6_fib_counters[vrf_index][i];
2194       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2195       counter->address = ip6;
2196       counter->address_length = v->address_length;
2197       counter->packets = clib_net_to_host_u64 (v->packets);
2198       counter->bytes = clib_net_to_host_u64 (v->bytes);
2199       v++;
2200     }
2201 }
2202
2203 static void vl_api_vnet_ip6_nbr_counters_t_handler
2204   (vl_api_vnet_ip6_nbr_counters_t * mp)
2205 {
2206   /* not supported */
2207 }
2208
2209 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2210   (vl_api_vnet_ip6_nbr_counters_t * mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   vl_api_ip6_nbr_counter_t *v;
2214   ip6_nbr_counter_t *counter;
2215   struct in6_addr ip6;
2216   u32 sw_if_index;
2217   u32 count;
2218   int i;
2219
2220   sw_if_index = ntohl (mp->sw_if_index);
2221   count = ntohl (mp->count);
2222   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2223
2224   if (mp->begin)
2225     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2226
2227   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2228   for (i = 0; i < count; i++)
2229     {
2230       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2231       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2232       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2233       counter->address = ip6;
2234       counter->packets = clib_net_to_host_u64 (v->packets);
2235       counter->bytes = clib_net_to_host_u64 (v->bytes);
2236       v++;
2237     }
2238 }
2239
2240 static void vl_api_get_first_msg_id_reply_t_handler
2241   (vl_api_get_first_msg_id_reply_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   i32 retval = ntohl (mp->retval);
2245
2246   if (vam->async_mode)
2247     {
2248       vam->async_errors += (retval < 0);
2249     }
2250   else
2251     {
2252       vam->retval = retval;
2253       vam->result_ready = 1;
2254     }
2255   if (retval >= 0)
2256     {
2257       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2258     }
2259 }
2260
2261 static void vl_api_get_first_msg_id_reply_t_handler_json
2262   (vl_api_get_first_msg_id_reply_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t node;
2266
2267   vat_json_init_object (&node);
2268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2269   vat_json_object_add_uint (&node, "first_msg_id",
2270                             (uint) ntohs (mp->first_msg_id));
2271
2272   vat_json_print (vam->ofp, &node);
2273   vat_json_free (&node);
2274
2275   vam->retval = ntohl (mp->retval);
2276   vam->result_ready = 1;
2277 }
2278
2279 static void vl_api_get_node_graph_reply_t_handler
2280   (vl_api_get_node_graph_reply_t * mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   api_main_t *am = &api_main;
2284   i32 retval = ntohl (mp->retval);
2285   u8 *pvt_copy, *reply;
2286   void *oldheap;
2287   vlib_node_t *node;
2288   int i;
2289
2290   if (vam->async_mode)
2291     {
2292       vam->async_errors += (retval < 0);
2293     }
2294   else
2295     {
2296       vam->retval = retval;
2297       vam->result_ready = 1;
2298     }
2299
2300   /* "Should never happen..." */
2301   if (retval != 0)
2302     return;
2303
2304   reply = (u8 *) (mp->reply_in_shmem);
2305   pvt_copy = vec_dup (reply);
2306
2307   /* Toss the shared-memory original... */
2308   pthread_mutex_lock (&am->vlib_rp->mutex);
2309   oldheap = svm_push_data_heap (am->vlib_rp);
2310
2311   vec_free (reply);
2312
2313   svm_pop_heap (oldheap);
2314   pthread_mutex_unlock (&am->vlib_rp->mutex);
2315
2316   if (vam->graph_nodes)
2317     {
2318       hash_free (vam->graph_node_index_by_name);
2319
2320       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2321         {
2322           node = vam->graph_nodes[i];
2323           vec_free (node->name);
2324           vec_free (node->next_nodes);
2325           vec_free (node);
2326         }
2327       vec_free (vam->graph_nodes);
2328     }
2329
2330   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2331   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2332   vec_free (pvt_copy);
2333
2334   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2335     {
2336       node = vam->graph_nodes[i];
2337       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2338     }
2339 }
2340
2341 static void vl_api_get_node_graph_reply_t_handler_json
2342   (vl_api_get_node_graph_reply_t * mp)
2343 {
2344   vat_main_t *vam = &vat_main;
2345   api_main_t *am = &api_main;
2346   void *oldheap;
2347   vat_json_node_t node;
2348   u8 *reply;
2349
2350   /* $$$$ make this real? */
2351   vat_json_init_object (&node);
2352   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2353   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2354
2355   reply = (u8 *) (mp->reply_in_shmem);
2356
2357   /* Toss the shared-memory original... */
2358   pthread_mutex_lock (&am->vlib_rp->mutex);
2359   oldheap = svm_push_data_heap (am->vlib_rp);
2360
2361   vec_free (reply);
2362
2363   svm_pop_heap (oldheap);
2364   pthread_mutex_unlock (&am->vlib_rp->mutex);
2365
2366   vat_json_print (vam->ofp, &node);
2367   vat_json_free (&node);
2368
2369   vam->retval = ntohl (mp->retval);
2370   vam->result_ready = 1;
2371 }
2372
2373 static void
2374 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2375 {
2376   vat_main_t *vam = &vat_main;
2377   u8 *s = 0;
2378
2379   if (mp->local)
2380     {
2381       s = format (s, "%=16d%=16d%=16d",
2382                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2383     }
2384   else
2385     {
2386       s = format (s, "%=16U%=16d%=16d",
2387                   mp->is_ipv6 ? format_ip6_address :
2388                   format_ip4_address,
2389                   mp->ip_address, mp->priority, mp->weight);
2390     }
2391
2392   print (vam->ofp, "%v", s);
2393   vec_free (s);
2394 }
2395
2396 static void
2397 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2398 {
2399   vat_main_t *vam = &vat_main;
2400   vat_json_node_t *node = NULL;
2401   struct in6_addr ip6;
2402   struct in_addr ip4;
2403
2404   if (VAT_JSON_ARRAY != vam->json_tree.type)
2405     {
2406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2407       vat_json_init_array (&vam->json_tree);
2408     }
2409   node = vat_json_array_add (&vam->json_tree);
2410   vat_json_init_object (node);
2411
2412   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2413   vat_json_object_add_uint (node, "priority", mp->priority);
2414   vat_json_object_add_uint (node, "weight", mp->weight);
2415
2416   if (mp->local)
2417     vat_json_object_add_uint (node, "sw_if_index",
2418                               clib_net_to_host_u32 (mp->sw_if_index));
2419   else
2420     {
2421       if (mp->is_ipv6)
2422         {
2423           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2424           vat_json_object_add_ip6 (node, "address", ip6);
2425         }
2426       else
2427         {
2428           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2429           vat_json_object_add_ip4 (node, "address", ip4);
2430         }
2431     }
2432 }
2433
2434 static void
2435 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2436                                           mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   u8 *ls_name = 0;
2440
2441   ls_name = format (0, "%s", mp->ls_name);
2442
2443   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2444          ls_name);
2445   vec_free (ls_name);
2446 }
2447
2448 static void
2449   vl_api_one_locator_set_details_t_handler_json
2450   (vl_api_one_locator_set_details_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   vat_json_node_t *node = 0;
2454   u8 *ls_name = 0;
2455
2456   ls_name = format (0, "%s", mp->ls_name);
2457   vec_add1 (ls_name, 0);
2458
2459   if (VAT_JSON_ARRAY != vam->json_tree.type)
2460     {
2461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2462       vat_json_init_array (&vam->json_tree);
2463     }
2464   node = vat_json_array_add (&vam->json_tree);
2465
2466   vat_json_init_object (node);
2467   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2468   vat_json_object_add_uint (node, "ls_index",
2469                             clib_net_to_host_u32 (mp->ls_index));
2470   vec_free (ls_name);
2471 }
2472
2473 static u8 *
2474 format_lisp_flat_eid (u8 * s, va_list * args)
2475 {
2476   u32 type = va_arg (*args, u32);
2477   u8 *eid = va_arg (*args, u8 *);
2478   u32 eid_len = va_arg (*args, u32);
2479
2480   switch (type)
2481     {
2482     case 0:
2483       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2484     case 1:
2485       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2486     case 2:
2487       return format (s, "%U", format_ethernet_address, eid);
2488     }
2489   return 0;
2490 }
2491
2492 static u8 *
2493 format_lisp_eid_vat (u8 * s, va_list * args)
2494 {
2495   u32 type = va_arg (*args, u32);
2496   u8 *eid = va_arg (*args, u8 *);
2497   u32 eid_len = va_arg (*args, u32);
2498   u8 *seid = va_arg (*args, u8 *);
2499   u32 seid_len = va_arg (*args, u32);
2500   u32 is_src_dst = va_arg (*args, u32);
2501
2502   if (is_src_dst)
2503     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2504
2505   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2506
2507   return s;
2508 }
2509
2510 static void
2511 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   u8 *s = 0, *eid = 0;
2515
2516   if (~0 == mp->locator_set_index)
2517     s = format (0, "action: %d", mp->action);
2518   else
2519     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2520
2521   eid = format (0, "%U", format_lisp_eid_vat,
2522                 mp->eid_type,
2523                 mp->eid,
2524                 mp->eid_prefix_len,
2525                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2526   vec_add1 (eid, 0);
2527
2528   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2529          clib_net_to_host_u32 (mp->vni),
2530          eid,
2531          mp->is_local ? "local" : "remote",
2532          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2533          clib_net_to_host_u16 (mp->key_id), mp->key);
2534
2535   vec_free (s);
2536   vec_free (eid);
2537 }
2538
2539 static void
2540 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2541                                              * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   vat_json_node_t *node = 0;
2545   u8 *eid = 0;
2546
2547   if (VAT_JSON_ARRAY != vam->json_tree.type)
2548     {
2549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2550       vat_json_init_array (&vam->json_tree);
2551     }
2552   node = vat_json_array_add (&vam->json_tree);
2553
2554   vat_json_init_object (node);
2555   if (~0 == mp->locator_set_index)
2556     vat_json_object_add_uint (node, "action", mp->action);
2557   else
2558     vat_json_object_add_uint (node, "locator_set_index",
2559                               clib_net_to_host_u32 (mp->locator_set_index));
2560
2561   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2562   eid = format (0, "%U", format_lisp_eid_vat,
2563                 mp->eid_type,
2564                 mp->eid,
2565                 mp->eid_prefix_len,
2566                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2567   vec_add1 (eid, 0);
2568   vat_json_object_add_string_copy (node, "eid", eid);
2569   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2570   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2571   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2572
2573   if (mp->key_id)
2574     {
2575       vat_json_object_add_uint (node, "key_id",
2576                                 clib_net_to_host_u16 (mp->key_id));
2577       vat_json_object_add_string_copy (node, "key", mp->key);
2578     }
2579   vec_free (eid);
2580 }
2581
2582 static void
2583   vl_api_one_eid_table_map_details_t_handler
2584   (vl_api_one_eid_table_map_details_t * mp)
2585 {
2586   vat_main_t *vam = &vat_main;
2587
2588   u8 *line = format (0, "%=10d%=10d",
2589                      clib_net_to_host_u32 (mp->vni),
2590                      clib_net_to_host_u32 (mp->dp_table));
2591   print (vam->ofp, "%v", line);
2592   vec_free (line);
2593 }
2594
2595 static void
2596   vl_api_one_eid_table_map_details_t_handler_json
2597   (vl_api_one_eid_table_map_details_t * mp)
2598 {
2599   vat_main_t *vam = &vat_main;
2600   vat_json_node_t *node = NULL;
2601
2602   if (VAT_JSON_ARRAY != vam->json_tree.type)
2603     {
2604       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2605       vat_json_init_array (&vam->json_tree);
2606     }
2607   node = vat_json_array_add (&vam->json_tree);
2608   vat_json_init_object (node);
2609   vat_json_object_add_uint (node, "dp_table",
2610                             clib_net_to_host_u32 (mp->dp_table));
2611   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2612 }
2613
2614 static void
2615   vl_api_one_eid_table_vni_details_t_handler
2616   (vl_api_one_eid_table_vni_details_t * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2621   print (vam->ofp, "%v", line);
2622   vec_free (line);
2623 }
2624
2625 static void
2626   vl_api_one_eid_table_vni_details_t_handler_json
2627   (vl_api_one_eid_table_vni_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631
2632   if (VAT_JSON_ARRAY != vam->json_tree.type)
2633     {
2634       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2635       vat_json_init_array (&vam->json_tree);
2636     }
2637   node = vat_json_array_add (&vam->json_tree);
2638   vat_json_init_object (node);
2639   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2640 }
2641
2642 static void
2643   vl_api_show_one_map_register_state_reply_t_handler
2644   (vl_api_show_one_map_register_state_reply_t * mp)
2645 {
2646   vat_main_t *vam = &vat_main;
2647   int retval = clib_net_to_host_u32 (mp->retval);
2648
2649   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2650
2651   vam->retval = retval;
2652   vam->result_ready = 1;
2653 }
2654
2655 static void
2656   vl_api_show_one_map_register_state_reply_t_handler_json
2657   (vl_api_show_one_map_register_state_reply_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t _node, *node = &_node;
2661   int retval = clib_net_to_host_u32 (mp->retval);
2662
2663   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2664
2665   vat_json_init_object (node);
2666   vat_json_object_add_string_copy (node, "state", s);
2667
2668   vat_json_print (vam->ofp, node);
2669   vat_json_free (node);
2670
2671   vam->retval = retval;
2672   vam->result_ready = 1;
2673   vec_free (s);
2674 }
2675
2676 static void
2677   vl_api_show_one_rloc_probe_state_reply_t_handler
2678   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2679 {
2680   vat_main_t *vam = &vat_main;
2681   int retval = clib_net_to_host_u32 (mp->retval);
2682
2683   if (retval)
2684     goto end;
2685
2686   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2687 end:
2688   vam->retval = retval;
2689   vam->result_ready = 1;
2690 }
2691
2692 static void
2693   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2694   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2695 {
2696   vat_main_t *vam = &vat_main;
2697   vat_json_node_t _node, *node = &_node;
2698   int retval = clib_net_to_host_u32 (mp->retval);
2699
2700   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2701   vat_json_init_object (node);
2702   vat_json_object_add_string_copy (node, "state", s);
2703
2704   vat_json_print (vam->ofp, node);
2705   vat_json_free (node);
2706
2707   vam->retval = retval;
2708   vam->result_ready = 1;
2709   vec_free (s);
2710 }
2711
2712 static void
2713 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2714 {
2715   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2716   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2717 }
2718
2719 static void
2720   gpe_fwd_entries_get_reply_t_net_to_host
2721   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2722 {
2723   u32 i;
2724
2725   mp->count = clib_net_to_host_u32 (mp->count);
2726   for (i = 0; i < mp->count; i++)
2727     {
2728       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2729     }
2730 }
2731
2732 static u8 *
2733 format_gpe_encap_mode (u8 * s, va_list * args)
2734 {
2735   u32 mode = va_arg (*args, u32);
2736
2737   switch (mode)
2738     {
2739     case 0:
2740       return format (s, "lisp");
2741     case 1:
2742       return format (s, "vxlan");
2743     }
2744   return 0;
2745 }
2746
2747 static void
2748   vl_api_gpe_get_encap_mode_reply_t_handler
2749   (vl_api_gpe_get_encap_mode_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752
2753   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2754   vam->retval = ntohl (mp->retval);
2755   vam->result_ready = 1;
2756 }
2757
2758 static void
2759   vl_api_gpe_get_encap_mode_reply_t_handler_json
2760   (vl_api_gpe_get_encap_mode_reply_t * mp)
2761 {
2762   vat_main_t *vam = &vat_main;
2763   vat_json_node_t node;
2764
2765   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2766   vec_add1 (encap_mode, 0);
2767
2768   vat_json_init_object (&node);
2769   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2770
2771   vec_free (encap_mode);
2772   vat_json_print (vam->ofp, &node);
2773   vat_json_free (&node);
2774
2775   vam->retval = ntohl (mp->retval);
2776   vam->result_ready = 1;
2777 }
2778
2779 static void
2780   vl_api_gpe_fwd_entry_path_details_t_handler
2781   (vl_api_gpe_fwd_entry_path_details_t * mp)
2782 {
2783   vat_main_t *vam = &vat_main;
2784   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2785
2786   if (mp->lcl_loc.is_ip4)
2787     format_ip_address_fcn = format_ip4_address;
2788   else
2789     format_ip_address_fcn = format_ip6_address;
2790
2791   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2792          format_ip_address_fcn, &mp->lcl_loc,
2793          format_ip_address_fcn, &mp->rmt_loc);
2794 }
2795
2796 static void
2797 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2798 {
2799   struct in6_addr ip6;
2800   struct in_addr ip4;
2801
2802   if (loc->is_ip4)
2803     {
2804       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2805       vat_json_object_add_ip4 (n, "address", ip4);
2806     }
2807   else
2808     {
2809       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2810       vat_json_object_add_ip6 (n, "address", ip6);
2811     }
2812   vat_json_object_add_uint (n, "weight", loc->weight);
2813 }
2814
2815 static void
2816   vl_api_gpe_fwd_entry_path_details_t_handler_json
2817   (vl_api_gpe_fwd_entry_path_details_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   vat_json_node_t *node = NULL;
2821   vat_json_node_t *loc_node;
2822
2823   if (VAT_JSON_ARRAY != vam->json_tree.type)
2824     {
2825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2826       vat_json_init_array (&vam->json_tree);
2827     }
2828   node = vat_json_array_add (&vam->json_tree);
2829   vat_json_init_object (node);
2830
2831   loc_node = vat_json_object_add (node, "local_locator");
2832   vat_json_init_object (loc_node);
2833   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2834
2835   loc_node = vat_json_object_add (node, "remote_locator");
2836   vat_json_init_object (loc_node);
2837   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2838 }
2839
2840 static void
2841   vl_api_gpe_fwd_entries_get_reply_t_handler
2842   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   u32 i;
2846   int retval = clib_net_to_host_u32 (mp->retval);
2847   vl_api_gpe_fwd_entry_t *e;
2848
2849   if (retval)
2850     goto end;
2851
2852   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2853
2854   for (i = 0; i < mp->count; i++)
2855     {
2856       e = &mp->entries[i];
2857       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2858              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2859              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2860     }
2861
2862 end:
2863   vam->retval = retval;
2864   vam->result_ready = 1;
2865 }
2866
2867 static void
2868   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2869   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2870 {
2871   u8 *s = 0;
2872   vat_main_t *vam = &vat_main;
2873   vat_json_node_t *e = 0, root;
2874   u32 i;
2875   int retval = clib_net_to_host_u32 (mp->retval);
2876   vl_api_gpe_fwd_entry_t *fwd;
2877
2878   if (retval)
2879     goto end;
2880
2881   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2882   vat_json_init_array (&root);
2883
2884   for (i = 0; i < mp->count; i++)
2885     {
2886       e = vat_json_array_add (&root);
2887       fwd = &mp->entries[i];
2888
2889       vat_json_init_object (e);
2890       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2891       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2892
2893       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2894                   fwd->leid_prefix_len);
2895       vec_add1 (s, 0);
2896       vat_json_object_add_string_copy (e, "leid", s);
2897       vec_free (s);
2898
2899       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2900                   fwd->reid_prefix_len);
2901       vec_add1 (s, 0);
2902       vat_json_object_add_string_copy (e, "reid", s);
2903       vec_free (s);
2904     }
2905
2906   vat_json_print (vam->ofp, &root);
2907   vat_json_free (&root);
2908
2909 end:
2910   vam->retval = retval;
2911   vam->result_ready = 1;
2912 }
2913
2914 static void
2915   vl_api_one_adjacencies_get_reply_t_handler
2916   (vl_api_one_adjacencies_get_reply_t * mp)
2917 {
2918   vat_main_t *vam = &vat_main;
2919   u32 i, n;
2920   int retval = clib_net_to_host_u32 (mp->retval);
2921   vl_api_one_adjacency_t *a;
2922
2923   if (retval)
2924     goto end;
2925
2926   n = clib_net_to_host_u32 (mp->count);
2927
2928   for (i = 0; i < n; i++)
2929     {
2930       a = &mp->adjacencies[i];
2931       print (vam->ofp, "%U %40U",
2932              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2933              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2934     }
2935
2936 end:
2937   vam->retval = retval;
2938   vam->result_ready = 1;
2939 }
2940
2941 static void
2942   vl_api_one_adjacencies_get_reply_t_handler_json
2943   (vl_api_one_adjacencies_get_reply_t * mp)
2944 {
2945   u8 *s = 0;
2946   vat_main_t *vam = &vat_main;
2947   vat_json_node_t *e = 0, root;
2948   u32 i, n;
2949   int retval = clib_net_to_host_u32 (mp->retval);
2950   vl_api_one_adjacency_t *a;
2951
2952   if (retval)
2953     goto end;
2954
2955   n = clib_net_to_host_u32 (mp->count);
2956   vat_json_init_array (&root);
2957
2958   for (i = 0; i < n; i++)
2959     {
2960       e = vat_json_array_add (&root);
2961       a = &mp->adjacencies[i];
2962
2963       vat_json_init_object (e);
2964       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2965                   a->leid_prefix_len);
2966       vec_add1 (s, 0);
2967       vat_json_object_add_string_copy (e, "leid", s);
2968       vec_free (s);
2969
2970       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2971                   a->reid_prefix_len);
2972       vec_add1 (s, 0);
2973       vat_json_object_add_string_copy (e, "reid", s);
2974       vec_free (s);
2975     }
2976
2977   vat_json_print (vam->ofp, &root);
2978   vat_json_free (&root);
2979
2980 end:
2981   vam->retval = retval;
2982   vam->result_ready = 1;
2983 }
2984
2985 static void
2986 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
2987 {
2988   vat_main_t *vam = &vat_main;
2989
2990   print (vam->ofp, "%=20U",
2991          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2992          mp->ip_address);
2993 }
2994
2995 static void
2996   vl_api_one_map_server_details_t_handler_json
2997   (vl_api_one_map_server_details_t * mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   vat_json_node_t *node = NULL;
3001   struct in6_addr ip6;
3002   struct in_addr ip4;
3003
3004   if (VAT_JSON_ARRAY != vam->json_tree.type)
3005     {
3006       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3007       vat_json_init_array (&vam->json_tree);
3008     }
3009   node = vat_json_array_add (&vam->json_tree);
3010
3011   vat_json_init_object (node);
3012   if (mp->is_ipv6)
3013     {
3014       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3015       vat_json_object_add_ip6 (node, "map-server", ip6);
3016     }
3017   else
3018     {
3019       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3020       vat_json_object_add_ip4 (node, "map-server", ip4);
3021     }
3022 }
3023
3024 static void
3025 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3026                                            * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029
3030   print (vam->ofp, "%=20U",
3031          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3032          mp->ip_address);
3033 }
3034
3035 static void
3036   vl_api_one_map_resolver_details_t_handler_json
3037   (vl_api_one_map_resolver_details_t * mp)
3038 {
3039   vat_main_t *vam = &vat_main;
3040   vat_json_node_t *node = NULL;
3041   struct in6_addr ip6;
3042   struct in_addr ip4;
3043
3044   if (VAT_JSON_ARRAY != vam->json_tree.type)
3045     {
3046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3047       vat_json_init_array (&vam->json_tree);
3048     }
3049   node = vat_json_array_add (&vam->json_tree);
3050
3051   vat_json_init_object (node);
3052   if (mp->is_ipv6)
3053     {
3054       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3055       vat_json_object_add_ip6 (node, "map resolver", ip6);
3056     }
3057   else
3058     {
3059       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3060       vat_json_object_add_ip4 (node, "map resolver", ip4);
3061     }
3062 }
3063
3064 static void
3065 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3066 {
3067   vat_main_t *vam = &vat_main;
3068   i32 retval = ntohl (mp->retval);
3069
3070   if (0 <= retval)
3071     {
3072       print (vam->ofp, "feature: %s\ngpe: %s",
3073              mp->feature_status ? "enabled" : "disabled",
3074              mp->gpe_status ? "enabled" : "disabled");
3075     }
3076
3077   vam->retval = retval;
3078   vam->result_ready = 1;
3079 }
3080
3081 static void
3082   vl_api_show_one_status_reply_t_handler_json
3083   (vl_api_show_one_status_reply_t * mp)
3084 {
3085   vat_main_t *vam = &vat_main;
3086   vat_json_node_t node;
3087   u8 *gpe_status = NULL;
3088   u8 *feature_status = NULL;
3089
3090   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3091   feature_status = format (0, "%s",
3092                            mp->feature_status ? "enabled" : "disabled");
3093   vec_add1 (gpe_status, 0);
3094   vec_add1 (feature_status, 0);
3095
3096   vat_json_init_object (&node);
3097   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3098   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3099
3100   vec_free (gpe_status);
3101   vec_free (feature_status);
3102
3103   vat_json_print (vam->ofp, &node);
3104   vat_json_free (&node);
3105
3106   vam->retval = ntohl (mp->retval);
3107   vam->result_ready = 1;
3108 }
3109
3110 static void
3111   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3112   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3113 {
3114   vat_main_t *vam = &vat_main;
3115   i32 retval = ntohl (mp->retval);
3116
3117   if (retval >= 0)
3118     {
3119       print (vam->ofp, "%=20s", mp->locator_set_name);
3120     }
3121
3122   vam->retval = retval;
3123   vam->result_ready = 1;
3124 }
3125
3126 static void
3127   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3128   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   vat_json_node_t *node = NULL;
3132
3133   if (VAT_JSON_ARRAY != vam->json_tree.type)
3134     {
3135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3136       vat_json_init_array (&vam->json_tree);
3137     }
3138   node = vat_json_array_add (&vam->json_tree);
3139
3140   vat_json_init_object (node);
3141   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3142
3143   vat_json_print (vam->ofp, node);
3144   vat_json_free (node);
3145
3146   vam->retval = ntohl (mp->retval);
3147   vam->result_ready = 1;
3148 }
3149
3150 static u8 *
3151 format_lisp_map_request_mode (u8 * s, va_list * args)
3152 {
3153   u32 mode = va_arg (*args, u32);
3154
3155   switch (mode)
3156     {
3157     case 0:
3158       return format (0, "dst-only");
3159     case 1:
3160       return format (0, "src-dst");
3161     }
3162   return 0;
3163 }
3164
3165 static void
3166   vl_api_show_one_map_request_mode_reply_t_handler
3167   (vl_api_show_one_map_request_mode_reply_t * mp)
3168 {
3169   vat_main_t *vam = &vat_main;
3170   i32 retval = ntohl (mp->retval);
3171
3172   if (0 <= retval)
3173     {
3174       u32 mode = mp->mode;
3175       print (vam->ofp, "map_request_mode: %U",
3176              format_lisp_map_request_mode, mode);
3177     }
3178
3179   vam->retval = retval;
3180   vam->result_ready = 1;
3181 }
3182
3183 static void
3184   vl_api_show_one_map_request_mode_reply_t_handler_json
3185   (vl_api_show_one_map_request_mode_reply_t * mp)
3186 {
3187   vat_main_t *vam = &vat_main;
3188   vat_json_node_t node;
3189   u8 *s = 0;
3190   u32 mode;
3191
3192   mode = mp->mode;
3193   s = format (0, "%U", format_lisp_map_request_mode, mode);
3194   vec_add1 (s, 0);
3195
3196   vat_json_init_object (&node);
3197   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3198   vat_json_print (vam->ofp, &node);
3199   vat_json_free (&node);
3200
3201   vec_free (s);
3202   vam->retval = ntohl (mp->retval);
3203   vam->result_ready = 1;
3204 }
3205
3206 static void
3207 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3208 {
3209   vat_main_t *vam = &vat_main;
3210   i32 retval = ntohl (mp->retval);
3211
3212   if (0 <= retval)
3213     {
3214       print (vam->ofp, "%-20s%-16s",
3215              mp->status ? "enabled" : "disabled",
3216              mp->status ? (char *) mp->locator_set_name : "");
3217     }
3218
3219   vam->retval = retval;
3220   vam->result_ready = 1;
3221 }
3222
3223 static void
3224 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227   vat_json_node_t node;
3228   u8 *status = 0;
3229
3230   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3231   vec_add1 (status, 0);
3232
3233   vat_json_init_object (&node);
3234   vat_json_object_add_string_copy (&node, "status", status);
3235   if (mp->status)
3236     {
3237       vat_json_object_add_string_copy (&node, "locator_set",
3238                                        mp->locator_set_name);
3239     }
3240
3241   vec_free (status);
3242
3243   vat_json_print (vam->ofp, &node);
3244   vat_json_free (&node);
3245
3246   vam->retval = ntohl (mp->retval);
3247   vam->result_ready = 1;
3248 }
3249
3250 static u8 *
3251 format_policer_type (u8 * s, va_list * va)
3252 {
3253   u32 i = va_arg (*va, u32);
3254
3255   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3256     s = format (s, "1r2c");
3257   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3258     s = format (s, "1r3c");
3259   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3260     s = format (s, "2r3c-2698");
3261   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3262     s = format (s, "2r3c-4115");
3263   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3264     s = format (s, "2r3c-mef5cf1");
3265   else
3266     s = format (s, "ILLEGAL");
3267   return s;
3268 }
3269
3270 static u8 *
3271 format_policer_rate_type (u8 * s, va_list * va)
3272 {
3273   u32 i = va_arg (*va, u32);
3274
3275   if (i == SSE2_QOS_RATE_KBPS)
3276     s = format (s, "kbps");
3277   else if (i == SSE2_QOS_RATE_PPS)
3278     s = format (s, "pps");
3279   else
3280     s = format (s, "ILLEGAL");
3281   return s;
3282 }
3283
3284 static u8 *
3285 format_policer_round_type (u8 * s, va_list * va)
3286 {
3287   u32 i = va_arg (*va, u32);
3288
3289   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3290     s = format (s, "closest");
3291   else if (i == SSE2_QOS_ROUND_TO_UP)
3292     s = format (s, "up");
3293   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3294     s = format (s, "down");
3295   else
3296     s = format (s, "ILLEGAL");
3297   return s;
3298 }
3299
3300 static u8 *
3301 format_policer_action_type (u8 * s, va_list * va)
3302 {
3303   u32 i = va_arg (*va, u32);
3304
3305   if (i == SSE2_QOS_ACTION_DROP)
3306     s = format (s, "drop");
3307   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3308     s = format (s, "transmit");
3309   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3310     s = format (s, "mark-and-transmit");
3311   else
3312     s = format (s, "ILLEGAL");
3313   return s;
3314 }
3315
3316 static u8 *
3317 format_dscp (u8 * s, va_list * va)
3318 {
3319   u32 i = va_arg (*va, u32);
3320   char *t = 0;
3321
3322   switch (i)
3323     {
3324 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3325       foreach_vnet_dscp
3326 #undef _
3327     default:
3328       return format (s, "ILLEGAL");
3329     }
3330   s = format (s, "%s", t);
3331   return s;
3332 }
3333
3334 static void
3335 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3336 {
3337   vat_main_t *vam = &vat_main;
3338   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3339
3340   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3341     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3342   else
3343     conform_dscp_str = format (0, "");
3344
3345   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3346     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3347   else
3348     exceed_dscp_str = format (0, "");
3349
3350   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3351     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3352   else
3353     violate_dscp_str = format (0, "");
3354
3355   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3356          "rate type %U, round type %U, %s rate, %s color-aware, "
3357          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3358          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3359          "conform action %U%s, exceed action %U%s, violate action %U%s",
3360          mp->name,
3361          format_policer_type, mp->type,
3362          ntohl (mp->cir),
3363          ntohl (mp->eir),
3364          clib_net_to_host_u64 (mp->cb),
3365          clib_net_to_host_u64 (mp->eb),
3366          format_policer_rate_type, mp->rate_type,
3367          format_policer_round_type, mp->round_type,
3368          mp->single_rate ? "single" : "dual",
3369          mp->color_aware ? "is" : "not",
3370          ntohl (mp->cir_tokens_per_period),
3371          ntohl (mp->pir_tokens_per_period),
3372          ntohl (mp->scale),
3373          ntohl (mp->current_limit),
3374          ntohl (mp->current_bucket),
3375          ntohl (mp->extended_limit),
3376          ntohl (mp->extended_bucket),
3377          clib_net_to_host_u64 (mp->last_update_time),
3378          format_policer_action_type, mp->conform_action_type,
3379          conform_dscp_str,
3380          format_policer_action_type, mp->exceed_action_type,
3381          exceed_dscp_str,
3382          format_policer_action_type, mp->violate_action_type,
3383          violate_dscp_str);
3384
3385   vec_free (conform_dscp_str);
3386   vec_free (exceed_dscp_str);
3387   vec_free (violate_dscp_str);
3388 }
3389
3390 static void vl_api_policer_details_t_handler_json
3391   (vl_api_policer_details_t * mp)
3392 {
3393   vat_main_t *vam = &vat_main;
3394   vat_json_node_t *node;
3395   u8 *rate_type_str, *round_type_str, *type_str;
3396   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3397
3398   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3399   round_type_str =
3400     format (0, "%U", format_policer_round_type, mp->round_type);
3401   type_str = format (0, "%U", format_policer_type, mp->type);
3402   conform_action_str = format (0, "%U", format_policer_action_type,
3403                                mp->conform_action_type);
3404   exceed_action_str = format (0, "%U", format_policer_action_type,
3405                               mp->exceed_action_type);
3406   violate_action_str = format (0, "%U", format_policer_action_type,
3407                                mp->violate_action_type);
3408
3409   if (VAT_JSON_ARRAY != vam->json_tree.type)
3410     {
3411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3412       vat_json_init_array (&vam->json_tree);
3413     }
3414   node = vat_json_array_add (&vam->json_tree);
3415
3416   vat_json_init_object (node);
3417   vat_json_object_add_string_copy (node, "name", mp->name);
3418   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3419   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3420   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3421   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3422   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3423   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3424   vat_json_object_add_string_copy (node, "type", type_str);
3425   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3426   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3427   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3428   vat_json_object_add_uint (node, "cir_tokens_per_period",
3429                             ntohl (mp->cir_tokens_per_period));
3430   vat_json_object_add_uint (node, "eir_tokens_per_period",
3431                             ntohl (mp->pir_tokens_per_period));
3432   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3433   vat_json_object_add_uint (node, "current_bucket",
3434                             ntohl (mp->current_bucket));
3435   vat_json_object_add_uint (node, "extended_limit",
3436                             ntohl (mp->extended_limit));
3437   vat_json_object_add_uint (node, "extended_bucket",
3438                             ntohl (mp->extended_bucket));
3439   vat_json_object_add_uint (node, "last_update_time",
3440                             ntohl (mp->last_update_time));
3441   vat_json_object_add_string_copy (node, "conform_action",
3442                                    conform_action_str);
3443   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3444     {
3445       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3446       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3447       vec_free (dscp_str);
3448     }
3449   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3450   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3451     {
3452       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3453       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3454       vec_free (dscp_str);
3455     }
3456   vat_json_object_add_string_copy (node, "violate_action",
3457                                    violate_action_str);
3458   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3459     {
3460       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3461       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3462       vec_free (dscp_str);
3463     }
3464
3465   vec_free (rate_type_str);
3466   vec_free (round_type_str);
3467   vec_free (type_str);
3468   vec_free (conform_action_str);
3469   vec_free (exceed_action_str);
3470   vec_free (violate_action_str);
3471 }
3472
3473 static void
3474 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3475                                            mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478   int i, count = ntohl (mp->count);
3479
3480   if (count > 0)
3481     print (vam->ofp, "classify table ids (%d) : ", count);
3482   for (i = 0; i < count; i++)
3483     {
3484       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3485       print (vam->ofp, (i < count - 1) ? "," : "");
3486     }
3487   vam->retval = ntohl (mp->retval);
3488   vam->result_ready = 1;
3489 }
3490
3491 static void
3492   vl_api_classify_table_ids_reply_t_handler_json
3493   (vl_api_classify_table_ids_reply_t * mp)
3494 {
3495   vat_main_t *vam = &vat_main;
3496   int i, count = ntohl (mp->count);
3497
3498   if (count > 0)
3499     {
3500       vat_json_node_t node;
3501
3502       vat_json_init_object (&node);
3503       for (i = 0; i < count; i++)
3504         {
3505           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3506         }
3507       vat_json_print (vam->ofp, &node);
3508       vat_json_free (&node);
3509     }
3510   vam->retval = ntohl (mp->retval);
3511   vam->result_ready = 1;
3512 }
3513
3514 static void
3515   vl_api_classify_table_by_interface_reply_t_handler
3516   (vl_api_classify_table_by_interface_reply_t * mp)
3517 {
3518   vat_main_t *vam = &vat_main;
3519   u32 table_id;
3520
3521   table_id = ntohl (mp->l2_table_id);
3522   if (table_id != ~0)
3523     print (vam->ofp, "l2 table id : %d", table_id);
3524   else
3525     print (vam->ofp, "l2 table id : No input ACL tables configured");
3526   table_id = ntohl (mp->ip4_table_id);
3527   if (table_id != ~0)
3528     print (vam->ofp, "ip4 table id : %d", table_id);
3529   else
3530     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3531   table_id = ntohl (mp->ip6_table_id);
3532   if (table_id != ~0)
3533     print (vam->ofp, "ip6 table id : %d", table_id);
3534   else
3535     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3536   vam->retval = ntohl (mp->retval);
3537   vam->result_ready = 1;
3538 }
3539
3540 static void
3541   vl_api_classify_table_by_interface_reply_t_handler_json
3542   (vl_api_classify_table_by_interface_reply_t * mp)
3543 {
3544   vat_main_t *vam = &vat_main;
3545   vat_json_node_t node;
3546
3547   vat_json_init_object (&node);
3548
3549   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3550   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3551   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3552
3553   vat_json_print (vam->ofp, &node);
3554   vat_json_free (&node);
3555
3556   vam->retval = ntohl (mp->retval);
3557   vam->result_ready = 1;
3558 }
3559
3560 static void vl_api_policer_add_del_reply_t_handler
3561   (vl_api_policer_add_del_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   i32 retval = ntohl (mp->retval);
3565   if (vam->async_mode)
3566     {
3567       vam->async_errors += (retval < 0);
3568     }
3569   else
3570     {
3571       vam->retval = retval;
3572       vam->result_ready = 1;
3573       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3574         /*
3575          * Note: this is just barely thread-safe, depends on
3576          * the main thread spinning waiting for an answer...
3577          */
3578         errmsg ("policer index %d", ntohl (mp->policer_index));
3579     }
3580 }
3581
3582 static void vl_api_policer_add_del_reply_t_handler_json
3583   (vl_api_policer_add_del_reply_t * mp)
3584 {
3585   vat_main_t *vam = &vat_main;
3586   vat_json_node_t node;
3587
3588   vat_json_init_object (&node);
3589   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3590   vat_json_object_add_uint (&node, "policer_index",
3591                             ntohl (mp->policer_index));
3592
3593   vat_json_print (vam->ofp, &node);
3594   vat_json_free (&node);
3595
3596   vam->retval = ntohl (mp->retval);
3597   vam->result_ready = 1;
3598 }
3599
3600 /* Format hex dump. */
3601 u8 *
3602 format_hex_bytes (u8 * s, va_list * va)
3603 {
3604   u8 *bytes = va_arg (*va, u8 *);
3605   int n_bytes = va_arg (*va, int);
3606   uword i;
3607
3608   /* Print short or long form depending on byte count. */
3609   uword short_form = n_bytes <= 32;
3610   uword indent = format_get_indent (s);
3611
3612   if (n_bytes == 0)
3613     return s;
3614
3615   for (i = 0; i < n_bytes; i++)
3616     {
3617       if (!short_form && (i % 32) == 0)
3618         s = format (s, "%08x: ", i);
3619       s = format (s, "%02x", bytes[i]);
3620       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3621         s = format (s, "\n%U", format_white_space, indent);
3622     }
3623
3624   return s;
3625 }
3626
3627 static void
3628 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3629                                             * mp)
3630 {
3631   vat_main_t *vam = &vat_main;
3632   i32 retval = ntohl (mp->retval);
3633   if (retval == 0)
3634     {
3635       print (vam->ofp, "classify table info :");
3636       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3637              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3638              ntohl (mp->miss_next_index));
3639       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3640              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3641              ntohl (mp->match_n_vectors));
3642       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3643              ntohl (mp->mask_length));
3644     }
3645   vam->retval = retval;
3646   vam->result_ready = 1;
3647 }
3648
3649 static void
3650   vl_api_classify_table_info_reply_t_handler_json
3651   (vl_api_classify_table_info_reply_t * mp)
3652 {
3653   vat_main_t *vam = &vat_main;
3654   vat_json_node_t node;
3655
3656   i32 retval = ntohl (mp->retval);
3657   if (retval == 0)
3658     {
3659       vat_json_init_object (&node);
3660
3661       vat_json_object_add_int (&node, "sessions",
3662                                ntohl (mp->active_sessions));
3663       vat_json_object_add_int (&node, "nexttbl",
3664                                ntohl (mp->next_table_index));
3665       vat_json_object_add_int (&node, "nextnode",
3666                                ntohl (mp->miss_next_index));
3667       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3668       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3669       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3670       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3671                       ntohl (mp->mask_length), 0);
3672       vat_json_object_add_string_copy (&node, "mask", s);
3673
3674       vat_json_print (vam->ofp, &node);
3675       vat_json_free (&node);
3676     }
3677   vam->retval = ntohl (mp->retval);
3678   vam->result_ready = 1;
3679 }
3680
3681 static void
3682 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3683                                            mp)
3684 {
3685   vat_main_t *vam = &vat_main;
3686
3687   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3688          ntohl (mp->hit_next_index), ntohl (mp->advance),
3689          ntohl (mp->opaque_index));
3690   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3691          ntohl (mp->match_length));
3692 }
3693
3694 static void
3695   vl_api_classify_session_details_t_handler_json
3696   (vl_api_classify_session_details_t * mp)
3697 {
3698   vat_main_t *vam = &vat_main;
3699   vat_json_node_t *node = NULL;
3700
3701   if (VAT_JSON_ARRAY != vam->json_tree.type)
3702     {
3703       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3704       vat_json_init_array (&vam->json_tree);
3705     }
3706   node = vat_json_array_add (&vam->json_tree);
3707
3708   vat_json_init_object (node);
3709   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3710   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3711   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3712   u8 *s =
3713     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3714             0);
3715   vat_json_object_add_string_copy (node, "match", s);
3716 }
3717
3718 static void vl_api_pg_create_interface_reply_t_handler
3719   (vl_api_pg_create_interface_reply_t * mp)
3720 {
3721   vat_main_t *vam = &vat_main;
3722
3723   vam->retval = ntohl (mp->retval);
3724   vam->result_ready = 1;
3725 }
3726
3727 static void vl_api_pg_create_interface_reply_t_handler_json
3728   (vl_api_pg_create_interface_reply_t * mp)
3729 {
3730   vat_main_t *vam = &vat_main;
3731   vat_json_node_t node;
3732
3733   i32 retval = ntohl (mp->retval);
3734   if (retval == 0)
3735     {
3736       vat_json_init_object (&node);
3737
3738       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3739
3740       vat_json_print (vam->ofp, &node);
3741       vat_json_free (&node);
3742     }
3743   vam->retval = ntohl (mp->retval);
3744   vam->result_ready = 1;
3745 }
3746
3747 static void vl_api_policer_classify_details_t_handler
3748   (vl_api_policer_classify_details_t * mp)
3749 {
3750   vat_main_t *vam = &vat_main;
3751
3752   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3753          ntohl (mp->table_index));
3754 }
3755
3756 static void vl_api_policer_classify_details_t_handler_json
3757   (vl_api_policer_classify_details_t * mp)
3758 {
3759   vat_main_t *vam = &vat_main;
3760   vat_json_node_t *node;
3761
3762   if (VAT_JSON_ARRAY != vam->json_tree.type)
3763     {
3764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3765       vat_json_init_array (&vam->json_tree);
3766     }
3767   node = vat_json_array_add (&vam->json_tree);
3768
3769   vat_json_init_object (node);
3770   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3771   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3772 }
3773
3774 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3775   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3776 {
3777   vat_main_t *vam = &vat_main;
3778   i32 retval = ntohl (mp->retval);
3779   if (vam->async_mode)
3780     {
3781       vam->async_errors += (retval < 0);
3782     }
3783   else
3784     {
3785       vam->retval = retval;
3786       vam->sw_if_index = ntohl (mp->sw_if_index);
3787       vam->result_ready = 1;
3788     }
3789 }
3790
3791 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3792   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3793 {
3794   vat_main_t *vam = &vat_main;
3795   vat_json_node_t node;
3796
3797   vat_json_init_object (&node);
3798   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3799   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3800
3801   vat_json_print (vam->ofp, &node);
3802   vat_json_free (&node);
3803
3804   vam->retval = ntohl (mp->retval);
3805   vam->result_ready = 1;
3806 }
3807
3808 static void vl_api_flow_classify_details_t_handler
3809   (vl_api_flow_classify_details_t * mp)
3810 {
3811   vat_main_t *vam = &vat_main;
3812
3813   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3814          ntohl (mp->table_index));
3815 }
3816
3817 static void vl_api_flow_classify_details_t_handler_json
3818   (vl_api_flow_classify_details_t * mp)
3819 {
3820   vat_main_t *vam = &vat_main;
3821   vat_json_node_t *node;
3822
3823   if (VAT_JSON_ARRAY != vam->json_tree.type)
3824     {
3825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3826       vat_json_init_array (&vam->json_tree);
3827     }
3828   node = vat_json_array_add (&vam->json_tree);
3829
3830   vat_json_init_object (node);
3831   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3832   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3833 }
3834
3835
3836
3837 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3838 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3839 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3840 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3841 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3842 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3843 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3844 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3845 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3846 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3847
3848 /*
3849  * Generate boilerplate reply handlers, which
3850  * dig the return value out of the xxx_reply_t API message,
3851  * stick it into vam->retval, and set vam->result_ready
3852  *
3853  * Could also do this by pointing N message decode slots at
3854  * a single function, but that could break in subtle ways.
3855  */
3856
3857 #define foreach_standard_reply_retval_handler           \
3858 _(sw_interface_set_flags_reply)                         \
3859 _(sw_interface_add_del_address_reply)                   \
3860 _(sw_interface_set_table_reply)                         \
3861 _(sw_interface_set_mpls_enable_reply)                   \
3862 _(sw_interface_set_vpath_reply)                         \
3863 _(sw_interface_set_vxlan_bypass_reply)                  \
3864 _(sw_interface_set_l2_bridge_reply)                     \
3865 _(bridge_domain_add_del_reply)                          \
3866 _(sw_interface_set_l2_xconnect_reply)                   \
3867 _(l2fib_add_del_reply)                                  \
3868 _(ip_add_del_route_reply)                               \
3869 _(ip_mroute_add_del_reply)                              \
3870 _(mpls_route_add_del_reply)                             \
3871 _(mpls_ip_bind_unbind_reply)                            \
3872 _(proxy_arp_add_del_reply)                              \
3873 _(proxy_arp_intfc_enable_disable_reply)                 \
3874 _(sw_interface_set_unnumbered_reply)                    \
3875 _(ip_neighbor_add_del_reply)                            \
3876 _(reset_vrf_reply)                                      \
3877 _(oam_add_del_reply)                                    \
3878 _(reset_fib_reply)                                      \
3879 _(dhcp_proxy_config_reply)                              \
3880 _(dhcp_proxy_set_vss_reply)                             \
3881 _(dhcp_client_config_reply)                             \
3882 _(set_ip_flow_hash_reply)                               \
3883 _(sw_interface_ip6_enable_disable_reply)                \
3884 _(sw_interface_ip6_set_link_local_address_reply)        \
3885 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3886 _(sw_interface_ip6nd_ra_config_reply)                   \
3887 _(set_arp_neighbor_limit_reply)                         \
3888 _(l2_patch_add_del_reply)                               \
3889 _(sr_tunnel_add_del_reply)                              \
3890 _(sr_policy_add_del_reply)                              \
3891 _(sr_multicast_map_add_del_reply)                       \
3892 _(classify_add_del_session_reply)                       \
3893 _(classify_set_interface_ip_table_reply)                \
3894 _(classify_set_interface_l2_tables_reply)               \
3895 _(l2tpv3_set_tunnel_cookies_reply)                      \
3896 _(l2tpv3_interface_enable_disable_reply)                \
3897 _(l2tpv3_set_lookup_key_reply)                          \
3898 _(l2_fib_clear_table_reply)                             \
3899 _(l2_interface_efp_filter_reply)                        \
3900 _(l2_interface_vlan_tag_rewrite_reply)                  \
3901 _(modify_vhost_user_if_reply)                           \
3902 _(delete_vhost_user_if_reply)                           \
3903 _(want_ip4_arp_events_reply)                            \
3904 _(want_ip6_nd_events_reply)                             \
3905 _(input_acl_set_interface_reply)                        \
3906 _(ipsec_spd_add_del_reply)                              \
3907 _(ipsec_interface_add_del_spd_reply)                    \
3908 _(ipsec_spd_add_del_entry_reply)                        \
3909 _(ipsec_sad_add_del_entry_reply)                        \
3910 _(ipsec_sa_set_key_reply)                               \
3911 _(ikev2_profile_add_del_reply)                          \
3912 _(ikev2_profile_set_auth_reply)                         \
3913 _(ikev2_profile_set_id_reply)                           \
3914 _(ikev2_profile_set_ts_reply)                           \
3915 _(ikev2_set_local_key_reply)                            \
3916 _(ikev2_set_responder_reply)                            \
3917 _(ikev2_set_ike_transforms_reply)                       \
3918 _(ikev2_set_esp_transforms_reply)                       \
3919 _(ikev2_set_sa_lifetime_reply)                          \
3920 _(ikev2_initiate_sa_init_reply)                         \
3921 _(ikev2_initiate_del_ike_sa_reply)                      \
3922 _(ikev2_initiate_del_child_sa_reply)                    \
3923 _(ikev2_initiate_rekey_child_sa_reply)                  \
3924 _(delete_loopback_reply)                                \
3925 _(bd_ip_mac_add_del_reply)                              \
3926 _(map_del_domain_reply)                                 \
3927 _(map_add_del_rule_reply)                               \
3928 _(want_interface_events_reply)                          \
3929 _(want_stats_reply)                                     \
3930 _(cop_interface_enable_disable_reply)                   \
3931 _(cop_whitelist_enable_disable_reply)                   \
3932 _(sw_interface_clear_stats_reply)                       \
3933 _(ioam_enable_reply)                              \
3934 _(ioam_disable_reply)                              \
3935 _(one_add_del_locator_reply)                            \
3936 _(one_add_del_local_eid_reply)                          \
3937 _(one_add_del_remote_mapping_reply)                     \
3938 _(one_add_del_adjacency_reply)                          \
3939 _(one_add_del_map_resolver_reply)                       \
3940 _(one_add_del_map_server_reply)                         \
3941 _(one_enable_disable_reply)                             \
3942 _(one_rloc_probe_enable_disable_reply)                  \
3943 _(one_map_register_enable_disable_reply)                \
3944 _(one_pitr_set_locator_set_reply)                       \
3945 _(one_map_request_mode_reply)                           \
3946 _(one_add_del_map_request_itr_rlocs_reply)              \
3947 _(one_eid_table_add_del_map_reply)                      \
3948 _(gpe_add_del_fwd_entry_reply)                          \
3949 _(gpe_enable_disable_reply)                             \
3950 _(gpe_set_encap_mode_reply)                             \
3951 _(gpe_add_del_iface_reply)                              \
3952 _(vxlan_gpe_add_del_tunnel_reply)                       \
3953 _(af_packet_delete_reply)                               \
3954 _(policer_classify_set_interface_reply)                 \
3955 _(netmap_create_reply)                                  \
3956 _(netmap_delete_reply)                                  \
3957 _(set_ipfix_exporter_reply)                             \
3958 _(set_ipfix_classify_stream_reply)                      \
3959 _(ipfix_classify_table_add_del_reply)                   \
3960 _(flow_classify_set_interface_reply)                    \
3961 _(sw_interface_span_enable_disable_reply)               \
3962 _(pg_capture_reply)                                     \
3963 _(pg_enable_disable_reply)                              \
3964 _(ip_source_and_port_range_check_add_del_reply)         \
3965 _(ip_source_and_port_range_check_interface_add_del_reply)\
3966 _(delete_subif_reply)                                   \
3967 _(l2_interface_pbb_tag_rewrite_reply)                   \
3968 _(punt_reply)                                           \
3969 _(feature_enable_disable_reply)                         \
3970 _(sw_interface_tag_add_del_reply)                       \
3971 _(sw_interface_set_mtu_reply)
3972
3973 #if DPDK > 0
3974 #define foreach_standard_dpdk_reply_retval_handler      \
3975 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3976 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3977 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3978 #endif
3979
3980 #define _(n)                                    \
3981     static void vl_api_##n##_t_handler          \
3982     (vl_api_##n##_t * mp)                       \
3983     {                                           \
3984         vat_main_t * vam = &vat_main;           \
3985         i32 retval = ntohl(mp->retval);         \
3986         if (vam->async_mode) {                  \
3987             vam->async_errors += (retval < 0);  \
3988         } else {                                \
3989             vam->retval = retval;               \
3990             vam->result_ready = 1;              \
3991         }                                       \
3992     }
3993 foreach_standard_reply_retval_handler;
3994 #undef _
3995
3996 #define _(n)                                    \
3997     static void vl_api_##n##_t_handler_json     \
3998     (vl_api_##n##_t * mp)                       \
3999     {                                           \
4000         vat_main_t * vam = &vat_main;           \
4001         vat_json_node_t node;                   \
4002         vat_json_init_object(&node);            \
4003         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4004         vat_json_print(vam->ofp, &node);        \
4005         vam->retval = ntohl(mp->retval);        \
4006         vam->result_ready = 1;                  \
4007     }
4008 foreach_standard_reply_retval_handler;
4009 #undef _
4010
4011 #if DPDK > 0
4012 #define _(n)                                    \
4013     static void vl_api_##n##_t_handler          \
4014     (vl_api_##n##_t * mp)                       \
4015     {                                           \
4016         vat_main_t * vam = &vat_main;           \
4017         i32 retval = ntohl(mp->retval);         \
4018         if (vam->async_mode) {                  \
4019             vam->async_errors += (retval < 0);  \
4020         } else {                                \
4021             vam->retval = retval;               \
4022             vam->result_ready = 1;              \
4023         }                                       \
4024     }
4025 foreach_standard_dpdk_reply_retval_handler;
4026 #undef _
4027
4028 #define _(n)                                    \
4029     static void vl_api_##n##_t_handler_json     \
4030     (vl_api_##n##_t * mp)                       \
4031     {                                           \
4032         vat_main_t * vam = &vat_main;           \
4033         vat_json_node_t node;                   \
4034         vat_json_init_object(&node);            \
4035         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4036         vat_json_print(vam->ofp, &node);        \
4037         vam->retval = ntohl(mp->retval);        \
4038         vam->result_ready = 1;                  \
4039     }
4040 foreach_standard_dpdk_reply_retval_handler;
4041 #undef _
4042 #endif
4043
4044 /*
4045  * Table of message reply handlers, must include boilerplate handlers
4046  * we just generated
4047  */
4048
4049 #define foreach_vpe_api_reply_msg                                       \
4050 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4051 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4052 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4053 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4054 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4055 _(CLI_REPLY, cli_reply)                                                 \
4056 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4057 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4058   sw_interface_add_del_address_reply)                                   \
4059 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4060 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4061 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4062 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4063 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4064   sw_interface_set_l2_xconnect_reply)                                   \
4065 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4066   sw_interface_set_l2_bridge_reply)                                     \
4067 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4068 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4069 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4070 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4071 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4072 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4073 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4074 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4075 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4076 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4077 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4078 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4079 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4080 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4081 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4082 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4083   proxy_arp_intfc_enable_disable_reply)                                 \
4084 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4085 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4086   sw_interface_set_unnumbered_reply)                                    \
4087 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4088 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4089 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4090 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4091 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4092 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4093 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4094 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4095 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4096 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4097 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4098 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4099   sw_interface_ip6_enable_disable_reply)                                \
4100 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4101   sw_interface_ip6_set_link_local_address_reply)                        \
4102 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4103   sw_interface_ip6nd_ra_prefix_reply)                                   \
4104 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4105   sw_interface_ip6nd_ra_config_reply)                                   \
4106 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4107 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4108 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4109 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4110 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4111 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4112 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4113 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4114 classify_set_interface_ip_table_reply)                                  \
4115 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4116   classify_set_interface_l2_tables_reply)                               \
4117 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4118 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4119 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4120 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4121 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4122   l2tpv3_interface_enable_disable_reply)                                \
4123 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4124 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4125 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4126 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4127 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4128 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4129 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4130 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4131 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4132 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4133 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4134 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4135 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4136 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4137 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4138 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4139 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4140 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4141 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4142 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4143 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4144 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4145 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4146 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4147 _(IP_DETAILS, ip_details)                                               \
4148 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4149 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4150 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4151 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4152 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4153 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4154 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4155 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4156 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4157 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4158 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4159 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4160 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4161 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4162 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4163 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4164 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4165 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4166 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4167 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4168 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4169 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4170 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4171 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4172 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4173 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
4174 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4175 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4176 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4177 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4178 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4179 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4180 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4181 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4182 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4183 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4184 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4185 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4186 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4187 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4188 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4189 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4190 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4191 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4192 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4193 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4194 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4195 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4196 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4197   one_map_register_enable_disable_reply)                                \
4198 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4199   one_rloc_probe_enable_disable_reply)                                  \
4200 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4201 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4202 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4203 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4204 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4205 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4206 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4207 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4208 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4209 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4210 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4211 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4212 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4213 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4214 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4215 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4216 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4217 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4218   gpe_fwd_entry_path_details)                                           \
4219 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4220 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4221   one_add_del_map_request_itr_rlocs_reply)                              \
4222 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4223   one_get_map_request_itr_rlocs_reply)                                  \
4224 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4225 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4226 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4227 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4228   show_one_map_register_state_reply)                                    \
4229 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4230 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4231 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4232 _(POLICER_DETAILS, policer_details)                                     \
4233 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4234 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4235 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4236 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4237 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4238 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4239 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4240 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4241 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4242 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4243 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4244 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4245 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4246 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4247 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4248 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4249 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4250 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4251 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4252 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4253 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4254 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4255 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4256 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4257 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4258  ip_source_and_port_range_check_add_del_reply)                          \
4259 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4260  ip_source_and_port_range_check_interface_add_del_reply)                \
4261 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4262 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4263 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4264 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4265 _(PUNT_REPLY, punt_reply)                                               \
4266 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4267 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4268 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4269 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4270 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4271 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4272 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4273 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4274
4275 #if DPDK > 0
4276 #define foreach_vpe_dpdk_api_reply_msg                                  \
4277 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
4278   sw_interface_set_dpdk_hqos_pipe_reply)                                \
4279 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
4280   sw_interface_set_dpdk_hqos_subport_reply)                             \
4281 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
4282   sw_interface_set_dpdk_hqos_tctbl_reply)
4283 #endif
4284
4285 typedef struct
4286 {
4287   u8 *name;
4288   u32 value;
4289 } name_sort_t;
4290
4291
4292 #define STR_VTR_OP_CASE(op)     \
4293     case L2_VTR_ ## op:         \
4294         return "" # op;
4295
4296 static const char *
4297 str_vtr_op (u32 vtr_op)
4298 {
4299   switch (vtr_op)
4300     {
4301       STR_VTR_OP_CASE (DISABLED);
4302       STR_VTR_OP_CASE (PUSH_1);
4303       STR_VTR_OP_CASE (PUSH_2);
4304       STR_VTR_OP_CASE (POP_1);
4305       STR_VTR_OP_CASE (POP_2);
4306       STR_VTR_OP_CASE (TRANSLATE_1_1);
4307       STR_VTR_OP_CASE (TRANSLATE_1_2);
4308       STR_VTR_OP_CASE (TRANSLATE_2_1);
4309       STR_VTR_OP_CASE (TRANSLATE_2_2);
4310     }
4311
4312   return "UNKNOWN";
4313 }
4314
4315 static int
4316 dump_sub_interface_table (vat_main_t * vam)
4317 {
4318   const sw_interface_subif_t *sub = NULL;
4319
4320   if (vam->json_output)
4321     {
4322       clib_warning
4323         ("JSON output supported only for VPE API calls and dump_stats_table");
4324       return -99;
4325     }
4326
4327   print (vam->ofp,
4328          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4329          "Interface", "sw_if_index",
4330          "sub id", "dot1ad", "tags", "outer id",
4331          "inner id", "exact", "default", "outer any", "inner any");
4332
4333   vec_foreach (sub, vam->sw_if_subif_table)
4334   {
4335     print (vam->ofp,
4336            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4337            sub->interface_name,
4338            sub->sw_if_index,
4339            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4340            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4341            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4342            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4343     if (sub->vtr_op != L2_VTR_DISABLED)
4344       {
4345         print (vam->ofp,
4346                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4347                "tag1: %d tag2: %d ]",
4348                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4349                sub->vtr_tag1, sub->vtr_tag2);
4350       }
4351   }
4352
4353   return 0;
4354 }
4355
4356 static int
4357 name_sort_cmp (void *a1, void *a2)
4358 {
4359   name_sort_t *n1 = a1;
4360   name_sort_t *n2 = a2;
4361
4362   return strcmp ((char *) n1->name, (char *) n2->name);
4363 }
4364
4365 static int
4366 dump_interface_table (vat_main_t * vam)
4367 {
4368   hash_pair_t *p;
4369   name_sort_t *nses = 0, *ns;
4370
4371   if (vam->json_output)
4372     {
4373       clib_warning
4374         ("JSON output supported only for VPE API calls and dump_stats_table");
4375       return -99;
4376     }
4377
4378   /* *INDENT-OFF* */
4379   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4380   ({
4381     vec_add2 (nses, ns, 1);
4382     ns->name = (u8 *)(p->key);
4383     ns->value = (u32) p->value[0];
4384   }));
4385   /* *INDENT-ON* */
4386
4387   vec_sort_with_function (nses, name_sort_cmp);
4388
4389   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4390   vec_foreach (ns, nses)
4391   {
4392     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4393   }
4394   vec_free (nses);
4395   return 0;
4396 }
4397
4398 static int
4399 dump_ip_table (vat_main_t * vam, int is_ipv6)
4400 {
4401   const ip_details_t *det = NULL;
4402   const ip_address_details_t *address = NULL;
4403   u32 i = ~0;
4404
4405   print (vam->ofp, "%-12s", "sw_if_index");
4406
4407   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4408   {
4409     i++;
4410     if (!det->present)
4411       {
4412         continue;
4413       }
4414     print (vam->ofp, "%-12d", i);
4415     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4416     if (!det->addr)
4417       {
4418         continue;
4419       }
4420     vec_foreach (address, det->addr)
4421     {
4422       print (vam->ofp,
4423              "            %-30U%-13d",
4424              is_ipv6 ? format_ip6_address : format_ip4_address,
4425              address->ip, address->prefix_length);
4426     }
4427   }
4428
4429   return 0;
4430 }
4431
4432 static int
4433 dump_ipv4_table (vat_main_t * vam)
4434 {
4435   if (vam->json_output)
4436     {
4437       clib_warning
4438         ("JSON output supported only for VPE API calls and dump_stats_table");
4439       return -99;
4440     }
4441
4442   return dump_ip_table (vam, 0);
4443 }
4444
4445 static int
4446 dump_ipv6_table (vat_main_t * vam)
4447 {
4448   if (vam->json_output)
4449     {
4450       clib_warning
4451         ("JSON output supported only for VPE API calls and dump_stats_table");
4452       return -99;
4453     }
4454
4455   return dump_ip_table (vam, 1);
4456 }
4457
4458 static char *
4459 counter_type_to_str (u8 counter_type, u8 is_combined)
4460 {
4461   if (!is_combined)
4462     {
4463       switch (counter_type)
4464         {
4465         case VNET_INTERFACE_COUNTER_DROP:
4466           return "drop";
4467         case VNET_INTERFACE_COUNTER_PUNT:
4468           return "punt";
4469         case VNET_INTERFACE_COUNTER_IP4:
4470           return "ip4";
4471         case VNET_INTERFACE_COUNTER_IP6:
4472           return "ip6";
4473         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4474           return "rx-no-buf";
4475         case VNET_INTERFACE_COUNTER_RX_MISS:
4476           return "rx-miss";
4477         case VNET_INTERFACE_COUNTER_RX_ERROR:
4478           return "rx-error";
4479         case VNET_INTERFACE_COUNTER_TX_ERROR:
4480           return "tx-error";
4481         default:
4482           return "INVALID-COUNTER-TYPE";
4483         }
4484     }
4485   else
4486     {
4487       switch (counter_type)
4488         {
4489         case VNET_INTERFACE_COUNTER_RX:
4490           return "rx";
4491         case VNET_INTERFACE_COUNTER_TX:
4492           return "tx";
4493         default:
4494           return "INVALID-COUNTER-TYPE";
4495         }
4496     }
4497 }
4498
4499 static int
4500 dump_stats_table (vat_main_t * vam)
4501 {
4502   vat_json_node_t node;
4503   vat_json_node_t *msg_array;
4504   vat_json_node_t *msg;
4505   vat_json_node_t *counter_array;
4506   vat_json_node_t *counter;
4507   interface_counter_t c;
4508   u64 packets;
4509   ip4_fib_counter_t *c4;
4510   ip6_fib_counter_t *c6;
4511   ip4_nbr_counter_t *n4;
4512   ip6_nbr_counter_t *n6;
4513   int i, j;
4514
4515   if (!vam->json_output)
4516     {
4517       clib_warning ("dump_stats_table supported only in JSON format");
4518       return -99;
4519     }
4520
4521   vat_json_init_object (&node);
4522
4523   /* interface counters */
4524   msg_array = vat_json_object_add (&node, "interface_counters");
4525   vat_json_init_array (msg_array);
4526   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4527     {
4528       msg = vat_json_array_add (msg_array);
4529       vat_json_init_object (msg);
4530       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4531                                        (u8 *) counter_type_to_str (i, 0));
4532       vat_json_object_add_int (msg, "is_combined", 0);
4533       counter_array = vat_json_object_add (msg, "data");
4534       vat_json_init_array (counter_array);
4535       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4536         {
4537           packets = vam->simple_interface_counters[i][j];
4538           vat_json_array_add_uint (counter_array, packets);
4539         }
4540     }
4541   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4542     {
4543       msg = vat_json_array_add (msg_array);
4544       vat_json_init_object (msg);
4545       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4546                                        (u8 *) counter_type_to_str (i, 1));
4547       vat_json_object_add_int (msg, "is_combined", 1);
4548       counter_array = vat_json_object_add (msg, "data");
4549       vat_json_init_array (counter_array);
4550       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4551         {
4552           c = vam->combined_interface_counters[i][j];
4553           counter = vat_json_array_add (counter_array);
4554           vat_json_init_object (counter);
4555           vat_json_object_add_uint (counter, "packets", c.packets);
4556           vat_json_object_add_uint (counter, "bytes", c.bytes);
4557         }
4558     }
4559
4560   /* ip4 fib counters */
4561   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4562   vat_json_init_array (msg_array);
4563   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4564     {
4565       msg = vat_json_array_add (msg_array);
4566       vat_json_init_object (msg);
4567       vat_json_object_add_uint (msg, "vrf_id",
4568                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4569       counter_array = vat_json_object_add (msg, "c");
4570       vat_json_init_array (counter_array);
4571       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4572         {
4573           counter = vat_json_array_add (counter_array);
4574           vat_json_init_object (counter);
4575           c4 = &vam->ip4_fib_counters[i][j];
4576           vat_json_object_add_ip4 (counter, "address", c4->address);
4577           vat_json_object_add_uint (counter, "address_length",
4578                                     c4->address_length);
4579           vat_json_object_add_uint (counter, "packets", c4->packets);
4580           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4581         }
4582     }
4583
4584   /* ip6 fib counters */
4585   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4586   vat_json_init_array (msg_array);
4587   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4588     {
4589       msg = vat_json_array_add (msg_array);
4590       vat_json_init_object (msg);
4591       vat_json_object_add_uint (msg, "vrf_id",
4592                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4593       counter_array = vat_json_object_add (msg, "c");
4594       vat_json_init_array (counter_array);
4595       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4596         {
4597           counter = vat_json_array_add (counter_array);
4598           vat_json_init_object (counter);
4599           c6 = &vam->ip6_fib_counters[i][j];
4600           vat_json_object_add_ip6 (counter, "address", c6->address);
4601           vat_json_object_add_uint (counter, "address_length",
4602                                     c6->address_length);
4603           vat_json_object_add_uint (counter, "packets", c6->packets);
4604           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4605         }
4606     }
4607
4608   /* ip4 nbr counters */
4609   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4610   vat_json_init_array (msg_array);
4611   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4612     {
4613       msg = vat_json_array_add (msg_array);
4614       vat_json_init_object (msg);
4615       vat_json_object_add_uint (msg, "sw_if_index", i);
4616       counter_array = vat_json_object_add (msg, "c");
4617       vat_json_init_array (counter_array);
4618       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4619         {
4620           counter = vat_json_array_add (counter_array);
4621           vat_json_init_object (counter);
4622           n4 = &vam->ip4_nbr_counters[i][j];
4623           vat_json_object_add_ip4 (counter, "address", n4->address);
4624           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4625           vat_json_object_add_uint (counter, "packets", n4->packets);
4626           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4627         }
4628     }
4629
4630   /* ip6 nbr counters */
4631   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4632   vat_json_init_array (msg_array);
4633   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4634     {
4635       msg = vat_json_array_add (msg_array);
4636       vat_json_init_object (msg);
4637       vat_json_object_add_uint (msg, "sw_if_index", i);
4638       counter_array = vat_json_object_add (msg, "c");
4639       vat_json_init_array (counter_array);
4640       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4641         {
4642           counter = vat_json_array_add (counter_array);
4643           vat_json_init_object (counter);
4644           n6 = &vam->ip6_nbr_counters[i][j];
4645           vat_json_object_add_ip6 (counter, "address", n6->address);
4646           vat_json_object_add_uint (counter, "packets", n6->packets);
4647           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4648         }
4649     }
4650
4651   vat_json_print (vam->ofp, &node);
4652   vat_json_free (&node);
4653
4654   return 0;
4655 }
4656
4657 int
4658 exec (vat_main_t * vam)
4659 {
4660   api_main_t *am = &api_main;
4661   vl_api_cli_request_t *mp;
4662   f64 timeout;
4663   void *oldheap;
4664   u8 *cmd = 0;
4665   unformat_input_t *i = vam->input;
4666
4667   if (vec_len (i->buffer) == 0)
4668     return -1;
4669
4670   if (vam->exec_mode == 0 && unformat (i, "mode"))
4671     {
4672       vam->exec_mode = 1;
4673       return 0;
4674     }
4675   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4676     {
4677       vam->exec_mode = 0;
4678       return 0;
4679     }
4680
4681
4682   M (CLI_REQUEST, mp);
4683
4684   /*
4685    * Copy cmd into shared memory.
4686    * In order for the CLI command to work, it
4687    * must be a vector ending in \n, not a C-string ending
4688    * in \n\0.
4689    */
4690   pthread_mutex_lock (&am->vlib_rp->mutex);
4691   oldheap = svm_push_data_heap (am->vlib_rp);
4692
4693   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4694   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4695
4696   svm_pop_heap (oldheap);
4697   pthread_mutex_unlock (&am->vlib_rp->mutex);
4698
4699   mp->cmd_in_shmem = (u64) cmd;
4700   S (mp);
4701   timeout = vat_time_now (vam) + 10.0;
4702
4703   while (vat_time_now (vam) < timeout)
4704     {
4705       if (vam->result_ready == 1)
4706         {
4707           u8 *free_me;
4708           if (vam->shmem_result != NULL)
4709             print (vam->ofp, "%s", vam->shmem_result);
4710           pthread_mutex_lock (&am->vlib_rp->mutex);
4711           oldheap = svm_push_data_heap (am->vlib_rp);
4712
4713           free_me = (u8 *) vam->shmem_result;
4714           vec_free (free_me);
4715
4716           svm_pop_heap (oldheap);
4717           pthread_mutex_unlock (&am->vlib_rp->mutex);
4718           return 0;
4719         }
4720     }
4721   return -99;
4722 }
4723
4724 /*
4725  * Future replacement of exec() that passes CLI buffers directly in
4726  * the API messages instead of an additional shared memory area.
4727  */
4728 static int
4729 exec_inband (vat_main_t * vam)
4730 {
4731   vl_api_cli_inband_t *mp;
4732   unformat_input_t *i = vam->input;
4733   int ret;
4734
4735   if (vec_len (i->buffer) == 0)
4736     return -1;
4737
4738   if (vam->exec_mode == 0 && unformat (i, "mode"))
4739     {
4740       vam->exec_mode = 1;
4741       return 0;
4742     }
4743   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4744     {
4745       vam->exec_mode = 0;
4746       return 0;
4747     }
4748
4749   /*
4750    * In order for the CLI command to work, it
4751    * must be a vector ending in \n, not a C-string ending
4752    * in \n\0.
4753    */
4754   u32 len = vec_len (vam->input->buffer);
4755   M2 (CLI_INBAND, mp, len);
4756   clib_memcpy (mp->cmd, vam->input->buffer, len);
4757   mp->length = htonl (len);
4758
4759   S (mp);
4760   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4761   return ret;
4762 }
4763
4764 static int
4765 api_create_loopback (vat_main_t * vam)
4766 {
4767   unformat_input_t *i = vam->input;
4768   vl_api_create_loopback_t *mp;
4769   u8 mac_address[6];
4770   u8 mac_set = 0;
4771   int ret;
4772
4773   memset (mac_address, 0, sizeof (mac_address));
4774
4775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4776     {
4777       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4778         mac_set = 1;
4779       else
4780         break;
4781     }
4782
4783   /* Construct the API message */
4784   M (CREATE_LOOPBACK, mp);
4785   if (mac_set)
4786     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4787
4788   S (mp);
4789   W (ret);
4790   return ret;
4791 }
4792
4793 static int
4794 api_delete_loopback (vat_main_t * vam)
4795 {
4796   unformat_input_t *i = vam->input;
4797   vl_api_delete_loopback_t *mp;
4798   u32 sw_if_index = ~0;
4799   int ret;
4800
4801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4802     {
4803       if (unformat (i, "sw_if_index %d", &sw_if_index))
4804         ;
4805       else
4806         break;
4807     }
4808
4809   if (sw_if_index == ~0)
4810     {
4811       errmsg ("missing sw_if_index");
4812       return -99;
4813     }
4814
4815   /* Construct the API message */
4816   M (DELETE_LOOPBACK, mp);
4817   mp->sw_if_index = ntohl (sw_if_index);
4818
4819   S (mp);
4820   W (ret);
4821   return ret;
4822 }
4823
4824 static int
4825 api_want_stats (vat_main_t * vam)
4826 {
4827   unformat_input_t *i = vam->input;
4828   vl_api_want_stats_t *mp;
4829   int enable = -1;
4830   int ret;
4831
4832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4833     {
4834       if (unformat (i, "enable"))
4835         enable = 1;
4836       else if (unformat (i, "disable"))
4837         enable = 0;
4838       else
4839         break;
4840     }
4841
4842   if (enable == -1)
4843     {
4844       errmsg ("missing enable|disable");
4845       return -99;
4846     }
4847
4848   M (WANT_STATS, mp);
4849   mp->enable_disable = enable;
4850
4851   S (mp);
4852   W (ret);
4853   return ret;
4854 }
4855
4856 static int
4857 api_want_interface_events (vat_main_t * vam)
4858 {
4859   unformat_input_t *i = vam->input;
4860   vl_api_want_interface_events_t *mp;
4861   int enable = -1;
4862   int ret;
4863
4864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4865     {
4866       if (unformat (i, "enable"))
4867         enable = 1;
4868       else if (unformat (i, "disable"))
4869         enable = 0;
4870       else
4871         break;
4872     }
4873
4874   if (enable == -1)
4875     {
4876       errmsg ("missing enable|disable");
4877       return -99;
4878     }
4879
4880   M (WANT_INTERFACE_EVENTS, mp);
4881   mp->enable_disable = enable;
4882
4883   vam->interface_event_display = enable;
4884
4885   S (mp);
4886   W (ret);
4887   return ret;
4888 }
4889
4890
4891 /* Note: non-static, called once to set up the initial intfc table */
4892 int
4893 api_sw_interface_dump (vat_main_t * vam)
4894 {
4895   vl_api_sw_interface_dump_t *mp;
4896   vl_api_control_ping_t *mp_ping;
4897   hash_pair_t *p;
4898   name_sort_t *nses = 0, *ns;
4899   sw_interface_subif_t *sub = NULL;
4900   int ret;
4901
4902   /* Toss the old name table */
4903   /* *INDENT-OFF* */
4904   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4905   ({
4906     vec_add2 (nses, ns, 1);
4907     ns->name = (u8 *)(p->key);
4908     ns->value = (u32) p->value[0];
4909   }));
4910   /* *INDENT-ON* */
4911
4912   hash_free (vam->sw_if_index_by_interface_name);
4913
4914   vec_foreach (ns, nses) vec_free (ns->name);
4915
4916   vec_free (nses);
4917
4918   vec_foreach (sub, vam->sw_if_subif_table)
4919   {
4920     vec_free (sub->interface_name);
4921   }
4922   vec_free (vam->sw_if_subif_table);
4923
4924   /* recreate the interface name hash table */
4925   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4926
4927   /* Get list of ethernets */
4928   M (SW_INTERFACE_DUMP, mp);
4929   mp->name_filter_valid = 1;
4930   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4931   S (mp);
4932
4933   /* and local / loopback interfaces */
4934   M (SW_INTERFACE_DUMP, mp);
4935   mp->name_filter_valid = 1;
4936   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4937   S (mp);
4938
4939   /* and packet-generator interfaces */
4940   M (SW_INTERFACE_DUMP, mp);
4941   mp->name_filter_valid = 1;
4942   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4943   S (mp);
4944
4945   /* and vxlan-gpe tunnel interfaces */
4946   M (SW_INTERFACE_DUMP, mp);
4947   mp->name_filter_valid = 1;
4948   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4949            sizeof (mp->name_filter) - 1);
4950   S (mp);
4951
4952   /* and vxlan tunnel interfaces */
4953   M (SW_INTERFACE_DUMP, mp);
4954   mp->name_filter_valid = 1;
4955   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4956   S (mp);
4957
4958   /* and host (af_packet) interfaces */
4959   M (SW_INTERFACE_DUMP, mp);
4960   mp->name_filter_valid = 1;
4961   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4962   S (mp);
4963
4964   /* and l2tpv3 tunnel interfaces */
4965   M (SW_INTERFACE_DUMP, mp);
4966   mp->name_filter_valid = 1;
4967   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4968            sizeof (mp->name_filter) - 1);
4969   S (mp);
4970
4971   /* and GRE tunnel interfaces */
4972   M (SW_INTERFACE_DUMP, mp);
4973   mp->name_filter_valid = 1;
4974   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4975   S (mp);
4976
4977   /* and LISP-GPE interfaces */
4978   M (SW_INTERFACE_DUMP, mp);
4979   mp->name_filter_valid = 1;
4980   strncpy ((char *) mp->name_filter, "lisp_gpe",
4981            sizeof (mp->name_filter) - 1);
4982   S (mp);
4983
4984   /* and IPSEC tunnel interfaces */
4985   M (SW_INTERFACE_DUMP, mp);
4986   mp->name_filter_valid = 1;
4987   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4988   S (mp);
4989
4990   /* Use a control ping for synchronization */
4991   M (CONTROL_PING, mp_ping);
4992   S (mp_ping);
4993
4994   W (ret);
4995   return ret;
4996 }
4997
4998 static int
4999 api_sw_interface_set_flags (vat_main_t * vam)
5000 {
5001   unformat_input_t *i = vam->input;
5002   vl_api_sw_interface_set_flags_t *mp;
5003   u32 sw_if_index;
5004   u8 sw_if_index_set = 0;
5005   u8 admin_up = 0, link_up = 0;
5006   int ret;
5007
5008   /* Parse args required to build the message */
5009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5010     {
5011       if (unformat (i, "admin-up"))
5012         admin_up = 1;
5013       else if (unformat (i, "admin-down"))
5014         admin_up = 0;
5015       else if (unformat (i, "link-up"))
5016         link_up = 1;
5017       else if (unformat (i, "link-down"))
5018         link_up = 0;
5019       else
5020         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5021         sw_if_index_set = 1;
5022       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5023         sw_if_index_set = 1;
5024       else
5025         break;
5026     }
5027
5028   if (sw_if_index_set == 0)
5029     {
5030       errmsg ("missing interface name or sw_if_index");
5031       return -99;
5032     }
5033
5034   /* Construct the API message */
5035   M (SW_INTERFACE_SET_FLAGS, mp);
5036   mp->sw_if_index = ntohl (sw_if_index);
5037   mp->admin_up_down = admin_up;
5038   mp->link_up_down = link_up;
5039
5040   /* send it... */
5041   S (mp);
5042
5043   /* Wait for a reply, return the good/bad news... */
5044   W (ret);
5045   return ret;
5046 }
5047
5048 static int
5049 api_sw_interface_clear_stats (vat_main_t * vam)
5050 {
5051   unformat_input_t *i = vam->input;
5052   vl_api_sw_interface_clear_stats_t *mp;
5053   u32 sw_if_index;
5054   u8 sw_if_index_set = 0;
5055   int ret;
5056
5057   /* Parse args required to build the message */
5058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5059     {
5060       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5061         sw_if_index_set = 1;
5062       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5063         sw_if_index_set = 1;
5064       else
5065         break;
5066     }
5067
5068   /* Construct the API message */
5069   M (SW_INTERFACE_CLEAR_STATS, mp);
5070
5071   if (sw_if_index_set == 1)
5072     mp->sw_if_index = ntohl (sw_if_index);
5073   else
5074     mp->sw_if_index = ~0;
5075
5076   /* send it... */
5077   S (mp);
5078
5079   /* Wait for a reply, return the good/bad news... */
5080   W (ret);
5081   return ret;
5082 }
5083
5084 #if DPDK >0
5085 static int
5086 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
5087 {
5088   unformat_input_t *i = vam->input;
5089   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
5090   u32 sw_if_index;
5091   u8 sw_if_index_set = 0;
5092   u32 subport;
5093   u8 subport_set = 0;
5094   u32 pipe;
5095   u8 pipe_set = 0;
5096   u32 profile;
5097   u8 profile_set = 0;
5098   int ret;
5099
5100   /* Parse args required to build the message */
5101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5102     {
5103       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5104         sw_if_index_set = 1;
5105       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5106         sw_if_index_set = 1;
5107       else if (unformat (i, "subport %u", &subport))
5108         subport_set = 1;
5109       else
5110         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5111         sw_if_index_set = 1;
5112       else if (unformat (i, "pipe %u", &pipe))
5113         pipe_set = 1;
5114       else if (unformat (i, "profile %u", &profile))
5115         profile_set = 1;
5116       else
5117         break;
5118     }
5119
5120   if (sw_if_index_set == 0)
5121     {
5122       errmsg ("missing interface name or sw_if_index");
5123       return -99;
5124     }
5125
5126   if (subport_set == 0)
5127     {
5128       errmsg ("missing subport ");
5129       return -99;
5130     }
5131
5132   if (pipe_set == 0)
5133     {
5134       errmsg ("missing pipe");
5135       return -99;
5136     }
5137
5138   if (profile_set == 0)
5139     {
5140       errmsg ("missing profile");
5141       return -99;
5142     }
5143
5144   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, mp);
5145
5146   mp->sw_if_index = ntohl (sw_if_index);
5147   mp->subport = ntohl (subport);
5148   mp->pipe = ntohl (pipe);
5149   mp->profile = ntohl (profile);
5150
5151
5152   S (mp);
5153   W (ret);
5154   return ret;
5155 }
5156
5157 static int
5158 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5159 {
5160   unformat_input_t *i = vam->input;
5161   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
5162   u32 sw_if_index;
5163   u8 sw_if_index_set = 0;
5164   u32 subport;
5165   u8 subport_set = 0;
5166   u32 tb_rate = 1250000000;     /* 10GbE */
5167   u32 tb_size = 1000000;
5168   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5169   u32 tc_period = 10;
5170   int ret;
5171
5172   /* Parse args required to build the message */
5173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5174     {
5175       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5176         sw_if_index_set = 1;
5177       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5178         sw_if_index_set = 1;
5179       else if (unformat (i, "subport %u", &subport))
5180         subport_set = 1;
5181       else
5182         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5183         sw_if_index_set = 1;
5184       else if (unformat (i, "rate %u", &tb_rate))
5185         {
5186           u32 tc_id;
5187
5188           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5189                tc_id++)
5190             tc_rate[tc_id] = tb_rate;
5191         }
5192       else if (unformat (i, "bktsize %u", &tb_size))
5193         ;
5194       else if (unformat (i, "tc0 %u", &tc_rate[0]))
5195         ;
5196       else if (unformat (i, "tc1 %u", &tc_rate[1]))
5197         ;
5198       else if (unformat (i, "tc2 %u", &tc_rate[2]))
5199         ;
5200       else if (unformat (i, "tc3 %u", &tc_rate[3]))
5201         ;
5202       else if (unformat (i, "period %u", &tc_period))
5203         ;
5204       else
5205         break;
5206     }
5207
5208   if (sw_if_index_set == 0)
5209     {
5210       errmsg ("missing interface name or sw_if_index");
5211       return -99;
5212     }
5213
5214   if (subport_set == 0)
5215     {
5216       errmsg ("missing subport ");
5217       return -99;
5218     }
5219
5220   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, mp);
5221
5222   mp->sw_if_index = ntohl (sw_if_index);
5223   mp->subport = ntohl (subport);
5224   mp->tb_rate = ntohl (tb_rate);
5225   mp->tb_size = ntohl (tb_size);
5226   mp->tc_rate[0] = ntohl (tc_rate[0]);
5227   mp->tc_rate[1] = ntohl (tc_rate[1]);
5228   mp->tc_rate[2] = ntohl (tc_rate[2]);
5229   mp->tc_rate[3] = ntohl (tc_rate[3]);
5230   mp->tc_period = ntohl (tc_period);
5231
5232   S (mp);
5233   W (ret);
5234   return ret;
5235 }
5236
5237 static int
5238 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5239 {
5240   unformat_input_t *i = vam->input;
5241   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
5242   u32 sw_if_index;
5243   u8 sw_if_index_set = 0;
5244   u8 entry_set = 0;
5245   u8 tc_set = 0;
5246   u8 queue_set = 0;
5247   u32 entry, tc, queue;
5248   int ret;
5249
5250   /* Parse args required to build the message */
5251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5252     {
5253       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5254         sw_if_index_set = 1;
5255       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5256         sw_if_index_set = 1;
5257       else if (unformat (i, "entry %d", &entry))
5258         entry_set = 1;
5259       else if (unformat (i, "tc %d", &tc))
5260         tc_set = 1;
5261       else if (unformat (i, "queue %d", &queue))
5262         queue_set = 1;
5263       else
5264         break;
5265     }
5266
5267   if (sw_if_index_set == 0)
5268     {
5269       errmsg ("missing interface name or sw_if_index");
5270       return -99;
5271     }
5272
5273   if (entry_set == 0)
5274     {
5275       errmsg ("missing entry ");
5276       return -99;
5277     }
5278
5279   if (tc_set == 0)
5280     {
5281       errmsg ("missing traffic class ");
5282       return -99;
5283     }
5284
5285   if (queue_set == 0)
5286     {
5287       errmsg ("missing queue ");
5288       return -99;
5289     }
5290
5291   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, mp);
5292
5293   mp->sw_if_index = ntohl (sw_if_index);
5294   mp->entry = ntohl (entry);
5295   mp->tc = ntohl (tc);
5296   mp->queue = ntohl (queue);
5297
5298   S (mp);
5299   W (ret);
5300   return ret;
5301 }
5302 #endif
5303
5304 static int
5305 api_sw_interface_add_del_address (vat_main_t * vam)
5306 {
5307   unformat_input_t *i = vam->input;
5308   vl_api_sw_interface_add_del_address_t *mp;
5309   u32 sw_if_index;
5310   u8 sw_if_index_set = 0;
5311   u8 is_add = 1, del_all = 0;
5312   u32 address_length = 0;
5313   u8 v4_address_set = 0;
5314   u8 v6_address_set = 0;
5315   ip4_address_t v4address;
5316   ip6_address_t v6address;
5317   int ret;
5318
5319   /* Parse args required to build the message */
5320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5321     {
5322       if (unformat (i, "del-all"))
5323         del_all = 1;
5324       else if (unformat (i, "del"))
5325         is_add = 0;
5326       else
5327         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5328         sw_if_index_set = 1;
5329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5330         sw_if_index_set = 1;
5331       else if (unformat (i, "%U/%d",
5332                          unformat_ip4_address, &v4address, &address_length))
5333         v4_address_set = 1;
5334       else if (unformat (i, "%U/%d",
5335                          unformat_ip6_address, &v6address, &address_length))
5336         v6_address_set = 1;
5337       else
5338         break;
5339     }
5340
5341   if (sw_if_index_set == 0)
5342     {
5343       errmsg ("missing interface name or sw_if_index");
5344       return -99;
5345     }
5346   if (v4_address_set && v6_address_set)
5347     {
5348       errmsg ("both v4 and v6 addresses set");
5349       return -99;
5350     }
5351   if (!v4_address_set && !v6_address_set && !del_all)
5352     {
5353       errmsg ("no addresses set");
5354       return -99;
5355     }
5356
5357   /* Construct the API message */
5358   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5359
5360   mp->sw_if_index = ntohl (sw_if_index);
5361   mp->is_add = is_add;
5362   mp->del_all = del_all;
5363   if (v6_address_set)
5364     {
5365       mp->is_ipv6 = 1;
5366       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5367     }
5368   else
5369     {
5370       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5371     }
5372   mp->address_length = address_length;
5373
5374   /* send it... */
5375   S (mp);
5376
5377   /* Wait for a reply, return good/bad news  */
5378   W (ret);
5379   return ret;
5380 }
5381
5382 static int
5383 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5384 {
5385   unformat_input_t *i = vam->input;
5386   vl_api_sw_interface_set_mpls_enable_t *mp;
5387   u32 sw_if_index;
5388   u8 sw_if_index_set = 0;
5389   u8 enable = 1;
5390   int ret;
5391
5392   /* Parse args required to build the message */
5393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5394     {
5395       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5396         sw_if_index_set = 1;
5397       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5398         sw_if_index_set = 1;
5399       else if (unformat (i, "disable"))
5400         enable = 0;
5401       else if (unformat (i, "dis"))
5402         enable = 0;
5403       else
5404         break;
5405     }
5406
5407   if (sw_if_index_set == 0)
5408     {
5409       errmsg ("missing interface name or sw_if_index");
5410       return -99;
5411     }
5412
5413   /* Construct the API message */
5414   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5415
5416   mp->sw_if_index = ntohl (sw_if_index);
5417   mp->enable = enable;
5418
5419   /* send it... */
5420   S (mp);
5421
5422   /* Wait for a reply... */
5423   W (ret);
5424   return ret;
5425 }
5426
5427 static int
5428 api_sw_interface_set_table (vat_main_t * vam)
5429 {
5430   unformat_input_t *i = vam->input;
5431   vl_api_sw_interface_set_table_t *mp;
5432   u32 sw_if_index, vrf_id = 0;
5433   u8 sw_if_index_set = 0;
5434   u8 is_ipv6 = 0;
5435   int ret;
5436
5437   /* Parse args required to build the message */
5438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5439     {
5440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5441         sw_if_index_set = 1;
5442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5443         sw_if_index_set = 1;
5444       else if (unformat (i, "vrf %d", &vrf_id))
5445         ;
5446       else if (unformat (i, "ipv6"))
5447         is_ipv6 = 1;
5448       else
5449         break;
5450     }
5451
5452   if (sw_if_index_set == 0)
5453     {
5454       errmsg ("missing interface name or sw_if_index");
5455       return -99;
5456     }
5457
5458   /* Construct the API message */
5459   M (SW_INTERFACE_SET_TABLE, mp);
5460
5461   mp->sw_if_index = ntohl (sw_if_index);
5462   mp->is_ipv6 = is_ipv6;
5463   mp->vrf_id = ntohl (vrf_id);
5464
5465   /* send it... */
5466   S (mp);
5467
5468   /* Wait for a reply... */
5469   W (ret);
5470   return ret;
5471 }
5472
5473 static void vl_api_sw_interface_get_table_reply_t_handler
5474   (vl_api_sw_interface_get_table_reply_t * mp)
5475 {
5476   vat_main_t *vam = &vat_main;
5477
5478   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5479
5480   vam->retval = ntohl (mp->retval);
5481   vam->result_ready = 1;
5482
5483 }
5484
5485 static void vl_api_sw_interface_get_table_reply_t_handler_json
5486   (vl_api_sw_interface_get_table_reply_t * mp)
5487 {
5488   vat_main_t *vam = &vat_main;
5489   vat_json_node_t node;
5490
5491   vat_json_init_object (&node);
5492   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5493   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5494
5495   vat_json_print (vam->ofp, &node);
5496   vat_json_free (&node);
5497
5498   vam->retval = ntohl (mp->retval);
5499   vam->result_ready = 1;
5500 }
5501
5502 static int
5503 api_sw_interface_get_table (vat_main_t * vam)
5504 {
5505   unformat_input_t *i = vam->input;
5506   vl_api_sw_interface_get_table_t *mp;
5507   u32 sw_if_index;
5508   u8 sw_if_index_set = 0;
5509   u8 is_ipv6 = 0;
5510   int ret;
5511
5512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5513     {
5514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5515         sw_if_index_set = 1;
5516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5517         sw_if_index_set = 1;
5518       else if (unformat (i, "ipv6"))
5519         is_ipv6 = 1;
5520       else
5521         break;
5522     }
5523
5524   if (sw_if_index_set == 0)
5525     {
5526       errmsg ("missing interface name or sw_if_index");
5527       return -99;
5528     }
5529
5530   M (SW_INTERFACE_GET_TABLE, mp);
5531   mp->sw_if_index = htonl (sw_if_index);
5532   mp->is_ipv6 = is_ipv6;
5533
5534   S (mp);
5535   W (ret);
5536   return ret;
5537 }
5538
5539 static int
5540 api_sw_interface_set_vpath (vat_main_t * vam)
5541 {
5542   unformat_input_t *i = vam->input;
5543   vl_api_sw_interface_set_vpath_t *mp;
5544   u32 sw_if_index = 0;
5545   u8 sw_if_index_set = 0;
5546   u8 is_enable = 0;
5547   int ret;
5548
5549   /* Parse args required to build the message */
5550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5551     {
5552       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5553         sw_if_index_set = 1;
5554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5555         sw_if_index_set = 1;
5556       else if (unformat (i, "enable"))
5557         is_enable = 1;
5558       else if (unformat (i, "disable"))
5559         is_enable = 0;
5560       else
5561         break;
5562     }
5563
5564   if (sw_if_index_set == 0)
5565     {
5566       errmsg ("missing interface name or sw_if_index");
5567       return -99;
5568     }
5569
5570   /* Construct the API message */
5571   M (SW_INTERFACE_SET_VPATH, mp);
5572
5573   mp->sw_if_index = ntohl (sw_if_index);
5574   mp->enable = is_enable;
5575
5576   /* send it... */
5577   S (mp);
5578
5579   /* Wait for a reply... */
5580   W (ret);
5581   return ret;
5582 }
5583
5584 static int
5585 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5586 {
5587   unformat_input_t *i = vam->input;
5588   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5589   u32 sw_if_index = 0;
5590   u8 sw_if_index_set = 0;
5591   u8 is_enable = 1;
5592   u8 is_ipv6 = 0;
5593   int ret;
5594
5595   /* Parse args required to build the message */
5596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5597     {
5598       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5599         sw_if_index_set = 1;
5600       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5601         sw_if_index_set = 1;
5602       else if (unformat (i, "enable"))
5603         is_enable = 1;
5604       else if (unformat (i, "disable"))
5605         is_enable = 0;
5606       else if (unformat (i, "ip4"))
5607         is_ipv6 = 0;
5608       else if (unformat (i, "ip6"))
5609         is_ipv6 = 1;
5610       else
5611         break;
5612     }
5613
5614   if (sw_if_index_set == 0)
5615     {
5616       errmsg ("missing interface name or sw_if_index");
5617       return -99;
5618     }
5619
5620   /* Construct the API message */
5621   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5622
5623   mp->sw_if_index = ntohl (sw_if_index);
5624   mp->enable = is_enable;
5625   mp->is_ipv6 = is_ipv6;
5626
5627   /* send it... */
5628   S (mp);
5629
5630   /* Wait for a reply... */
5631   W (ret);
5632   return ret;
5633 }
5634
5635 static int
5636 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5637 {
5638   unformat_input_t *i = vam->input;
5639   vl_api_sw_interface_set_l2_xconnect_t *mp;
5640   u32 rx_sw_if_index;
5641   u8 rx_sw_if_index_set = 0;
5642   u32 tx_sw_if_index;
5643   u8 tx_sw_if_index_set = 0;
5644   u8 enable = 1;
5645   int ret;
5646
5647   /* Parse args required to build the message */
5648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5649     {
5650       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5651         rx_sw_if_index_set = 1;
5652       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5653         tx_sw_if_index_set = 1;
5654       else if (unformat (i, "rx"))
5655         {
5656           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5657             {
5658               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5659                             &rx_sw_if_index))
5660                 rx_sw_if_index_set = 1;
5661             }
5662           else
5663             break;
5664         }
5665       else if (unformat (i, "tx"))
5666         {
5667           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5668             {
5669               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5670                             &tx_sw_if_index))
5671                 tx_sw_if_index_set = 1;
5672             }
5673           else
5674             break;
5675         }
5676       else if (unformat (i, "enable"))
5677         enable = 1;
5678       else if (unformat (i, "disable"))
5679         enable = 0;
5680       else
5681         break;
5682     }
5683
5684   if (rx_sw_if_index_set == 0)
5685     {
5686       errmsg ("missing rx interface name or rx_sw_if_index");
5687       return -99;
5688     }
5689
5690   if (enable && (tx_sw_if_index_set == 0))
5691     {
5692       errmsg ("missing tx interface name or tx_sw_if_index");
5693       return -99;
5694     }
5695
5696   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5697
5698   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5699   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5700   mp->enable = enable;
5701
5702   S (mp);
5703   W (ret);
5704   return ret;
5705 }
5706
5707 static int
5708 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5709 {
5710   unformat_input_t *i = vam->input;
5711   vl_api_sw_interface_set_l2_bridge_t *mp;
5712   u32 rx_sw_if_index;
5713   u8 rx_sw_if_index_set = 0;
5714   u32 bd_id;
5715   u8 bd_id_set = 0;
5716   u8 bvi = 0;
5717   u32 shg = 0;
5718   u8 enable = 1;
5719   int ret;
5720
5721   /* Parse args required to build the message */
5722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723     {
5724       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5725         rx_sw_if_index_set = 1;
5726       else if (unformat (i, "bd_id %d", &bd_id))
5727         bd_id_set = 1;
5728       else
5729         if (unformat
5730             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5731         rx_sw_if_index_set = 1;
5732       else if (unformat (i, "shg %d", &shg))
5733         ;
5734       else if (unformat (i, "bvi"))
5735         bvi = 1;
5736       else if (unformat (i, "enable"))
5737         enable = 1;
5738       else if (unformat (i, "disable"))
5739         enable = 0;
5740       else
5741         break;
5742     }
5743
5744   if (rx_sw_if_index_set == 0)
5745     {
5746       errmsg ("missing rx interface name or sw_if_index");
5747       return -99;
5748     }
5749
5750   if (enable && (bd_id_set == 0))
5751     {
5752       errmsg ("missing bridge domain");
5753       return -99;
5754     }
5755
5756   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5757
5758   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5759   mp->bd_id = ntohl (bd_id);
5760   mp->shg = (u8) shg;
5761   mp->bvi = bvi;
5762   mp->enable = enable;
5763
5764   S (mp);
5765   W (ret);
5766   return ret;
5767 }
5768
5769 static int
5770 api_bridge_domain_dump (vat_main_t * vam)
5771 {
5772   unformat_input_t *i = vam->input;
5773   vl_api_bridge_domain_dump_t *mp;
5774   vl_api_control_ping_t *mp_ping;
5775   u32 bd_id = ~0;
5776   int ret;
5777
5778   /* Parse args required to build the message */
5779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780     {
5781       if (unformat (i, "bd_id %d", &bd_id))
5782         ;
5783       else
5784         break;
5785     }
5786
5787   M (BRIDGE_DOMAIN_DUMP, mp);
5788   mp->bd_id = ntohl (bd_id);
5789   S (mp);
5790
5791   /* Use a control ping for synchronization */
5792   M (CONTROL_PING, mp_ping);
5793   S (mp_ping);
5794
5795   W (ret);
5796   return ret;
5797 }
5798
5799 static int
5800 api_bridge_domain_add_del (vat_main_t * vam)
5801 {
5802   unformat_input_t *i = vam->input;
5803   vl_api_bridge_domain_add_del_t *mp;
5804   u32 bd_id = ~0;
5805   u8 is_add = 1;
5806   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5807   u32 mac_age = 0;
5808   int ret;
5809
5810   /* Parse args required to build the message */
5811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5812     {
5813       if (unformat (i, "bd_id %d", &bd_id))
5814         ;
5815       else if (unformat (i, "flood %d", &flood))
5816         ;
5817       else if (unformat (i, "uu-flood %d", &uu_flood))
5818         ;
5819       else if (unformat (i, "forward %d", &forward))
5820         ;
5821       else if (unformat (i, "learn %d", &learn))
5822         ;
5823       else if (unformat (i, "arp-term %d", &arp_term))
5824         ;
5825       else if (unformat (i, "mac-age %d", &mac_age))
5826         ;
5827       else if (unformat (i, "del"))
5828         {
5829           is_add = 0;
5830           flood = uu_flood = forward = learn = 0;
5831         }
5832       else
5833         break;
5834     }
5835
5836   if (bd_id == ~0)
5837     {
5838       errmsg ("missing bridge domain");
5839       return -99;
5840     }
5841
5842   if (mac_age > 255)
5843     {
5844       errmsg ("mac age must be less than 256 ");
5845       return -99;
5846     }
5847
5848   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5849
5850   mp->bd_id = ntohl (bd_id);
5851   mp->flood = flood;
5852   mp->uu_flood = uu_flood;
5853   mp->forward = forward;
5854   mp->learn = learn;
5855   mp->arp_term = arp_term;
5856   mp->is_add = is_add;
5857   mp->mac_age = (u8) mac_age;
5858
5859   S (mp);
5860   W (ret);
5861   return ret;
5862 }
5863
5864 static int
5865 api_l2fib_add_del (vat_main_t * vam)
5866 {
5867   unformat_input_t *i = vam->input;
5868   vl_api_l2fib_add_del_t *mp;
5869   f64 timeout;
5870   u64 mac = 0;
5871   u8 mac_set = 0;
5872   u32 bd_id;
5873   u8 bd_id_set = 0;
5874   u32 sw_if_index = ~0;
5875   u8 sw_if_index_set = 0;
5876   u8 is_add = 1;
5877   u8 static_mac = 0;
5878   u8 filter_mac = 0;
5879   u8 bvi_mac = 0;
5880   int count = 1;
5881   f64 before = 0;
5882   int j;
5883
5884   /* Parse args required to build the message */
5885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5886     {
5887       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5888         mac_set = 1;
5889       else if (unformat (i, "bd_id %d", &bd_id))
5890         bd_id_set = 1;
5891       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5892         sw_if_index_set = 1;
5893       else if (unformat (i, "sw_if"))
5894         {
5895           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5896             {
5897               if (unformat
5898                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5899                 sw_if_index_set = 1;
5900             }
5901           else
5902             break;
5903         }
5904       else if (unformat (i, "static"))
5905         static_mac = 1;
5906       else if (unformat (i, "filter"))
5907         {
5908           filter_mac = 1;
5909           static_mac = 1;
5910         }
5911       else if (unformat (i, "bvi"))
5912         {
5913           bvi_mac = 1;
5914           static_mac = 1;
5915         }
5916       else if (unformat (i, "del"))
5917         is_add = 0;
5918       else if (unformat (i, "count %d", &count))
5919         ;
5920       else
5921         break;
5922     }
5923
5924   if (mac_set == 0)
5925     {
5926       errmsg ("missing mac address");
5927       return -99;
5928     }
5929
5930   if (bd_id_set == 0)
5931     {
5932       errmsg ("missing bridge domain");
5933       return -99;
5934     }
5935
5936   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5937     {
5938       errmsg ("missing interface name or sw_if_index");
5939       return -99;
5940     }
5941
5942   if (count > 1)
5943     {
5944       /* Turn on async mode */
5945       vam->async_mode = 1;
5946       vam->async_errors = 0;
5947       before = vat_time_now (vam);
5948     }
5949
5950   for (j = 0; j < count; j++)
5951     {
5952       M (L2FIB_ADD_DEL, mp);
5953
5954       mp->mac = mac;
5955       mp->bd_id = ntohl (bd_id);
5956       mp->is_add = is_add;
5957
5958       if (is_add)
5959         {
5960           mp->sw_if_index = ntohl (sw_if_index);
5961           mp->static_mac = static_mac;
5962           mp->filter_mac = filter_mac;
5963           mp->bvi_mac = bvi_mac;
5964         }
5965       increment_mac_address (&mac);
5966       /* send it... */
5967       S (mp);
5968     }
5969
5970   if (count > 1)
5971     {
5972       vl_api_control_ping_t *mp_ping;
5973       f64 after;
5974
5975       /* Shut off async mode */
5976       vam->async_mode = 0;
5977
5978       M (CONTROL_PING, mp_ping);
5979       S (mp_ping);
5980
5981       timeout = vat_time_now (vam) + 1.0;
5982       while (vat_time_now (vam) < timeout)
5983         if (vam->result_ready == 1)
5984           goto out;
5985       vam->retval = -99;
5986
5987     out:
5988       if (vam->retval == -99)
5989         errmsg ("timeout");
5990
5991       if (vam->async_errors > 0)
5992         {
5993           errmsg ("%d asynchronous errors", vam->async_errors);
5994           vam->retval = -98;
5995         }
5996       vam->async_errors = 0;
5997       after = vat_time_now (vam);
5998
5999       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6000              count, after - before, count / (after - before));
6001     }
6002   else
6003     {
6004       int ret;
6005
6006       /* Wait for a reply... */
6007       W (ret);
6008       return ret;
6009     }
6010   /* Return the good/bad news */
6011   return (vam->retval);
6012 }
6013
6014 static int
6015 api_l2_flags (vat_main_t * vam)
6016 {
6017   unformat_input_t *i = vam->input;
6018   vl_api_l2_flags_t *mp;
6019   u32 sw_if_index;
6020   u32 feature_bitmap = 0;
6021   u8 sw_if_index_set = 0;
6022   int ret;
6023
6024   /* Parse args required to build the message */
6025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6026     {
6027       if (unformat (i, "sw_if_index %d", &sw_if_index))
6028         sw_if_index_set = 1;
6029       else if (unformat (i, "sw_if"))
6030         {
6031           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6032             {
6033               if (unformat
6034                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6035                 sw_if_index_set = 1;
6036             }
6037           else
6038             break;
6039         }
6040       else if (unformat (i, "learn"))
6041         feature_bitmap |= L2INPUT_FEAT_LEARN;
6042       else if (unformat (i, "forward"))
6043         feature_bitmap |= L2INPUT_FEAT_FWD;
6044       else if (unformat (i, "flood"))
6045         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6046       else if (unformat (i, "uu-flood"))
6047         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6048       else
6049         break;
6050     }
6051
6052   if (sw_if_index_set == 0)
6053     {
6054       errmsg ("missing interface name or sw_if_index");
6055       return -99;
6056     }
6057
6058   M (L2_FLAGS, mp);
6059
6060   mp->sw_if_index = ntohl (sw_if_index);
6061   mp->feature_bitmap = ntohl (feature_bitmap);
6062
6063   S (mp);
6064   W (ret);
6065   return ret;
6066 }
6067
6068 static int
6069 api_bridge_flags (vat_main_t * vam)
6070 {
6071   unformat_input_t *i = vam->input;
6072   vl_api_bridge_flags_t *mp;
6073   u32 bd_id;
6074   u8 bd_id_set = 0;
6075   u8 is_set = 1;
6076   u32 flags = 0;
6077   int ret;
6078
6079   /* Parse args required to build the message */
6080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6081     {
6082       if (unformat (i, "bd_id %d", &bd_id))
6083         bd_id_set = 1;
6084       else if (unformat (i, "learn"))
6085         flags |= L2_LEARN;
6086       else if (unformat (i, "forward"))
6087         flags |= L2_FWD;
6088       else if (unformat (i, "flood"))
6089         flags |= L2_FLOOD;
6090       else if (unformat (i, "uu-flood"))
6091         flags |= L2_UU_FLOOD;
6092       else if (unformat (i, "arp-term"))
6093         flags |= L2_ARP_TERM;
6094       else if (unformat (i, "off"))
6095         is_set = 0;
6096       else if (unformat (i, "disable"))
6097         is_set = 0;
6098       else
6099         break;
6100     }
6101
6102   if (bd_id_set == 0)
6103     {
6104       errmsg ("missing bridge domain");
6105       return -99;
6106     }
6107
6108   M (BRIDGE_FLAGS, mp);
6109
6110   mp->bd_id = ntohl (bd_id);
6111   mp->feature_bitmap = ntohl (flags);
6112   mp->is_set = is_set;
6113
6114   S (mp);
6115   W (ret);
6116   return ret;
6117 }
6118
6119 static int
6120 api_bd_ip_mac_add_del (vat_main_t * vam)
6121 {
6122   unformat_input_t *i = vam->input;
6123   vl_api_bd_ip_mac_add_del_t *mp;
6124   u32 bd_id;
6125   u8 is_ipv6 = 0;
6126   u8 is_add = 1;
6127   u8 bd_id_set = 0;
6128   u8 ip_set = 0;
6129   u8 mac_set = 0;
6130   ip4_address_t v4addr;
6131   ip6_address_t v6addr;
6132   u8 macaddr[6];
6133   int ret;
6134
6135
6136   /* Parse args required to build the message */
6137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6138     {
6139       if (unformat (i, "bd_id %d", &bd_id))
6140         {
6141           bd_id_set++;
6142         }
6143       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6144         {
6145           ip_set++;
6146         }
6147       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6148         {
6149           ip_set++;
6150           is_ipv6++;
6151         }
6152       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6153         {
6154           mac_set++;
6155         }
6156       else if (unformat (i, "del"))
6157         is_add = 0;
6158       else
6159         break;
6160     }
6161
6162   if (bd_id_set == 0)
6163     {
6164       errmsg ("missing bridge domain");
6165       return -99;
6166     }
6167   else if (ip_set == 0)
6168     {
6169       errmsg ("missing IP address");
6170       return -99;
6171     }
6172   else if (mac_set == 0)
6173     {
6174       errmsg ("missing MAC address");
6175       return -99;
6176     }
6177
6178   M (BD_IP_MAC_ADD_DEL, mp);
6179
6180   mp->bd_id = ntohl (bd_id);
6181   mp->is_ipv6 = is_ipv6;
6182   mp->is_add = is_add;
6183   if (is_ipv6)
6184     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6185   else
6186     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6187   clib_memcpy (mp->mac_address, macaddr, 6);
6188   S (mp);
6189   W (ret);
6190   return ret;
6191 }
6192
6193 static int
6194 api_tap_connect (vat_main_t * vam)
6195 {
6196   unformat_input_t *i = vam->input;
6197   vl_api_tap_connect_t *mp;
6198   u8 mac_address[6];
6199   u8 random_mac = 1;
6200   u8 name_set = 0;
6201   u8 *tap_name;
6202   u8 *tag = 0;
6203   ip4_address_t ip4_address;
6204   u32 ip4_mask_width;
6205   int ip4_address_set = 0;
6206   ip6_address_t ip6_address;
6207   u32 ip6_mask_width;
6208   int ip6_address_set = 0;
6209   int ret;
6210
6211   memset (mac_address, 0, sizeof (mac_address));
6212
6213   /* Parse args required to build the message */
6214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6215     {
6216       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6217         {
6218           random_mac = 0;
6219         }
6220       else if (unformat (i, "random-mac"))
6221         random_mac = 1;
6222       else if (unformat (i, "tapname %s", &tap_name))
6223         name_set = 1;
6224       else if (unformat (i, "tag %s", &tag))
6225         ;
6226       else if (unformat (i, "address %U/%d",
6227                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6228         ip4_address_set = 1;
6229       else if (unformat (i, "address %U/%d",
6230                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6231         ip6_address_set = 1;
6232       else
6233         break;
6234     }
6235
6236   if (name_set == 0)
6237     {
6238       errmsg ("missing tap name");
6239       return -99;
6240     }
6241   if (vec_len (tap_name) > 63)
6242     {
6243       errmsg ("tap name too long");
6244       return -99;
6245     }
6246   vec_add1 (tap_name, 0);
6247
6248   if (vec_len (tag) > 63)
6249     {
6250       errmsg ("tag too long");
6251       return -99;
6252     }
6253
6254   /* Construct the API message */
6255   M (TAP_CONNECT, mp);
6256
6257   mp->use_random_mac = random_mac;
6258   clib_memcpy (mp->mac_address, mac_address, 6);
6259   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6260   if (tag)
6261     clib_memcpy (mp->tag, tag, vec_len (tag));
6262
6263   if (ip4_address_set)
6264     {
6265       mp->ip4_address_set = 1;
6266       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6267       mp->ip4_mask_width = ip4_mask_width;
6268     }
6269   if (ip6_address_set)
6270     {
6271       mp->ip6_address_set = 1;
6272       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6273       mp->ip6_mask_width = ip6_mask_width;
6274     }
6275
6276   vec_free (tap_name);
6277   vec_free (tag);
6278
6279   /* send it... */
6280   S (mp);
6281
6282   /* Wait for a reply... */
6283   W (ret);
6284   return ret;
6285 }
6286
6287 static int
6288 api_tap_modify (vat_main_t * vam)
6289 {
6290   unformat_input_t *i = vam->input;
6291   vl_api_tap_modify_t *mp;
6292   u8 mac_address[6];
6293   u8 random_mac = 1;
6294   u8 name_set = 0;
6295   u8 *tap_name;
6296   u32 sw_if_index = ~0;
6297   u8 sw_if_index_set = 0;
6298   int ret;
6299
6300   memset (mac_address, 0, sizeof (mac_address));
6301
6302   /* Parse args required to build the message */
6303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6304     {
6305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6306         sw_if_index_set = 1;
6307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6308         sw_if_index_set = 1;
6309       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6310         {
6311           random_mac = 0;
6312         }
6313       else if (unformat (i, "random-mac"))
6314         random_mac = 1;
6315       else if (unformat (i, "tapname %s", &tap_name))
6316         name_set = 1;
6317       else
6318         break;
6319     }
6320
6321   if (sw_if_index_set == 0)
6322     {
6323       errmsg ("missing vpp interface name");
6324       return -99;
6325     }
6326   if (name_set == 0)
6327     {
6328       errmsg ("missing tap name");
6329       return -99;
6330     }
6331   if (vec_len (tap_name) > 63)
6332     {
6333       errmsg ("tap name too long");
6334     }
6335   vec_add1 (tap_name, 0);
6336
6337   /* Construct the API message */
6338   M (TAP_MODIFY, mp);
6339
6340   mp->use_random_mac = random_mac;
6341   mp->sw_if_index = ntohl (sw_if_index);
6342   clib_memcpy (mp->mac_address, mac_address, 6);
6343   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6344   vec_free (tap_name);
6345
6346   /* send it... */
6347   S (mp);
6348
6349   /* Wait for a reply... */
6350   W (ret);
6351   return ret;
6352 }
6353
6354 static int
6355 api_tap_delete (vat_main_t * vam)
6356 {
6357   unformat_input_t *i = vam->input;
6358   vl_api_tap_delete_t *mp;
6359   u32 sw_if_index = ~0;
6360   u8 sw_if_index_set = 0;
6361   int ret;
6362
6363   /* Parse args required to build the message */
6364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6365     {
6366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6367         sw_if_index_set = 1;
6368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6369         sw_if_index_set = 1;
6370       else
6371         break;
6372     }
6373
6374   if (sw_if_index_set == 0)
6375     {
6376       errmsg ("missing vpp interface name");
6377       return -99;
6378     }
6379
6380   /* Construct the API message */
6381   M (TAP_DELETE, mp);
6382
6383   mp->sw_if_index = ntohl (sw_if_index);
6384
6385   /* send it... */
6386   S (mp);
6387
6388   /* Wait for a reply... */
6389   W (ret);
6390   return ret;
6391 }
6392
6393 static int
6394 api_ip_add_del_route (vat_main_t * vam)
6395 {
6396   unformat_input_t *i = vam->input;
6397   vl_api_ip_add_del_route_t *mp;
6398   u32 sw_if_index = ~0, vrf_id = 0;
6399   u8 is_ipv6 = 0;
6400   u8 is_local = 0, is_drop = 0;
6401   u8 is_unreach = 0, is_prohibit = 0;
6402   u8 create_vrf_if_needed = 0;
6403   u8 is_add = 1;
6404   u32 next_hop_weight = 1;
6405   u8 not_last = 0;
6406   u8 is_multipath = 0;
6407   u8 address_set = 0;
6408   u8 address_length_set = 0;
6409   u32 next_hop_table_id = 0;
6410   u32 resolve_attempts = 0;
6411   u32 dst_address_length = 0;
6412   u8 next_hop_set = 0;
6413   ip4_address_t v4_dst_address, v4_next_hop_address;
6414   ip6_address_t v6_dst_address, v6_next_hop_address;
6415   int count = 1;
6416   int j;
6417   f64 before = 0;
6418   u32 random_add_del = 0;
6419   u32 *random_vector = 0;
6420   uword *random_hash;
6421   u32 random_seed = 0xdeaddabe;
6422   u32 classify_table_index = ~0;
6423   u8 is_classify = 0;
6424   u8 resolve_host = 0, resolve_attached = 0;
6425   mpls_label_t *next_hop_out_label_stack = NULL;
6426   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6427   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6428
6429   /* Parse args required to build the message */
6430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6431     {
6432       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6433         ;
6434       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6435         ;
6436       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6437         {
6438           address_set = 1;
6439           is_ipv6 = 0;
6440         }
6441       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6442         {
6443           address_set = 1;
6444           is_ipv6 = 1;
6445         }
6446       else if (unformat (i, "/%d", &dst_address_length))
6447         {
6448           address_length_set = 1;
6449         }
6450
6451       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6452                                          &v4_next_hop_address))
6453         {
6454           next_hop_set = 1;
6455         }
6456       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6457                                          &v6_next_hop_address))
6458         {
6459           next_hop_set = 1;
6460         }
6461       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6462         ;
6463       else if (unformat (i, "weight %d", &next_hop_weight))
6464         ;
6465       else if (unformat (i, "drop"))
6466         {
6467           is_drop = 1;
6468         }
6469       else if (unformat (i, "null-send-unreach"))
6470         {
6471           is_unreach = 1;
6472         }
6473       else if (unformat (i, "null-send-prohibit"))
6474         {
6475           is_prohibit = 1;
6476         }
6477       else if (unformat (i, "local"))
6478         {
6479           is_local = 1;
6480         }
6481       else if (unformat (i, "classify %d", &classify_table_index))
6482         {
6483           is_classify = 1;
6484         }
6485       else if (unformat (i, "del"))
6486         is_add = 0;
6487       else if (unformat (i, "add"))
6488         is_add = 1;
6489       else if (unformat (i, "not-last"))
6490         not_last = 1;
6491       else if (unformat (i, "resolve-via-host"))
6492         resolve_host = 1;
6493       else if (unformat (i, "resolve-via-attached"))
6494         resolve_attached = 1;
6495       else if (unformat (i, "multipath"))
6496         is_multipath = 1;
6497       else if (unformat (i, "vrf %d", &vrf_id))
6498         ;
6499       else if (unformat (i, "create-vrf"))
6500         create_vrf_if_needed = 1;
6501       else if (unformat (i, "count %d", &count))
6502         ;
6503       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6504         ;
6505       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6506         ;
6507       else if (unformat (i, "out-label %d", &next_hop_out_label))
6508         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6509       else if (unformat (i, "via-label %d", &next_hop_via_label))
6510         ;
6511       else if (unformat (i, "random"))
6512         random_add_del = 1;
6513       else if (unformat (i, "seed %d", &random_seed))
6514         ;
6515       else
6516         {
6517           clib_warning ("parse error '%U'", format_unformat_error, i);
6518           return -99;
6519         }
6520     }
6521
6522   if (!next_hop_set && !is_drop && !is_local &&
6523       !is_classify && !is_unreach && !is_prohibit &&
6524       MPLS_LABEL_INVALID == next_hop_via_label)
6525     {
6526       errmsg
6527         ("next hop / local / drop / unreach / prohibit / classify not set");
6528       return -99;
6529     }
6530
6531   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6532     {
6533       errmsg ("next hop and next-hop via label set");
6534       return -99;
6535     }
6536   if (address_set == 0)
6537     {
6538       errmsg ("missing addresses");
6539       return -99;
6540     }
6541
6542   if (address_length_set == 0)
6543     {
6544       errmsg ("missing address length");
6545       return -99;
6546     }
6547
6548   /* Generate a pile of unique, random routes */
6549   if (random_add_del)
6550     {
6551       u32 this_random_address;
6552       random_hash = hash_create (count, sizeof (uword));
6553
6554       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6555       for (j = 0; j <= count; j++)
6556         {
6557           do
6558             {
6559               this_random_address = random_u32 (&random_seed);
6560               this_random_address =
6561                 clib_host_to_net_u32 (this_random_address);
6562             }
6563           while (hash_get (random_hash, this_random_address));
6564           vec_add1 (random_vector, this_random_address);
6565           hash_set (random_hash, this_random_address, 1);
6566         }
6567       hash_free (random_hash);
6568       v4_dst_address.as_u32 = random_vector[0];
6569     }
6570
6571   if (count > 1)
6572     {
6573       /* Turn on async mode */
6574       vam->async_mode = 1;
6575       vam->async_errors = 0;
6576       before = vat_time_now (vam);
6577     }
6578
6579   for (j = 0; j < count; j++)
6580     {
6581       /* Construct the API message */
6582       M2 (IP_ADD_DEL_ROUTE, mp,
6583           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6584
6585       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6586       mp->table_id = ntohl (vrf_id);
6587       mp->create_vrf_if_needed = create_vrf_if_needed;
6588
6589       mp->is_add = is_add;
6590       mp->is_drop = is_drop;
6591       mp->is_unreach = is_unreach;
6592       mp->is_prohibit = is_prohibit;
6593       mp->is_ipv6 = is_ipv6;
6594       mp->is_local = is_local;
6595       mp->is_classify = is_classify;
6596       mp->is_multipath = is_multipath;
6597       mp->is_resolve_host = resolve_host;
6598       mp->is_resolve_attached = resolve_attached;
6599       mp->not_last = not_last;
6600       mp->next_hop_weight = next_hop_weight;
6601       mp->dst_address_length = dst_address_length;
6602       mp->next_hop_table_id = ntohl (next_hop_table_id);
6603       mp->classify_table_index = ntohl (classify_table_index);
6604       mp->next_hop_via_label = ntohl (next_hop_via_label);
6605       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6606       if (0 != mp->next_hop_n_out_labels)
6607         {
6608           memcpy (mp->next_hop_out_label_stack,
6609                   next_hop_out_label_stack,
6610                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6611           vec_free (next_hop_out_label_stack);
6612         }
6613
6614       if (is_ipv6)
6615         {
6616           clib_memcpy (mp->dst_address, &v6_dst_address,
6617                        sizeof (v6_dst_address));
6618           if (next_hop_set)
6619             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6620                          sizeof (v6_next_hop_address));
6621           increment_v6_address (&v6_dst_address);
6622         }
6623       else
6624         {
6625           clib_memcpy (mp->dst_address, &v4_dst_address,
6626                        sizeof (v4_dst_address));
6627           if (next_hop_set)
6628             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6629                          sizeof (v4_next_hop_address));
6630           if (random_add_del)
6631             v4_dst_address.as_u32 = random_vector[j + 1];
6632           else
6633             increment_v4_address (&v4_dst_address);
6634         }
6635       /* send it... */
6636       S (mp);
6637       /* If we receive SIGTERM, stop now... */
6638       if (vam->do_exit)
6639         break;
6640     }
6641
6642   /* When testing multiple add/del ops, use a control-ping to sync */
6643   if (count > 1)
6644     {
6645       vl_api_control_ping_t *mp_ping;
6646       f64 after;
6647       f64 timeout;
6648
6649       /* Shut off async mode */
6650       vam->async_mode = 0;
6651
6652       M (CONTROL_PING, mp_ping);
6653       S (mp_ping);
6654
6655       timeout = vat_time_now (vam) + 1.0;
6656       while (vat_time_now (vam) < timeout)
6657         if (vam->result_ready == 1)
6658           goto out;
6659       vam->retval = -99;
6660
6661     out:
6662       if (vam->retval == -99)
6663         errmsg ("timeout");
6664
6665       if (vam->async_errors > 0)
6666         {
6667           errmsg ("%d asynchronous errors", vam->async_errors);
6668           vam->retval = -98;
6669         }
6670       vam->async_errors = 0;
6671       after = vat_time_now (vam);
6672
6673       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6674       if (j > 0)
6675         count = j;
6676
6677       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6678              count, after - before, count / (after - before));
6679     }
6680   else
6681     {
6682       int ret;
6683
6684       /* Wait for a reply... */
6685       W (ret);
6686       return ret;
6687     }
6688
6689   /* Return the good/bad news */
6690   return (vam->retval);
6691 }
6692
6693 static int
6694 api_ip_mroute_add_del (vat_main_t * vam)
6695 {
6696   unformat_input_t *i = vam->input;
6697   vl_api_ip_mroute_add_del_t *mp;
6698   u32 sw_if_index = ~0, vrf_id = 0;
6699   u8 is_ipv6 = 0;
6700   u8 is_local = 0;
6701   u8 create_vrf_if_needed = 0;
6702   u8 is_add = 1;
6703   u8 address_set = 0;
6704   u32 grp_address_length = 0;
6705   ip4_address_t v4_grp_address, v4_src_address;
6706   ip6_address_t v6_grp_address, v6_src_address;
6707   mfib_itf_flags_t iflags = 0;
6708   mfib_entry_flags_t eflags = 0;
6709   int ret;
6710
6711   /* Parse args required to build the message */
6712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6713     {
6714       if (unformat (i, "sw_if_index %d", &sw_if_index))
6715         ;
6716       else if (unformat (i, "%U %U",
6717                          unformat_ip4_address, &v4_src_address,
6718                          unformat_ip4_address, &v4_grp_address))
6719         {
6720           grp_address_length = 64;
6721           address_set = 1;
6722           is_ipv6 = 0;
6723         }
6724       else if (unformat (i, "%U %U",
6725                          unformat_ip6_address, &v6_src_address,
6726                          unformat_ip6_address, &v6_grp_address))
6727         {
6728           grp_address_length = 256;
6729           address_set = 1;
6730           is_ipv6 = 1;
6731         }
6732       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6733         {
6734           memset (&v4_src_address, 0, sizeof (v4_src_address));
6735           grp_address_length = 32;
6736           address_set = 1;
6737           is_ipv6 = 0;
6738         }
6739       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6740         {
6741           memset (&v6_src_address, 0, sizeof (v6_src_address));
6742           grp_address_length = 128;
6743           address_set = 1;
6744           is_ipv6 = 1;
6745         }
6746       else if (unformat (i, "/%d", &grp_address_length))
6747         ;
6748       else if (unformat (i, "local"))
6749         {
6750           is_local = 1;
6751         }
6752       else if (unformat (i, "del"))
6753         is_add = 0;
6754       else if (unformat (i, "add"))
6755         is_add = 1;
6756       else if (unformat (i, "vrf %d", &vrf_id))
6757         ;
6758       else if (unformat (i, "create-vrf"))
6759         create_vrf_if_needed = 1;
6760       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6761         ;
6762       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6763         ;
6764       else
6765         {
6766           clib_warning ("parse error '%U'", format_unformat_error, i);
6767           return -99;
6768         }
6769     }
6770
6771   if (address_set == 0)
6772     {
6773       errmsg ("missing addresses\n");
6774       return -99;
6775     }
6776
6777   /* Construct the API message */
6778   M (IP_MROUTE_ADD_DEL, mp);
6779
6780   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6781   mp->table_id = ntohl (vrf_id);
6782   mp->create_vrf_if_needed = create_vrf_if_needed;
6783
6784   mp->is_add = is_add;
6785   mp->is_ipv6 = is_ipv6;
6786   mp->is_local = is_local;
6787   mp->itf_flags = ntohl (iflags);
6788   mp->entry_flags = ntohl (eflags);
6789   mp->grp_address_length = grp_address_length;
6790   mp->grp_address_length = ntohs (mp->grp_address_length);
6791
6792   if (is_ipv6)
6793     {
6794       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6795       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6796     }
6797   else
6798     {
6799       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6800       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6801
6802     }
6803
6804   /* send it... */
6805   S (mp);
6806   /* Wait for a reply... */
6807   W (ret);
6808   return ret;
6809 }
6810
6811 static int
6812 api_mpls_route_add_del (vat_main_t * vam)
6813 {
6814   unformat_input_t *i = vam->input;
6815   vl_api_mpls_route_add_del_t *mp;
6816   u32 sw_if_index = ~0, table_id = 0;
6817   u8 create_table_if_needed = 0;
6818   u8 is_add = 1;
6819   u32 next_hop_weight = 1;
6820   u8 is_multipath = 0;
6821   u32 next_hop_table_id = 0;
6822   u8 next_hop_set = 0;
6823   ip4_address_t v4_next_hop_address = {
6824     .as_u32 = 0,
6825   };
6826   ip6_address_t v6_next_hop_address = { {0} };
6827   int count = 1;
6828   int j;
6829   f64 before = 0;
6830   u32 classify_table_index = ~0;
6831   u8 is_classify = 0;
6832   u8 resolve_host = 0, resolve_attached = 0;
6833   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6834   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6835   mpls_label_t *next_hop_out_label_stack = NULL;
6836   mpls_label_t local_label = MPLS_LABEL_INVALID;
6837   u8 is_eos = 0;
6838   u8 next_hop_proto_is_ip4 = 1;
6839
6840   /* Parse args required to build the message */
6841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6842     {
6843       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6844         ;
6845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6846         ;
6847       else if (unformat (i, "%d", &local_label))
6848         ;
6849       else if (unformat (i, "eos"))
6850         is_eos = 1;
6851       else if (unformat (i, "non-eos"))
6852         is_eos = 0;
6853       else if (unformat (i, "via %U", unformat_ip4_address,
6854                          &v4_next_hop_address))
6855         {
6856           next_hop_set = 1;
6857           next_hop_proto_is_ip4 = 1;
6858         }
6859       else if (unformat (i, "via %U", unformat_ip6_address,
6860                          &v6_next_hop_address))
6861         {
6862           next_hop_set = 1;
6863           next_hop_proto_is_ip4 = 0;
6864         }
6865       else if (unformat (i, "weight %d", &next_hop_weight))
6866         ;
6867       else if (unformat (i, "create-table"))
6868         create_table_if_needed = 1;
6869       else if (unformat (i, "classify %d", &classify_table_index))
6870         {
6871           is_classify = 1;
6872         }
6873       else if (unformat (i, "del"))
6874         is_add = 0;
6875       else if (unformat (i, "add"))
6876         is_add = 1;
6877       else if (unformat (i, "resolve-via-host"))
6878         resolve_host = 1;
6879       else if (unformat (i, "resolve-via-attached"))
6880         resolve_attached = 1;
6881       else if (unformat (i, "multipath"))
6882         is_multipath = 1;
6883       else if (unformat (i, "count %d", &count))
6884         ;
6885       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6886         {
6887           next_hop_set = 1;
6888           next_hop_proto_is_ip4 = 1;
6889         }
6890       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6891         {
6892           next_hop_set = 1;
6893           next_hop_proto_is_ip4 = 0;
6894         }
6895       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6896         ;
6897       else if (unformat (i, "via-label %d", &next_hop_via_label))
6898         ;
6899       else if (unformat (i, "out-label %d", &next_hop_out_label))
6900         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6901       else
6902         {
6903           clib_warning ("parse error '%U'", format_unformat_error, i);
6904           return -99;
6905         }
6906     }
6907
6908   if (!next_hop_set && !is_classify)
6909     {
6910       errmsg ("next hop / classify not set");
6911       return -99;
6912     }
6913
6914   if (MPLS_LABEL_INVALID == local_label)
6915     {
6916       errmsg ("missing label");
6917       return -99;
6918     }
6919
6920   if (count > 1)
6921     {
6922       /* Turn on async mode */
6923       vam->async_mode = 1;
6924       vam->async_errors = 0;
6925       before = vat_time_now (vam);
6926     }
6927
6928   for (j = 0; j < count; j++)
6929     {
6930       /* Construct the API message */
6931       M2 (MPLS_ROUTE_ADD_DEL, mp,
6932           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6933
6934       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6935       mp->mr_table_id = ntohl (table_id);
6936       mp->mr_create_table_if_needed = create_table_if_needed;
6937
6938       mp->mr_is_add = is_add;
6939       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6940       mp->mr_is_classify = is_classify;
6941       mp->mr_is_multipath = is_multipath;
6942       mp->mr_is_resolve_host = resolve_host;
6943       mp->mr_is_resolve_attached = resolve_attached;
6944       mp->mr_next_hop_weight = next_hop_weight;
6945       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6946       mp->mr_classify_table_index = ntohl (classify_table_index);
6947       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6948       mp->mr_label = ntohl (local_label);
6949       mp->mr_eos = is_eos;
6950
6951       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6952       if (0 != mp->mr_next_hop_n_out_labels)
6953         {
6954           memcpy (mp->mr_next_hop_out_label_stack,
6955                   next_hop_out_label_stack,
6956                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6957           vec_free (next_hop_out_label_stack);
6958         }
6959
6960       if (next_hop_set)
6961         {
6962           if (next_hop_proto_is_ip4)
6963             {
6964               clib_memcpy (mp->mr_next_hop,
6965                            &v4_next_hop_address,
6966                            sizeof (v4_next_hop_address));
6967             }
6968           else
6969             {
6970               clib_memcpy (mp->mr_next_hop,
6971                            &v6_next_hop_address,
6972                            sizeof (v6_next_hop_address));
6973             }
6974         }
6975       local_label++;
6976
6977       /* send it... */
6978       S (mp);
6979       /* If we receive SIGTERM, stop now... */
6980       if (vam->do_exit)
6981         break;
6982     }
6983
6984   /* When testing multiple add/del ops, use a control-ping to sync */
6985   if (count > 1)
6986     {
6987       vl_api_control_ping_t *mp_ping;
6988       f64 after;
6989       f64 timeout;
6990
6991       /* Shut off async mode */
6992       vam->async_mode = 0;
6993
6994       M (CONTROL_PING, mp_ping);
6995       S (mp_ping);
6996
6997       timeout = vat_time_now (vam) + 1.0;
6998       while (vat_time_now (vam) < timeout)
6999         if (vam->result_ready == 1)
7000           goto out;
7001       vam->retval = -99;
7002
7003     out:
7004       if (vam->retval == -99)
7005         errmsg ("timeout");
7006
7007       if (vam->async_errors > 0)
7008         {
7009           errmsg ("%d asynchronous errors", vam->async_errors);
7010           vam->retval = -98;
7011         }
7012       vam->async_errors = 0;
7013       after = vat_time_now (vam);
7014
7015       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7016       if (j > 0)
7017         count = j;
7018
7019       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7020              count, after - before, count / (after - before));
7021     }
7022   else
7023     {
7024       int ret;
7025
7026       /* Wait for a reply... */
7027       W (ret);
7028       return ret;
7029     }
7030
7031   /* Return the good/bad news */
7032   return (vam->retval);
7033 }
7034
7035 static int
7036 api_mpls_ip_bind_unbind (vat_main_t * vam)
7037 {
7038   unformat_input_t *i = vam->input;
7039   vl_api_mpls_ip_bind_unbind_t *mp;
7040   u32 ip_table_id = 0;
7041   u8 create_table_if_needed = 0;
7042   u8 is_bind = 1;
7043   u8 is_ip4 = 1;
7044   ip4_address_t v4_address;
7045   ip6_address_t v6_address;
7046   u32 address_length;
7047   u8 address_set = 0;
7048   mpls_label_t local_label = MPLS_LABEL_INVALID;
7049   int ret;
7050
7051   /* Parse args required to build the message */
7052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7053     {
7054       if (unformat (i, "%U/%d", unformat_ip4_address,
7055                     &v4_address, &address_length))
7056         {
7057           is_ip4 = 1;
7058           address_set = 1;
7059         }
7060       else if (unformat (i, "%U/%d", unformat_ip6_address,
7061                          &v6_address, &address_length))
7062         {
7063           is_ip4 = 0;
7064           address_set = 1;
7065         }
7066       else if (unformat (i, "%d", &local_label))
7067         ;
7068       else if (unformat (i, "create-table"))
7069         create_table_if_needed = 1;
7070       else if (unformat (i, "table-id %d", &ip_table_id))
7071         ;
7072       else if (unformat (i, "unbind"))
7073         is_bind = 0;
7074       else if (unformat (i, "bind"))
7075         is_bind = 1;
7076       else
7077         {
7078           clib_warning ("parse error '%U'", format_unformat_error, i);
7079           return -99;
7080         }
7081     }
7082
7083   if (!address_set)
7084     {
7085       errmsg ("IP addres not set");
7086       return -99;
7087     }
7088
7089   if (MPLS_LABEL_INVALID == local_label)
7090     {
7091       errmsg ("missing label");
7092       return -99;
7093     }
7094
7095   /* Construct the API message */
7096   M (MPLS_IP_BIND_UNBIND, mp);
7097
7098   mp->mb_create_table_if_needed = create_table_if_needed;
7099   mp->mb_is_bind = is_bind;
7100   mp->mb_is_ip4 = is_ip4;
7101   mp->mb_ip_table_id = ntohl (ip_table_id);
7102   mp->mb_mpls_table_id = 0;
7103   mp->mb_label = ntohl (local_label);
7104   mp->mb_address_length = address_length;
7105
7106   if (is_ip4)
7107     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7108   else
7109     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7110
7111   /* send it... */
7112   S (mp);
7113
7114   /* Wait for a reply... */
7115   W (ret);
7116   return ret;
7117 }
7118
7119 static int
7120 api_proxy_arp_add_del (vat_main_t * vam)
7121 {
7122   unformat_input_t *i = vam->input;
7123   vl_api_proxy_arp_add_del_t *mp;
7124   u32 vrf_id = 0;
7125   u8 is_add = 1;
7126   ip4_address_t lo, hi;
7127   u8 range_set = 0;
7128   int ret;
7129
7130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7131     {
7132       if (unformat (i, "vrf %d", &vrf_id))
7133         ;
7134       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7135                          unformat_ip4_address, &hi))
7136         range_set = 1;
7137       else if (unformat (i, "del"))
7138         is_add = 0;
7139       else
7140         {
7141           clib_warning ("parse error '%U'", format_unformat_error, i);
7142           return -99;
7143         }
7144     }
7145
7146   if (range_set == 0)
7147     {
7148       errmsg ("address range not set");
7149       return -99;
7150     }
7151
7152   M (PROXY_ARP_ADD_DEL, mp);
7153
7154   mp->vrf_id = ntohl (vrf_id);
7155   mp->is_add = is_add;
7156   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7157   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7158
7159   S (mp);
7160   W (ret);
7161   return ret;
7162 }
7163
7164 static int
7165 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7166 {
7167   unformat_input_t *i = vam->input;
7168   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7169   u32 sw_if_index;
7170   u8 enable = 1;
7171   u8 sw_if_index_set = 0;
7172   int ret;
7173
7174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7175     {
7176       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7177         sw_if_index_set = 1;
7178       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7179         sw_if_index_set = 1;
7180       else if (unformat (i, "enable"))
7181         enable = 1;
7182       else if (unformat (i, "disable"))
7183         enable = 0;
7184       else
7185         {
7186           clib_warning ("parse error '%U'", format_unformat_error, i);
7187           return -99;
7188         }
7189     }
7190
7191   if (sw_if_index_set == 0)
7192     {
7193       errmsg ("missing interface name or sw_if_index");
7194       return -99;
7195     }
7196
7197   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7198
7199   mp->sw_if_index = ntohl (sw_if_index);
7200   mp->enable_disable = enable;
7201
7202   S (mp);
7203   W (ret);
7204   return ret;
7205 }
7206
7207 static int
7208 api_mpls_tunnel_add_del (vat_main_t * vam)
7209 {
7210   unformat_input_t *i = vam->input;
7211   vl_api_mpls_tunnel_add_del_t *mp;
7212
7213   u8 is_add = 1;
7214   u8 l2_only = 0;
7215   u32 sw_if_index = ~0;
7216   u32 next_hop_sw_if_index = ~0;
7217   u32 next_hop_proto_is_ip4 = 1;
7218
7219   u32 next_hop_table_id = 0;
7220   ip4_address_t v4_next_hop_address = {
7221     .as_u32 = 0,
7222   };
7223   ip6_address_t v6_next_hop_address = { {0} };
7224   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7225   int ret;
7226
7227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228     {
7229       if (unformat (i, "add"))
7230         is_add = 1;
7231       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7232         is_add = 0;
7233       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7234         ;
7235       else if (unformat (i, "via %U",
7236                          unformat_ip4_address, &v4_next_hop_address))
7237         {
7238           next_hop_proto_is_ip4 = 1;
7239         }
7240       else if (unformat (i, "via %U",
7241                          unformat_ip6_address, &v6_next_hop_address))
7242         {
7243           next_hop_proto_is_ip4 = 0;
7244         }
7245       else if (unformat (i, "l2-only"))
7246         l2_only = 1;
7247       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7248         ;
7249       else if (unformat (i, "out-label %d", &next_hop_out_label))
7250         vec_add1 (labels, ntohl (next_hop_out_label));
7251       else
7252         {
7253           clib_warning ("parse error '%U'", format_unformat_error, i);
7254           return -99;
7255         }
7256     }
7257
7258   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7259
7260   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7261   mp->mt_sw_if_index = ntohl (sw_if_index);
7262   mp->mt_is_add = is_add;
7263   mp->mt_l2_only = l2_only;
7264   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7265   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7266
7267   mp->mt_next_hop_n_out_labels = vec_len (labels);
7268
7269   if (0 != mp->mt_next_hop_n_out_labels)
7270     {
7271       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7272                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7273       vec_free (labels);
7274     }
7275
7276   if (next_hop_proto_is_ip4)
7277     {
7278       clib_memcpy (mp->mt_next_hop,
7279                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7280     }
7281   else
7282     {
7283       clib_memcpy (mp->mt_next_hop,
7284                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7285     }
7286
7287   S (mp);
7288   W (ret);
7289   return ret;
7290 }
7291
7292 static int
7293 api_sw_interface_set_unnumbered (vat_main_t * vam)
7294 {
7295   unformat_input_t *i = vam->input;
7296   vl_api_sw_interface_set_unnumbered_t *mp;
7297   u32 sw_if_index;
7298   u32 unnum_sw_index = ~0;
7299   u8 is_add = 1;
7300   u8 sw_if_index_set = 0;
7301   int ret;
7302
7303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7304     {
7305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7306         sw_if_index_set = 1;
7307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7308         sw_if_index_set = 1;
7309       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7310         ;
7311       else if (unformat (i, "del"))
7312         is_add = 0;
7313       else
7314         {
7315           clib_warning ("parse error '%U'", format_unformat_error, i);
7316           return -99;
7317         }
7318     }
7319
7320   if (sw_if_index_set == 0)
7321     {
7322       errmsg ("missing interface name or sw_if_index");
7323       return -99;
7324     }
7325
7326   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7327
7328   mp->sw_if_index = ntohl (sw_if_index);
7329   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7330   mp->is_add = is_add;
7331
7332   S (mp);
7333   W (ret);
7334   return ret;
7335 }
7336
7337 static int
7338 api_ip_neighbor_add_del (vat_main_t * vam)
7339 {
7340   unformat_input_t *i = vam->input;
7341   vl_api_ip_neighbor_add_del_t *mp;
7342   u32 sw_if_index;
7343   u8 sw_if_index_set = 0;
7344   u32 vrf_id = 0;
7345   u8 is_add = 1;
7346   u8 is_static = 0;
7347   u8 mac_address[6];
7348   u8 mac_set = 0;
7349   u8 v4_address_set = 0;
7350   u8 v6_address_set = 0;
7351   ip4_address_t v4address;
7352   ip6_address_t v6address;
7353   int ret;
7354
7355   memset (mac_address, 0, sizeof (mac_address));
7356
7357   /* Parse args required to build the message */
7358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7359     {
7360       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7361         {
7362           mac_set = 1;
7363         }
7364       else if (unformat (i, "del"))
7365         is_add = 0;
7366       else
7367         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7368         sw_if_index_set = 1;
7369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7370         sw_if_index_set = 1;
7371       else if (unformat (i, "is_static"))
7372         is_static = 1;
7373       else if (unformat (i, "vrf %d", &vrf_id))
7374         ;
7375       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7376         v4_address_set = 1;
7377       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7378         v6_address_set = 1;
7379       else
7380         {
7381           clib_warning ("parse error '%U'", format_unformat_error, i);
7382           return -99;
7383         }
7384     }
7385
7386   if (sw_if_index_set == 0)
7387     {
7388       errmsg ("missing interface name or sw_if_index");
7389       return -99;
7390     }
7391   if (v4_address_set && v6_address_set)
7392     {
7393       errmsg ("both v4 and v6 addresses set");
7394       return -99;
7395     }
7396   if (!v4_address_set && !v6_address_set)
7397     {
7398       errmsg ("no address set");
7399       return -99;
7400     }
7401
7402   /* Construct the API message */
7403   M (IP_NEIGHBOR_ADD_DEL, mp);
7404
7405   mp->sw_if_index = ntohl (sw_if_index);
7406   mp->is_add = is_add;
7407   mp->vrf_id = ntohl (vrf_id);
7408   mp->is_static = is_static;
7409   if (mac_set)
7410     clib_memcpy (mp->mac_address, mac_address, 6);
7411   if (v6_address_set)
7412     {
7413       mp->is_ipv6 = 1;
7414       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7415     }
7416   else
7417     {
7418       /* mp->is_ipv6 = 0; via memset in M macro above */
7419       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7420     }
7421
7422   /* send it... */
7423   S (mp);
7424
7425   /* Wait for a reply, return good/bad news  */
7426   W (ret);
7427   return ret;
7428 }
7429
7430 static int
7431 api_reset_vrf (vat_main_t * vam)
7432 {
7433   unformat_input_t *i = vam->input;
7434   vl_api_reset_vrf_t *mp;
7435   u32 vrf_id = 0;
7436   u8 is_ipv6 = 0;
7437   u8 vrf_id_set = 0;
7438   int ret;
7439
7440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7441     {
7442       if (unformat (i, "vrf %d", &vrf_id))
7443         vrf_id_set = 1;
7444       else if (unformat (i, "ipv6"))
7445         is_ipv6 = 1;
7446       else
7447         {
7448           clib_warning ("parse error '%U'", format_unformat_error, i);
7449           return -99;
7450         }
7451     }
7452
7453   if (vrf_id_set == 0)
7454     {
7455       errmsg ("missing vrf id");
7456       return -99;
7457     }
7458
7459   M (RESET_VRF, mp);
7460
7461   mp->vrf_id = ntohl (vrf_id);
7462   mp->is_ipv6 = is_ipv6;
7463
7464   S (mp);
7465   W (ret);
7466   return ret;
7467 }
7468
7469 static int
7470 api_create_vlan_subif (vat_main_t * vam)
7471 {
7472   unformat_input_t *i = vam->input;
7473   vl_api_create_vlan_subif_t *mp;
7474   u32 sw_if_index;
7475   u8 sw_if_index_set = 0;
7476   u32 vlan_id;
7477   u8 vlan_id_set = 0;
7478   int ret;
7479
7480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7481     {
7482       if (unformat (i, "sw_if_index %d", &sw_if_index))
7483         sw_if_index_set = 1;
7484       else
7485         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7486         sw_if_index_set = 1;
7487       else if (unformat (i, "vlan %d", &vlan_id))
7488         vlan_id_set = 1;
7489       else
7490         {
7491           clib_warning ("parse error '%U'", format_unformat_error, i);
7492           return -99;
7493         }
7494     }
7495
7496   if (sw_if_index_set == 0)
7497     {
7498       errmsg ("missing interface name or sw_if_index");
7499       return -99;
7500     }
7501
7502   if (vlan_id_set == 0)
7503     {
7504       errmsg ("missing vlan_id");
7505       return -99;
7506     }
7507   M (CREATE_VLAN_SUBIF, mp);
7508
7509   mp->sw_if_index = ntohl (sw_if_index);
7510   mp->vlan_id = ntohl (vlan_id);
7511
7512   S (mp);
7513   W (ret);
7514   return ret;
7515 }
7516
7517 #define foreach_create_subif_bit                \
7518 _(no_tags)                                      \
7519 _(one_tag)                                      \
7520 _(two_tags)                                     \
7521 _(dot1ad)                                       \
7522 _(exact_match)                                  \
7523 _(default_sub)                                  \
7524 _(outer_vlan_id_any)                            \
7525 _(inner_vlan_id_any)
7526
7527 static int
7528 api_create_subif (vat_main_t * vam)
7529 {
7530   unformat_input_t *i = vam->input;
7531   vl_api_create_subif_t *mp;
7532   u32 sw_if_index;
7533   u8 sw_if_index_set = 0;
7534   u32 sub_id;
7535   u8 sub_id_set = 0;
7536   u32 no_tags = 0;
7537   u32 one_tag = 0;
7538   u32 two_tags = 0;
7539   u32 dot1ad = 0;
7540   u32 exact_match = 0;
7541   u32 default_sub = 0;
7542   u32 outer_vlan_id_any = 0;
7543   u32 inner_vlan_id_any = 0;
7544   u32 tmp;
7545   u16 outer_vlan_id = 0;
7546   u16 inner_vlan_id = 0;
7547   int ret;
7548
7549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7550     {
7551       if (unformat (i, "sw_if_index %d", &sw_if_index))
7552         sw_if_index_set = 1;
7553       else
7554         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7555         sw_if_index_set = 1;
7556       else if (unformat (i, "sub_id %d", &sub_id))
7557         sub_id_set = 1;
7558       else if (unformat (i, "outer_vlan_id %d", &tmp))
7559         outer_vlan_id = tmp;
7560       else if (unformat (i, "inner_vlan_id %d", &tmp))
7561         inner_vlan_id = tmp;
7562
7563 #define _(a) else if (unformat (i, #a)) a = 1 ;
7564       foreach_create_subif_bit
7565 #undef _
7566         else
7567         {
7568           clib_warning ("parse error '%U'", format_unformat_error, i);
7569           return -99;
7570         }
7571     }
7572
7573   if (sw_if_index_set == 0)
7574     {
7575       errmsg ("missing interface name or sw_if_index");
7576       return -99;
7577     }
7578
7579   if (sub_id_set == 0)
7580     {
7581       errmsg ("missing sub_id");
7582       return -99;
7583     }
7584   M (CREATE_SUBIF, mp);
7585
7586   mp->sw_if_index = ntohl (sw_if_index);
7587   mp->sub_id = ntohl (sub_id);
7588
7589 #define _(a) mp->a = a;
7590   foreach_create_subif_bit;
7591 #undef _
7592
7593   mp->outer_vlan_id = ntohs (outer_vlan_id);
7594   mp->inner_vlan_id = ntohs (inner_vlan_id);
7595
7596   S (mp);
7597   W (ret);
7598   return ret;
7599 }
7600
7601 static int
7602 api_oam_add_del (vat_main_t * vam)
7603 {
7604   unformat_input_t *i = vam->input;
7605   vl_api_oam_add_del_t *mp;
7606   u32 vrf_id = 0;
7607   u8 is_add = 1;
7608   ip4_address_t src, dst;
7609   u8 src_set = 0;
7610   u8 dst_set = 0;
7611   int ret;
7612
7613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7614     {
7615       if (unformat (i, "vrf %d", &vrf_id))
7616         ;
7617       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7618         src_set = 1;
7619       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7620         dst_set = 1;
7621       else if (unformat (i, "del"))
7622         is_add = 0;
7623       else
7624         {
7625           clib_warning ("parse error '%U'", format_unformat_error, i);
7626           return -99;
7627         }
7628     }
7629
7630   if (src_set == 0)
7631     {
7632       errmsg ("missing src addr");
7633       return -99;
7634     }
7635
7636   if (dst_set == 0)
7637     {
7638       errmsg ("missing dst addr");
7639       return -99;
7640     }
7641
7642   M (OAM_ADD_DEL, mp);
7643
7644   mp->vrf_id = ntohl (vrf_id);
7645   mp->is_add = is_add;
7646   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7647   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7648
7649   S (mp);
7650   W (ret);
7651   return ret;
7652 }
7653
7654 static int
7655 api_reset_fib (vat_main_t * vam)
7656 {
7657   unformat_input_t *i = vam->input;
7658   vl_api_reset_fib_t *mp;
7659   u32 vrf_id = 0;
7660   u8 is_ipv6 = 0;
7661   u8 vrf_id_set = 0;
7662
7663   int ret;
7664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7665     {
7666       if (unformat (i, "vrf %d", &vrf_id))
7667         vrf_id_set = 1;
7668       else if (unformat (i, "ipv6"))
7669         is_ipv6 = 1;
7670       else
7671         {
7672           clib_warning ("parse error '%U'", format_unformat_error, i);
7673           return -99;
7674         }
7675     }
7676
7677   if (vrf_id_set == 0)
7678     {
7679       errmsg ("missing vrf id");
7680       return -99;
7681     }
7682
7683   M (RESET_FIB, mp);
7684
7685   mp->vrf_id = ntohl (vrf_id);
7686   mp->is_ipv6 = is_ipv6;
7687
7688   S (mp);
7689   W (ret);
7690   return ret;
7691 }
7692
7693 static int
7694 api_dhcp_proxy_config (vat_main_t * vam)
7695 {
7696   unformat_input_t *i = vam->input;
7697   vl_api_dhcp_proxy_config_t *mp;
7698   u32 rx_vrf_id = 0;
7699   u32 server_vrf_id = 0;
7700   u8 is_add = 1;
7701   u8 v4_address_set = 0;
7702   u8 v6_address_set = 0;
7703   ip4_address_t v4address;
7704   ip6_address_t v6address;
7705   u8 v4_src_address_set = 0;
7706   u8 v6_src_address_set = 0;
7707   ip4_address_t v4srcaddress;
7708   ip6_address_t v6srcaddress;
7709   int ret;
7710
7711   /* Parse args required to build the message */
7712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7713     {
7714       if (unformat (i, "del"))
7715         is_add = 0;
7716       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7717         ;
7718       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7719         ;
7720       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7721         v4_address_set = 1;
7722       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7723         v6_address_set = 1;
7724       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7725         v4_src_address_set = 1;
7726       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7727         v6_src_address_set = 1;
7728       else
7729         break;
7730     }
7731
7732   if (v4_address_set && v6_address_set)
7733     {
7734       errmsg ("both v4 and v6 server addresses set");
7735       return -99;
7736     }
7737   if (!v4_address_set && !v6_address_set)
7738     {
7739       errmsg ("no server addresses set");
7740       return -99;
7741     }
7742
7743   if (v4_src_address_set && v6_src_address_set)
7744     {
7745       errmsg ("both v4 and v6  src addresses set");
7746       return -99;
7747     }
7748   if (!v4_src_address_set && !v6_src_address_set)
7749     {
7750       errmsg ("no src addresses set");
7751       return -99;
7752     }
7753
7754   if (!(v4_src_address_set && v4_address_set) &&
7755       !(v6_src_address_set && v6_address_set))
7756     {
7757       errmsg ("no matching server and src addresses set");
7758       return -99;
7759     }
7760
7761   /* Construct the API message */
7762   M (DHCP_PROXY_CONFIG, mp);
7763
7764   mp->is_add = is_add;
7765   mp->rx_vrf_id = ntohl (rx_vrf_id);
7766   mp->server_vrf_id = ntohl (server_vrf_id);
7767   if (v6_address_set)
7768     {
7769       mp->is_ipv6 = 1;
7770       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7771       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7772     }
7773   else
7774     {
7775       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7776       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7777     }
7778
7779   /* send it... */
7780   S (mp);
7781
7782   /* Wait for a reply, return good/bad news  */
7783   W (ret);
7784   return ret;
7785 }
7786
7787 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7788 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7789
7790 static void
7791 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7792 {
7793   vat_main_t *vam = &vat_main;
7794
7795   if (mp->is_ipv6)
7796     print (vam->ofp,
7797            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7798            ntohl (mp->rx_vrf_id),
7799            ntohl (mp->server_vrf_id),
7800            format_ip6_address, mp->dhcp_server,
7801            format_ip6_address, mp->dhcp_src_address,
7802            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7803   else
7804     print (vam->ofp,
7805            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7806            ntohl (mp->rx_vrf_id),
7807            ntohl (mp->server_vrf_id),
7808            format_ip4_address, mp->dhcp_server,
7809            format_ip4_address, mp->dhcp_src_address,
7810            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7811 }
7812
7813 static void vl_api_dhcp_proxy_details_t_handler_json
7814   (vl_api_dhcp_proxy_details_t * mp)
7815 {
7816   vat_main_t *vam = &vat_main;
7817   vat_json_node_t *node = NULL;
7818   struct in_addr ip4;
7819   struct in6_addr ip6;
7820
7821   if (VAT_JSON_ARRAY != vam->json_tree.type)
7822     {
7823       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7824       vat_json_init_array (&vam->json_tree);
7825     }
7826   node = vat_json_array_add (&vam->json_tree);
7827
7828   vat_json_init_object (node);
7829   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7830   vat_json_object_add_uint (node, "server-table-id",
7831                             ntohl (mp->server_vrf_id));
7832   if (mp->is_ipv6)
7833     {
7834       clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7835       vat_json_object_add_ip6 (node, "server_address", ip6);
7836       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7837       vat_json_object_add_ip6 (node, "src_address", ip6);
7838     }
7839   else
7840     {
7841       clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7842       vat_json_object_add_ip4 (node, "server_address", ip4);
7843       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7844       vat_json_object_add_ip4 (node, "src_address", ip4);
7845     }
7846   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7847   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7848 }
7849
7850 static int
7851 api_dhcp_proxy_dump (vat_main_t * vam)
7852 {
7853   unformat_input_t *i = vam->input;
7854   vl_api_control_ping_t *mp_ping;
7855   vl_api_dhcp_proxy_dump_t *mp;
7856   u8 is_ipv6 = 0;
7857   int ret;
7858
7859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7860     {
7861       if (unformat (i, "ipv6"))
7862         is_ipv6 = 1;
7863       else
7864         {
7865           clib_warning ("parse error '%U'", format_unformat_error, i);
7866           return -99;
7867         }
7868     }
7869
7870   M (DHCP_PROXY_DUMP, mp);
7871
7872   mp->is_ip6 = is_ipv6;
7873   S (mp);
7874
7875   /* Use a control ping for synchronization */
7876   M (CONTROL_PING, mp_ping);
7877   S (mp_ping);
7878
7879   W (ret);
7880   return ret;
7881 }
7882
7883 static int
7884 api_dhcp_proxy_set_vss (vat_main_t * vam)
7885 {
7886   unformat_input_t *i = vam->input;
7887   vl_api_dhcp_proxy_set_vss_t *mp;
7888   u8 is_ipv6 = 0;
7889   u8 is_add = 1;
7890   u32 tbl_id;
7891   u8 tbl_id_set = 0;
7892   u32 oui;
7893   u8 oui_set = 0;
7894   u32 fib_id;
7895   u8 fib_id_set = 0;
7896   int ret;
7897
7898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7899     {
7900       if (unformat (i, "tbl_id %d", &tbl_id))
7901         tbl_id_set = 1;
7902       if (unformat (i, "fib_id %d", &fib_id))
7903         fib_id_set = 1;
7904       if (unformat (i, "oui %d", &oui))
7905         oui_set = 1;
7906       else if (unformat (i, "ipv6"))
7907         is_ipv6 = 1;
7908       else if (unformat (i, "del"))
7909         is_add = 0;
7910       else
7911         {
7912           clib_warning ("parse error '%U'", format_unformat_error, i);
7913           return -99;
7914         }
7915     }
7916
7917   if (tbl_id_set == 0)
7918     {
7919       errmsg ("missing tbl id");
7920       return -99;
7921     }
7922
7923   if (fib_id_set == 0)
7924     {
7925       errmsg ("missing fib id");
7926       return -99;
7927     }
7928   if (oui_set == 0)
7929     {
7930       errmsg ("missing oui");
7931       return -99;
7932     }
7933
7934   M (DHCP_PROXY_SET_VSS, mp);
7935   mp->tbl_id = ntohl (tbl_id);
7936   mp->fib_id = ntohl (fib_id);
7937   mp->oui = ntohl (oui);
7938   mp->is_ipv6 = is_ipv6;
7939   mp->is_add = is_add;
7940
7941   S (mp);
7942   W (ret);
7943   return ret;
7944 }
7945
7946 static int
7947 api_dhcp_client_config (vat_main_t * vam)
7948 {
7949   unformat_input_t *i = vam->input;
7950   vl_api_dhcp_client_config_t *mp;
7951   u32 sw_if_index;
7952   u8 sw_if_index_set = 0;
7953   u8 is_add = 1;
7954   u8 *hostname = 0;
7955   u8 disable_event = 0;
7956   int ret;
7957
7958   /* Parse args required to build the message */
7959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7960     {
7961       if (unformat (i, "del"))
7962         is_add = 0;
7963       else
7964         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7965         sw_if_index_set = 1;
7966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7967         sw_if_index_set = 1;
7968       else if (unformat (i, "hostname %s", &hostname))
7969         ;
7970       else if (unformat (i, "disable_event"))
7971         disable_event = 1;
7972       else
7973         break;
7974     }
7975
7976   if (sw_if_index_set == 0)
7977     {
7978       errmsg ("missing interface name or sw_if_index");
7979       return -99;
7980     }
7981
7982   if (vec_len (hostname) > 63)
7983     {
7984       errmsg ("hostname too long");
7985     }
7986   vec_add1 (hostname, 0);
7987
7988   /* Construct the API message */
7989   M (DHCP_CLIENT_CONFIG, mp);
7990
7991   mp->sw_if_index = ntohl (sw_if_index);
7992   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7993   vec_free (hostname);
7994   mp->is_add = is_add;
7995   mp->want_dhcp_event = disable_event ? 0 : 1;
7996   mp->pid = getpid ();
7997
7998   /* send it... */
7999   S (mp);
8000
8001   /* Wait for a reply, return good/bad news  */
8002   W (ret);
8003   return ret;
8004 }
8005
8006 static int
8007 api_set_ip_flow_hash (vat_main_t * vam)
8008 {
8009   unformat_input_t *i = vam->input;
8010   vl_api_set_ip_flow_hash_t *mp;
8011   u32 vrf_id = 0;
8012   u8 is_ipv6 = 0;
8013   u8 vrf_id_set = 0;
8014   u8 src = 0;
8015   u8 dst = 0;
8016   u8 sport = 0;
8017   u8 dport = 0;
8018   u8 proto = 0;
8019   u8 reverse = 0;
8020   int ret;
8021
8022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8023     {
8024       if (unformat (i, "vrf %d", &vrf_id))
8025         vrf_id_set = 1;
8026       else if (unformat (i, "ipv6"))
8027         is_ipv6 = 1;
8028       else if (unformat (i, "src"))
8029         src = 1;
8030       else if (unformat (i, "dst"))
8031         dst = 1;
8032       else if (unformat (i, "sport"))
8033         sport = 1;
8034       else if (unformat (i, "dport"))
8035         dport = 1;
8036       else if (unformat (i, "proto"))
8037         proto = 1;
8038       else if (unformat (i, "reverse"))
8039         reverse = 1;
8040
8041       else
8042         {
8043           clib_warning ("parse error '%U'", format_unformat_error, i);
8044           return -99;
8045         }
8046     }
8047
8048   if (vrf_id_set == 0)
8049     {
8050       errmsg ("missing vrf id");
8051       return -99;
8052     }
8053
8054   M (SET_IP_FLOW_HASH, mp);
8055   mp->src = src;
8056   mp->dst = dst;
8057   mp->sport = sport;
8058   mp->dport = dport;
8059   mp->proto = proto;
8060   mp->reverse = reverse;
8061   mp->vrf_id = ntohl (vrf_id);
8062   mp->is_ipv6 = is_ipv6;
8063
8064   S (mp);
8065   W (ret);
8066   return ret;
8067 }
8068
8069 static int
8070 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8071 {
8072   unformat_input_t *i = vam->input;
8073   vl_api_sw_interface_ip6_enable_disable_t *mp;
8074   u32 sw_if_index;
8075   u8 sw_if_index_set = 0;
8076   u8 enable = 0;
8077   int ret;
8078
8079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8080     {
8081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8082         sw_if_index_set = 1;
8083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8084         sw_if_index_set = 1;
8085       else if (unformat (i, "enable"))
8086         enable = 1;
8087       else if (unformat (i, "disable"))
8088         enable = 0;
8089       else
8090         {
8091           clib_warning ("parse error '%U'", format_unformat_error, i);
8092           return -99;
8093         }
8094     }
8095
8096   if (sw_if_index_set == 0)
8097     {
8098       errmsg ("missing interface name or sw_if_index");
8099       return -99;
8100     }
8101
8102   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8103
8104   mp->sw_if_index = ntohl (sw_if_index);
8105   mp->enable = enable;
8106
8107   S (mp);
8108   W (ret);
8109   return ret;
8110 }
8111
8112 static int
8113 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8114 {
8115   unformat_input_t *i = vam->input;
8116   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8117   u32 sw_if_index;
8118   u8 sw_if_index_set = 0;
8119   u8 v6_address_set = 0;
8120   ip6_address_t v6address;
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", api_unformat_sw_if_index, vam, &sw_if_index))
8127         sw_if_index_set = 1;
8128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8129         sw_if_index_set = 1;
8130       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8131         v6_address_set = 1;
8132       else
8133         break;
8134     }
8135
8136   if (sw_if_index_set == 0)
8137     {
8138       errmsg ("missing interface name or sw_if_index");
8139       return -99;
8140     }
8141   if (!v6_address_set)
8142     {
8143       errmsg ("no address set");
8144       return -99;
8145     }
8146
8147   /* Construct the API message */
8148   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8149
8150   mp->sw_if_index = ntohl (sw_if_index);
8151   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8152
8153   /* send it... */
8154   S (mp);
8155
8156   /* Wait for a reply, return good/bad news  */
8157   W (ret);
8158   return ret;
8159 }
8160
8161
8162 static int
8163 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8164 {
8165   unformat_input_t *i = vam->input;
8166   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8167   u32 sw_if_index;
8168   u8 sw_if_index_set = 0;
8169   u32 address_length = 0;
8170   u8 v6_address_set = 0;
8171   ip6_address_t v6address;
8172   u8 use_default = 0;
8173   u8 no_advertise = 0;
8174   u8 off_link = 0;
8175   u8 no_autoconfig = 0;
8176   u8 no_onlink = 0;
8177   u8 is_no = 0;
8178   u32 val_lifetime = 0;
8179   u32 pref_lifetime = 0;
8180   int ret;
8181
8182   /* Parse args required to build the message */
8183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8184     {
8185       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8186         sw_if_index_set = 1;
8187       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8188         sw_if_index_set = 1;
8189       else if (unformat (i, "%U/%d",
8190                          unformat_ip6_address, &v6address, &address_length))
8191         v6_address_set = 1;
8192       else if (unformat (i, "val_life %d", &val_lifetime))
8193         ;
8194       else if (unformat (i, "pref_life %d", &pref_lifetime))
8195         ;
8196       else if (unformat (i, "def"))
8197         use_default = 1;
8198       else if (unformat (i, "noadv"))
8199         no_advertise = 1;
8200       else if (unformat (i, "offl"))
8201         off_link = 1;
8202       else if (unformat (i, "noauto"))
8203         no_autoconfig = 1;
8204       else if (unformat (i, "nolink"))
8205         no_onlink = 1;
8206       else if (unformat (i, "isno"))
8207         is_no = 1;
8208       else
8209         {
8210           clib_warning ("parse error '%U'", format_unformat_error, i);
8211           return -99;
8212         }
8213     }
8214
8215   if (sw_if_index_set == 0)
8216     {
8217       errmsg ("missing interface name or sw_if_index");
8218       return -99;
8219     }
8220   if (!v6_address_set)
8221     {
8222       errmsg ("no address set");
8223       return -99;
8224     }
8225
8226   /* Construct the API message */
8227   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8228
8229   mp->sw_if_index = ntohl (sw_if_index);
8230   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8231   mp->address_length = address_length;
8232   mp->use_default = use_default;
8233   mp->no_advertise = no_advertise;
8234   mp->off_link = off_link;
8235   mp->no_autoconfig = no_autoconfig;
8236   mp->no_onlink = no_onlink;
8237   mp->is_no = is_no;
8238   mp->val_lifetime = ntohl (val_lifetime);
8239   mp->pref_lifetime = ntohl (pref_lifetime);
8240
8241   /* send it... */
8242   S (mp);
8243
8244   /* Wait for a reply, return good/bad news  */
8245   W (ret);
8246   return ret;
8247 }
8248
8249 static int
8250 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8251 {
8252   unformat_input_t *i = vam->input;
8253   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8254   u32 sw_if_index;
8255   u8 sw_if_index_set = 0;
8256   u8 suppress = 0;
8257   u8 managed = 0;
8258   u8 other = 0;
8259   u8 ll_option = 0;
8260   u8 send_unicast = 0;
8261   u8 cease = 0;
8262   u8 is_no = 0;
8263   u8 default_router = 0;
8264   u32 max_interval = 0;
8265   u32 min_interval = 0;
8266   u32 lifetime = 0;
8267   u32 initial_count = 0;
8268   u32 initial_interval = 0;
8269   int ret;
8270
8271
8272   /* Parse args required to build the message */
8273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8274     {
8275       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8276         sw_if_index_set = 1;
8277       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8278         sw_if_index_set = 1;
8279       else if (unformat (i, "maxint %d", &max_interval))
8280         ;
8281       else if (unformat (i, "minint %d", &min_interval))
8282         ;
8283       else if (unformat (i, "life %d", &lifetime))
8284         ;
8285       else if (unformat (i, "count %d", &initial_count))
8286         ;
8287       else if (unformat (i, "interval %d", &initial_interval))
8288         ;
8289       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8290         suppress = 1;
8291       else if (unformat (i, "managed"))
8292         managed = 1;
8293       else if (unformat (i, "other"))
8294         other = 1;
8295       else if (unformat (i, "ll"))
8296         ll_option = 1;
8297       else if (unformat (i, "send"))
8298         send_unicast = 1;
8299       else if (unformat (i, "cease"))
8300         cease = 1;
8301       else if (unformat (i, "isno"))
8302         is_no = 1;
8303       else if (unformat (i, "def"))
8304         default_router = 1;
8305       else
8306         {
8307           clib_warning ("parse error '%U'", format_unformat_error, i);
8308           return -99;
8309         }
8310     }
8311
8312   if (sw_if_index_set == 0)
8313     {
8314       errmsg ("missing interface name or sw_if_index");
8315       return -99;
8316     }
8317
8318   /* Construct the API message */
8319   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8320
8321   mp->sw_if_index = ntohl (sw_if_index);
8322   mp->max_interval = ntohl (max_interval);
8323   mp->min_interval = ntohl (min_interval);
8324   mp->lifetime = ntohl (lifetime);
8325   mp->initial_count = ntohl (initial_count);
8326   mp->initial_interval = ntohl (initial_interval);
8327   mp->suppress = suppress;
8328   mp->managed = managed;
8329   mp->other = other;
8330   mp->ll_option = ll_option;
8331   mp->send_unicast = send_unicast;
8332   mp->cease = cease;
8333   mp->is_no = is_no;
8334   mp->default_router = default_router;
8335
8336   /* send it... */
8337   S (mp);
8338
8339   /* Wait for a reply, return good/bad news  */
8340   W (ret);
8341   return ret;
8342 }
8343
8344 static int
8345 api_set_arp_neighbor_limit (vat_main_t * vam)
8346 {
8347   unformat_input_t *i = vam->input;
8348   vl_api_set_arp_neighbor_limit_t *mp;
8349   u32 arp_nbr_limit;
8350   u8 limit_set = 0;
8351   u8 is_ipv6 = 0;
8352   int ret;
8353
8354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8355     {
8356       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8357         limit_set = 1;
8358       else if (unformat (i, "ipv6"))
8359         is_ipv6 = 1;
8360       else
8361         {
8362           clib_warning ("parse error '%U'", format_unformat_error, i);
8363           return -99;
8364         }
8365     }
8366
8367   if (limit_set == 0)
8368     {
8369       errmsg ("missing limit value");
8370       return -99;
8371     }
8372
8373   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8374
8375   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8376   mp->is_ipv6 = is_ipv6;
8377
8378   S (mp);
8379   W (ret);
8380   return ret;
8381 }
8382
8383 static int
8384 api_l2_patch_add_del (vat_main_t * vam)
8385 {
8386   unformat_input_t *i = vam->input;
8387   vl_api_l2_patch_add_del_t *mp;
8388   u32 rx_sw_if_index;
8389   u8 rx_sw_if_index_set = 0;
8390   u32 tx_sw_if_index;
8391   u8 tx_sw_if_index_set = 0;
8392   u8 is_add = 1;
8393   int ret;
8394
8395   /* Parse args required to build the message */
8396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8397     {
8398       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8399         rx_sw_if_index_set = 1;
8400       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8401         tx_sw_if_index_set = 1;
8402       else if (unformat (i, "rx"))
8403         {
8404           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8405             {
8406               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8407                             &rx_sw_if_index))
8408                 rx_sw_if_index_set = 1;
8409             }
8410           else
8411             break;
8412         }
8413       else if (unformat (i, "tx"))
8414         {
8415           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8416             {
8417               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8418                             &tx_sw_if_index))
8419                 tx_sw_if_index_set = 1;
8420             }
8421           else
8422             break;
8423         }
8424       else if (unformat (i, "del"))
8425         is_add = 0;
8426       else
8427         break;
8428     }
8429
8430   if (rx_sw_if_index_set == 0)
8431     {
8432       errmsg ("missing rx interface name or rx_sw_if_index");
8433       return -99;
8434     }
8435
8436   if (tx_sw_if_index_set == 0)
8437     {
8438       errmsg ("missing tx interface name or tx_sw_if_index");
8439       return -99;
8440     }
8441
8442   M (L2_PATCH_ADD_DEL, mp);
8443
8444   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8445   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8446   mp->is_add = is_add;
8447
8448   S (mp);
8449   W (ret);
8450   return ret;
8451 }
8452
8453 static int
8454 api_ioam_enable (vat_main_t * vam)
8455 {
8456   unformat_input_t *input = vam->input;
8457   vl_api_ioam_enable_t *mp;
8458   u32 id = 0;
8459   int has_trace_option = 0;
8460   int has_pot_option = 0;
8461   int has_seqno_option = 0;
8462   int has_analyse_option = 0;
8463   int ret;
8464
8465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8466     {
8467       if (unformat (input, "trace"))
8468         has_trace_option = 1;
8469       else if (unformat (input, "pot"))
8470         has_pot_option = 1;
8471       else if (unformat (input, "seqno"))
8472         has_seqno_option = 1;
8473       else if (unformat (input, "analyse"))
8474         has_analyse_option = 1;
8475       else
8476         break;
8477     }
8478   M (IOAM_ENABLE, mp);
8479   mp->id = htons (id);
8480   mp->seqno = has_seqno_option;
8481   mp->analyse = has_analyse_option;
8482   mp->pot_enable = has_pot_option;
8483   mp->trace_enable = has_trace_option;
8484
8485   S (mp);
8486   W (ret);
8487   return ret;
8488 }
8489
8490
8491 static int
8492 api_ioam_disable (vat_main_t * vam)
8493 {
8494   vl_api_ioam_disable_t *mp;
8495   int ret;
8496
8497   M (IOAM_DISABLE, mp);
8498   S (mp);
8499   W (ret);
8500   return ret;
8501 }
8502
8503 static int
8504 api_sr_tunnel_add_del (vat_main_t * vam)
8505 {
8506   unformat_input_t *i = vam->input;
8507   vl_api_sr_tunnel_add_del_t *mp;
8508   int is_del = 0;
8509   int pl_index;
8510   ip6_address_t src_address;
8511   int src_address_set = 0;
8512   ip6_address_t dst_address;
8513   u32 dst_mask_width;
8514   int dst_address_set = 0;
8515   u16 flags = 0;
8516   u32 rx_table_id = 0;
8517   u32 tx_table_id = 0;
8518   ip6_address_t *segments = 0;
8519   ip6_address_t *this_seg;
8520   ip6_address_t *tags = 0;
8521   ip6_address_t *this_tag;
8522   ip6_address_t next_address, tag;
8523   u8 *name = 0;
8524   u8 *policy_name = 0;
8525   int ret;
8526
8527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8528     {
8529       if (unformat (i, "del"))
8530         is_del = 1;
8531       else if (unformat (i, "name %s", &name))
8532         ;
8533       else if (unformat (i, "policy %s", &policy_name))
8534         ;
8535       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8536         ;
8537       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8538         ;
8539       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8540         src_address_set = 1;
8541       else if (unformat (i, "dst %U/%d",
8542                          unformat_ip6_address, &dst_address, &dst_mask_width))
8543         dst_address_set = 1;
8544       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8545         {
8546           vec_add2 (segments, this_seg, 1);
8547           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8548                        sizeof (*this_seg));
8549         }
8550       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8551         {
8552           vec_add2 (tags, this_tag, 1);
8553           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8554         }
8555       else if (unformat (i, "clean"))
8556         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8557       else if (unformat (i, "protected"))
8558         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8559       else if (unformat (i, "InPE %d", &pl_index))
8560         {
8561           if (pl_index <= 0 || pl_index > 4)
8562             {
8563             pl_index_range_error:
8564               errmsg ("pl index %d out of range", pl_index);
8565               return -99;
8566             }
8567           flags |=
8568             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8569         }
8570       else if (unformat (i, "EgPE %d", &pl_index))
8571         {
8572           if (pl_index <= 0 || pl_index > 4)
8573             goto pl_index_range_error;
8574           flags |=
8575             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8576         }
8577       else if (unformat (i, "OrgSrc %d", &pl_index))
8578         {
8579           if (pl_index <= 0 || pl_index > 4)
8580             goto pl_index_range_error;
8581           flags |=
8582             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8583         }
8584       else
8585         break;
8586     }
8587
8588   if (!src_address_set)
8589     {
8590       errmsg ("src address required");
8591       return -99;
8592     }
8593
8594   if (!dst_address_set)
8595     {
8596       errmsg ("dst address required");
8597       return -99;
8598     }
8599
8600   if (!segments)
8601     {
8602       errmsg ("at least one sr segment required");
8603       return -99;
8604     }
8605
8606   M2 (SR_TUNNEL_ADD_DEL, mp,
8607       vec_len (segments) * sizeof (ip6_address_t)
8608       + vec_len (tags) * sizeof (ip6_address_t));
8609
8610   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8611   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8612   mp->dst_mask_width = dst_mask_width;
8613   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8614   mp->n_segments = vec_len (segments);
8615   mp->n_tags = vec_len (tags);
8616   mp->is_add = is_del == 0;
8617   clib_memcpy (mp->segs_and_tags, segments,
8618                vec_len (segments) * sizeof (ip6_address_t));
8619   clib_memcpy (mp->segs_and_tags +
8620                vec_len (segments) * sizeof (ip6_address_t), tags,
8621                vec_len (tags) * sizeof (ip6_address_t));
8622
8623   mp->outer_vrf_id = ntohl (rx_table_id);
8624   mp->inner_vrf_id = ntohl (tx_table_id);
8625   memcpy (mp->name, name, vec_len (name));
8626   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8627
8628   vec_free (segments);
8629   vec_free (tags);
8630
8631   S (mp);
8632   W (ret);
8633   return ret;
8634 }
8635
8636 static int
8637 api_sr_policy_add_del (vat_main_t * vam)
8638 {
8639   unformat_input_t *input = vam->input;
8640   vl_api_sr_policy_add_del_t *mp;
8641   int is_del = 0;
8642   u8 *name = 0;
8643   u8 *tunnel_name = 0;
8644   u8 **tunnel_names = 0;
8645
8646   int name_set = 0;
8647   int tunnel_set = 0;
8648   int j = 0;
8649   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8650   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8651   int ret;
8652
8653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8654     {
8655       if (unformat (input, "del"))
8656         is_del = 1;
8657       else if (unformat (input, "name %s", &name))
8658         name_set = 1;
8659       else if (unformat (input, "tunnel %s", &tunnel_name))
8660         {
8661           if (tunnel_name)
8662             {
8663               vec_add1 (tunnel_names, tunnel_name);
8664               /* For serializer:
8665                  - length = #bytes to store in serial vector
8666                  - +1 = byte to store that length
8667                */
8668               tunnel_names_length += (vec_len (tunnel_name) + 1);
8669               tunnel_set = 1;
8670               tunnel_name = 0;
8671             }
8672         }
8673       else
8674         break;
8675     }
8676
8677   if (!name_set)
8678     {
8679       errmsg ("policy name required");
8680       return -99;
8681     }
8682
8683   if ((!tunnel_set) && (!is_del))
8684     {
8685       errmsg ("tunnel name required");
8686       return -99;
8687     }
8688
8689   M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
8690
8691
8692
8693   mp->is_add = !is_del;
8694
8695   memcpy (mp->name, name, vec_len (name));
8696   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8697   u8 *serial_orig = 0;
8698   vec_validate (serial_orig, tunnel_names_length);
8699   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8700   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8701
8702   for (j = 0; j < vec_len (tunnel_names); j++)
8703     {
8704       tun_name_len = vec_len (tunnel_names[j]);
8705       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8706       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8707       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8708       serial_orig += tun_name_len;      // Advance past the copy
8709     }
8710   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8711
8712   vec_free (tunnel_names);
8713   vec_free (tunnel_name);
8714
8715   S (mp);
8716   W (ret);
8717   return ret;
8718 }
8719
8720 static int
8721 api_sr_multicast_map_add_del (vat_main_t * vam)
8722 {
8723   unformat_input_t *input = vam->input;
8724   vl_api_sr_multicast_map_add_del_t *mp;
8725   int is_del = 0;
8726   ip6_address_t multicast_address;
8727   u8 *policy_name = 0;
8728   int multicast_address_set = 0;
8729   int ret;
8730
8731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8732     {
8733       if (unformat (input, "del"))
8734         is_del = 1;
8735       else
8736         if (unformat
8737             (input, "address %U", unformat_ip6_address, &multicast_address))
8738         multicast_address_set = 1;
8739       else if (unformat (input, "sr-policy %s", &policy_name))
8740         ;
8741       else
8742         break;
8743     }
8744
8745   if (!is_del && !policy_name)
8746     {
8747       errmsg ("sr-policy name required");
8748       return -99;
8749     }
8750
8751
8752   if (!multicast_address_set)
8753     {
8754       errmsg ("address required");
8755       return -99;
8756     }
8757
8758   M (SR_MULTICAST_MAP_ADD_DEL, mp);
8759
8760   mp->is_add = !is_del;
8761   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8762   clib_memcpy (mp->multicast_address, &multicast_address,
8763                sizeof (mp->multicast_address));
8764
8765
8766   vec_free (policy_name);
8767
8768   S (mp);
8769   W (ret);
8770   return ret;
8771 }
8772
8773
8774 #define foreach_tcp_proto_field                 \
8775 _(src_port)                                     \
8776 _(dst_port)
8777
8778 #define foreach_udp_proto_field                 \
8779 _(src_port)                                     \
8780 _(dst_port)
8781
8782 #define foreach_ip4_proto_field                 \
8783 _(src_address)                                  \
8784 _(dst_address)                                  \
8785 _(tos)                                          \
8786 _(length)                                       \
8787 _(fragment_id)                                  \
8788 _(ttl)                                          \
8789 _(protocol)                                     \
8790 _(checksum)
8791
8792 typedef struct
8793 {
8794   u16 src_port, dst_port;
8795 } tcpudp_header_t;
8796
8797 #if VPP_API_TEST_BUILTIN == 0
8798 uword
8799 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8800 {
8801   u8 **maskp = va_arg (*args, u8 **);
8802   u8 *mask = 0;
8803   u8 found_something = 0;
8804   tcp_header_t *tcp;
8805
8806 #define _(a) u8 a=0;
8807   foreach_tcp_proto_field;
8808 #undef _
8809
8810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (0);
8813 #define _(a) else if (unformat (input, #a)) a=1;
8814       foreach_tcp_proto_field
8815 #undef _
8816         else
8817         break;
8818     }
8819
8820 #define _(a) found_something += a;
8821   foreach_tcp_proto_field;
8822 #undef _
8823
8824   if (found_something == 0)
8825     return 0;
8826
8827   vec_validate (mask, sizeof (*tcp) - 1);
8828
8829   tcp = (tcp_header_t *) mask;
8830
8831 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8832   foreach_tcp_proto_field;
8833 #undef _
8834
8835   *maskp = mask;
8836   return 1;
8837 }
8838
8839 uword
8840 unformat_udp_mask (unformat_input_t * input, va_list * args)
8841 {
8842   u8 **maskp = va_arg (*args, u8 **);
8843   u8 *mask = 0;
8844   u8 found_something = 0;
8845   udp_header_t *udp;
8846
8847 #define _(a) u8 a=0;
8848   foreach_udp_proto_field;
8849 #undef _
8850
8851   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8852     {
8853       if (0);
8854 #define _(a) else if (unformat (input, #a)) a=1;
8855       foreach_udp_proto_field
8856 #undef _
8857         else
8858         break;
8859     }
8860
8861 #define _(a) found_something += a;
8862   foreach_udp_proto_field;
8863 #undef _
8864
8865   if (found_something == 0)
8866     return 0;
8867
8868   vec_validate (mask, sizeof (*udp) - 1);
8869
8870   udp = (udp_header_t *) mask;
8871
8872 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8873   foreach_udp_proto_field;
8874 #undef _
8875
8876   *maskp = mask;
8877   return 1;
8878 }
8879
8880 uword
8881 unformat_l4_mask (unformat_input_t * input, va_list * args)
8882 {
8883   u8 **maskp = va_arg (*args, u8 **);
8884   u16 src_port = 0, dst_port = 0;
8885   tcpudp_header_t *tcpudp;
8886
8887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8888     {
8889       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8890         return 1;
8891       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8892         return 1;
8893       else if (unformat (input, "src_port"))
8894         src_port = 0xFFFF;
8895       else if (unformat (input, "dst_port"))
8896         dst_port = 0xFFFF;
8897       else
8898         return 0;
8899     }
8900
8901   if (!src_port && !dst_port)
8902     return 0;
8903
8904   u8 *mask = 0;
8905   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8906
8907   tcpudp = (tcpudp_header_t *) mask;
8908   tcpudp->src_port = src_port;
8909   tcpudp->dst_port = dst_port;
8910
8911   *maskp = mask;
8912
8913   return 1;
8914 }
8915
8916 uword
8917 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8918 {
8919   u8 **maskp = va_arg (*args, u8 **);
8920   u8 *mask = 0;
8921   u8 found_something = 0;
8922   ip4_header_t *ip;
8923
8924 #define _(a) u8 a=0;
8925   foreach_ip4_proto_field;
8926 #undef _
8927   u8 version = 0;
8928   u8 hdr_length = 0;
8929
8930
8931   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8932     {
8933       if (unformat (input, "version"))
8934         version = 1;
8935       else if (unformat (input, "hdr_length"))
8936         hdr_length = 1;
8937       else if (unformat (input, "src"))
8938         src_address = 1;
8939       else if (unformat (input, "dst"))
8940         dst_address = 1;
8941       else if (unformat (input, "proto"))
8942         protocol = 1;
8943
8944 #define _(a) else if (unformat (input, #a)) a=1;
8945       foreach_ip4_proto_field
8946 #undef _
8947         else
8948         break;
8949     }
8950
8951 #define _(a) found_something += a;
8952   foreach_ip4_proto_field;
8953 #undef _
8954
8955   if (found_something == 0)
8956     return 0;
8957
8958   vec_validate (mask, sizeof (*ip) - 1);
8959
8960   ip = (ip4_header_t *) mask;
8961
8962 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8963   foreach_ip4_proto_field;
8964 #undef _
8965
8966   ip->ip_version_and_header_length = 0;
8967
8968   if (version)
8969     ip->ip_version_and_header_length |= 0xF0;
8970
8971   if (hdr_length)
8972     ip->ip_version_and_header_length |= 0x0F;
8973
8974   *maskp = mask;
8975   return 1;
8976 }
8977
8978 #define foreach_ip6_proto_field                 \
8979 _(src_address)                                  \
8980 _(dst_address)                                  \
8981 _(payload_length)                               \
8982 _(hop_limit)                                    \
8983 _(protocol)
8984
8985 uword
8986 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8987 {
8988   u8 **maskp = va_arg (*args, u8 **);
8989   u8 *mask = 0;
8990   u8 found_something = 0;
8991   ip6_header_t *ip;
8992   u32 ip_version_traffic_class_and_flow_label;
8993
8994 #define _(a) u8 a=0;
8995   foreach_ip6_proto_field;
8996 #undef _
8997   u8 version = 0;
8998   u8 traffic_class = 0;
8999   u8 flow_label = 0;
9000
9001   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9002     {
9003       if (unformat (input, "version"))
9004         version = 1;
9005       else if (unformat (input, "traffic-class"))
9006         traffic_class = 1;
9007       else if (unformat (input, "flow-label"))
9008         flow_label = 1;
9009       else if (unformat (input, "src"))
9010         src_address = 1;
9011       else if (unformat (input, "dst"))
9012         dst_address = 1;
9013       else if (unformat (input, "proto"))
9014         protocol = 1;
9015
9016 #define _(a) else if (unformat (input, #a)) a=1;
9017       foreach_ip6_proto_field
9018 #undef _
9019         else
9020         break;
9021     }
9022
9023 #define _(a) found_something += a;
9024   foreach_ip6_proto_field;
9025 #undef _
9026
9027   if (found_something == 0)
9028     return 0;
9029
9030   vec_validate (mask, sizeof (*ip) - 1);
9031
9032   ip = (ip6_header_t *) mask;
9033
9034 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9035   foreach_ip6_proto_field;
9036 #undef _
9037
9038   ip_version_traffic_class_and_flow_label = 0;
9039
9040   if (version)
9041     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9042
9043   if (traffic_class)
9044     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9045
9046   if (flow_label)
9047     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9048
9049   ip->ip_version_traffic_class_and_flow_label =
9050     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9051
9052   *maskp = mask;
9053   return 1;
9054 }
9055
9056 uword
9057 unformat_l3_mask (unformat_input_t * input, va_list * args)
9058 {
9059   u8 **maskp = va_arg (*args, u8 **);
9060
9061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9062     {
9063       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9064         return 1;
9065       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9066         return 1;
9067       else
9068         break;
9069     }
9070   return 0;
9071 }
9072
9073 uword
9074 unformat_l2_mask (unformat_input_t * input, va_list * args)
9075 {
9076   u8 **maskp = va_arg (*args, u8 **);
9077   u8 *mask = 0;
9078   u8 src = 0;
9079   u8 dst = 0;
9080   u8 proto = 0;
9081   u8 tag1 = 0;
9082   u8 tag2 = 0;
9083   u8 ignore_tag1 = 0;
9084   u8 ignore_tag2 = 0;
9085   u8 cos1 = 0;
9086   u8 cos2 = 0;
9087   u8 dot1q = 0;
9088   u8 dot1ad = 0;
9089   int len = 14;
9090
9091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9092     {
9093       if (unformat (input, "src"))
9094         src = 1;
9095       else if (unformat (input, "dst"))
9096         dst = 1;
9097       else if (unformat (input, "proto"))
9098         proto = 1;
9099       else if (unformat (input, "tag1"))
9100         tag1 = 1;
9101       else if (unformat (input, "tag2"))
9102         tag2 = 1;
9103       else if (unformat (input, "ignore-tag1"))
9104         ignore_tag1 = 1;
9105       else if (unformat (input, "ignore-tag2"))
9106         ignore_tag2 = 1;
9107       else if (unformat (input, "cos1"))
9108         cos1 = 1;
9109       else if (unformat (input, "cos2"))
9110         cos2 = 1;
9111       else if (unformat (input, "dot1q"))
9112         dot1q = 1;
9113       else if (unformat (input, "dot1ad"))
9114         dot1ad = 1;
9115       else
9116         break;
9117     }
9118   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9119        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9120     return 0;
9121
9122   if (tag1 || ignore_tag1 || cos1 || dot1q)
9123     len = 18;
9124   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9125     len = 22;
9126
9127   vec_validate (mask, len - 1);
9128
9129   if (dst)
9130     memset (mask, 0xff, 6);
9131
9132   if (src)
9133     memset (mask + 6, 0xff, 6);
9134
9135   if (tag2 || dot1ad)
9136     {
9137       /* inner vlan tag */
9138       if (tag2)
9139         {
9140           mask[19] = 0xff;
9141           mask[18] = 0x0f;
9142         }
9143       if (cos2)
9144         mask[18] |= 0xe0;
9145       if (proto)
9146         mask[21] = mask[20] = 0xff;
9147       if (tag1)
9148         {
9149           mask[15] = 0xff;
9150           mask[14] = 0x0f;
9151         }
9152       if (cos1)
9153         mask[14] |= 0xe0;
9154       *maskp = mask;
9155       return 1;
9156     }
9157   if (tag1 | dot1q)
9158     {
9159       if (tag1)
9160         {
9161           mask[15] = 0xff;
9162           mask[14] = 0x0f;
9163         }
9164       if (cos1)
9165         mask[14] |= 0xe0;
9166       if (proto)
9167         mask[16] = mask[17] = 0xff;
9168
9169       *maskp = mask;
9170       return 1;
9171     }
9172   if (cos2)
9173     mask[18] |= 0xe0;
9174   if (cos1)
9175     mask[14] |= 0xe0;
9176   if (proto)
9177     mask[12] = mask[13] = 0xff;
9178
9179   *maskp = mask;
9180   return 1;
9181 }
9182
9183 uword
9184 unformat_classify_mask (unformat_input_t * input, va_list * args)
9185 {
9186   u8 **maskp = va_arg (*args, u8 **);
9187   u32 *skipp = va_arg (*args, u32 *);
9188   u32 *matchp = va_arg (*args, u32 *);
9189   u32 match;
9190   u8 *mask = 0;
9191   u8 *l2 = 0;
9192   u8 *l3 = 0;
9193   u8 *l4 = 0;
9194   int i;
9195
9196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9197     {
9198       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9199         ;
9200       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9201         ;
9202       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9203         ;
9204       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9205         ;
9206       else
9207         break;
9208     }
9209
9210   if (l4 && !l3)
9211     {
9212       vec_free (mask);
9213       vec_free (l2);
9214       vec_free (l4);
9215       return 0;
9216     }
9217
9218   if (mask || l2 || l3 || l4)
9219     {
9220       if (l2 || l3 || l4)
9221         {
9222           /* "With a free Ethernet header in every package" */
9223           if (l2 == 0)
9224             vec_validate (l2, 13);
9225           mask = l2;
9226           if (vec_len (l3))
9227             {
9228               vec_append (mask, l3);
9229               vec_free (l3);
9230             }
9231           if (vec_len (l4))
9232             {
9233               vec_append (mask, l4);
9234               vec_free (l4);
9235             }
9236         }
9237
9238       /* Scan forward looking for the first significant mask octet */
9239       for (i = 0; i < vec_len (mask); i++)
9240         if (mask[i])
9241           break;
9242
9243       /* compute (skip, match) params */
9244       *skipp = i / sizeof (u32x4);
9245       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9246
9247       /* Pad mask to an even multiple of the vector size */
9248       while (vec_len (mask) % sizeof (u32x4))
9249         vec_add1 (mask, 0);
9250
9251       match = vec_len (mask) / sizeof (u32x4);
9252
9253       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9254         {
9255           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9256           if (*tmp || *(tmp + 1))
9257             break;
9258           match--;
9259         }
9260       if (match == 0)
9261         clib_warning ("BUG: match 0");
9262
9263       _vec_len (mask) = match * sizeof (u32x4);
9264
9265       *matchp = match;
9266       *maskp = mask;
9267
9268       return 1;
9269     }
9270
9271   return 0;
9272 }
9273 #endif /* VPP_API_TEST_BUILTIN */
9274
9275 #define foreach_l2_next                         \
9276 _(drop, DROP)                                   \
9277 _(ethernet, ETHERNET_INPUT)                     \
9278 _(ip4, IP4_INPUT)                               \
9279 _(ip6, IP6_INPUT)
9280
9281 uword
9282 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9283 {
9284   u32 *miss_next_indexp = va_arg (*args, u32 *);
9285   u32 next_index = 0;
9286   u32 tmp;
9287
9288 #define _(n,N) \
9289   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9290   foreach_l2_next;
9291 #undef _
9292
9293   if (unformat (input, "%d", &tmp))
9294     {
9295       next_index = tmp;
9296       goto out;
9297     }
9298
9299   return 0;
9300
9301 out:
9302   *miss_next_indexp = next_index;
9303   return 1;
9304 }
9305
9306 #define foreach_ip_next                         \
9307 _(drop, DROP)                                   \
9308 _(local, LOCAL)                                 \
9309 _(rewrite, REWRITE)
9310
9311 uword
9312 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9313 {
9314   u32 *miss_next_indexp = va_arg (*args, u32 *);
9315   u32 next_index = 0;
9316   u32 tmp;
9317
9318 #define _(n,N) \
9319   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9320   foreach_ip_next;
9321 #undef _
9322
9323   if (unformat (input, "%d", &tmp))
9324     {
9325       next_index = tmp;
9326       goto out;
9327     }
9328
9329   return 0;
9330
9331 out:
9332   *miss_next_indexp = next_index;
9333   return 1;
9334 }
9335
9336 #define foreach_acl_next                        \
9337 _(deny, DENY)
9338
9339 uword
9340 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9341 {
9342   u32 *miss_next_indexp = va_arg (*args, u32 *);
9343   u32 next_index = 0;
9344   u32 tmp;
9345
9346 #define _(n,N) \
9347   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9348   foreach_acl_next;
9349 #undef _
9350
9351   if (unformat (input, "permit"))
9352     {
9353       next_index = ~0;
9354       goto out;
9355     }
9356   else if (unformat (input, "%d", &tmp))
9357     {
9358       next_index = tmp;
9359       goto out;
9360     }
9361
9362   return 0;
9363
9364 out:
9365   *miss_next_indexp = next_index;
9366   return 1;
9367 }
9368
9369 uword
9370 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9371 {
9372   u32 *r = va_arg (*args, u32 *);
9373
9374   if (unformat (input, "conform-color"))
9375     *r = POLICE_CONFORM;
9376   else if (unformat (input, "exceed-color"))
9377     *r = POLICE_EXCEED;
9378   else
9379     return 0;
9380
9381   return 1;
9382 }
9383
9384 static int
9385 api_classify_add_del_table (vat_main_t * vam)
9386 {
9387   unformat_input_t *i = vam->input;
9388   vl_api_classify_add_del_table_t *mp;
9389
9390   u32 nbuckets = 2;
9391   u32 skip = ~0;
9392   u32 match = ~0;
9393   int is_add = 1;
9394   int del_chain = 0;
9395   u32 table_index = ~0;
9396   u32 next_table_index = ~0;
9397   u32 miss_next_index = ~0;
9398   u32 memory_size = 32 << 20;
9399   u8 *mask = 0;
9400   u32 current_data_flag = 0;
9401   int current_data_offset = 0;
9402   int ret;
9403
9404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9405     {
9406       if (unformat (i, "del"))
9407         is_add = 0;
9408       else if (unformat (i, "del-chain"))
9409         {
9410           is_add = 0;
9411           del_chain = 1;
9412         }
9413       else if (unformat (i, "buckets %d", &nbuckets))
9414         ;
9415       else if (unformat (i, "memory_size %d", &memory_size))
9416         ;
9417       else if (unformat (i, "skip %d", &skip))
9418         ;
9419       else if (unformat (i, "match %d", &match))
9420         ;
9421       else if (unformat (i, "table %d", &table_index))
9422         ;
9423       else if (unformat (i, "mask %U", unformat_classify_mask,
9424                          &mask, &skip, &match))
9425         ;
9426       else if (unformat (i, "next-table %d", &next_table_index))
9427         ;
9428       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9429                          &miss_next_index))
9430         ;
9431       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9432                          &miss_next_index))
9433         ;
9434       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9435                          &miss_next_index))
9436         ;
9437       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9438         ;
9439       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9440         ;
9441       else
9442         break;
9443     }
9444
9445   if (is_add && mask == 0)
9446     {
9447       errmsg ("Mask required");
9448       return -99;
9449     }
9450
9451   if (is_add && skip == ~0)
9452     {
9453       errmsg ("skip count required");
9454       return -99;
9455     }
9456
9457   if (is_add && match == ~0)
9458     {
9459       errmsg ("match count required");
9460       return -99;
9461     }
9462
9463   if (!is_add && table_index == ~0)
9464     {
9465       errmsg ("table index required for delete");
9466       return -99;
9467     }
9468
9469   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9470
9471   mp->is_add = is_add;
9472   mp->del_chain = del_chain;
9473   mp->table_index = ntohl (table_index);
9474   mp->nbuckets = ntohl (nbuckets);
9475   mp->memory_size = ntohl (memory_size);
9476   mp->skip_n_vectors = ntohl (skip);
9477   mp->match_n_vectors = ntohl (match);
9478   mp->next_table_index = ntohl (next_table_index);
9479   mp->miss_next_index = ntohl (miss_next_index);
9480   mp->current_data_flag = ntohl (current_data_flag);
9481   mp->current_data_offset = ntohl (current_data_offset);
9482   clib_memcpy (mp->mask, mask, vec_len (mask));
9483
9484   vec_free (mask);
9485
9486   S (mp);
9487   W (ret);
9488   return ret;
9489 }
9490
9491 #if VPP_API_TEST_BUILTIN == 0
9492 uword
9493 unformat_l4_match (unformat_input_t * input, va_list * args)
9494 {
9495   u8 **matchp = va_arg (*args, u8 **);
9496
9497   u8 *proto_header = 0;
9498   int src_port = 0;
9499   int dst_port = 0;
9500
9501   tcpudp_header_t h;
9502
9503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9504     {
9505       if (unformat (input, "src_port %d", &src_port))
9506         ;
9507       else if (unformat (input, "dst_port %d", &dst_port))
9508         ;
9509       else
9510         return 0;
9511     }
9512
9513   h.src_port = clib_host_to_net_u16 (src_port);
9514   h.dst_port = clib_host_to_net_u16 (dst_port);
9515   vec_validate (proto_header, sizeof (h) - 1);
9516   memcpy (proto_header, &h, sizeof (h));
9517
9518   *matchp = proto_header;
9519
9520   return 1;
9521 }
9522
9523 uword
9524 unformat_ip4_match (unformat_input_t * input, va_list * args)
9525 {
9526   u8 **matchp = va_arg (*args, u8 **);
9527   u8 *match = 0;
9528   ip4_header_t *ip;
9529   int version = 0;
9530   u32 version_val;
9531   int hdr_length = 0;
9532   u32 hdr_length_val;
9533   int src = 0, dst = 0;
9534   ip4_address_t src_val, dst_val;
9535   int proto = 0;
9536   u32 proto_val;
9537   int tos = 0;
9538   u32 tos_val;
9539   int length = 0;
9540   u32 length_val;
9541   int fragment_id = 0;
9542   u32 fragment_id_val;
9543   int ttl = 0;
9544   int ttl_val;
9545   int checksum = 0;
9546   u32 checksum_val;
9547
9548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9549     {
9550       if (unformat (input, "version %d", &version_val))
9551         version = 1;
9552       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9553         hdr_length = 1;
9554       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9555         src = 1;
9556       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9557         dst = 1;
9558       else if (unformat (input, "proto %d", &proto_val))
9559         proto = 1;
9560       else if (unformat (input, "tos %d", &tos_val))
9561         tos = 1;
9562       else if (unformat (input, "length %d", &length_val))
9563         length = 1;
9564       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9565         fragment_id = 1;
9566       else if (unformat (input, "ttl %d", &ttl_val))
9567         ttl = 1;
9568       else if (unformat (input, "checksum %d", &checksum_val))
9569         checksum = 1;
9570       else
9571         break;
9572     }
9573
9574   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9575       + ttl + checksum == 0)
9576     return 0;
9577
9578   /*
9579    * Aligned because we use the real comparison functions
9580    */
9581   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9582
9583   ip = (ip4_header_t *) match;
9584
9585   /* These are realistically matched in practice */
9586   if (src)
9587     ip->src_address.as_u32 = src_val.as_u32;
9588
9589   if (dst)
9590     ip->dst_address.as_u32 = dst_val.as_u32;
9591
9592   if (proto)
9593     ip->protocol = proto_val;
9594
9595
9596   /* These are not, but they're included for completeness */
9597   if (version)
9598     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9599
9600   if (hdr_length)
9601     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9602
9603   if (tos)
9604     ip->tos = tos_val;
9605
9606   if (length)
9607     ip->length = clib_host_to_net_u16 (length_val);
9608
9609   if (ttl)
9610     ip->ttl = ttl_val;
9611
9612   if (checksum)
9613     ip->checksum = clib_host_to_net_u16 (checksum_val);
9614
9615   *matchp = match;
9616   return 1;
9617 }
9618
9619 uword
9620 unformat_ip6_match (unformat_input_t * input, va_list * args)
9621 {
9622   u8 **matchp = va_arg (*args, u8 **);
9623   u8 *match = 0;
9624   ip6_header_t *ip;
9625   int version = 0;
9626   u32 version_val;
9627   u8 traffic_class = 0;
9628   u32 traffic_class_val = 0;
9629   u8 flow_label = 0;
9630   u8 flow_label_val;
9631   int src = 0, dst = 0;
9632   ip6_address_t src_val, dst_val;
9633   int proto = 0;
9634   u32 proto_val;
9635   int payload_length = 0;
9636   u32 payload_length_val;
9637   int hop_limit = 0;
9638   int hop_limit_val;
9639   u32 ip_version_traffic_class_and_flow_label;
9640
9641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9642     {
9643       if (unformat (input, "version %d", &version_val))
9644         version = 1;
9645       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9646         traffic_class = 1;
9647       else if (unformat (input, "flow_label %d", &flow_label_val))
9648         flow_label = 1;
9649       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9650         src = 1;
9651       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9652         dst = 1;
9653       else if (unformat (input, "proto %d", &proto_val))
9654         proto = 1;
9655       else if (unformat (input, "payload_length %d", &payload_length_val))
9656         payload_length = 1;
9657       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9658         hop_limit = 1;
9659       else
9660         break;
9661     }
9662
9663   if (version + traffic_class + flow_label + src + dst + proto +
9664       payload_length + hop_limit == 0)
9665     return 0;
9666
9667   /*
9668    * Aligned because we use the real comparison functions
9669    */
9670   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9671
9672   ip = (ip6_header_t *) match;
9673
9674   if (src)
9675     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9676
9677   if (dst)
9678     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9679
9680   if (proto)
9681     ip->protocol = proto_val;
9682
9683   ip_version_traffic_class_and_flow_label = 0;
9684
9685   if (version)
9686     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9687
9688   if (traffic_class)
9689     ip_version_traffic_class_and_flow_label |=
9690       (traffic_class_val & 0xFF) << 20;
9691
9692   if (flow_label)
9693     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9694
9695   ip->ip_version_traffic_class_and_flow_label =
9696     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9697
9698   if (payload_length)
9699     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9700
9701   if (hop_limit)
9702     ip->hop_limit = hop_limit_val;
9703
9704   *matchp = match;
9705   return 1;
9706 }
9707
9708 uword
9709 unformat_l3_match (unformat_input_t * input, va_list * args)
9710 {
9711   u8 **matchp = va_arg (*args, u8 **);
9712
9713   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9714     {
9715       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9716         return 1;
9717       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9718         return 1;
9719       else
9720         break;
9721     }
9722   return 0;
9723 }
9724
9725 uword
9726 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9727 {
9728   u8 *tagp = va_arg (*args, u8 *);
9729   u32 tag;
9730
9731   if (unformat (input, "%d", &tag))
9732     {
9733       tagp[0] = (tag >> 8) & 0x0F;
9734       tagp[1] = tag & 0xFF;
9735       return 1;
9736     }
9737
9738   return 0;
9739 }
9740
9741 uword
9742 unformat_l2_match (unformat_input_t * input, va_list * args)
9743 {
9744   u8 **matchp = va_arg (*args, u8 **);
9745   u8 *match = 0;
9746   u8 src = 0;
9747   u8 src_val[6];
9748   u8 dst = 0;
9749   u8 dst_val[6];
9750   u8 proto = 0;
9751   u16 proto_val;
9752   u8 tag1 = 0;
9753   u8 tag1_val[2];
9754   u8 tag2 = 0;
9755   u8 tag2_val[2];
9756   int len = 14;
9757   u8 ignore_tag1 = 0;
9758   u8 ignore_tag2 = 0;
9759   u8 cos1 = 0;
9760   u8 cos2 = 0;
9761   u32 cos1_val = 0;
9762   u32 cos2_val = 0;
9763
9764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9765     {
9766       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9767         src = 1;
9768       else
9769         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9770         dst = 1;
9771       else if (unformat (input, "proto %U",
9772                          unformat_ethernet_type_host_byte_order, &proto_val))
9773         proto = 1;
9774       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9775         tag1 = 1;
9776       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9777         tag2 = 1;
9778       else if (unformat (input, "ignore-tag1"))
9779         ignore_tag1 = 1;
9780       else if (unformat (input, "ignore-tag2"))
9781         ignore_tag2 = 1;
9782       else if (unformat (input, "cos1 %d", &cos1_val))
9783         cos1 = 1;
9784       else if (unformat (input, "cos2 %d", &cos2_val))
9785         cos2 = 1;
9786       else
9787         break;
9788     }
9789   if ((src + dst + proto + tag1 + tag2 +
9790        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9791     return 0;
9792
9793   if (tag1 || ignore_tag1 || cos1)
9794     len = 18;
9795   if (tag2 || ignore_tag2 || cos2)
9796     len = 22;
9797
9798   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9799
9800   if (dst)
9801     clib_memcpy (match, dst_val, 6);
9802
9803   if (src)
9804     clib_memcpy (match + 6, src_val, 6);
9805
9806   if (tag2)
9807     {
9808       /* inner vlan tag */
9809       match[19] = tag2_val[1];
9810       match[18] = tag2_val[0];
9811       if (cos2)
9812         match[18] |= (cos2_val & 0x7) << 5;
9813       if (proto)
9814         {
9815           match[21] = proto_val & 0xff;
9816           match[20] = proto_val >> 8;
9817         }
9818       if (tag1)
9819         {
9820           match[15] = tag1_val[1];
9821           match[14] = tag1_val[0];
9822         }
9823       if (cos1)
9824         match[14] |= (cos1_val & 0x7) << 5;
9825       *matchp = match;
9826       return 1;
9827     }
9828   if (tag1)
9829     {
9830       match[15] = tag1_val[1];
9831       match[14] = tag1_val[0];
9832       if (proto)
9833         {
9834           match[17] = proto_val & 0xff;
9835           match[16] = proto_val >> 8;
9836         }
9837       if (cos1)
9838         match[14] |= (cos1_val & 0x7) << 5;
9839
9840       *matchp = match;
9841       return 1;
9842     }
9843   if (cos2)
9844     match[18] |= (cos2_val & 0x7) << 5;
9845   if (cos1)
9846     match[14] |= (cos1_val & 0x7) << 5;
9847   if (proto)
9848     {
9849       match[13] = proto_val & 0xff;
9850       match[12] = proto_val >> 8;
9851     }
9852
9853   *matchp = match;
9854   return 1;
9855 }
9856 #endif
9857
9858 uword
9859 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9860 {
9861   u8 **matchp = va_arg (*args, u8 **);
9862   u32 skip_n_vectors = va_arg (*args, u32);
9863   u32 match_n_vectors = va_arg (*args, u32);
9864
9865   u8 *match = 0;
9866   u8 *l2 = 0;
9867   u8 *l3 = 0;
9868   u8 *l4 = 0;
9869
9870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9871     {
9872       if (unformat (input, "hex %U", unformat_hex_string, &match))
9873         ;
9874       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9875         ;
9876       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9877         ;
9878       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9879         ;
9880       else
9881         break;
9882     }
9883
9884   if (l4 && !l3)
9885     {
9886       vec_free (match);
9887       vec_free (l2);
9888       vec_free (l4);
9889       return 0;
9890     }
9891
9892   if (match || l2 || l3 || l4)
9893     {
9894       if (l2 || l3 || l4)
9895         {
9896           /* "Win a free Ethernet header in every packet" */
9897           if (l2 == 0)
9898             vec_validate_aligned (l2, 13, sizeof (u32x4));
9899           match = l2;
9900           if (vec_len (l3))
9901             {
9902               vec_append_aligned (match, l3, sizeof (u32x4));
9903               vec_free (l3);
9904             }
9905           if (vec_len (l4))
9906             {
9907               vec_append_aligned (match, l4, sizeof (u32x4));
9908               vec_free (l4);
9909             }
9910         }
9911
9912       /* Make sure the vector is big enough even if key is all 0's */
9913       vec_validate_aligned
9914         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9915          sizeof (u32x4));
9916
9917       /* Set size, include skipped vectors */
9918       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9919
9920       *matchp = match;
9921
9922       return 1;
9923     }
9924
9925   return 0;
9926 }
9927
9928 static int
9929 api_classify_add_del_session (vat_main_t * vam)
9930 {
9931   unformat_input_t *i = vam->input;
9932   vl_api_classify_add_del_session_t *mp;
9933   int is_add = 1;
9934   u32 table_index = ~0;
9935   u32 hit_next_index = ~0;
9936   u32 opaque_index = ~0;
9937   u8 *match = 0;
9938   i32 advance = 0;
9939   u32 skip_n_vectors = 0;
9940   u32 match_n_vectors = 0;
9941   u32 action = 0;
9942   u32 metadata = 0;
9943   int ret;
9944
9945   /*
9946    * Warning: you have to supply skip_n and match_n
9947    * because the API client cant simply look at the classify
9948    * table object.
9949    */
9950
9951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9952     {
9953       if (unformat (i, "del"))
9954         is_add = 0;
9955       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9956                          &hit_next_index))
9957         ;
9958       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9959                          &hit_next_index))
9960         ;
9961       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9962                          &hit_next_index))
9963         ;
9964       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9965         ;
9966       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9967         ;
9968       else if (unformat (i, "opaque-index %d", &opaque_index))
9969         ;
9970       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9971         ;
9972       else if (unformat (i, "match_n %d", &match_n_vectors))
9973         ;
9974       else if (unformat (i, "match %U", api_unformat_classify_match,
9975                          &match, skip_n_vectors, match_n_vectors))
9976         ;
9977       else if (unformat (i, "advance %d", &advance))
9978         ;
9979       else if (unformat (i, "table-index %d", &table_index))
9980         ;
9981       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9982         action = 1;
9983       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9984         action = 2;
9985       else if (unformat (i, "action %d", &action))
9986         ;
9987       else if (unformat (i, "metadata %d", &metadata))
9988         ;
9989       else
9990         break;
9991     }
9992
9993   if (table_index == ~0)
9994     {
9995       errmsg ("Table index required");
9996       return -99;
9997     }
9998
9999   if (is_add && match == 0)
10000     {
10001       errmsg ("Match value required");
10002       return -99;
10003     }
10004
10005   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10006
10007   mp->is_add = is_add;
10008   mp->table_index = ntohl (table_index);
10009   mp->hit_next_index = ntohl (hit_next_index);
10010   mp->opaque_index = ntohl (opaque_index);
10011   mp->advance = ntohl (advance);
10012   mp->action = action;
10013   mp->metadata = ntohl (metadata);
10014   clib_memcpy (mp->match, match, vec_len (match));
10015   vec_free (match);
10016
10017   S (mp);
10018   W (ret);
10019   return ret;
10020 }
10021
10022 static int
10023 api_classify_set_interface_ip_table (vat_main_t * vam)
10024 {
10025   unformat_input_t *i = vam->input;
10026   vl_api_classify_set_interface_ip_table_t *mp;
10027   u32 sw_if_index;
10028   int sw_if_index_set;
10029   u32 table_index = ~0;
10030   u8 is_ipv6 = 0;
10031   int ret;
10032
10033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10034     {
10035       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10036         sw_if_index_set = 1;
10037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10038         sw_if_index_set = 1;
10039       else if (unformat (i, "table %d", &table_index))
10040         ;
10041       else
10042         {
10043           clib_warning ("parse error '%U'", format_unformat_error, i);
10044           return -99;
10045         }
10046     }
10047
10048   if (sw_if_index_set == 0)
10049     {
10050       errmsg ("missing interface name or sw_if_index");
10051       return -99;
10052     }
10053
10054
10055   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10056
10057   mp->sw_if_index = ntohl (sw_if_index);
10058   mp->table_index = ntohl (table_index);
10059   mp->is_ipv6 = is_ipv6;
10060
10061   S (mp);
10062   W (ret);
10063   return ret;
10064 }
10065
10066 static int
10067 api_classify_set_interface_l2_tables (vat_main_t * vam)
10068 {
10069   unformat_input_t *i = vam->input;
10070   vl_api_classify_set_interface_l2_tables_t *mp;
10071   u32 sw_if_index;
10072   int sw_if_index_set;
10073   u32 ip4_table_index = ~0;
10074   u32 ip6_table_index = ~0;
10075   u32 other_table_index = ~0;
10076   u32 is_input = 1;
10077   int ret;
10078
10079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10080     {
10081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10082         sw_if_index_set = 1;
10083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10084         sw_if_index_set = 1;
10085       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10086         ;
10087       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10088         ;
10089       else if (unformat (i, "other-table %d", &other_table_index))
10090         ;
10091       else if (unformat (i, "is-input %d", &is_input))
10092         ;
10093       else
10094         {
10095           clib_warning ("parse error '%U'", format_unformat_error, i);
10096           return -99;
10097         }
10098     }
10099
10100   if (sw_if_index_set == 0)
10101     {
10102       errmsg ("missing interface name or sw_if_index");
10103       return -99;
10104     }
10105
10106
10107   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10108
10109   mp->sw_if_index = ntohl (sw_if_index);
10110   mp->ip4_table_index = ntohl (ip4_table_index);
10111   mp->ip6_table_index = ntohl (ip6_table_index);
10112   mp->other_table_index = ntohl (other_table_index);
10113   mp->is_input = (u8) is_input;
10114
10115   S (mp);
10116   W (ret);
10117   return ret;
10118 }
10119
10120 static int
10121 api_set_ipfix_exporter (vat_main_t * vam)
10122 {
10123   unformat_input_t *i = vam->input;
10124   vl_api_set_ipfix_exporter_t *mp;
10125   ip4_address_t collector_address;
10126   u8 collector_address_set = 0;
10127   u32 collector_port = ~0;
10128   ip4_address_t src_address;
10129   u8 src_address_set = 0;
10130   u32 vrf_id = ~0;
10131   u32 path_mtu = ~0;
10132   u32 template_interval = ~0;
10133   u8 udp_checksum = 0;
10134   int ret;
10135
10136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10137     {
10138       if (unformat (i, "collector_address %U", unformat_ip4_address,
10139                     &collector_address))
10140         collector_address_set = 1;
10141       else if (unformat (i, "collector_port %d", &collector_port))
10142         ;
10143       else if (unformat (i, "src_address %U", unformat_ip4_address,
10144                          &src_address))
10145         src_address_set = 1;
10146       else if (unformat (i, "vrf_id %d", &vrf_id))
10147         ;
10148       else if (unformat (i, "path_mtu %d", &path_mtu))
10149         ;
10150       else if (unformat (i, "template_interval %d", &template_interval))
10151         ;
10152       else if (unformat (i, "udp_checksum"))
10153         udp_checksum = 1;
10154       else
10155         break;
10156     }
10157
10158   if (collector_address_set == 0)
10159     {
10160       errmsg ("collector_address required");
10161       return -99;
10162     }
10163
10164   if (src_address_set == 0)
10165     {
10166       errmsg ("src_address required");
10167       return -99;
10168     }
10169
10170   M (SET_IPFIX_EXPORTER, mp);
10171
10172   memcpy (mp->collector_address, collector_address.data,
10173           sizeof (collector_address.data));
10174   mp->collector_port = htons ((u16) collector_port);
10175   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10176   mp->vrf_id = htonl (vrf_id);
10177   mp->path_mtu = htonl (path_mtu);
10178   mp->template_interval = htonl (template_interval);
10179   mp->udp_checksum = udp_checksum;
10180
10181   S (mp);
10182   W (ret);
10183   return ret;
10184 }
10185
10186 static int
10187 api_set_ipfix_classify_stream (vat_main_t * vam)
10188 {
10189   unformat_input_t *i = vam->input;
10190   vl_api_set_ipfix_classify_stream_t *mp;
10191   u32 domain_id = 0;
10192   u32 src_port = UDP_DST_PORT_ipfix;
10193   int ret;
10194
10195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10196     {
10197       if (unformat (i, "domain %d", &domain_id))
10198         ;
10199       else if (unformat (i, "src_port %d", &src_port))
10200         ;
10201       else
10202         {
10203           errmsg ("unknown input `%U'", format_unformat_error, i);
10204           return -99;
10205         }
10206     }
10207
10208   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10209
10210   mp->domain_id = htonl (domain_id);
10211   mp->src_port = htons ((u16) src_port);
10212
10213   S (mp);
10214   W (ret);
10215   return ret;
10216 }
10217
10218 static int
10219 api_ipfix_classify_table_add_del (vat_main_t * vam)
10220 {
10221   unformat_input_t *i = vam->input;
10222   vl_api_ipfix_classify_table_add_del_t *mp;
10223   int is_add = -1;
10224   u32 classify_table_index = ~0;
10225   u8 ip_version = 0;
10226   u8 transport_protocol = 255;
10227   int ret;
10228
10229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10230     {
10231       if (unformat (i, "add"))
10232         is_add = 1;
10233       else if (unformat (i, "del"))
10234         is_add = 0;
10235       else if (unformat (i, "table %d", &classify_table_index))
10236         ;
10237       else if (unformat (i, "ip4"))
10238         ip_version = 4;
10239       else if (unformat (i, "ip6"))
10240         ip_version = 6;
10241       else if (unformat (i, "tcp"))
10242         transport_protocol = 6;
10243       else if (unformat (i, "udp"))
10244         transport_protocol = 17;
10245       else
10246         {
10247           errmsg ("unknown input `%U'", format_unformat_error, i);
10248           return -99;
10249         }
10250     }
10251
10252   if (is_add == -1)
10253     {
10254       errmsg ("expecting: add|del");
10255       return -99;
10256     }
10257   if (classify_table_index == ~0)
10258     {
10259       errmsg ("classifier table not specified");
10260       return -99;
10261     }
10262   if (ip_version == 0)
10263     {
10264       errmsg ("IP version not specified");
10265       return -99;
10266     }
10267
10268   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10269
10270   mp->is_add = is_add;
10271   mp->table_id = htonl (classify_table_index);
10272   mp->ip_version = ip_version;
10273   mp->transport_protocol = transport_protocol;
10274
10275   S (mp);
10276   W (ret);
10277   return ret;
10278 }
10279
10280 static int
10281 api_get_node_index (vat_main_t * vam)
10282 {
10283   unformat_input_t *i = vam->input;
10284   vl_api_get_node_index_t *mp;
10285   u8 *name = 0;
10286   int ret;
10287
10288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10289     {
10290       if (unformat (i, "node %s", &name))
10291         ;
10292       else
10293         break;
10294     }
10295   if (name == 0)
10296     {
10297       errmsg ("node name required");
10298       return -99;
10299     }
10300   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10301     {
10302       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10303       return -99;
10304     }
10305
10306   M (GET_NODE_INDEX, mp);
10307   clib_memcpy (mp->node_name, name, vec_len (name));
10308   vec_free (name);
10309
10310   S (mp);
10311   W (ret);
10312   return ret;
10313 }
10314
10315 static int
10316 api_get_next_index (vat_main_t * vam)
10317 {
10318   unformat_input_t *i = vam->input;
10319   vl_api_get_next_index_t *mp;
10320   u8 *node_name = 0, *next_node_name = 0;
10321   int ret;
10322
10323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10324     {
10325       if (unformat (i, "node-name %s", &node_name))
10326         ;
10327       else if (unformat (i, "next-node-name %s", &next_node_name))
10328         break;
10329     }
10330
10331   if (node_name == 0)
10332     {
10333       errmsg ("node name required");
10334       return -99;
10335     }
10336   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10337     {
10338       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10339       return -99;
10340     }
10341
10342   if (next_node_name == 0)
10343     {
10344       errmsg ("next node name required");
10345       return -99;
10346     }
10347   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10348     {
10349       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10350       return -99;
10351     }
10352
10353   M (GET_NEXT_INDEX, mp);
10354   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10355   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10356   vec_free (node_name);
10357   vec_free (next_node_name);
10358
10359   S (mp);
10360   W (ret);
10361   return ret;
10362 }
10363
10364 static int
10365 api_add_node_next (vat_main_t * vam)
10366 {
10367   unformat_input_t *i = vam->input;
10368   vl_api_add_node_next_t *mp;
10369   u8 *name = 0;
10370   u8 *next = 0;
10371   int ret;
10372
10373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10374     {
10375       if (unformat (i, "node %s", &name))
10376         ;
10377       else if (unformat (i, "next %s", &next))
10378         ;
10379       else
10380         break;
10381     }
10382   if (name == 0)
10383     {
10384       errmsg ("node name required");
10385       return -99;
10386     }
10387   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10388     {
10389       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10390       return -99;
10391     }
10392   if (next == 0)
10393     {
10394       errmsg ("next node required");
10395       return -99;
10396     }
10397   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10398     {
10399       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10400       return -99;
10401     }
10402
10403   M (ADD_NODE_NEXT, mp);
10404   clib_memcpy (mp->node_name, name, vec_len (name));
10405   clib_memcpy (mp->next_name, next, vec_len (next));
10406   vec_free (name);
10407   vec_free (next);
10408
10409   S (mp);
10410   W (ret);
10411   return ret;
10412 }
10413
10414 static int
10415 api_l2tpv3_create_tunnel (vat_main_t * vam)
10416 {
10417   unformat_input_t *i = vam->input;
10418   ip6_address_t client_address, our_address;
10419   int client_address_set = 0;
10420   int our_address_set = 0;
10421   u32 local_session_id = 0;
10422   u32 remote_session_id = 0;
10423   u64 local_cookie = 0;
10424   u64 remote_cookie = 0;
10425   u8 l2_sublayer_present = 0;
10426   vl_api_l2tpv3_create_tunnel_t *mp;
10427   int ret;
10428
10429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10430     {
10431       if (unformat (i, "client_address %U", unformat_ip6_address,
10432                     &client_address))
10433         client_address_set = 1;
10434       else if (unformat (i, "our_address %U", unformat_ip6_address,
10435                          &our_address))
10436         our_address_set = 1;
10437       else if (unformat (i, "local_session_id %d", &local_session_id))
10438         ;
10439       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10440         ;
10441       else if (unformat (i, "local_cookie %lld", &local_cookie))
10442         ;
10443       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10444         ;
10445       else if (unformat (i, "l2-sublayer-present"))
10446         l2_sublayer_present = 1;
10447       else
10448         break;
10449     }
10450
10451   if (client_address_set == 0)
10452     {
10453       errmsg ("client_address required");
10454       return -99;
10455     }
10456
10457   if (our_address_set == 0)
10458     {
10459       errmsg ("our_address required");
10460       return -99;
10461     }
10462
10463   M (L2TPV3_CREATE_TUNNEL, mp);
10464
10465   clib_memcpy (mp->client_address, client_address.as_u8,
10466                sizeof (mp->client_address));
10467
10468   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10469
10470   mp->local_session_id = ntohl (local_session_id);
10471   mp->remote_session_id = ntohl (remote_session_id);
10472   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10473   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10474   mp->l2_sublayer_present = l2_sublayer_present;
10475   mp->is_ipv6 = 1;
10476
10477   S (mp);
10478   W (ret);
10479   return ret;
10480 }
10481
10482 static int
10483 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10484 {
10485   unformat_input_t *i = vam->input;
10486   u32 sw_if_index;
10487   u8 sw_if_index_set = 0;
10488   u64 new_local_cookie = 0;
10489   u64 new_remote_cookie = 0;
10490   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10491   int ret;
10492
10493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10494     {
10495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10496         sw_if_index_set = 1;
10497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10498         sw_if_index_set = 1;
10499       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10500         ;
10501       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10502         ;
10503       else
10504         break;
10505     }
10506
10507   if (sw_if_index_set == 0)
10508     {
10509       errmsg ("missing interface name or sw_if_index");
10510       return -99;
10511     }
10512
10513   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10514
10515   mp->sw_if_index = ntohl (sw_if_index);
10516   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10517   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10518
10519   S (mp);
10520   W (ret);
10521   return ret;
10522 }
10523
10524 static int
10525 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10526 {
10527   unformat_input_t *i = vam->input;
10528   vl_api_l2tpv3_interface_enable_disable_t *mp;
10529   u32 sw_if_index;
10530   u8 sw_if_index_set = 0;
10531   u8 enable_disable = 1;
10532   int ret;
10533
10534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10535     {
10536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10537         sw_if_index_set = 1;
10538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10539         sw_if_index_set = 1;
10540       else if (unformat (i, "enable"))
10541         enable_disable = 1;
10542       else if (unformat (i, "disable"))
10543         enable_disable = 0;
10544       else
10545         break;
10546     }
10547
10548   if (sw_if_index_set == 0)
10549     {
10550       errmsg ("missing interface name or sw_if_index");
10551       return -99;
10552     }
10553
10554   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10555
10556   mp->sw_if_index = ntohl (sw_if_index);
10557   mp->enable_disable = enable_disable;
10558
10559   S (mp);
10560   W (ret);
10561   return ret;
10562 }
10563
10564 static int
10565 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10566 {
10567   unformat_input_t *i = vam->input;
10568   vl_api_l2tpv3_set_lookup_key_t *mp;
10569   u8 key = ~0;
10570   int ret;
10571
10572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10573     {
10574       if (unformat (i, "lookup_v6_src"))
10575         key = L2T_LOOKUP_SRC_ADDRESS;
10576       else if (unformat (i, "lookup_v6_dst"))
10577         key = L2T_LOOKUP_DST_ADDRESS;
10578       else if (unformat (i, "lookup_session_id"))
10579         key = L2T_LOOKUP_SESSION_ID;
10580       else
10581         break;
10582     }
10583
10584   if (key == (u8) ~ 0)
10585     {
10586       errmsg ("l2tp session lookup key unset");
10587       return -99;
10588     }
10589
10590   M (L2TPV3_SET_LOOKUP_KEY, mp);
10591
10592   mp->key = key;
10593
10594   S (mp);
10595   W (ret);
10596   return ret;
10597 }
10598
10599 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10600   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10601 {
10602   vat_main_t *vam = &vat_main;
10603
10604   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10605          format_ip6_address, mp->our_address,
10606          format_ip6_address, mp->client_address,
10607          clib_net_to_host_u32 (mp->sw_if_index));
10608
10609   print (vam->ofp,
10610          "   local cookies %016llx %016llx remote cookie %016llx",
10611          clib_net_to_host_u64 (mp->local_cookie[0]),
10612          clib_net_to_host_u64 (mp->local_cookie[1]),
10613          clib_net_to_host_u64 (mp->remote_cookie));
10614
10615   print (vam->ofp, "   local session-id %d remote session-id %d",
10616          clib_net_to_host_u32 (mp->local_session_id),
10617          clib_net_to_host_u32 (mp->remote_session_id));
10618
10619   print (vam->ofp, "   l2 specific sublayer %s\n",
10620          mp->l2_sublayer_present ? "preset" : "absent");
10621
10622 }
10623
10624 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10625   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10626 {
10627   vat_main_t *vam = &vat_main;
10628   vat_json_node_t *node = NULL;
10629   struct in6_addr addr;
10630
10631   if (VAT_JSON_ARRAY != vam->json_tree.type)
10632     {
10633       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10634       vat_json_init_array (&vam->json_tree);
10635     }
10636   node = vat_json_array_add (&vam->json_tree);
10637
10638   vat_json_init_object (node);
10639
10640   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10641   vat_json_object_add_ip6 (node, "our_address", addr);
10642   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10643   vat_json_object_add_ip6 (node, "client_address", addr);
10644
10645   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10646   vat_json_init_array (lc);
10647   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10648   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10649   vat_json_object_add_uint (node, "remote_cookie",
10650                             clib_net_to_host_u64 (mp->remote_cookie));
10651
10652   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10653   vat_json_object_add_uint (node, "local_session_id",
10654                             clib_net_to_host_u32 (mp->local_session_id));
10655   vat_json_object_add_uint (node, "remote_session_id",
10656                             clib_net_to_host_u32 (mp->remote_session_id));
10657   vat_json_object_add_string_copy (node, "l2_sublayer",
10658                                    mp->l2_sublayer_present ? (u8 *) "present"
10659                                    : (u8 *) "absent");
10660 }
10661
10662 static int
10663 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10664 {
10665   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10666   vl_api_control_ping_t *mp_ping;
10667   int ret;
10668
10669   /* Get list of l2tpv3-tunnel interfaces */
10670   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10671   S (mp);
10672
10673   /* Use a control ping for synchronization */
10674   M (CONTROL_PING, mp_ping);
10675   S (mp_ping);
10676
10677   W (ret);
10678   return ret;
10679 }
10680
10681
10682 static void vl_api_sw_interface_tap_details_t_handler
10683   (vl_api_sw_interface_tap_details_t * mp)
10684 {
10685   vat_main_t *vam = &vat_main;
10686
10687   print (vam->ofp, "%-16s %d",
10688          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10689 }
10690
10691 static void vl_api_sw_interface_tap_details_t_handler_json
10692   (vl_api_sw_interface_tap_details_t * mp)
10693 {
10694   vat_main_t *vam = &vat_main;
10695   vat_json_node_t *node = NULL;
10696
10697   if (VAT_JSON_ARRAY != vam->json_tree.type)
10698     {
10699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10700       vat_json_init_array (&vam->json_tree);
10701     }
10702   node = vat_json_array_add (&vam->json_tree);
10703
10704   vat_json_init_object (node);
10705   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10706   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10707 }
10708
10709 static int
10710 api_sw_interface_tap_dump (vat_main_t * vam)
10711 {
10712   vl_api_sw_interface_tap_dump_t *mp;
10713   vl_api_control_ping_t *mp_ping;
10714   int ret;
10715
10716   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10717   /* Get list of tap interfaces */
10718   M (SW_INTERFACE_TAP_DUMP, mp);
10719   S (mp);
10720
10721   /* Use a control ping for synchronization */
10722   M (CONTROL_PING, mp_ping);
10723   S (mp_ping);
10724
10725   W (ret);
10726   return ret;
10727 }
10728
10729 static uword unformat_vxlan_decap_next
10730   (unformat_input_t * input, va_list * args)
10731 {
10732   u32 *result = va_arg (*args, u32 *);
10733   u32 tmp;
10734
10735   if (unformat (input, "l2"))
10736     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10737   else if (unformat (input, "%d", &tmp))
10738     *result = tmp;
10739   else
10740     return 0;
10741   return 1;
10742 }
10743
10744 static int
10745 api_vxlan_add_del_tunnel (vat_main_t * vam)
10746 {
10747   unformat_input_t *line_input = vam->input;
10748   vl_api_vxlan_add_del_tunnel_t *mp;
10749   ip46_address_t src, dst;
10750   u8 is_add = 1;
10751   u8 ipv4_set = 0, ipv6_set = 0;
10752   u8 src_set = 0;
10753   u8 dst_set = 0;
10754   u8 grp_set = 0;
10755   u32 mcast_sw_if_index = ~0;
10756   u32 encap_vrf_id = 0;
10757   u32 decap_next_index = ~0;
10758   u32 vni = 0;
10759   int ret;
10760
10761   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10762   memset (&src, 0, sizeof src);
10763   memset (&dst, 0, sizeof dst);
10764
10765   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10766     {
10767       if (unformat (line_input, "del"))
10768         is_add = 0;
10769       else
10770         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10771         {
10772           ipv4_set = 1;
10773           src_set = 1;
10774         }
10775       else
10776         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10777         {
10778           ipv4_set = 1;
10779           dst_set = 1;
10780         }
10781       else
10782         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10783         {
10784           ipv6_set = 1;
10785           src_set = 1;
10786         }
10787       else
10788         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10789         {
10790           ipv6_set = 1;
10791           dst_set = 1;
10792         }
10793       else if (unformat (line_input, "group %U %U",
10794                          unformat_ip4_address, &dst.ip4,
10795                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10796         {
10797           grp_set = dst_set = 1;
10798           ipv4_set = 1;
10799         }
10800       else if (unformat (line_input, "group %U",
10801                          unformat_ip4_address, &dst.ip4))
10802         {
10803           grp_set = dst_set = 1;
10804           ipv4_set = 1;
10805         }
10806       else if (unformat (line_input, "group %U %U",
10807                          unformat_ip6_address, &dst.ip6,
10808                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10809         {
10810           grp_set = dst_set = 1;
10811           ipv6_set = 1;
10812         }
10813       else if (unformat (line_input, "group %U",
10814                          unformat_ip6_address, &dst.ip6))
10815         {
10816           grp_set = dst_set = 1;
10817           ipv6_set = 1;
10818         }
10819       else
10820         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10821         ;
10822       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10823         ;
10824       else if (unformat (line_input, "decap-next %U",
10825                          unformat_vxlan_decap_next, &decap_next_index))
10826         ;
10827       else if (unformat (line_input, "vni %d", &vni))
10828         ;
10829       else
10830         {
10831           errmsg ("parse error '%U'", format_unformat_error, line_input);
10832           return -99;
10833         }
10834     }
10835
10836   if (src_set == 0)
10837     {
10838       errmsg ("tunnel src address not specified");
10839       return -99;
10840     }
10841   if (dst_set == 0)
10842     {
10843       errmsg ("tunnel dst address not specified");
10844       return -99;
10845     }
10846
10847   if (grp_set && !ip46_address_is_multicast (&dst))
10848     {
10849       errmsg ("tunnel group address not multicast");
10850       return -99;
10851     }
10852   if (grp_set && mcast_sw_if_index == ~0)
10853     {
10854       errmsg ("tunnel nonexistent multicast device");
10855       return -99;
10856     }
10857   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10858     {
10859       errmsg ("tunnel dst address must be unicast");
10860       return -99;
10861     }
10862
10863
10864   if (ipv4_set && ipv6_set)
10865     {
10866       errmsg ("both IPv4 and IPv6 addresses specified");
10867       return -99;
10868     }
10869
10870   if ((vni == 0) || (vni >> 24))
10871     {
10872       errmsg ("vni not specified or out of range");
10873       return -99;
10874     }
10875
10876   M (VXLAN_ADD_DEL_TUNNEL, mp);
10877
10878   if (ipv6_set)
10879     {
10880       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10881       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10882     }
10883   else
10884     {
10885       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10886       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10887     }
10888   mp->encap_vrf_id = ntohl (encap_vrf_id);
10889   mp->decap_next_index = ntohl (decap_next_index);
10890   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10891   mp->vni = ntohl (vni);
10892   mp->is_add = is_add;
10893   mp->is_ipv6 = ipv6_set;
10894
10895   S (mp);
10896   W (ret);
10897   return ret;
10898 }
10899
10900 static void vl_api_vxlan_tunnel_details_t_handler
10901   (vl_api_vxlan_tunnel_details_t * mp)
10902 {
10903   vat_main_t *vam = &vat_main;
10904   ip46_address_t src, dst;
10905
10906   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10907   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10908
10909   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10910          ntohl (mp->sw_if_index),
10911          format_ip46_address, &src, IP46_TYPE_ANY,
10912          format_ip46_address, &dst, IP46_TYPE_ANY,
10913          ntohl (mp->encap_vrf_id),
10914          ntohl (mp->decap_next_index), ntohl (mp->vni),
10915          ntohl (mp->mcast_sw_if_index));
10916 }
10917
10918 static void vl_api_vxlan_tunnel_details_t_handler_json
10919   (vl_api_vxlan_tunnel_details_t * mp)
10920 {
10921   vat_main_t *vam = &vat_main;
10922   vat_json_node_t *node = NULL;
10923
10924   if (VAT_JSON_ARRAY != vam->json_tree.type)
10925     {
10926       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10927       vat_json_init_array (&vam->json_tree);
10928     }
10929   node = vat_json_array_add (&vam->json_tree);
10930
10931   vat_json_init_object (node);
10932   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10933   if (mp->is_ipv6)
10934     {
10935       struct in6_addr ip6;
10936
10937       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10938       vat_json_object_add_ip6 (node, "src_address", ip6);
10939       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10940       vat_json_object_add_ip6 (node, "dst_address", ip6);
10941     }
10942   else
10943     {
10944       struct in_addr ip4;
10945
10946       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10947       vat_json_object_add_ip4 (node, "src_address", ip4);
10948       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10949       vat_json_object_add_ip4 (node, "dst_address", ip4);
10950     }
10951   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10952   vat_json_object_add_uint (node, "decap_next_index",
10953                             ntohl (mp->decap_next_index));
10954   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10955   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10956   vat_json_object_add_uint (node, "mcast_sw_if_index",
10957                             ntohl (mp->mcast_sw_if_index));
10958 }
10959
10960 static int
10961 api_vxlan_tunnel_dump (vat_main_t * vam)
10962 {
10963   unformat_input_t *i = vam->input;
10964   vl_api_vxlan_tunnel_dump_t *mp;
10965   vl_api_control_ping_t *mp_ping;
10966   u32 sw_if_index;
10967   u8 sw_if_index_set = 0;
10968   int ret;
10969
10970   /* Parse args required to build the message */
10971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10972     {
10973       if (unformat (i, "sw_if_index %d", &sw_if_index))
10974         sw_if_index_set = 1;
10975       else
10976         break;
10977     }
10978
10979   if (sw_if_index_set == 0)
10980     {
10981       sw_if_index = ~0;
10982     }
10983
10984   if (!vam->json_output)
10985     {
10986       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10987              "sw_if_index", "src_address", "dst_address",
10988              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10989     }
10990
10991   /* Get list of vxlan-tunnel interfaces */
10992   M (VXLAN_TUNNEL_DUMP, mp);
10993
10994   mp->sw_if_index = htonl (sw_if_index);
10995
10996   S (mp);
10997
10998   /* Use a control ping for synchronization */
10999   M (CONTROL_PING, mp_ping);
11000   S (mp_ping);
11001
11002   W (ret);
11003   return ret;
11004 }
11005
11006 static int
11007 api_gre_add_del_tunnel (vat_main_t * vam)
11008 {
11009   unformat_input_t *line_input = vam->input;
11010   vl_api_gre_add_del_tunnel_t *mp;
11011   ip4_address_t src4, dst4;
11012   u8 is_add = 1;
11013   u8 teb = 0;
11014   u8 src_set = 0;
11015   u8 dst_set = 0;
11016   u32 outer_fib_id = 0;
11017   int ret;
11018
11019   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11020     {
11021       if (unformat (line_input, "del"))
11022         is_add = 0;
11023       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11024         src_set = 1;
11025       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11026         dst_set = 1;
11027       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11028         ;
11029       else if (unformat (line_input, "teb"))
11030         teb = 1;
11031       else
11032         {
11033           errmsg ("parse error '%U'", format_unformat_error, line_input);
11034           return -99;
11035         }
11036     }
11037
11038   if (src_set == 0)
11039     {
11040       errmsg ("tunnel src address not specified");
11041       return -99;
11042     }
11043   if (dst_set == 0)
11044     {
11045       errmsg ("tunnel dst address not specified");
11046       return -99;
11047     }
11048
11049
11050   M (GRE_ADD_DEL_TUNNEL, mp);
11051
11052   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
11053   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
11054   mp->outer_fib_id = ntohl (outer_fib_id);
11055   mp->is_add = is_add;
11056   mp->teb = teb;
11057
11058   S (mp);
11059   W (ret);
11060   return ret;
11061 }
11062
11063 static void vl_api_gre_tunnel_details_t_handler
11064   (vl_api_gre_tunnel_details_t * mp)
11065 {
11066   vat_main_t *vam = &vat_main;
11067
11068   print (vam->ofp, "%11d%15U%15U%6d%14d",
11069          ntohl (mp->sw_if_index),
11070          format_ip4_address, &mp->src_address,
11071          format_ip4_address, &mp->dst_address,
11072          mp->teb, ntohl (mp->outer_fib_id));
11073 }
11074
11075 static void vl_api_gre_tunnel_details_t_handler_json
11076   (vl_api_gre_tunnel_details_t * mp)
11077 {
11078   vat_main_t *vam = &vat_main;
11079   vat_json_node_t *node = NULL;
11080   struct in_addr ip4;
11081
11082   if (VAT_JSON_ARRAY != vam->json_tree.type)
11083     {
11084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11085       vat_json_init_array (&vam->json_tree);
11086     }
11087   node = vat_json_array_add (&vam->json_tree);
11088
11089   vat_json_init_object (node);
11090   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11091   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11092   vat_json_object_add_ip4 (node, "src_address", ip4);
11093   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11094   vat_json_object_add_ip4 (node, "dst_address", ip4);
11095   vat_json_object_add_uint (node, "teb", mp->teb);
11096   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11097 }
11098
11099 static int
11100 api_gre_tunnel_dump (vat_main_t * vam)
11101 {
11102   unformat_input_t *i = vam->input;
11103   vl_api_gre_tunnel_dump_t *mp;
11104   vl_api_control_ping_t *mp_ping;
11105   u32 sw_if_index;
11106   u8 sw_if_index_set = 0;
11107   int ret;
11108
11109   /* Parse args required to build the message */
11110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11111     {
11112       if (unformat (i, "sw_if_index %d", &sw_if_index))
11113         sw_if_index_set = 1;
11114       else
11115         break;
11116     }
11117
11118   if (sw_if_index_set == 0)
11119     {
11120       sw_if_index = ~0;
11121     }
11122
11123   if (!vam->json_output)
11124     {
11125       print (vam->ofp, "%11s%15s%15s%6s%14s",
11126              "sw_if_index", "src_address", "dst_address", "teb",
11127              "outer_fib_id");
11128     }
11129
11130   /* Get list of gre-tunnel interfaces */
11131   M (GRE_TUNNEL_DUMP, mp);
11132
11133   mp->sw_if_index = htonl (sw_if_index);
11134
11135   S (mp);
11136
11137   /* Use a control ping for synchronization */
11138   M (CONTROL_PING, mp_ping);
11139   S (mp_ping);
11140
11141   W (ret);
11142   return ret;
11143 }
11144
11145 static int
11146 api_l2_fib_clear_table (vat_main_t * vam)
11147 {
11148 //  unformat_input_t * i = vam->input;
11149   vl_api_l2_fib_clear_table_t *mp;
11150   int ret;
11151
11152   M (L2_FIB_CLEAR_TABLE, mp);
11153
11154   S (mp);
11155   W (ret);
11156   return ret;
11157 }
11158
11159 static int
11160 api_l2_interface_efp_filter (vat_main_t * vam)
11161 {
11162   unformat_input_t *i = vam->input;
11163   vl_api_l2_interface_efp_filter_t *mp;
11164   u32 sw_if_index;
11165   u8 enable = 1;
11166   u8 sw_if_index_set = 0;
11167   int ret;
11168
11169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11170     {
11171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11172         sw_if_index_set = 1;
11173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11174         sw_if_index_set = 1;
11175       else if (unformat (i, "enable"))
11176         enable = 1;
11177       else if (unformat (i, "disable"))
11178         enable = 0;
11179       else
11180         {
11181           clib_warning ("parse error '%U'", format_unformat_error, i);
11182           return -99;
11183         }
11184     }
11185
11186   if (sw_if_index_set == 0)
11187     {
11188       errmsg ("missing sw_if_index");
11189       return -99;
11190     }
11191
11192   M (L2_INTERFACE_EFP_FILTER, mp);
11193
11194   mp->sw_if_index = ntohl (sw_if_index);
11195   mp->enable_disable = enable;
11196
11197   S (mp);
11198   W (ret);
11199   return ret;
11200 }
11201
11202 #define foreach_vtr_op                          \
11203 _("disable",  L2_VTR_DISABLED)                  \
11204 _("push-1",  L2_VTR_PUSH_1)                     \
11205 _("push-2",  L2_VTR_PUSH_2)                     \
11206 _("pop-1",  L2_VTR_POP_1)                       \
11207 _("pop-2",  L2_VTR_POP_2)                       \
11208 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11209 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11210 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11211 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11212
11213 static int
11214 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11215 {
11216   unformat_input_t *i = vam->input;
11217   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11218   u32 sw_if_index;
11219   u8 sw_if_index_set = 0;
11220   u8 vtr_op_set = 0;
11221   u32 vtr_op = 0;
11222   u32 push_dot1q = 1;
11223   u32 tag1 = ~0;
11224   u32 tag2 = ~0;
11225   int ret;
11226
11227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11228     {
11229       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11230         sw_if_index_set = 1;
11231       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11232         sw_if_index_set = 1;
11233       else if (unformat (i, "vtr_op %d", &vtr_op))
11234         vtr_op_set = 1;
11235 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11236       foreach_vtr_op
11237 #undef _
11238         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11239         ;
11240       else if (unformat (i, "tag1 %d", &tag1))
11241         ;
11242       else if (unformat (i, "tag2 %d", &tag2))
11243         ;
11244       else
11245         {
11246           clib_warning ("parse error '%U'", format_unformat_error, i);
11247           return -99;
11248         }
11249     }
11250
11251   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11252     {
11253       errmsg ("missing vtr operation or sw_if_index");
11254       return -99;
11255     }
11256
11257   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11258   mp->sw_if_index = ntohl (sw_if_index);
11259   mp->vtr_op = ntohl (vtr_op);
11260   mp->push_dot1q = ntohl (push_dot1q);
11261   mp->tag1 = ntohl (tag1);
11262   mp->tag2 = ntohl (tag2);
11263
11264   S (mp);
11265   W (ret);
11266   return ret;
11267 }
11268
11269 static int
11270 api_create_vhost_user_if (vat_main_t * vam)
11271 {
11272   unformat_input_t *i = vam->input;
11273   vl_api_create_vhost_user_if_t *mp;
11274   u8 *file_name;
11275   u8 is_server = 0;
11276   u8 file_name_set = 0;
11277   u32 custom_dev_instance = ~0;
11278   u8 hwaddr[6];
11279   u8 use_custom_mac = 0;
11280   u8 *tag = 0;
11281   int ret;
11282
11283   /* Shut up coverity */
11284   memset (hwaddr, 0, sizeof (hwaddr));
11285
11286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11287     {
11288       if (unformat (i, "socket %s", &file_name))
11289         {
11290           file_name_set = 1;
11291         }
11292       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11293         ;
11294       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11295         use_custom_mac = 1;
11296       else if (unformat (i, "server"))
11297         is_server = 1;
11298       else if (unformat (i, "tag %s", &tag))
11299         ;
11300       else
11301         break;
11302     }
11303
11304   if (file_name_set == 0)
11305     {
11306       errmsg ("missing socket file name");
11307       return -99;
11308     }
11309
11310   if (vec_len (file_name) > 255)
11311     {
11312       errmsg ("socket file name too long");
11313       return -99;
11314     }
11315   vec_add1 (file_name, 0);
11316
11317   M (CREATE_VHOST_USER_IF, mp);
11318
11319   mp->is_server = is_server;
11320   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11321   vec_free (file_name);
11322   if (custom_dev_instance != ~0)
11323     {
11324       mp->renumber = 1;
11325       mp->custom_dev_instance = ntohl (custom_dev_instance);
11326     }
11327   mp->use_custom_mac = use_custom_mac;
11328   clib_memcpy (mp->mac_address, hwaddr, 6);
11329   if (tag)
11330     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11331   vec_free (tag);
11332
11333   S (mp);
11334   W (ret);
11335   return ret;
11336 }
11337
11338 static int
11339 api_modify_vhost_user_if (vat_main_t * vam)
11340 {
11341   unformat_input_t *i = vam->input;
11342   vl_api_modify_vhost_user_if_t *mp;
11343   u8 *file_name;
11344   u8 is_server = 0;
11345   u8 file_name_set = 0;
11346   u32 custom_dev_instance = ~0;
11347   u8 sw_if_index_set = 0;
11348   u32 sw_if_index = (u32) ~ 0;
11349   int ret;
11350
11351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11352     {
11353       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11354         sw_if_index_set = 1;
11355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11356         sw_if_index_set = 1;
11357       else if (unformat (i, "socket %s", &file_name))
11358         {
11359           file_name_set = 1;
11360         }
11361       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11362         ;
11363       else if (unformat (i, "server"))
11364         is_server = 1;
11365       else
11366         break;
11367     }
11368
11369   if (sw_if_index_set == 0)
11370     {
11371       errmsg ("missing sw_if_index or interface name");
11372       return -99;
11373     }
11374
11375   if (file_name_set == 0)
11376     {
11377       errmsg ("missing socket file name");
11378       return -99;
11379     }
11380
11381   if (vec_len (file_name) > 255)
11382     {
11383       errmsg ("socket file name too long");
11384       return -99;
11385     }
11386   vec_add1 (file_name, 0);
11387
11388   M (MODIFY_VHOST_USER_IF, mp);
11389
11390   mp->sw_if_index = ntohl (sw_if_index);
11391   mp->is_server = is_server;
11392   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11393   vec_free (file_name);
11394   if (custom_dev_instance != ~0)
11395     {
11396       mp->renumber = 1;
11397       mp->custom_dev_instance = ntohl (custom_dev_instance);
11398     }
11399
11400   S (mp);
11401   W (ret);
11402   return ret;
11403 }
11404
11405 static int
11406 api_delete_vhost_user_if (vat_main_t * vam)
11407 {
11408   unformat_input_t *i = vam->input;
11409   vl_api_delete_vhost_user_if_t *mp;
11410   u32 sw_if_index = ~0;
11411   u8 sw_if_index_set = 0;
11412   int ret;
11413
11414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11415     {
11416       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11417         sw_if_index_set = 1;
11418       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11419         sw_if_index_set = 1;
11420       else
11421         break;
11422     }
11423
11424   if (sw_if_index_set == 0)
11425     {
11426       errmsg ("missing sw_if_index or interface name");
11427       return -99;
11428     }
11429
11430
11431   M (DELETE_VHOST_USER_IF, mp);
11432
11433   mp->sw_if_index = ntohl (sw_if_index);
11434
11435   S (mp);
11436   W (ret);
11437   return ret;
11438 }
11439
11440 static void vl_api_sw_interface_vhost_user_details_t_handler
11441   (vl_api_sw_interface_vhost_user_details_t * mp)
11442 {
11443   vat_main_t *vam = &vat_main;
11444
11445   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11446          (char *) mp->interface_name,
11447          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11448          clib_net_to_host_u64 (mp->features), mp->is_server,
11449          ntohl (mp->num_regions), (char *) mp->sock_filename);
11450   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11451 }
11452
11453 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11454   (vl_api_sw_interface_vhost_user_details_t * mp)
11455 {
11456   vat_main_t *vam = &vat_main;
11457   vat_json_node_t *node = NULL;
11458
11459   if (VAT_JSON_ARRAY != vam->json_tree.type)
11460     {
11461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11462       vat_json_init_array (&vam->json_tree);
11463     }
11464   node = vat_json_array_add (&vam->json_tree);
11465
11466   vat_json_init_object (node);
11467   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11468   vat_json_object_add_string_copy (node, "interface_name",
11469                                    mp->interface_name);
11470   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11471                             ntohl (mp->virtio_net_hdr_sz));
11472   vat_json_object_add_uint (node, "features",
11473                             clib_net_to_host_u64 (mp->features));
11474   vat_json_object_add_uint (node, "is_server", mp->is_server);
11475   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11476   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11477   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11478 }
11479
11480 static int
11481 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11482 {
11483   vl_api_sw_interface_vhost_user_dump_t *mp;
11484   vl_api_control_ping_t *mp_ping;
11485   int ret;
11486   print (vam->ofp,
11487          "Interface name           idx hdr_sz features server regions filename");
11488
11489   /* Get list of vhost-user interfaces */
11490   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11491   S (mp);
11492
11493   /* Use a control ping for synchronization */
11494   M (CONTROL_PING, mp_ping);
11495   S (mp_ping);
11496
11497   W (ret);
11498   return ret;
11499 }
11500
11501 static int
11502 api_show_version (vat_main_t * vam)
11503 {
11504   vl_api_show_version_t *mp;
11505   int ret;
11506
11507   M (SHOW_VERSION, mp);
11508
11509   S (mp);
11510   W (ret);
11511   return ret;
11512 }
11513
11514
11515 static int
11516 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11517 {
11518   unformat_input_t *line_input = vam->input;
11519   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11520   ip4_address_t local4, remote4;
11521   ip6_address_t local6, remote6;
11522   u8 is_add = 1;
11523   u8 ipv4_set = 0, ipv6_set = 0;
11524   u8 local_set = 0;
11525   u8 remote_set = 0;
11526   u32 encap_vrf_id = 0;
11527   u32 decap_vrf_id = 0;
11528   u8 protocol = ~0;
11529   u32 vni;
11530   u8 vni_set = 0;
11531   int ret;
11532
11533   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11534     {
11535       if (unformat (line_input, "del"))
11536         is_add = 0;
11537       else if (unformat (line_input, "local %U",
11538                          unformat_ip4_address, &local4))
11539         {
11540           local_set = 1;
11541           ipv4_set = 1;
11542         }
11543       else if (unformat (line_input, "remote %U",
11544                          unformat_ip4_address, &remote4))
11545         {
11546           remote_set = 1;
11547           ipv4_set = 1;
11548         }
11549       else if (unformat (line_input, "local %U",
11550                          unformat_ip6_address, &local6))
11551         {
11552           local_set = 1;
11553           ipv6_set = 1;
11554         }
11555       else if (unformat (line_input, "remote %U",
11556                          unformat_ip6_address, &remote6))
11557         {
11558           remote_set = 1;
11559           ipv6_set = 1;
11560         }
11561       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11562         ;
11563       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11564         ;
11565       else if (unformat (line_input, "vni %d", &vni))
11566         vni_set = 1;
11567       else if (unformat (line_input, "next-ip4"))
11568         protocol = 1;
11569       else if (unformat (line_input, "next-ip6"))
11570         protocol = 2;
11571       else if (unformat (line_input, "next-ethernet"))
11572         protocol = 3;
11573       else if (unformat (line_input, "next-nsh"))
11574         protocol = 4;
11575       else
11576         {
11577           errmsg ("parse error '%U'", format_unformat_error, line_input);
11578           return -99;
11579         }
11580     }
11581
11582   if (local_set == 0)
11583     {
11584       errmsg ("tunnel local address not specified");
11585       return -99;
11586     }
11587   if (remote_set == 0)
11588     {
11589       errmsg ("tunnel remote address not specified");
11590       return -99;
11591     }
11592   if (ipv4_set && ipv6_set)
11593     {
11594       errmsg ("both IPv4 and IPv6 addresses specified");
11595       return -99;
11596     }
11597
11598   if (vni_set == 0)
11599     {
11600       errmsg ("vni not specified");
11601       return -99;
11602     }
11603
11604   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11605
11606
11607   if (ipv6_set)
11608     {
11609       clib_memcpy (&mp->local, &local6, sizeof (local6));
11610       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11611     }
11612   else
11613     {
11614       clib_memcpy (&mp->local, &local4, sizeof (local4));
11615       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11616     }
11617
11618   mp->encap_vrf_id = ntohl (encap_vrf_id);
11619   mp->decap_vrf_id = ntohl (decap_vrf_id);
11620   mp->protocol = protocol;
11621   mp->vni = ntohl (vni);
11622   mp->is_add = is_add;
11623   mp->is_ipv6 = ipv6_set;
11624
11625   S (mp);
11626   W (ret);
11627   return ret;
11628 }
11629
11630 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11631   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11632 {
11633   vat_main_t *vam = &vat_main;
11634
11635   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11636          ntohl (mp->sw_if_index),
11637          format_ip46_address, &(mp->local[0]),
11638          format_ip46_address, &(mp->remote[0]),
11639          ntohl (mp->vni),
11640          ntohl (mp->protocol),
11641          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11642 }
11643
11644 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11645   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11646 {
11647   vat_main_t *vam = &vat_main;
11648   vat_json_node_t *node = NULL;
11649   struct in_addr ip4;
11650   struct in6_addr ip6;
11651
11652   if (VAT_JSON_ARRAY != vam->json_tree.type)
11653     {
11654       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11655       vat_json_init_array (&vam->json_tree);
11656     }
11657   node = vat_json_array_add (&vam->json_tree);
11658
11659   vat_json_init_object (node);
11660   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11661   if (mp->is_ipv6)
11662     {
11663       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11664       vat_json_object_add_ip6 (node, "local", ip6);
11665       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11666       vat_json_object_add_ip6 (node, "remote", ip6);
11667     }
11668   else
11669     {
11670       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11671       vat_json_object_add_ip4 (node, "local", ip4);
11672       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11673       vat_json_object_add_ip4 (node, "remote", ip4);
11674     }
11675   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11676   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11677   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11678   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11679   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11680 }
11681
11682 static int
11683 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11684 {
11685   unformat_input_t *i = vam->input;
11686   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11687   vl_api_control_ping_t *mp_ping;
11688   u32 sw_if_index;
11689   u8 sw_if_index_set = 0;
11690   int ret;
11691
11692   /* Parse args required to build the message */
11693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11694     {
11695       if (unformat (i, "sw_if_index %d", &sw_if_index))
11696         sw_if_index_set = 1;
11697       else
11698         break;
11699     }
11700
11701   if (sw_if_index_set == 0)
11702     {
11703       sw_if_index = ~0;
11704     }
11705
11706   if (!vam->json_output)
11707     {
11708       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11709              "sw_if_index", "local", "remote", "vni",
11710              "protocol", "encap_vrf_id", "decap_vrf_id");
11711     }
11712
11713   /* Get list of vxlan-tunnel interfaces */
11714   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11715
11716   mp->sw_if_index = htonl (sw_if_index);
11717
11718   S (mp);
11719
11720   /* Use a control ping for synchronization */
11721   M (CONTROL_PING, mp_ping);
11722   S (mp_ping);
11723
11724   W (ret);
11725   return ret;
11726 }
11727
11728 u8 *
11729 format_l2_fib_mac_address (u8 * s, va_list * args)
11730 {
11731   u8 *a = va_arg (*args, u8 *);
11732
11733   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11734                  a[2], a[3], a[4], a[5], a[6], a[7]);
11735 }
11736
11737 static void vl_api_l2_fib_table_entry_t_handler
11738   (vl_api_l2_fib_table_entry_t * mp)
11739 {
11740   vat_main_t *vam = &vat_main;
11741
11742   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11743          "       %d       %d     %d",
11744          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11745          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11746          mp->bvi_mac);
11747 }
11748
11749 static void vl_api_l2_fib_table_entry_t_handler_json
11750   (vl_api_l2_fib_table_entry_t * mp)
11751 {
11752   vat_main_t *vam = &vat_main;
11753   vat_json_node_t *node = NULL;
11754
11755   if (VAT_JSON_ARRAY != vam->json_tree.type)
11756     {
11757       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11758       vat_json_init_array (&vam->json_tree);
11759     }
11760   node = vat_json_array_add (&vam->json_tree);
11761
11762   vat_json_init_object (node);
11763   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11764   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11765   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11766   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11767   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11768   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11769 }
11770
11771 static int
11772 api_l2_fib_table_dump (vat_main_t * vam)
11773 {
11774   unformat_input_t *i = vam->input;
11775   vl_api_l2_fib_table_dump_t *mp;
11776   vl_api_control_ping_t *mp_ping;
11777   u32 bd_id;
11778   u8 bd_id_set = 0;
11779   int ret;
11780
11781   /* Parse args required to build the message */
11782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11783     {
11784       if (unformat (i, "bd_id %d", &bd_id))
11785         bd_id_set = 1;
11786       else
11787         break;
11788     }
11789
11790   if (bd_id_set == 0)
11791     {
11792       errmsg ("missing bridge domain");
11793       return -99;
11794     }
11795
11796   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11797
11798   /* Get list of l2 fib entries */
11799   M (L2_FIB_TABLE_DUMP, mp);
11800
11801   mp->bd_id = ntohl (bd_id);
11802   S (mp);
11803
11804   /* Use a control ping for synchronization */
11805   M (CONTROL_PING, mp_ping);
11806   S (mp_ping);
11807
11808   W (ret);
11809   return ret;
11810 }
11811
11812
11813 static int
11814 api_interface_name_renumber (vat_main_t * vam)
11815 {
11816   unformat_input_t *line_input = vam->input;
11817   vl_api_interface_name_renumber_t *mp;
11818   u32 sw_if_index = ~0;
11819   u32 new_show_dev_instance = ~0;
11820   int ret;
11821
11822   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11823     {
11824       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11825                     &sw_if_index))
11826         ;
11827       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11828         ;
11829       else if (unformat (line_input, "new_show_dev_instance %d",
11830                          &new_show_dev_instance))
11831         ;
11832       else
11833         break;
11834     }
11835
11836   if (sw_if_index == ~0)
11837     {
11838       errmsg ("missing interface name or sw_if_index");
11839       return -99;
11840     }
11841
11842   if (new_show_dev_instance == ~0)
11843     {
11844       errmsg ("missing new_show_dev_instance");
11845       return -99;
11846     }
11847
11848   M (INTERFACE_NAME_RENUMBER, mp);
11849
11850   mp->sw_if_index = ntohl (sw_if_index);
11851   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11852
11853   S (mp);
11854   W (ret);
11855   return ret;
11856 }
11857
11858 static int
11859 api_want_ip4_arp_events (vat_main_t * vam)
11860 {
11861   unformat_input_t *line_input = vam->input;
11862   vl_api_want_ip4_arp_events_t *mp;
11863   ip4_address_t address;
11864   int address_set = 0;
11865   u32 enable_disable = 1;
11866   int ret;
11867
11868   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11869     {
11870       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11871         address_set = 1;
11872       else if (unformat (line_input, "del"))
11873         enable_disable = 0;
11874       else
11875         break;
11876     }
11877
11878   if (address_set == 0)
11879     {
11880       errmsg ("missing addresses");
11881       return -99;
11882     }
11883
11884   M (WANT_IP4_ARP_EVENTS, mp);
11885   mp->enable_disable = enable_disable;
11886   mp->pid = getpid ();
11887   mp->address = address.as_u32;
11888
11889   S (mp);
11890   W (ret);
11891   return ret;
11892 }
11893
11894 static int
11895 api_want_ip6_nd_events (vat_main_t * vam)
11896 {
11897   unformat_input_t *line_input = vam->input;
11898   vl_api_want_ip6_nd_events_t *mp;
11899   ip6_address_t address;
11900   int address_set = 0;
11901   u32 enable_disable = 1;
11902   int ret;
11903
11904   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11905     {
11906       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11907         address_set = 1;
11908       else if (unformat (line_input, "del"))
11909         enable_disable = 0;
11910       else
11911         break;
11912     }
11913
11914   if (address_set == 0)
11915     {
11916       errmsg ("missing addresses");
11917       return -99;
11918     }
11919
11920   M (WANT_IP6_ND_EVENTS, mp);
11921   mp->enable_disable = enable_disable;
11922   mp->pid = getpid ();
11923   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11924
11925   S (mp);
11926   W (ret);
11927   return ret;
11928 }
11929
11930 static int
11931 api_input_acl_set_interface (vat_main_t * vam)
11932 {
11933   unformat_input_t *i = vam->input;
11934   vl_api_input_acl_set_interface_t *mp;
11935   u32 sw_if_index;
11936   int sw_if_index_set;
11937   u32 ip4_table_index = ~0;
11938   u32 ip6_table_index = ~0;
11939   u32 l2_table_index = ~0;
11940   u8 is_add = 1;
11941   int ret;
11942
11943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11944     {
11945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11946         sw_if_index_set = 1;
11947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11948         sw_if_index_set = 1;
11949       else if (unformat (i, "del"))
11950         is_add = 0;
11951       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11952         ;
11953       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11954         ;
11955       else if (unformat (i, "l2-table %d", &l2_table_index))
11956         ;
11957       else
11958         {
11959           clib_warning ("parse error '%U'", format_unformat_error, i);
11960           return -99;
11961         }
11962     }
11963
11964   if (sw_if_index_set == 0)
11965     {
11966       errmsg ("missing interface name or sw_if_index");
11967       return -99;
11968     }
11969
11970   M (INPUT_ACL_SET_INTERFACE, mp);
11971
11972   mp->sw_if_index = ntohl (sw_if_index);
11973   mp->ip4_table_index = ntohl (ip4_table_index);
11974   mp->ip6_table_index = ntohl (ip6_table_index);
11975   mp->l2_table_index = ntohl (l2_table_index);
11976   mp->is_add = is_add;
11977
11978   S (mp);
11979   W (ret);
11980   return ret;
11981 }
11982
11983 static int
11984 api_ip_address_dump (vat_main_t * vam)
11985 {
11986   unformat_input_t *i = vam->input;
11987   vl_api_ip_address_dump_t *mp;
11988   vl_api_control_ping_t *mp_ping;
11989   u32 sw_if_index = ~0;
11990   u8 sw_if_index_set = 0;
11991   u8 ipv4_set = 0;
11992   u8 ipv6_set = 0;
11993   int ret;
11994
11995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11996     {
11997       if (unformat (i, "sw_if_index %d", &sw_if_index))
11998         sw_if_index_set = 1;
11999       else
12000         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12001         sw_if_index_set = 1;
12002       else if (unformat (i, "ipv4"))
12003         ipv4_set = 1;
12004       else if (unformat (i, "ipv6"))
12005         ipv6_set = 1;
12006       else
12007         break;
12008     }
12009
12010   if (ipv4_set && ipv6_set)
12011     {
12012       errmsg ("ipv4 and ipv6 flags cannot be both set");
12013       return -99;
12014     }
12015
12016   if ((!ipv4_set) && (!ipv6_set))
12017     {
12018       errmsg ("no ipv4 nor ipv6 flag set");
12019       return -99;
12020     }
12021
12022   if (sw_if_index_set == 0)
12023     {
12024       errmsg ("missing interface name or sw_if_index");
12025       return -99;
12026     }
12027
12028   vam->current_sw_if_index = sw_if_index;
12029   vam->is_ipv6 = ipv6_set;
12030
12031   M (IP_ADDRESS_DUMP, mp);
12032   mp->sw_if_index = ntohl (sw_if_index);
12033   mp->is_ipv6 = ipv6_set;
12034   S (mp);
12035
12036   /* Use a control ping for synchronization */
12037   M (CONTROL_PING, mp_ping);
12038   S (mp_ping);
12039
12040   W (ret);
12041   return ret;
12042 }
12043
12044 static int
12045 api_ip_dump (vat_main_t * vam)
12046 {
12047   vl_api_ip_dump_t *mp;
12048   vl_api_control_ping_t *mp_ping;
12049   unformat_input_t *in = vam->input;
12050   int ipv4_set = 0;
12051   int ipv6_set = 0;
12052   int is_ipv6;
12053   int i;
12054   int ret;
12055
12056   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12057     {
12058       if (unformat (in, "ipv4"))
12059         ipv4_set = 1;
12060       else if (unformat (in, "ipv6"))
12061         ipv6_set = 1;
12062       else
12063         break;
12064     }
12065
12066   if (ipv4_set && ipv6_set)
12067     {
12068       errmsg ("ipv4 and ipv6 flags cannot be both set");
12069       return -99;
12070     }
12071
12072   if ((!ipv4_set) && (!ipv6_set))
12073     {
12074       errmsg ("no ipv4 nor ipv6 flag set");
12075       return -99;
12076     }
12077
12078   is_ipv6 = ipv6_set;
12079   vam->is_ipv6 = is_ipv6;
12080
12081   /* free old data */
12082   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12083     {
12084       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12085     }
12086   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12087
12088   M (IP_DUMP, mp);
12089   mp->is_ipv6 = ipv6_set;
12090   S (mp);
12091
12092   /* Use a control ping for synchronization */
12093   M (CONTROL_PING, mp_ping);
12094   S (mp_ping);
12095
12096   W (ret);
12097   return ret;
12098 }
12099
12100 static int
12101 api_ipsec_spd_add_del (vat_main_t * vam)
12102 {
12103   unformat_input_t *i = vam->input;
12104   vl_api_ipsec_spd_add_del_t *mp;
12105   u32 spd_id = ~0;
12106   u8 is_add = 1;
12107   int ret;
12108
12109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12110     {
12111       if (unformat (i, "spd_id %d", &spd_id))
12112         ;
12113       else if (unformat (i, "del"))
12114         is_add = 0;
12115       else
12116         {
12117           clib_warning ("parse error '%U'", format_unformat_error, i);
12118           return -99;
12119         }
12120     }
12121   if (spd_id == ~0)
12122     {
12123       errmsg ("spd_id must be set");
12124       return -99;
12125     }
12126
12127   M (IPSEC_SPD_ADD_DEL, mp);
12128
12129   mp->spd_id = ntohl (spd_id);
12130   mp->is_add = is_add;
12131
12132   S (mp);
12133   W (ret);
12134   return ret;
12135 }
12136
12137 static int
12138 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12139 {
12140   unformat_input_t *i = vam->input;
12141   vl_api_ipsec_interface_add_del_spd_t *mp;
12142   u32 sw_if_index;
12143   u8 sw_if_index_set = 0;
12144   u32 spd_id = (u32) ~ 0;
12145   u8 is_add = 1;
12146   int ret;
12147
12148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12149     {
12150       if (unformat (i, "del"))
12151         is_add = 0;
12152       else if (unformat (i, "spd_id %d", &spd_id))
12153         ;
12154       else
12155         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12156         sw_if_index_set = 1;
12157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12158         sw_if_index_set = 1;
12159       else
12160         {
12161           clib_warning ("parse error '%U'", format_unformat_error, i);
12162           return -99;
12163         }
12164
12165     }
12166
12167   if (spd_id == (u32) ~ 0)
12168     {
12169       errmsg ("spd_id must be set");
12170       return -99;
12171     }
12172
12173   if (sw_if_index_set == 0)
12174     {
12175       errmsg ("missing interface name or sw_if_index");
12176       return -99;
12177     }
12178
12179   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12180
12181   mp->spd_id = ntohl (spd_id);
12182   mp->sw_if_index = ntohl (sw_if_index);
12183   mp->is_add = is_add;
12184
12185   S (mp);
12186   W (ret);
12187   return ret;
12188 }
12189
12190 static int
12191 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12192 {
12193   unformat_input_t *i = vam->input;
12194   vl_api_ipsec_spd_add_del_entry_t *mp;
12195   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12196   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12197   i32 priority = 0;
12198   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12199   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12200   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12201   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12202   int ret;
12203
12204   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12205   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12206   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12207   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12208   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12209   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12210
12211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12212     {
12213       if (unformat (i, "del"))
12214         is_add = 0;
12215       if (unformat (i, "outbound"))
12216         is_outbound = 1;
12217       if (unformat (i, "inbound"))
12218         is_outbound = 0;
12219       else if (unformat (i, "spd_id %d", &spd_id))
12220         ;
12221       else if (unformat (i, "sa_id %d", &sa_id))
12222         ;
12223       else if (unformat (i, "priority %d", &priority))
12224         ;
12225       else if (unformat (i, "protocol %d", &protocol))
12226         ;
12227       else if (unformat (i, "lport_start %d", &lport_start))
12228         ;
12229       else if (unformat (i, "lport_stop %d", &lport_stop))
12230         ;
12231       else if (unformat (i, "rport_start %d", &rport_start))
12232         ;
12233       else if (unformat (i, "rport_stop %d", &rport_stop))
12234         ;
12235       else
12236         if (unformat
12237             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12238         {
12239           is_ipv6 = 0;
12240           is_ip_any = 0;
12241         }
12242       else
12243         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12244         {
12245           is_ipv6 = 0;
12246           is_ip_any = 0;
12247         }
12248       else
12249         if (unformat
12250             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12251         {
12252           is_ipv6 = 0;
12253           is_ip_any = 0;
12254         }
12255       else
12256         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12257         {
12258           is_ipv6 = 0;
12259           is_ip_any = 0;
12260         }
12261       else
12262         if (unformat
12263             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12264         {
12265           is_ipv6 = 1;
12266           is_ip_any = 0;
12267         }
12268       else
12269         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12270         {
12271           is_ipv6 = 1;
12272           is_ip_any = 0;
12273         }
12274       else
12275         if (unformat
12276             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12277         {
12278           is_ipv6 = 1;
12279           is_ip_any = 0;
12280         }
12281       else
12282         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12283         {
12284           is_ipv6 = 1;
12285           is_ip_any = 0;
12286         }
12287       else
12288         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12289         {
12290           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12291             {
12292               clib_warning ("unsupported action: 'resolve'");
12293               return -99;
12294             }
12295         }
12296       else
12297         {
12298           clib_warning ("parse error '%U'", format_unformat_error, i);
12299           return -99;
12300         }
12301
12302     }
12303
12304   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12305
12306   mp->spd_id = ntohl (spd_id);
12307   mp->priority = ntohl (priority);
12308   mp->is_outbound = is_outbound;
12309
12310   mp->is_ipv6 = is_ipv6;
12311   if (is_ipv6 || is_ip_any)
12312     {
12313       clib_memcpy (mp->remote_address_start, &raddr6_start,
12314                    sizeof (ip6_address_t));
12315       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12316                    sizeof (ip6_address_t));
12317       clib_memcpy (mp->local_address_start, &laddr6_start,
12318                    sizeof (ip6_address_t));
12319       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12320                    sizeof (ip6_address_t));
12321     }
12322   else
12323     {
12324       clib_memcpy (mp->remote_address_start, &raddr4_start,
12325                    sizeof (ip4_address_t));
12326       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12327                    sizeof (ip4_address_t));
12328       clib_memcpy (mp->local_address_start, &laddr4_start,
12329                    sizeof (ip4_address_t));
12330       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12331                    sizeof (ip4_address_t));
12332     }
12333   mp->protocol = (u8) protocol;
12334   mp->local_port_start = ntohs ((u16) lport_start);
12335   mp->local_port_stop = ntohs ((u16) lport_stop);
12336   mp->remote_port_start = ntohs ((u16) rport_start);
12337   mp->remote_port_stop = ntohs ((u16) rport_stop);
12338   mp->policy = (u8) policy;
12339   mp->sa_id = ntohl (sa_id);
12340   mp->is_add = is_add;
12341   mp->is_ip_any = is_ip_any;
12342   S (mp);
12343   W (ret);
12344   return ret;
12345 }
12346
12347 static int
12348 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12349 {
12350   unformat_input_t *i = vam->input;
12351   vl_api_ipsec_sad_add_del_entry_t *mp;
12352   u32 sad_id = 0, spi = 0;
12353   u8 *ck = 0, *ik = 0;
12354   u8 is_add = 1;
12355
12356   u8 protocol = IPSEC_PROTOCOL_AH;
12357   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12358   u32 crypto_alg = 0, integ_alg = 0;
12359   ip4_address_t tun_src4;
12360   ip4_address_t tun_dst4;
12361   ip6_address_t tun_src6;
12362   ip6_address_t tun_dst6;
12363   int ret;
12364
12365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12366     {
12367       if (unformat (i, "del"))
12368         is_add = 0;
12369       else if (unformat (i, "sad_id %d", &sad_id))
12370         ;
12371       else if (unformat (i, "spi %d", &spi))
12372         ;
12373       else if (unformat (i, "esp"))
12374         protocol = IPSEC_PROTOCOL_ESP;
12375       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12376         {
12377           is_tunnel = 1;
12378           is_tunnel_ipv6 = 0;
12379         }
12380       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12381         {
12382           is_tunnel = 1;
12383           is_tunnel_ipv6 = 0;
12384         }
12385       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12386         {
12387           is_tunnel = 1;
12388           is_tunnel_ipv6 = 1;
12389         }
12390       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12391         {
12392           is_tunnel = 1;
12393           is_tunnel_ipv6 = 1;
12394         }
12395       else
12396         if (unformat
12397             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12398         {
12399           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12400               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12401             {
12402               clib_warning ("unsupported crypto-alg: '%U'",
12403                             format_ipsec_crypto_alg, crypto_alg);
12404               return -99;
12405             }
12406         }
12407       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12408         ;
12409       else
12410         if (unformat
12411             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12412         {
12413           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12414               integ_alg >= IPSEC_INTEG_N_ALG)
12415             {
12416               clib_warning ("unsupported integ-alg: '%U'",
12417                             format_ipsec_integ_alg, integ_alg);
12418               return -99;
12419             }
12420         }
12421       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12422         ;
12423       else
12424         {
12425           clib_warning ("parse error '%U'", format_unformat_error, i);
12426           return -99;
12427         }
12428
12429     }
12430
12431   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12432
12433   mp->sad_id = ntohl (sad_id);
12434   mp->is_add = is_add;
12435   mp->protocol = protocol;
12436   mp->spi = ntohl (spi);
12437   mp->is_tunnel = is_tunnel;
12438   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12439   mp->crypto_algorithm = crypto_alg;
12440   mp->integrity_algorithm = integ_alg;
12441   mp->crypto_key_length = vec_len (ck);
12442   mp->integrity_key_length = vec_len (ik);
12443
12444   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12445     mp->crypto_key_length = sizeof (mp->crypto_key);
12446
12447   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12448     mp->integrity_key_length = sizeof (mp->integrity_key);
12449
12450   if (ck)
12451     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12452   if (ik)
12453     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12454
12455   if (is_tunnel)
12456     {
12457       if (is_tunnel_ipv6)
12458         {
12459           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12460                        sizeof (ip6_address_t));
12461           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12462                        sizeof (ip6_address_t));
12463         }
12464       else
12465         {
12466           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12467                        sizeof (ip4_address_t));
12468           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12469                        sizeof (ip4_address_t));
12470         }
12471     }
12472
12473   S (mp);
12474   W (ret);
12475   return ret;
12476 }
12477
12478 static int
12479 api_ipsec_sa_set_key (vat_main_t * vam)
12480 {
12481   unformat_input_t *i = vam->input;
12482   vl_api_ipsec_sa_set_key_t *mp;
12483   u32 sa_id;
12484   u8 *ck = 0, *ik = 0;
12485   int ret;
12486
12487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12488     {
12489       if (unformat (i, "sa_id %d", &sa_id))
12490         ;
12491       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12492         ;
12493       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12494         ;
12495       else
12496         {
12497           clib_warning ("parse error '%U'", format_unformat_error, i);
12498           return -99;
12499         }
12500     }
12501
12502   M (IPSEC_SA_SET_KEY, mp);
12503
12504   mp->sa_id = ntohl (sa_id);
12505   mp->crypto_key_length = vec_len (ck);
12506   mp->integrity_key_length = vec_len (ik);
12507
12508   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12509     mp->crypto_key_length = sizeof (mp->crypto_key);
12510
12511   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12512     mp->integrity_key_length = sizeof (mp->integrity_key);
12513
12514   if (ck)
12515     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12516   if (ik)
12517     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12518
12519   S (mp);
12520   W (ret);
12521   return ret;
12522 }
12523
12524 static int
12525 api_ikev2_profile_add_del (vat_main_t * vam)
12526 {
12527   unformat_input_t *i = vam->input;
12528   vl_api_ikev2_profile_add_del_t *mp;
12529   u8 is_add = 1;
12530   u8 *name = 0;
12531   int ret;
12532
12533   const char *valid_chars = "a-zA-Z0-9_";
12534
12535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12536     {
12537       if (unformat (i, "del"))
12538         is_add = 0;
12539       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12540         vec_add1 (name, 0);
12541       else
12542         {
12543           errmsg ("parse error '%U'", format_unformat_error, i);
12544           return -99;
12545         }
12546     }
12547
12548   if (!vec_len (name))
12549     {
12550       errmsg ("profile name must be specified");
12551       return -99;
12552     }
12553
12554   if (vec_len (name) > 64)
12555     {
12556       errmsg ("profile name too long");
12557       return -99;
12558     }
12559
12560   M (IKEV2_PROFILE_ADD_DEL, mp);
12561
12562   clib_memcpy (mp->name, name, vec_len (name));
12563   mp->is_add = is_add;
12564   vec_free (name);
12565
12566   S (mp);
12567   W (ret);
12568   return ret;
12569 }
12570
12571 static int
12572 api_ikev2_profile_set_auth (vat_main_t * vam)
12573 {
12574   unformat_input_t *i = vam->input;
12575   vl_api_ikev2_profile_set_auth_t *mp;
12576   u8 *name = 0;
12577   u8 *data = 0;
12578   u32 auth_method = 0;
12579   u8 is_hex = 0;
12580   int ret;
12581
12582   const char *valid_chars = "a-zA-Z0-9_";
12583
12584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12585     {
12586       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12587         vec_add1 (name, 0);
12588       else if (unformat (i, "auth_method %U",
12589                          unformat_ikev2_auth_method, &auth_method))
12590         ;
12591       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12592         is_hex = 1;
12593       else if (unformat (i, "auth_data %v", &data))
12594         ;
12595       else
12596         {
12597           errmsg ("parse error '%U'", format_unformat_error, i);
12598           return -99;
12599         }
12600     }
12601
12602   if (!vec_len (name))
12603     {
12604       errmsg ("profile name must be specified");
12605       return -99;
12606     }
12607
12608   if (vec_len (name) > 64)
12609     {
12610       errmsg ("profile name too long");
12611       return -99;
12612     }
12613
12614   if (!vec_len (data))
12615     {
12616       errmsg ("auth_data must be specified");
12617       return -99;
12618     }
12619
12620   if (!auth_method)
12621     {
12622       errmsg ("auth_method must be specified");
12623       return -99;
12624     }
12625
12626   M (IKEV2_PROFILE_SET_AUTH, mp);
12627
12628   mp->is_hex = is_hex;
12629   mp->auth_method = (u8) auth_method;
12630   mp->data_len = vec_len (data);
12631   clib_memcpy (mp->name, name, vec_len (name));
12632   clib_memcpy (mp->data, data, vec_len (data));
12633   vec_free (name);
12634   vec_free (data);
12635
12636   S (mp);
12637   W (ret);
12638   return ret;
12639 }
12640
12641 static int
12642 api_ikev2_profile_set_id (vat_main_t * vam)
12643 {
12644   unformat_input_t *i = vam->input;
12645   vl_api_ikev2_profile_set_id_t *mp;
12646   u8 *name = 0;
12647   u8 *data = 0;
12648   u8 is_local = 0;
12649   u32 id_type = 0;
12650   ip4_address_t ip4;
12651   int ret;
12652
12653   const char *valid_chars = "a-zA-Z0-9_";
12654
12655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12656     {
12657       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12658         vec_add1 (name, 0);
12659       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12660         ;
12661       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12662         {
12663           data = vec_new (u8, 4);
12664           clib_memcpy (data, ip4.as_u8, 4);
12665         }
12666       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12667         ;
12668       else if (unformat (i, "id_data %v", &data))
12669         ;
12670       else if (unformat (i, "local"))
12671         is_local = 1;
12672       else if (unformat (i, "remote"))
12673         is_local = 0;
12674       else
12675         {
12676           errmsg ("parse error '%U'", format_unformat_error, i);
12677           return -99;
12678         }
12679     }
12680
12681   if (!vec_len (name))
12682     {
12683       errmsg ("profile name must be specified");
12684       return -99;
12685     }
12686
12687   if (vec_len (name) > 64)
12688     {
12689       errmsg ("profile name too long");
12690       return -99;
12691     }
12692
12693   if (!vec_len (data))
12694     {
12695       errmsg ("id_data must be specified");
12696       return -99;
12697     }
12698
12699   if (!id_type)
12700     {
12701       errmsg ("id_type must be specified");
12702       return -99;
12703     }
12704
12705   M (IKEV2_PROFILE_SET_ID, mp);
12706
12707   mp->is_local = is_local;
12708   mp->id_type = (u8) id_type;
12709   mp->data_len = vec_len (data);
12710   clib_memcpy (mp->name, name, vec_len (name));
12711   clib_memcpy (mp->data, data, vec_len (data));
12712   vec_free (name);
12713   vec_free (data);
12714
12715   S (mp);
12716   W (ret);
12717   return ret;
12718 }
12719
12720 static int
12721 api_ikev2_profile_set_ts (vat_main_t * vam)
12722 {
12723   unformat_input_t *i = vam->input;
12724   vl_api_ikev2_profile_set_ts_t *mp;
12725   u8 *name = 0;
12726   u8 is_local = 0;
12727   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12728   ip4_address_t start_addr, end_addr;
12729
12730   const char *valid_chars = "a-zA-Z0-9_";
12731   int ret;
12732
12733   start_addr.as_u32 = 0;
12734   end_addr.as_u32 = (u32) ~ 0;
12735
12736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12737     {
12738       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12739         vec_add1 (name, 0);
12740       else if (unformat (i, "protocol %d", &proto))
12741         ;
12742       else if (unformat (i, "start_port %d", &start_port))
12743         ;
12744       else if (unformat (i, "end_port %d", &end_port))
12745         ;
12746       else
12747         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12748         ;
12749       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12750         ;
12751       else if (unformat (i, "local"))
12752         is_local = 1;
12753       else if (unformat (i, "remote"))
12754         is_local = 0;
12755       else
12756         {
12757           errmsg ("parse error '%U'", format_unformat_error, i);
12758           return -99;
12759         }
12760     }
12761
12762   if (!vec_len (name))
12763     {
12764       errmsg ("profile name must be specified");
12765       return -99;
12766     }
12767
12768   if (vec_len (name) > 64)
12769     {
12770       errmsg ("profile name too long");
12771       return -99;
12772     }
12773
12774   M (IKEV2_PROFILE_SET_TS, mp);
12775
12776   mp->is_local = is_local;
12777   mp->proto = (u8) proto;
12778   mp->start_port = (u16) start_port;
12779   mp->end_port = (u16) end_port;
12780   mp->start_addr = start_addr.as_u32;
12781   mp->end_addr = end_addr.as_u32;
12782   clib_memcpy (mp->name, name, vec_len (name));
12783   vec_free (name);
12784
12785   S (mp);
12786   W (ret);
12787   return ret;
12788 }
12789
12790 static int
12791 api_ikev2_set_local_key (vat_main_t * vam)
12792 {
12793   unformat_input_t *i = vam->input;
12794   vl_api_ikev2_set_local_key_t *mp;
12795   u8 *file = 0;
12796   int ret;
12797
12798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12799     {
12800       if (unformat (i, "file %v", &file))
12801         vec_add1 (file, 0);
12802       else
12803         {
12804           errmsg ("parse error '%U'", format_unformat_error, i);
12805           return -99;
12806         }
12807     }
12808
12809   if (!vec_len (file))
12810     {
12811       errmsg ("RSA key file must be specified");
12812       return -99;
12813     }
12814
12815   if (vec_len (file) > 256)
12816     {
12817       errmsg ("file name too long");
12818       return -99;
12819     }
12820
12821   M (IKEV2_SET_LOCAL_KEY, mp);
12822
12823   clib_memcpy (mp->key_file, file, vec_len (file));
12824   vec_free (file);
12825
12826   S (mp);
12827   W (ret);
12828   return ret;
12829 }
12830
12831 static int
12832 api_ikev2_set_responder (vat_main_t * vam)
12833 {
12834   unformat_input_t *i = vam->input;
12835   vl_api_ikev2_set_responder_t *mp;
12836   int ret;
12837   u8 *name = 0;
12838   u32 sw_if_index = ~0;
12839   ip4_address_t address;
12840
12841   const char *valid_chars = "a-zA-Z0-9_";
12842
12843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12844     {
12845       if (unformat
12846           (i, "%U interface %d address %U", unformat_token, valid_chars,
12847            &name, &sw_if_index, unformat_ip4_address, &address))
12848         vec_add1 (name, 0);
12849       else
12850         {
12851           errmsg ("parse error '%U'", format_unformat_error, i);
12852           return -99;
12853         }
12854     }
12855
12856   if (!vec_len (name))
12857     {
12858       errmsg ("profile name must be specified");
12859       return -99;
12860     }
12861
12862   if (vec_len (name) > 64)
12863     {
12864       errmsg ("profile name too long");
12865       return -99;
12866     }
12867
12868   M (IKEV2_SET_RESPONDER, mp);
12869
12870   clib_memcpy (mp->name, name, vec_len (name));
12871   vec_free (name);
12872
12873   mp->sw_if_index = sw_if_index;
12874   clib_memcpy (mp->address, &address, sizeof (address));
12875
12876   S (mp);
12877   W (ret);
12878   return ret;
12879 }
12880
12881 static int
12882 api_ikev2_set_ike_transforms (vat_main_t * vam)
12883 {
12884   unformat_input_t *i = vam->input;
12885   vl_api_ikev2_set_ike_transforms_t *mp;
12886   int ret;
12887   u8 *name = 0;
12888   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12889
12890   const char *valid_chars = "a-zA-Z0-9_";
12891
12892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12893     {
12894       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12895                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12896         vec_add1 (name, 0);
12897       else
12898         {
12899           errmsg ("parse error '%U'", format_unformat_error, i);
12900           return -99;
12901         }
12902     }
12903
12904   if (!vec_len (name))
12905     {
12906       errmsg ("profile name must be specified");
12907       return -99;
12908     }
12909
12910   if (vec_len (name) > 64)
12911     {
12912       errmsg ("profile name too long");
12913       return -99;
12914     }
12915
12916   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12917
12918   clib_memcpy (mp->name, name, vec_len (name));
12919   vec_free (name);
12920   mp->crypto_alg = crypto_alg;
12921   mp->crypto_key_size = crypto_key_size;
12922   mp->integ_alg = integ_alg;
12923   mp->dh_group = dh_group;
12924
12925   S (mp);
12926   W (ret);
12927   return ret;
12928 }
12929
12930
12931 static int
12932 api_ikev2_set_esp_transforms (vat_main_t * vam)
12933 {
12934   unformat_input_t *i = vam->input;
12935   vl_api_ikev2_set_esp_transforms_t *mp;
12936   int ret;
12937   u8 *name = 0;
12938   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12939
12940   const char *valid_chars = "a-zA-Z0-9_";
12941
12942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12943     {
12944       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12945                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12946         vec_add1 (name, 0);
12947       else
12948         {
12949           errmsg ("parse error '%U'", format_unformat_error, i);
12950           return -99;
12951         }
12952     }
12953
12954   if (!vec_len (name))
12955     {
12956       errmsg ("profile name must be specified");
12957       return -99;
12958     }
12959
12960   if (vec_len (name) > 64)
12961     {
12962       errmsg ("profile name too long");
12963       return -99;
12964     }
12965
12966   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12967
12968   clib_memcpy (mp->name, name, vec_len (name));
12969   vec_free (name);
12970   mp->crypto_alg = crypto_alg;
12971   mp->crypto_key_size = crypto_key_size;
12972   mp->integ_alg = integ_alg;
12973   mp->dh_group = dh_group;
12974
12975   S (mp);
12976   W (ret);
12977   return ret;
12978 }
12979
12980 static int
12981 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12982 {
12983   unformat_input_t *i = vam->input;
12984   vl_api_ikev2_set_sa_lifetime_t *mp;
12985   int ret;
12986   u8 *name = 0;
12987   u64 lifetime, lifetime_maxdata;
12988   u32 lifetime_jitter, handover;
12989
12990   const char *valid_chars = "a-zA-Z0-9_";
12991
12992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12993     {
12994       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12995                     &lifetime, &lifetime_jitter, &handover,
12996                     &lifetime_maxdata))
12997         vec_add1 (name, 0);
12998       else
12999         {
13000           errmsg ("parse error '%U'", format_unformat_error, i);
13001           return -99;
13002         }
13003     }
13004
13005   if (!vec_len (name))
13006     {
13007       errmsg ("profile name must be specified");
13008       return -99;
13009     }
13010
13011   if (vec_len (name) > 64)
13012     {
13013       errmsg ("profile name too long");
13014       return -99;
13015     }
13016
13017   M (IKEV2_SET_SA_LIFETIME, mp);
13018
13019   clib_memcpy (mp->name, name, vec_len (name));
13020   vec_free (name);
13021   mp->lifetime = lifetime;
13022   mp->lifetime_jitter = lifetime_jitter;
13023   mp->handover = handover;
13024   mp->lifetime_maxdata = lifetime_maxdata;
13025
13026   S (mp);
13027   W (ret);
13028   return ret;
13029 }
13030
13031 static int
13032 api_ikev2_initiate_sa_init (vat_main_t * vam)
13033 {
13034   unformat_input_t *i = vam->input;
13035   vl_api_ikev2_initiate_sa_init_t *mp;
13036   int ret;
13037   u8 *name = 0;
13038
13039   const char *valid_chars = "a-zA-Z0-9_";
13040
13041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13042     {
13043       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13044         vec_add1 (name, 0);
13045       else
13046         {
13047           errmsg ("parse error '%U'", format_unformat_error, i);
13048           return -99;
13049         }
13050     }
13051
13052   if (!vec_len (name))
13053     {
13054       errmsg ("profile name must be specified");
13055       return -99;
13056     }
13057
13058   if (vec_len (name) > 64)
13059     {
13060       errmsg ("profile name too long");
13061       return -99;
13062     }
13063
13064   M (IKEV2_INITIATE_SA_INIT, mp);
13065
13066   clib_memcpy (mp->name, name, vec_len (name));
13067   vec_free (name);
13068
13069   S (mp);
13070   W (ret);
13071   return ret;
13072 }
13073
13074 static int
13075 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13076 {
13077   unformat_input_t *i = vam->input;
13078   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13079   int ret;
13080   u64 ispi;
13081
13082
13083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13084     {
13085       if (unformat (i, "%lx", &ispi))
13086         ;
13087       else
13088         {
13089           errmsg ("parse error '%U'", format_unformat_error, i);
13090           return -99;
13091         }
13092     }
13093
13094   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13095
13096   mp->ispi = ispi;
13097
13098   S (mp);
13099   W (ret);
13100   return ret;
13101 }
13102
13103 static int
13104 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13105 {
13106   unformat_input_t *i = vam->input;
13107   vl_api_ikev2_initiate_del_child_sa_t *mp;
13108   int ret;
13109   u32 ispi;
13110
13111
13112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13113     {
13114       if (unformat (i, "%x", &ispi))
13115         ;
13116       else
13117         {
13118           errmsg ("parse error '%U'", format_unformat_error, i);
13119           return -99;
13120         }
13121     }
13122
13123   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13124
13125   mp->ispi = ispi;
13126
13127   S (mp);
13128   W (ret);
13129   return ret;
13130 }
13131
13132 static int
13133 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13134 {
13135   unformat_input_t *i = vam->input;
13136   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13137   int ret;
13138   u32 ispi;
13139
13140
13141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13142     {
13143       if (unformat (i, "%x", &ispi))
13144         ;
13145       else
13146         {
13147           errmsg ("parse error '%U'", format_unformat_error, i);
13148           return -99;
13149         }
13150     }
13151
13152   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13153
13154   mp->ispi = ispi;
13155
13156   S (mp);
13157   W (ret);
13158   return ret;
13159 }
13160
13161 /*
13162  * MAP
13163  */
13164 static int
13165 api_map_add_domain (vat_main_t * vam)
13166 {
13167   unformat_input_t *i = vam->input;
13168   vl_api_map_add_domain_t *mp;
13169
13170   ip4_address_t ip4_prefix;
13171   ip6_address_t ip6_prefix;
13172   ip6_address_t ip6_src;
13173   u32 num_m_args = 0;
13174   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13175     0, psid_length = 0;
13176   u8 is_translation = 0;
13177   u32 mtu = 0;
13178   u32 ip6_src_len = 128;
13179   int ret;
13180
13181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13182     {
13183       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13184                     &ip4_prefix, &ip4_prefix_len))
13185         num_m_args++;
13186       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13187                          &ip6_prefix, &ip6_prefix_len))
13188         num_m_args++;
13189       else
13190         if (unformat
13191             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13192              &ip6_src_len))
13193         num_m_args++;
13194       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13195         num_m_args++;
13196       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13197         num_m_args++;
13198       else if (unformat (i, "psid-offset %d", &psid_offset))
13199         num_m_args++;
13200       else if (unformat (i, "psid-len %d", &psid_length))
13201         num_m_args++;
13202       else if (unformat (i, "mtu %d", &mtu))
13203         num_m_args++;
13204       else if (unformat (i, "map-t"))
13205         is_translation = 1;
13206       else
13207         {
13208           clib_warning ("parse error '%U'", format_unformat_error, i);
13209           return -99;
13210         }
13211     }
13212
13213   if (num_m_args < 3)
13214     {
13215       errmsg ("mandatory argument(s) missing");
13216       return -99;
13217     }
13218
13219   /* Construct the API message */
13220   M (MAP_ADD_DOMAIN, mp);
13221
13222   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13223   mp->ip4_prefix_len = ip4_prefix_len;
13224
13225   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13226   mp->ip6_prefix_len = ip6_prefix_len;
13227
13228   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13229   mp->ip6_src_prefix_len = ip6_src_len;
13230
13231   mp->ea_bits_len = ea_bits_len;
13232   mp->psid_offset = psid_offset;
13233   mp->psid_length = psid_length;
13234   mp->is_translation = is_translation;
13235   mp->mtu = htons (mtu);
13236
13237   /* send it... */
13238   S (mp);
13239
13240   /* Wait for a reply, return good/bad news  */
13241   W (ret);
13242   return ret;
13243 }
13244
13245 static int
13246 api_map_del_domain (vat_main_t * vam)
13247 {
13248   unformat_input_t *i = vam->input;
13249   vl_api_map_del_domain_t *mp;
13250
13251   u32 num_m_args = 0;
13252   u32 index;
13253   int ret;
13254
13255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13256     {
13257       if (unformat (i, "index %d", &index))
13258         num_m_args++;
13259       else
13260         {
13261           clib_warning ("parse error '%U'", format_unformat_error, i);
13262           return -99;
13263         }
13264     }
13265
13266   if (num_m_args != 1)
13267     {
13268       errmsg ("mandatory argument(s) missing");
13269       return -99;
13270     }
13271
13272   /* Construct the API message */
13273   M (MAP_DEL_DOMAIN, mp);
13274
13275   mp->index = ntohl (index);
13276
13277   /* send it... */
13278   S (mp);
13279
13280   /* Wait for a reply, return good/bad news  */
13281   W (ret);
13282   return ret;
13283 }
13284
13285 static int
13286 api_map_add_del_rule (vat_main_t * vam)
13287 {
13288   unformat_input_t *i = vam->input;
13289   vl_api_map_add_del_rule_t *mp;
13290   u8 is_add = 1;
13291   ip6_address_t ip6_dst;
13292   u32 num_m_args = 0, index, psid = 0;
13293   int ret;
13294
13295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13296     {
13297       if (unformat (i, "index %d", &index))
13298         num_m_args++;
13299       else if (unformat (i, "psid %d", &psid))
13300         num_m_args++;
13301       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13302         num_m_args++;
13303       else if (unformat (i, "del"))
13304         {
13305           is_add = 0;
13306         }
13307       else
13308         {
13309           clib_warning ("parse error '%U'", format_unformat_error, i);
13310           return -99;
13311         }
13312     }
13313
13314   /* Construct the API message */
13315   M (MAP_ADD_DEL_RULE, mp);
13316
13317   mp->index = ntohl (index);
13318   mp->is_add = is_add;
13319   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13320   mp->psid = ntohs (psid);
13321
13322   /* send it... */
13323   S (mp);
13324
13325   /* Wait for a reply, return good/bad news  */
13326   W (ret);
13327   return ret;
13328 }
13329
13330 static int
13331 api_map_domain_dump (vat_main_t * vam)
13332 {
13333   vl_api_map_domain_dump_t *mp;
13334   vl_api_control_ping_t *mp_ping;
13335   int ret;
13336
13337   /* Construct the API message */
13338   M (MAP_DOMAIN_DUMP, mp);
13339
13340   /* send it... */
13341   S (mp);
13342
13343   /* Use a control ping for synchronization */
13344   M (CONTROL_PING, mp_ping);
13345   S (mp_ping);
13346
13347   W (ret);
13348   return ret;
13349 }
13350
13351 static int
13352 api_map_rule_dump (vat_main_t * vam)
13353 {
13354   unformat_input_t *i = vam->input;
13355   vl_api_map_rule_dump_t *mp;
13356   vl_api_control_ping_t *mp_ping;
13357   u32 domain_index = ~0;
13358   int ret;
13359
13360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13361     {
13362       if (unformat (i, "index %u", &domain_index))
13363         ;
13364       else
13365         break;
13366     }
13367
13368   if (domain_index == ~0)
13369     {
13370       clib_warning ("parse error: domain index expected");
13371       return -99;
13372     }
13373
13374   /* Construct the API message */
13375   M (MAP_RULE_DUMP, mp);
13376
13377   mp->domain_index = htonl (domain_index);
13378
13379   /* send it... */
13380   S (mp);
13381
13382   /* Use a control ping for synchronization */
13383   M (CONTROL_PING, mp_ping);
13384   S (mp_ping);
13385
13386   W (ret);
13387   return ret;
13388 }
13389
13390 static void vl_api_map_add_domain_reply_t_handler
13391   (vl_api_map_add_domain_reply_t * mp)
13392 {
13393   vat_main_t *vam = &vat_main;
13394   i32 retval = ntohl (mp->retval);
13395
13396   if (vam->async_mode)
13397     {
13398       vam->async_errors += (retval < 0);
13399     }
13400   else
13401     {
13402       vam->retval = retval;
13403       vam->result_ready = 1;
13404     }
13405 }
13406
13407 static void vl_api_map_add_domain_reply_t_handler_json
13408   (vl_api_map_add_domain_reply_t * mp)
13409 {
13410   vat_main_t *vam = &vat_main;
13411   vat_json_node_t node;
13412
13413   vat_json_init_object (&node);
13414   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13415   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13416
13417   vat_json_print (vam->ofp, &node);
13418   vat_json_free (&node);
13419
13420   vam->retval = ntohl (mp->retval);
13421   vam->result_ready = 1;
13422 }
13423
13424 static int
13425 api_get_first_msg_id (vat_main_t * vam)
13426 {
13427   vl_api_get_first_msg_id_t *mp;
13428   unformat_input_t *i = vam->input;
13429   u8 *name;
13430   u8 name_set = 0;
13431   int ret;
13432
13433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13434     {
13435       if (unformat (i, "client %s", &name))
13436         name_set = 1;
13437       else
13438         break;
13439     }
13440
13441   if (name_set == 0)
13442     {
13443       errmsg ("missing client name");
13444       return -99;
13445     }
13446   vec_add1 (name, 0);
13447
13448   if (vec_len (name) > 63)
13449     {
13450       errmsg ("client name too long");
13451       return -99;
13452     }
13453
13454   M (GET_FIRST_MSG_ID, mp);
13455   clib_memcpy (mp->name, name, vec_len (name));
13456   S (mp);
13457   W (ret);
13458   return ret;
13459 }
13460
13461 static int
13462 api_cop_interface_enable_disable (vat_main_t * vam)
13463 {
13464   unformat_input_t *line_input = vam->input;
13465   vl_api_cop_interface_enable_disable_t *mp;
13466   u32 sw_if_index = ~0;
13467   u8 enable_disable = 1;
13468   int ret;
13469
13470   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13471     {
13472       if (unformat (line_input, "disable"))
13473         enable_disable = 0;
13474       if (unformat (line_input, "enable"))
13475         enable_disable = 1;
13476       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13477                          vam, &sw_if_index))
13478         ;
13479       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13480         ;
13481       else
13482         break;
13483     }
13484
13485   if (sw_if_index == ~0)
13486     {
13487       errmsg ("missing interface name or sw_if_index");
13488       return -99;
13489     }
13490
13491   /* Construct the API message */
13492   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13493   mp->sw_if_index = ntohl (sw_if_index);
13494   mp->enable_disable = enable_disable;
13495
13496   /* send it... */
13497   S (mp);
13498   /* Wait for the reply */
13499   W (ret);
13500   return ret;
13501 }
13502
13503 static int
13504 api_cop_whitelist_enable_disable (vat_main_t * vam)
13505 {
13506   unformat_input_t *line_input = vam->input;
13507   vl_api_cop_whitelist_enable_disable_t *mp;
13508   u32 sw_if_index = ~0;
13509   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13510   u32 fib_id = 0;
13511   int ret;
13512
13513   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13514     {
13515       if (unformat (line_input, "ip4"))
13516         ip4 = 1;
13517       else if (unformat (line_input, "ip6"))
13518         ip6 = 1;
13519       else if (unformat (line_input, "default"))
13520         default_cop = 1;
13521       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13522                          vam, &sw_if_index))
13523         ;
13524       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13525         ;
13526       else if (unformat (line_input, "fib-id %d", &fib_id))
13527         ;
13528       else
13529         break;
13530     }
13531
13532   if (sw_if_index == ~0)
13533     {
13534       errmsg ("missing interface name or sw_if_index");
13535       return -99;
13536     }
13537
13538   /* Construct the API message */
13539   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13540   mp->sw_if_index = ntohl (sw_if_index);
13541   mp->fib_id = ntohl (fib_id);
13542   mp->ip4 = ip4;
13543   mp->ip6 = ip6;
13544   mp->default_cop = default_cop;
13545
13546   /* send it... */
13547   S (mp);
13548   /* Wait for the reply */
13549   W (ret);
13550   return ret;
13551 }
13552
13553 static int
13554 api_get_node_graph (vat_main_t * vam)
13555 {
13556   vl_api_get_node_graph_t *mp;
13557   int ret;
13558
13559   M (GET_NODE_GRAPH, mp);
13560
13561   /* send it... */
13562   S (mp);
13563   /* Wait for the reply */
13564   W (ret);
13565   return ret;
13566 }
13567
13568 /* *INDENT-OFF* */
13569 /** Used for parsing LISP eids */
13570 typedef CLIB_PACKED(struct{
13571   u8 addr[16];   /**< eid address */
13572   u32 len;       /**< prefix length if IP */
13573   u8 type;      /**< type of eid */
13574 }) lisp_eid_vat_t;
13575 /* *INDENT-ON* */
13576
13577 static uword
13578 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13579 {
13580   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13581
13582   memset (a, 0, sizeof (a[0]));
13583
13584   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13585     {
13586       a->type = 0;              /* ipv4 type */
13587     }
13588   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13589     {
13590       a->type = 1;              /* ipv6 type */
13591     }
13592   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13593     {
13594       a->type = 2;              /* mac type */
13595     }
13596   else
13597     {
13598       return 0;
13599     }
13600
13601   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13602     {
13603       return 0;
13604     }
13605
13606   return 1;
13607 }
13608
13609 static int
13610 lisp_eid_size_vat (u8 type)
13611 {
13612   switch (type)
13613     {
13614     case 0:
13615       return 4;
13616     case 1:
13617       return 16;
13618     case 2:
13619       return 6;
13620     }
13621   return 0;
13622 }
13623
13624 static void
13625 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13626 {
13627   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13628 }
13629
13630 static int
13631 api_one_add_del_locator_set (vat_main_t * vam)
13632 {
13633   unformat_input_t *input = vam->input;
13634   vl_api_one_add_del_locator_set_t *mp;
13635   u8 is_add = 1;
13636   u8 *locator_set_name = NULL;
13637   u8 locator_set_name_set = 0;
13638   vl_api_local_locator_t locator, *locators = 0;
13639   u32 sw_if_index, priority, weight;
13640   u32 data_len = 0;
13641
13642   int ret;
13643   /* Parse args required to build the message */
13644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13645     {
13646       if (unformat (input, "del"))
13647         {
13648           is_add = 0;
13649         }
13650       else if (unformat (input, "locator-set %s", &locator_set_name))
13651         {
13652           locator_set_name_set = 1;
13653         }
13654       else if (unformat (input, "sw_if_index %u p %u w %u",
13655                          &sw_if_index, &priority, &weight))
13656         {
13657           locator.sw_if_index = htonl (sw_if_index);
13658           locator.priority = priority;
13659           locator.weight = weight;
13660           vec_add1 (locators, locator);
13661         }
13662       else
13663         if (unformat
13664             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13665              &sw_if_index, &priority, &weight))
13666         {
13667           locator.sw_if_index = htonl (sw_if_index);
13668           locator.priority = priority;
13669           locator.weight = weight;
13670           vec_add1 (locators, locator);
13671         }
13672       else
13673         break;
13674     }
13675
13676   if (locator_set_name_set == 0)
13677     {
13678       errmsg ("missing locator-set name");
13679       vec_free (locators);
13680       return -99;
13681     }
13682
13683   if (vec_len (locator_set_name) > 64)
13684     {
13685       errmsg ("locator-set name too long");
13686       vec_free (locator_set_name);
13687       vec_free (locators);
13688       return -99;
13689     }
13690   vec_add1 (locator_set_name, 0);
13691
13692   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13693
13694   /* Construct the API message */
13695   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13696
13697   mp->is_add = is_add;
13698   clib_memcpy (mp->locator_set_name, locator_set_name,
13699                vec_len (locator_set_name));
13700   vec_free (locator_set_name);
13701
13702   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13703   if (locators)
13704     clib_memcpy (mp->locators, locators, data_len);
13705   vec_free (locators);
13706
13707   /* send it... */
13708   S (mp);
13709
13710   /* Wait for a reply... */
13711   W (ret);
13712   return ret;
13713 }
13714
13715 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13716
13717 static int
13718 api_one_add_del_locator (vat_main_t * vam)
13719 {
13720   unformat_input_t *input = vam->input;
13721   vl_api_one_add_del_locator_t *mp;
13722   u32 tmp_if_index = ~0;
13723   u32 sw_if_index = ~0;
13724   u8 sw_if_index_set = 0;
13725   u8 sw_if_index_if_name_set = 0;
13726   u32 priority = ~0;
13727   u8 priority_set = 0;
13728   u32 weight = ~0;
13729   u8 weight_set = 0;
13730   u8 is_add = 1;
13731   u8 *locator_set_name = NULL;
13732   u8 locator_set_name_set = 0;
13733   int ret;
13734
13735   /* Parse args required to build the message */
13736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13737     {
13738       if (unformat (input, "del"))
13739         {
13740           is_add = 0;
13741         }
13742       else if (unformat (input, "locator-set %s", &locator_set_name))
13743         {
13744           locator_set_name_set = 1;
13745         }
13746       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13747                          &tmp_if_index))
13748         {
13749           sw_if_index_if_name_set = 1;
13750           sw_if_index = tmp_if_index;
13751         }
13752       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13753         {
13754           sw_if_index_set = 1;
13755           sw_if_index = tmp_if_index;
13756         }
13757       else if (unformat (input, "p %d", &priority))
13758         {
13759           priority_set = 1;
13760         }
13761       else if (unformat (input, "w %d", &weight))
13762         {
13763           weight_set = 1;
13764         }
13765       else
13766         break;
13767     }
13768
13769   if (locator_set_name_set == 0)
13770     {
13771       errmsg ("missing locator-set name");
13772       return -99;
13773     }
13774
13775   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13776     {
13777       errmsg ("missing sw_if_index");
13778       vec_free (locator_set_name);
13779       return -99;
13780     }
13781
13782   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13783     {
13784       errmsg ("cannot use both params interface name and sw_if_index");
13785       vec_free (locator_set_name);
13786       return -99;
13787     }
13788
13789   if (priority_set == 0)
13790     {
13791       errmsg ("missing locator-set priority");
13792       vec_free (locator_set_name);
13793       return -99;
13794     }
13795
13796   if (weight_set == 0)
13797     {
13798       errmsg ("missing locator-set weight");
13799       vec_free (locator_set_name);
13800       return -99;
13801     }
13802
13803   if (vec_len (locator_set_name) > 64)
13804     {
13805       errmsg ("locator-set name too long");
13806       vec_free (locator_set_name);
13807       return -99;
13808     }
13809   vec_add1 (locator_set_name, 0);
13810
13811   /* Construct the API message */
13812   M (ONE_ADD_DEL_LOCATOR, mp);
13813
13814   mp->is_add = is_add;
13815   mp->sw_if_index = ntohl (sw_if_index);
13816   mp->priority = priority;
13817   mp->weight = weight;
13818   clib_memcpy (mp->locator_set_name, locator_set_name,
13819                vec_len (locator_set_name));
13820   vec_free (locator_set_name);
13821
13822   /* send it... */
13823   S (mp);
13824
13825   /* Wait for a reply... */
13826   W (ret);
13827   return ret;
13828 }
13829
13830 #define api_lisp_add_del_locator api_one_add_del_locator
13831
13832 uword
13833 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13834 {
13835   u32 *key_id = va_arg (*args, u32 *);
13836   u8 *s = 0;
13837
13838   if (unformat (input, "%s", &s))
13839     {
13840       if (!strcmp ((char *) s, "sha1"))
13841         key_id[0] = HMAC_SHA_1_96;
13842       else if (!strcmp ((char *) s, "sha256"))
13843         key_id[0] = HMAC_SHA_256_128;
13844       else
13845         {
13846           clib_warning ("invalid key_id: '%s'", s);
13847           key_id[0] = HMAC_NO_KEY;
13848         }
13849     }
13850   else
13851     return 0;
13852
13853   vec_free (s);
13854   return 1;
13855 }
13856
13857 static int
13858 api_one_add_del_local_eid (vat_main_t * vam)
13859 {
13860   unformat_input_t *input = vam->input;
13861   vl_api_one_add_del_local_eid_t *mp;
13862   u8 is_add = 1;
13863   u8 eid_set = 0;
13864   lisp_eid_vat_t _eid, *eid = &_eid;
13865   u8 *locator_set_name = 0;
13866   u8 locator_set_name_set = 0;
13867   u32 vni = 0;
13868   u16 key_id = 0;
13869   u8 *key = 0;
13870   int ret;
13871
13872   /* Parse args required to build the message */
13873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13874     {
13875       if (unformat (input, "del"))
13876         {
13877           is_add = 0;
13878         }
13879       else if (unformat (input, "vni %d", &vni))
13880         {
13881           ;
13882         }
13883       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13884         {
13885           eid_set = 1;
13886         }
13887       else if (unformat (input, "locator-set %s", &locator_set_name))
13888         {
13889           locator_set_name_set = 1;
13890         }
13891       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13892         ;
13893       else if (unformat (input, "secret-key %_%v%_", &key))
13894         ;
13895       else
13896         break;
13897     }
13898
13899   if (locator_set_name_set == 0)
13900     {
13901       errmsg ("missing locator-set name");
13902       return -99;
13903     }
13904
13905   if (0 == eid_set)
13906     {
13907       errmsg ("EID address not set!");
13908       vec_free (locator_set_name);
13909       return -99;
13910     }
13911
13912   if (key && (0 == key_id))
13913     {
13914       errmsg ("invalid key_id!");
13915       return -99;
13916     }
13917
13918   if (vec_len (key) > 64)
13919     {
13920       errmsg ("key too long");
13921       vec_free (key);
13922       return -99;
13923     }
13924
13925   if (vec_len (locator_set_name) > 64)
13926     {
13927       errmsg ("locator-set name too long");
13928       vec_free (locator_set_name);
13929       return -99;
13930     }
13931   vec_add1 (locator_set_name, 0);
13932
13933   /* Construct the API message */
13934   M (ONE_ADD_DEL_LOCAL_EID, mp);
13935
13936   mp->is_add = is_add;
13937   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13938   mp->eid_type = eid->type;
13939   mp->prefix_len = eid->len;
13940   mp->vni = clib_host_to_net_u32 (vni);
13941   mp->key_id = clib_host_to_net_u16 (key_id);
13942   clib_memcpy (mp->locator_set_name, locator_set_name,
13943                vec_len (locator_set_name));
13944   clib_memcpy (mp->key, key, vec_len (key));
13945
13946   vec_free (locator_set_name);
13947   vec_free (key);
13948
13949   /* send it... */
13950   S (mp);
13951
13952   /* Wait for a reply... */
13953   W (ret);
13954   return ret;
13955 }
13956
13957 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13958
13959 static int
13960 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13961 {
13962   u32 dp_table = 0, vni = 0;;
13963   unformat_input_t *input = vam->input;
13964   vl_api_gpe_add_del_fwd_entry_t *mp;
13965   u8 is_add = 1;
13966   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13967   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13968   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13969   u32 action = ~0, w;
13970   ip4_address_t rmt_rloc4, lcl_rloc4;
13971   ip6_address_t rmt_rloc6, lcl_rloc6;
13972   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13973   int ret;
13974
13975   memset (&rloc, 0, sizeof (rloc));
13976
13977   /* Parse args required to build the message */
13978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13979     {
13980       if (unformat (input, "del"))
13981         is_add = 0;
13982       else if (unformat (input, "add"))
13983         is_add = 1;
13984       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13985         {
13986           rmt_eid_set = 1;
13987         }
13988       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13989         {
13990           lcl_eid_set = 1;
13991         }
13992       else if (unformat (input, "vrf %d", &dp_table))
13993         ;
13994       else if (unformat (input, "bd %d", &dp_table))
13995         ;
13996       else if (unformat (input, "vni %d", &vni))
13997         ;
13998       else if (unformat (input, "w %d", &w))
13999         {
14000           if (!curr_rloc)
14001             {
14002               errmsg ("No RLOC configured for setting priority/weight!");
14003               return -99;
14004             }
14005           curr_rloc->weight = w;
14006         }
14007       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14008                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14009         {
14010           rloc.is_ip4 = 1;
14011
14012           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14013           rloc.weight = 0;
14014           vec_add1 (lcl_locs, rloc);
14015
14016           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14017           vec_add1 (rmt_locs, rloc);
14018           /* weight saved in rmt loc */
14019           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14020         }
14021       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14022                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14023         {
14024           rloc.is_ip4 = 0;
14025           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14026           rloc.weight = 0;
14027           vec_add1 (lcl_locs, rloc);
14028
14029           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14030           vec_add1 (rmt_locs, rloc);
14031           /* weight saved in rmt loc */
14032           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14033         }
14034       else if (unformat (input, "action %d", &action))
14035         {
14036           ;
14037         }
14038       else
14039         {
14040           clib_warning ("parse error '%U'", format_unformat_error, input);
14041           return -99;
14042         }
14043     }
14044
14045   if (!rmt_eid_set)
14046     {
14047       errmsg ("remote eid addresses not set");
14048       return -99;
14049     }
14050
14051   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14052     {
14053       errmsg ("eid types don't match");
14054       return -99;
14055     }
14056
14057   if (0 == rmt_locs && (u32) ~ 0 == action)
14058     {
14059       errmsg ("action not set for negative mapping");
14060       return -99;
14061     }
14062
14063   /* Construct the API message */
14064   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14065       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14066
14067   mp->is_add = is_add;
14068   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14069   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14070   mp->eid_type = rmt_eid->type;
14071   mp->dp_table = clib_host_to_net_u32 (dp_table);
14072   mp->vni = clib_host_to_net_u32 (vni);
14073   mp->rmt_len = rmt_eid->len;
14074   mp->lcl_len = lcl_eid->len;
14075   mp->action = action;
14076
14077   if (0 != rmt_locs && 0 != lcl_locs)
14078     {
14079       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14080       clib_memcpy (mp->locs, lcl_locs,
14081                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14082
14083       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14084       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14085                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14086     }
14087   vec_free (lcl_locs);
14088   vec_free (rmt_locs);
14089
14090   /* send it... */
14091   S (mp);
14092
14093   /* Wait for a reply... */
14094   W (ret);
14095   return ret;
14096 }
14097
14098 static int
14099 api_one_add_del_map_server (vat_main_t * vam)
14100 {
14101   unformat_input_t *input = vam->input;
14102   vl_api_one_add_del_map_server_t *mp;
14103   u8 is_add = 1;
14104   u8 ipv4_set = 0;
14105   u8 ipv6_set = 0;
14106   ip4_address_t ipv4;
14107   ip6_address_t ipv6;
14108   int ret;
14109
14110   /* Parse args required to build the message */
14111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14112     {
14113       if (unformat (input, "del"))
14114         {
14115           is_add = 0;
14116         }
14117       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14118         {
14119           ipv4_set = 1;
14120         }
14121       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14122         {
14123           ipv6_set = 1;
14124         }
14125       else
14126         break;
14127     }
14128
14129   if (ipv4_set && ipv6_set)
14130     {
14131       errmsg ("both eid v4 and v6 addresses set");
14132       return -99;
14133     }
14134
14135   if (!ipv4_set && !ipv6_set)
14136     {
14137       errmsg ("eid addresses not set");
14138       return -99;
14139     }
14140
14141   /* Construct the API message */
14142   M (ONE_ADD_DEL_MAP_SERVER, mp);
14143
14144   mp->is_add = is_add;
14145   if (ipv6_set)
14146     {
14147       mp->is_ipv6 = 1;
14148       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14149     }
14150   else
14151     {
14152       mp->is_ipv6 = 0;
14153       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14154     }
14155
14156   /* send it... */
14157   S (mp);
14158
14159   /* Wait for a reply... */
14160   W (ret);
14161   return ret;
14162 }
14163
14164 #define api_lisp_add_del_map_server api_one_add_del_map_server
14165
14166 static int
14167 api_one_add_del_map_resolver (vat_main_t * vam)
14168 {
14169   unformat_input_t *input = vam->input;
14170   vl_api_one_add_del_map_resolver_t *mp;
14171   u8 is_add = 1;
14172   u8 ipv4_set = 0;
14173   u8 ipv6_set = 0;
14174   ip4_address_t ipv4;
14175   ip6_address_t ipv6;
14176   int ret;
14177
14178   /* Parse args required to build the message */
14179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14180     {
14181       if (unformat (input, "del"))
14182         {
14183           is_add = 0;
14184         }
14185       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14186         {
14187           ipv4_set = 1;
14188         }
14189       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14190         {
14191           ipv6_set = 1;
14192         }
14193       else
14194         break;
14195     }
14196
14197   if (ipv4_set && ipv6_set)
14198     {
14199       errmsg ("both eid v4 and v6 addresses set");
14200       return -99;
14201     }
14202
14203   if (!ipv4_set && !ipv6_set)
14204     {
14205       errmsg ("eid addresses not set");
14206       return -99;
14207     }
14208
14209   /* Construct the API message */
14210   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14211
14212   mp->is_add = is_add;
14213   if (ipv6_set)
14214     {
14215       mp->is_ipv6 = 1;
14216       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14217     }
14218   else
14219     {
14220       mp->is_ipv6 = 0;
14221       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14222     }
14223
14224   /* send it... */
14225   S (mp);
14226
14227   /* Wait for a reply... */
14228   W (ret);
14229   return ret;
14230 }
14231
14232 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14233
14234 static int
14235 api_lisp_gpe_enable_disable (vat_main_t * vam)
14236 {
14237   unformat_input_t *input = vam->input;
14238   vl_api_gpe_enable_disable_t *mp;
14239   u8 is_set = 0;
14240   u8 is_en = 1;
14241   int ret;
14242
14243   /* Parse args required to build the message */
14244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14245     {
14246       if (unformat (input, "enable"))
14247         {
14248           is_set = 1;
14249           is_en = 1;
14250         }
14251       else if (unformat (input, "disable"))
14252         {
14253           is_set = 1;
14254           is_en = 0;
14255         }
14256       else
14257         break;
14258     }
14259
14260   if (is_set == 0)
14261     {
14262       errmsg ("Value not set");
14263       return -99;
14264     }
14265
14266   /* Construct the API message */
14267   M (GPE_ENABLE_DISABLE, mp);
14268
14269   mp->is_en = is_en;
14270
14271   /* send it... */
14272   S (mp);
14273
14274   /* Wait for a reply... */
14275   W (ret);
14276   return ret;
14277 }
14278
14279 static int
14280 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14281 {
14282   unformat_input_t *input = vam->input;
14283   vl_api_one_rloc_probe_enable_disable_t *mp;
14284   u8 is_set = 0;
14285   u8 is_en = 0;
14286   int ret;
14287
14288   /* Parse args required to build the message */
14289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14290     {
14291       if (unformat (input, "enable"))
14292         {
14293           is_set = 1;
14294           is_en = 1;
14295         }
14296       else if (unformat (input, "disable"))
14297         is_set = 1;
14298       else
14299         break;
14300     }
14301
14302   if (!is_set)
14303     {
14304       errmsg ("Value not set");
14305       return -99;
14306     }
14307
14308   /* Construct the API message */
14309   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14310
14311   mp->is_enabled = is_en;
14312
14313   /* send it... */
14314   S (mp);
14315
14316   /* Wait for a reply... */
14317   W (ret);
14318   return ret;
14319 }
14320
14321 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14322
14323 static int
14324 api_one_map_register_enable_disable (vat_main_t * vam)
14325 {
14326   unformat_input_t *input = vam->input;
14327   vl_api_one_map_register_enable_disable_t *mp;
14328   u8 is_set = 0;
14329   u8 is_en = 0;
14330   int ret;
14331
14332   /* Parse args required to build the message */
14333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14334     {
14335       if (unformat (input, "enable"))
14336         {
14337           is_set = 1;
14338           is_en = 1;
14339         }
14340       else if (unformat (input, "disable"))
14341         is_set = 1;
14342       else
14343         break;
14344     }
14345
14346   if (!is_set)
14347     {
14348       errmsg ("Value not set");
14349       return -99;
14350     }
14351
14352   /* Construct the API message */
14353   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14354
14355   mp->is_enabled = is_en;
14356
14357   /* send it... */
14358   S (mp);
14359
14360   /* Wait for a reply... */
14361   W (ret);
14362   return ret;
14363 }
14364
14365 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14366
14367 static int
14368 api_one_enable_disable (vat_main_t * vam)
14369 {
14370   unformat_input_t *input = vam->input;
14371   vl_api_one_enable_disable_t *mp;
14372   u8 is_set = 0;
14373   u8 is_en = 0;
14374   int ret;
14375
14376   /* Parse args required to build the message */
14377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14378     {
14379       if (unformat (input, "enable"))
14380         {
14381           is_set = 1;
14382           is_en = 1;
14383         }
14384       else if (unformat (input, "disable"))
14385         {
14386           is_set = 1;
14387         }
14388       else
14389         break;
14390     }
14391
14392   if (!is_set)
14393     {
14394       errmsg ("Value not set");
14395       return -99;
14396     }
14397
14398   /* Construct the API message */
14399   M (ONE_ENABLE_DISABLE, mp);
14400
14401   mp->is_en = is_en;
14402
14403   /* send it... */
14404   S (mp);
14405
14406   /* Wait for a reply... */
14407   W (ret);
14408   return ret;
14409 }
14410
14411 #define api_lisp_enable_disable api_one_enable_disable
14412
14413 static int
14414 api_show_one_map_register_state (vat_main_t * vam)
14415 {
14416   vl_api_show_one_map_register_state_t *mp;
14417   int ret;
14418
14419   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14420
14421   /* send */
14422   S (mp);
14423
14424   /* wait for reply */
14425   W (ret);
14426   return ret;
14427 }
14428
14429 #define api_show_lisp_map_register_state api_show_one_map_register_state
14430
14431 static int
14432 api_show_one_rloc_probe_state (vat_main_t * vam)
14433 {
14434   vl_api_show_one_rloc_probe_state_t *mp;
14435   int ret;
14436
14437   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14438
14439   /* send */
14440   S (mp);
14441
14442   /* wait for reply */
14443   W (ret);
14444   return ret;
14445 }
14446
14447 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14448
14449 static int
14450 api_show_one_map_request_mode (vat_main_t * vam)
14451 {
14452   vl_api_show_one_map_request_mode_t *mp;
14453   int ret;
14454
14455   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14456
14457   /* send */
14458   S (mp);
14459
14460   /* wait for reply */
14461   W (ret);
14462   return ret;
14463 }
14464
14465 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14466
14467 static int
14468 api_one_map_request_mode (vat_main_t * vam)
14469 {
14470   unformat_input_t *input = vam->input;
14471   vl_api_one_map_request_mode_t *mp;
14472   u8 mode = 0;
14473   int ret;
14474
14475   /* Parse args required to build the message */
14476   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14477     {
14478       if (unformat (input, "dst-only"))
14479         mode = 0;
14480       else if (unformat (input, "src-dst"))
14481         mode = 1;
14482       else
14483         {
14484           errmsg ("parse error '%U'", format_unformat_error, input);
14485           return -99;
14486         }
14487     }
14488
14489   M (ONE_MAP_REQUEST_MODE, mp);
14490
14491   mp->mode = mode;
14492
14493   /* send */
14494   S (mp);
14495
14496   /* wait for reply */
14497   W (ret);
14498   return ret;
14499 }
14500
14501 #define api_lisp_map_request_mode api_one_map_request_mode
14502
14503 /**
14504  * Enable/disable ONE proxy ITR.
14505  *
14506  * @param vam vpp API test context
14507  * @return return code
14508  */
14509 static int
14510 api_one_pitr_set_locator_set (vat_main_t * vam)
14511 {
14512   u8 ls_name_set = 0;
14513   unformat_input_t *input = vam->input;
14514   vl_api_one_pitr_set_locator_set_t *mp;
14515   u8 is_add = 1;
14516   u8 *ls_name = 0;
14517   int ret;
14518
14519   /* Parse args required to build the message */
14520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14521     {
14522       if (unformat (input, "del"))
14523         is_add = 0;
14524       else if (unformat (input, "locator-set %s", &ls_name))
14525         ls_name_set = 1;
14526       else
14527         {
14528           errmsg ("parse error '%U'", format_unformat_error, input);
14529           return -99;
14530         }
14531     }
14532
14533   if (!ls_name_set)
14534     {
14535       errmsg ("locator-set name not set!");
14536       return -99;
14537     }
14538
14539   M (ONE_PITR_SET_LOCATOR_SET, mp);
14540
14541   mp->is_add = is_add;
14542   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14543   vec_free (ls_name);
14544
14545   /* send */
14546   S (mp);
14547
14548   /* wait for reply */
14549   W (ret);
14550   return ret;
14551 }
14552
14553 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14554
14555 static int
14556 api_show_one_pitr (vat_main_t * vam)
14557 {
14558   vl_api_show_one_pitr_t *mp;
14559   int ret;
14560
14561   if (!vam->json_output)
14562     {
14563       print (vam->ofp, "%=20s", "lisp status:");
14564     }
14565
14566   M (SHOW_ONE_PITR, mp);
14567   /* send it... */
14568   S (mp);
14569
14570   /* Wait for a reply... */
14571   W (ret);
14572   return ret;
14573 }
14574
14575 #define api_show_lisp_pitr api_show_one_pitr
14576
14577 /**
14578  * Add/delete mapping between vni and vrf
14579  */
14580 static int
14581 api_one_eid_table_add_del_map (vat_main_t * vam)
14582 {
14583   unformat_input_t *input = vam->input;
14584   vl_api_one_eid_table_add_del_map_t *mp;
14585   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14586   u32 vni, vrf, bd_index;
14587   int ret;
14588
14589   /* Parse args required to build the message */
14590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14591     {
14592       if (unformat (input, "del"))
14593         is_add = 0;
14594       else if (unformat (input, "vrf %d", &vrf))
14595         vrf_set = 1;
14596       else if (unformat (input, "bd_index %d", &bd_index))
14597         bd_index_set = 1;
14598       else if (unformat (input, "vni %d", &vni))
14599         vni_set = 1;
14600       else
14601         break;
14602     }
14603
14604   if (!vni_set || (!vrf_set && !bd_index_set))
14605     {
14606       errmsg ("missing arguments!");
14607       return -99;
14608     }
14609
14610   if (vrf_set && bd_index_set)
14611     {
14612       errmsg ("error: both vrf and bd entered!");
14613       return -99;
14614     }
14615
14616   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14617
14618   mp->is_add = is_add;
14619   mp->vni = htonl (vni);
14620   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14621   mp->is_l2 = bd_index_set;
14622
14623   /* send */
14624   S (mp);
14625
14626   /* wait for reply */
14627   W (ret);
14628   return ret;
14629 }
14630
14631 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14632
14633 uword
14634 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14635 {
14636   u32 *action = va_arg (*args, u32 *);
14637   u8 *s = 0;
14638
14639   if (unformat (input, "%s", &s))
14640     {
14641       if (!strcmp ((char *) s, "no-action"))
14642         action[0] = 0;
14643       else if (!strcmp ((char *) s, "natively-forward"))
14644         action[0] = 1;
14645       else if (!strcmp ((char *) s, "send-map-request"))
14646         action[0] = 2;
14647       else if (!strcmp ((char *) s, "drop"))
14648         action[0] = 3;
14649       else
14650         {
14651           clib_warning ("invalid action: '%s'", s);
14652           action[0] = 3;
14653         }
14654     }
14655   else
14656     return 0;
14657
14658   vec_free (s);
14659   return 1;
14660 }
14661
14662 /**
14663  * Add/del remote mapping to/from ONE control plane
14664  *
14665  * @param vam vpp API test context
14666  * @return return code
14667  */
14668 static int
14669 api_one_add_del_remote_mapping (vat_main_t * vam)
14670 {
14671   unformat_input_t *input = vam->input;
14672   vl_api_one_add_del_remote_mapping_t *mp;
14673   u32 vni = 0;
14674   lisp_eid_vat_t _eid, *eid = &_eid;
14675   lisp_eid_vat_t _seid, *seid = &_seid;
14676   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14677   u32 action = ~0, p, w, data_len;
14678   ip4_address_t rloc4;
14679   ip6_address_t rloc6;
14680   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14681   int ret;
14682
14683   memset (&rloc, 0, sizeof (rloc));
14684
14685   /* Parse args required to build the message */
14686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14687     {
14688       if (unformat (input, "del-all"))
14689         {
14690           del_all = 1;
14691         }
14692       else if (unformat (input, "del"))
14693         {
14694           is_add = 0;
14695         }
14696       else if (unformat (input, "add"))
14697         {
14698           is_add = 1;
14699         }
14700       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14701         {
14702           eid_set = 1;
14703         }
14704       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14705         {
14706           seid_set = 1;
14707         }
14708       else if (unformat (input, "vni %d", &vni))
14709         {
14710           ;
14711         }
14712       else if (unformat (input, "p %d w %d", &p, &w))
14713         {
14714           if (!curr_rloc)
14715             {
14716               errmsg ("No RLOC configured for setting priority/weight!");
14717               return -99;
14718             }
14719           curr_rloc->priority = p;
14720           curr_rloc->weight = w;
14721         }
14722       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14723         {
14724           rloc.is_ip4 = 1;
14725           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14726           vec_add1 (rlocs, rloc);
14727           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14728         }
14729       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14730         {
14731           rloc.is_ip4 = 0;
14732           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14733           vec_add1 (rlocs, rloc);
14734           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14735         }
14736       else if (unformat (input, "action %U",
14737                          unformat_negative_mapping_action, &action))
14738         {
14739           ;
14740         }
14741       else
14742         {
14743           clib_warning ("parse error '%U'", format_unformat_error, input);
14744           return -99;
14745         }
14746     }
14747
14748   if (0 == eid_set)
14749     {
14750       errmsg ("missing params!");
14751       return -99;
14752     }
14753
14754   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14755     {
14756       errmsg ("no action set for negative map-reply!");
14757       return -99;
14758     }
14759
14760   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14761
14762   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14763   mp->is_add = is_add;
14764   mp->vni = htonl (vni);
14765   mp->action = (u8) action;
14766   mp->is_src_dst = seid_set;
14767   mp->eid_len = eid->len;
14768   mp->seid_len = seid->len;
14769   mp->del_all = del_all;
14770   mp->eid_type = eid->type;
14771   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14772   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14773
14774   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14775   clib_memcpy (mp->rlocs, rlocs, data_len);
14776   vec_free (rlocs);
14777
14778   /* send it... */
14779   S (mp);
14780
14781   /* Wait for a reply... */
14782   W (ret);
14783   return ret;
14784 }
14785
14786 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14787
14788 /**
14789  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14790  * forwarding entries in data-plane accordingly.
14791  *
14792  * @param vam vpp API test context
14793  * @return return code
14794  */
14795 static int
14796 api_one_add_del_adjacency (vat_main_t * vam)
14797 {
14798   unformat_input_t *input = vam->input;
14799   vl_api_one_add_del_adjacency_t *mp;
14800   u32 vni = 0;
14801   ip4_address_t leid4, reid4;
14802   ip6_address_t leid6, reid6;
14803   u8 reid_mac[6] = { 0 };
14804   u8 leid_mac[6] = { 0 };
14805   u8 reid_type, leid_type;
14806   u32 leid_len = 0, reid_len = 0, len;
14807   u8 is_add = 1;
14808   int ret;
14809
14810   leid_type = reid_type = (u8) ~ 0;
14811
14812   /* Parse args required to build the message */
14813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14814     {
14815       if (unformat (input, "del"))
14816         {
14817           is_add = 0;
14818         }
14819       else if (unformat (input, "add"))
14820         {
14821           is_add = 1;
14822         }
14823       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14824                          &reid4, &len))
14825         {
14826           reid_type = 0;        /* ipv4 */
14827           reid_len = len;
14828         }
14829       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14830                          &reid6, &len))
14831         {
14832           reid_type = 1;        /* ipv6 */
14833           reid_len = len;
14834         }
14835       else if (unformat (input, "reid %U", unformat_ethernet_address,
14836                          reid_mac))
14837         {
14838           reid_type = 2;        /* mac */
14839         }
14840       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14841                          &leid4, &len))
14842         {
14843           leid_type = 0;        /* ipv4 */
14844           leid_len = len;
14845         }
14846       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14847                          &leid6, &len))
14848         {
14849           leid_type = 1;        /* ipv6 */
14850           leid_len = len;
14851         }
14852       else if (unformat (input, "leid %U", unformat_ethernet_address,
14853                          leid_mac))
14854         {
14855           leid_type = 2;        /* mac */
14856         }
14857       else if (unformat (input, "vni %d", &vni))
14858         {
14859           ;
14860         }
14861       else
14862         {
14863           errmsg ("parse error '%U'", format_unformat_error, input);
14864           return -99;
14865         }
14866     }
14867
14868   if ((u8) ~ 0 == reid_type)
14869     {
14870       errmsg ("missing params!");
14871       return -99;
14872     }
14873
14874   if (leid_type != reid_type)
14875     {
14876       errmsg ("remote and local EIDs are of different types!");
14877       return -99;
14878     }
14879
14880   M (ONE_ADD_DEL_ADJACENCY, mp);
14881   mp->is_add = is_add;
14882   mp->vni = htonl (vni);
14883   mp->leid_len = leid_len;
14884   mp->reid_len = reid_len;
14885   mp->eid_type = reid_type;
14886
14887   switch (mp->eid_type)
14888     {
14889     case 0:
14890       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14891       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14892       break;
14893     case 1:
14894       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14895       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14896       break;
14897     case 2:
14898       clib_memcpy (mp->leid, leid_mac, 6);
14899       clib_memcpy (mp->reid, reid_mac, 6);
14900       break;
14901     default:
14902       errmsg ("unknown EID type %d!", mp->eid_type);
14903       return 0;
14904     }
14905
14906   /* send it... */
14907   S (mp);
14908
14909   /* Wait for a reply... */
14910   W (ret);
14911   return ret;
14912 }
14913
14914 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14915
14916 uword
14917 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14918 {
14919   u32 *mode = va_arg (*args, u32 *);
14920
14921   if (unformat (input, "lisp"))
14922     *mode = 0;
14923   else if (unformat (input, "vxlan"))
14924     *mode = 1;
14925   else
14926     return 0;
14927
14928   return 1;
14929 }
14930
14931 static int
14932 api_gpe_get_encap_mode (vat_main_t * vam)
14933 {
14934   vl_api_gpe_get_encap_mode_t *mp;
14935   int ret;
14936
14937   /* Construct the API message */
14938   M (GPE_GET_ENCAP_MODE, mp);
14939
14940   /* send it... */
14941   S (mp);
14942
14943   /* Wait for a reply... */
14944   W (ret);
14945   return ret;
14946 }
14947
14948 static int
14949 api_gpe_set_encap_mode (vat_main_t * vam)
14950 {
14951   unformat_input_t *input = vam->input;
14952   vl_api_gpe_set_encap_mode_t *mp;
14953   int ret;
14954   u32 mode = 0;
14955
14956   /* Parse args required to build the message */
14957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14958     {
14959       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14960         ;
14961       else
14962         break;
14963     }
14964
14965   /* Construct the API message */
14966   M (GPE_SET_ENCAP_MODE, mp);
14967
14968   mp->mode = mode;
14969
14970   /* send it... */
14971   S (mp);
14972
14973   /* Wait for a reply... */
14974   W (ret);
14975   return ret;
14976 }
14977
14978 static int
14979 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14980 {
14981   unformat_input_t *input = vam->input;
14982   vl_api_gpe_add_del_iface_t *mp;
14983   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14984   u32 dp_table = 0, vni = 0;
14985   int ret;
14986
14987   /* Parse args required to build the message */
14988   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14989     {
14990       if (unformat (input, "up"))
14991         {
14992           action_set = 1;
14993           is_add = 1;
14994         }
14995       else if (unformat (input, "down"))
14996         {
14997           action_set = 1;
14998           is_add = 0;
14999         }
15000       else if (unformat (input, "table_id %d", &dp_table))
15001         {
15002           dp_table_set = 1;
15003         }
15004       else if (unformat (input, "bd_id %d", &dp_table))
15005         {
15006           dp_table_set = 1;
15007           is_l2 = 1;
15008         }
15009       else if (unformat (input, "vni %d", &vni))
15010         {
15011           vni_set = 1;
15012         }
15013       else
15014         break;
15015     }
15016
15017   if (action_set == 0)
15018     {
15019       errmsg ("Action not set");
15020       return -99;
15021     }
15022   if (dp_table_set == 0 || vni_set == 0)
15023     {
15024       errmsg ("vni and dp_table must be set");
15025       return -99;
15026     }
15027
15028   /* Construct the API message */
15029   M (GPE_ADD_DEL_IFACE, mp);
15030
15031   mp->is_add = is_add;
15032   mp->dp_table = dp_table;
15033   mp->is_l2 = is_l2;
15034   mp->vni = vni;
15035
15036   /* send it... */
15037   S (mp);
15038
15039   /* Wait for a reply... */
15040   W (ret);
15041   return ret;
15042 }
15043
15044 /**
15045  * Add/del map request itr rlocs from ONE control plane and updates
15046  *
15047  * @param vam vpp API test context
15048  * @return return code
15049  */
15050 static int
15051 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15052 {
15053   unformat_input_t *input = vam->input;
15054   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15055   u8 *locator_set_name = 0;
15056   u8 locator_set_name_set = 0;
15057   u8 is_add = 1;
15058   int ret;
15059
15060   /* Parse args required to build the message */
15061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15062     {
15063       if (unformat (input, "del"))
15064         {
15065           is_add = 0;
15066         }
15067       else if (unformat (input, "%_%v%_", &locator_set_name))
15068         {
15069           locator_set_name_set = 1;
15070         }
15071       else
15072         {
15073           clib_warning ("parse error '%U'", format_unformat_error, input);
15074           return -99;
15075         }
15076     }
15077
15078   if (is_add && !locator_set_name_set)
15079     {
15080       errmsg ("itr-rloc is not set!");
15081       return -99;
15082     }
15083
15084   if (is_add && vec_len (locator_set_name) > 64)
15085     {
15086       errmsg ("itr-rloc locator-set name too long");
15087       vec_free (locator_set_name);
15088       return -99;
15089     }
15090
15091   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15092   mp->is_add = is_add;
15093   if (is_add)
15094     {
15095       clib_memcpy (mp->locator_set_name, locator_set_name,
15096                    vec_len (locator_set_name));
15097     }
15098   else
15099     {
15100       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15101     }
15102   vec_free (locator_set_name);
15103
15104   /* send it... */
15105   S (mp);
15106
15107   /* Wait for a reply... */
15108   W (ret);
15109   return ret;
15110 }
15111
15112 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15113
15114 static int
15115 api_one_locator_dump (vat_main_t * vam)
15116 {
15117   unformat_input_t *input = vam->input;
15118   vl_api_one_locator_dump_t *mp;
15119   vl_api_control_ping_t *mp_ping;
15120   u8 is_index_set = 0, is_name_set = 0;
15121   u8 *ls_name = 0;
15122   u32 ls_index = ~0;
15123   int ret;
15124
15125   /* Parse args required to build the message */
15126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15127     {
15128       if (unformat (input, "ls_name %_%v%_", &ls_name))
15129         {
15130           is_name_set = 1;
15131         }
15132       else if (unformat (input, "ls_index %d", &ls_index))
15133         {
15134           is_index_set = 1;
15135         }
15136       else
15137         {
15138           errmsg ("parse error '%U'", format_unformat_error, input);
15139           return -99;
15140         }
15141     }
15142
15143   if (!is_index_set && !is_name_set)
15144     {
15145       errmsg ("error: expected one of index or name!");
15146       return -99;
15147     }
15148
15149   if (is_index_set && is_name_set)
15150     {
15151       errmsg ("error: only one param expected!");
15152       return -99;
15153     }
15154
15155   if (vec_len (ls_name) > 62)
15156     {
15157       errmsg ("error: locator set name too long!");
15158       return -99;
15159     }
15160
15161   if (!vam->json_output)
15162     {
15163       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15164     }
15165
15166   M (ONE_LOCATOR_DUMP, mp);
15167   mp->is_index_set = is_index_set;
15168
15169   if (is_index_set)
15170     mp->ls_index = clib_host_to_net_u32 (ls_index);
15171   else
15172     {
15173       vec_add1 (ls_name, 0);
15174       strncpy ((char *) mp->ls_name, (char *) ls_name,
15175                sizeof (mp->ls_name) - 1);
15176     }
15177
15178   /* send it... */
15179   S (mp);
15180
15181   /* Use a control ping for synchronization */
15182   M (CONTROL_PING, mp_ping);
15183   S (mp_ping);
15184
15185   /* Wait for a reply... */
15186   W (ret);
15187   return ret;
15188 }
15189
15190 #define api_lisp_locator_dump api_one_locator_dump
15191
15192 static int
15193 api_one_locator_set_dump (vat_main_t * vam)
15194 {
15195   vl_api_one_locator_set_dump_t *mp;
15196   vl_api_control_ping_t *mp_ping;
15197   unformat_input_t *input = vam->input;
15198   u8 filter = 0;
15199   int ret;
15200
15201   /* Parse args required to build the message */
15202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15203     {
15204       if (unformat (input, "local"))
15205         {
15206           filter = 1;
15207         }
15208       else if (unformat (input, "remote"))
15209         {
15210           filter = 2;
15211         }
15212       else
15213         {
15214           errmsg ("parse error '%U'", format_unformat_error, input);
15215           return -99;
15216         }
15217     }
15218
15219   if (!vam->json_output)
15220     {
15221       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15222     }
15223
15224   M (ONE_LOCATOR_SET_DUMP, mp);
15225
15226   mp->filter = filter;
15227
15228   /* send it... */
15229   S (mp);
15230
15231   /* Use a control ping for synchronization */
15232   M (CONTROL_PING, mp_ping);
15233   S (mp_ping);
15234
15235   /* Wait for a reply... */
15236   W (ret);
15237   return ret;
15238 }
15239
15240 #define api_lisp_locator_set_dump api_one_locator_set_dump
15241
15242 static int
15243 api_one_eid_table_map_dump (vat_main_t * vam)
15244 {
15245   u8 is_l2 = 0;
15246   u8 mode_set = 0;
15247   unformat_input_t *input = vam->input;
15248   vl_api_one_eid_table_map_dump_t *mp;
15249   vl_api_control_ping_t *mp_ping;
15250   int ret;
15251
15252   /* Parse args required to build the message */
15253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15254     {
15255       if (unformat (input, "l2"))
15256         {
15257           is_l2 = 1;
15258           mode_set = 1;
15259         }
15260       else if (unformat (input, "l3"))
15261         {
15262           is_l2 = 0;
15263           mode_set = 1;
15264         }
15265       else
15266         {
15267           errmsg ("parse error '%U'", format_unformat_error, input);
15268           return -99;
15269         }
15270     }
15271
15272   if (!mode_set)
15273     {
15274       errmsg ("expected one of 'l2' or 'l3' parameter!");
15275       return -99;
15276     }
15277
15278   if (!vam->json_output)
15279     {
15280       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15281     }
15282
15283   M (ONE_EID_TABLE_MAP_DUMP, mp);
15284   mp->is_l2 = is_l2;
15285
15286   /* send it... */
15287   S (mp);
15288
15289   /* Use a control ping for synchronization */
15290   M (CONTROL_PING, mp_ping);
15291   S (mp_ping);
15292
15293   /* Wait for a reply... */
15294   W (ret);
15295   return ret;
15296 }
15297
15298 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15299
15300 static int
15301 api_one_eid_table_vni_dump (vat_main_t * vam)
15302 {
15303   vl_api_one_eid_table_vni_dump_t *mp;
15304   vl_api_control_ping_t *mp_ping;
15305   int ret;
15306
15307   if (!vam->json_output)
15308     {
15309       print (vam->ofp, "VNI");
15310     }
15311
15312   M (ONE_EID_TABLE_VNI_DUMP, mp);
15313
15314   /* send it... */
15315   S (mp);
15316
15317   /* Use a control ping for synchronization */
15318   M (CONTROL_PING, mp_ping);
15319   S (mp_ping);
15320
15321   /* Wait for a reply... */
15322   W (ret);
15323   return ret;
15324 }
15325
15326 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15327
15328 static int
15329 api_one_eid_table_dump (vat_main_t * vam)
15330 {
15331   unformat_input_t *i = vam->input;
15332   vl_api_one_eid_table_dump_t *mp;
15333   vl_api_control_ping_t *mp_ping;
15334   struct in_addr ip4;
15335   struct in6_addr ip6;
15336   u8 mac[6];
15337   u8 eid_type = ~0, eid_set = 0;
15338   u32 prefix_length = ~0, t, vni = 0;
15339   u8 filter = 0;
15340   int ret;
15341
15342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15343     {
15344       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15345         {
15346           eid_set = 1;
15347           eid_type = 0;
15348           prefix_length = t;
15349         }
15350       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15351         {
15352           eid_set = 1;
15353           eid_type = 1;
15354           prefix_length = t;
15355         }
15356       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15357         {
15358           eid_set = 1;
15359           eid_type = 2;
15360         }
15361       else if (unformat (i, "vni %d", &t))
15362         {
15363           vni = t;
15364         }
15365       else if (unformat (i, "local"))
15366         {
15367           filter = 1;
15368         }
15369       else if (unformat (i, "remote"))
15370         {
15371           filter = 2;
15372         }
15373       else
15374         {
15375           errmsg ("parse error '%U'", format_unformat_error, i);
15376           return -99;
15377         }
15378     }
15379
15380   if (!vam->json_output)
15381     {
15382       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15383              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15384     }
15385
15386   M (ONE_EID_TABLE_DUMP, mp);
15387
15388   mp->filter = filter;
15389   if (eid_set)
15390     {
15391       mp->eid_set = 1;
15392       mp->vni = htonl (vni);
15393       mp->eid_type = eid_type;
15394       switch (eid_type)
15395         {
15396         case 0:
15397           mp->prefix_length = prefix_length;
15398           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15399           break;
15400         case 1:
15401           mp->prefix_length = prefix_length;
15402           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15403           break;
15404         case 2:
15405           clib_memcpy (mp->eid, mac, sizeof (mac));
15406           break;
15407         default:
15408           errmsg ("unknown EID type %d!", eid_type);
15409           return -99;
15410         }
15411     }
15412
15413   /* send it... */
15414   S (mp);
15415
15416   /* Use a control ping for synchronization */
15417   M (CONTROL_PING, mp_ping);
15418   S (mp_ping);
15419
15420   /* Wait for a reply... */
15421   W (ret);
15422   return ret;
15423 }
15424
15425 #define api_lisp_eid_table_dump api_one_eid_table_dump
15426
15427 static int
15428 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15429 {
15430   unformat_input_t *i = vam->input;
15431   vl_api_gpe_fwd_entries_get_t *mp;
15432   u8 vni_set = 0;
15433   u32 vni = ~0;
15434   int ret;
15435
15436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15437     {
15438       if (unformat (i, "vni %d", &vni))
15439         {
15440           vni_set = 1;
15441         }
15442       else
15443         {
15444           errmsg ("parse error '%U'", format_unformat_error, i);
15445           return -99;
15446         }
15447     }
15448
15449   if (!vni_set)
15450     {
15451       errmsg ("vni not set!");
15452       return -99;
15453     }
15454
15455   if (!vam->json_output)
15456     {
15457       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15458              "leid", "reid");
15459     }
15460
15461   M (GPE_FWD_ENTRIES_GET, mp);
15462   mp->vni = clib_host_to_net_u32 (vni);
15463
15464   /* send it... */
15465   S (mp);
15466
15467   /* Wait for a reply... */
15468   W (ret);
15469   return ret;
15470 }
15471
15472 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15473 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15474 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15475 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15476
15477 static int
15478 api_one_adjacencies_get (vat_main_t * vam)
15479 {
15480   unformat_input_t *i = vam->input;
15481   vl_api_one_adjacencies_get_t *mp;
15482   u8 vni_set = 0;
15483   u32 vni = ~0;
15484   int ret;
15485
15486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15487     {
15488       if (unformat (i, "vni %d", &vni))
15489         {
15490           vni_set = 1;
15491         }
15492       else
15493         {
15494           errmsg ("parse error '%U'", format_unformat_error, i);
15495           return -99;
15496         }
15497     }
15498
15499   if (!vni_set)
15500     {
15501       errmsg ("vni not set!");
15502       return -99;
15503     }
15504
15505   if (!vam->json_output)
15506     {
15507       print (vam->ofp, "%s %40s", "leid", "reid");
15508     }
15509
15510   M (ONE_ADJACENCIES_GET, mp);
15511   mp->vni = clib_host_to_net_u32 (vni);
15512
15513   /* send it... */
15514   S (mp);
15515
15516   /* Wait for a reply... */
15517   W (ret);
15518   return ret;
15519 }
15520
15521 #define api_lisp_adjacencies_get api_one_adjacencies_get
15522
15523 static int
15524 api_one_map_server_dump (vat_main_t * vam)
15525 {
15526   vl_api_one_map_server_dump_t *mp;
15527   vl_api_control_ping_t *mp_ping;
15528   int ret;
15529
15530   if (!vam->json_output)
15531     {
15532       print (vam->ofp, "%=20s", "Map server");
15533     }
15534
15535   M (ONE_MAP_SERVER_DUMP, mp);
15536   /* send it... */
15537   S (mp);
15538
15539   /* Use a control ping for synchronization */
15540   M (CONTROL_PING, mp_ping);
15541   S (mp_ping);
15542
15543   /* Wait for a reply... */
15544   W (ret);
15545   return ret;
15546 }
15547
15548 #define api_lisp_map_server_dump api_one_map_server_dump
15549
15550 static int
15551 api_one_map_resolver_dump (vat_main_t * vam)
15552 {
15553   vl_api_one_map_resolver_dump_t *mp;
15554   vl_api_control_ping_t *mp_ping;
15555   int ret;
15556
15557   if (!vam->json_output)
15558     {
15559       print (vam->ofp, "%=20s", "Map resolver");
15560     }
15561
15562   M (ONE_MAP_RESOLVER_DUMP, mp);
15563   /* send it... */
15564   S (mp);
15565
15566   /* Use a control ping for synchronization */
15567   M (CONTROL_PING, mp_ping);
15568   S (mp_ping);
15569
15570   /* Wait for a reply... */
15571   W (ret);
15572   return ret;
15573 }
15574
15575 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15576
15577 static int
15578 api_show_one_status (vat_main_t * vam)
15579 {
15580   vl_api_show_one_status_t *mp;
15581   int ret;
15582
15583   if (!vam->json_output)
15584     {
15585       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15586     }
15587
15588   M (SHOW_ONE_STATUS, mp);
15589   /* send it... */
15590   S (mp);
15591   /* Wait for a reply... */
15592   W (ret);
15593   return ret;
15594 }
15595
15596 #define api_show_lisp_status api_show_one_status
15597
15598 static int
15599 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15600 {
15601   vl_api_gpe_fwd_entry_path_dump_t *mp;
15602   vl_api_control_ping_t *mp_ping;
15603   unformat_input_t *i = vam->input;
15604   u32 fwd_entry_index = ~0;
15605   int ret;
15606
15607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15608     {
15609       if (unformat (i, "index %d", &fwd_entry_index))
15610         ;
15611       else
15612         break;
15613     }
15614
15615   if (~0 == fwd_entry_index)
15616     {
15617       errmsg ("no index specified!");
15618       return -99;
15619     }
15620
15621   if (!vam->json_output)
15622     {
15623       print (vam->ofp, "first line");
15624     }
15625
15626   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15627
15628   /* send it... */
15629   S (mp);
15630   /* Use a control ping for synchronization */
15631   M (CONTROL_PING, mp_ping);
15632   S (mp_ping);
15633
15634   /* Wait for a reply... */
15635   W (ret);
15636   return ret;
15637 }
15638
15639 static int
15640 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15641 {
15642   vl_api_one_get_map_request_itr_rlocs_t *mp;
15643   int ret;
15644
15645   if (!vam->json_output)
15646     {
15647       print (vam->ofp, "%=20s", "itr-rlocs:");
15648     }
15649
15650   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15651   /* send it... */
15652   S (mp);
15653   /* Wait for a reply... */
15654   W (ret);
15655   return ret;
15656 }
15657
15658 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15659
15660 static int
15661 api_af_packet_create (vat_main_t * vam)
15662 {
15663   unformat_input_t *i = vam->input;
15664   vl_api_af_packet_create_t *mp;
15665   u8 *host_if_name = 0;
15666   u8 hw_addr[6];
15667   u8 random_hw_addr = 1;
15668   int ret;
15669
15670   memset (hw_addr, 0, sizeof (hw_addr));
15671
15672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15673     {
15674       if (unformat (i, "name %s", &host_if_name))
15675         vec_add1 (host_if_name, 0);
15676       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15677         random_hw_addr = 0;
15678       else
15679         break;
15680     }
15681
15682   if (!vec_len (host_if_name))
15683     {
15684       errmsg ("host-interface name must be specified");
15685       return -99;
15686     }
15687
15688   if (vec_len (host_if_name) > 64)
15689     {
15690       errmsg ("host-interface name too long");
15691       return -99;
15692     }
15693
15694   M (AF_PACKET_CREATE, mp);
15695
15696   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15697   clib_memcpy (mp->hw_addr, hw_addr, 6);
15698   mp->use_random_hw_addr = random_hw_addr;
15699   vec_free (host_if_name);
15700
15701   S (mp);
15702   W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15703   return ret;
15704 }
15705
15706 static int
15707 api_af_packet_delete (vat_main_t * vam)
15708 {
15709   unformat_input_t *i = vam->input;
15710   vl_api_af_packet_delete_t *mp;
15711   u8 *host_if_name = 0;
15712   int ret;
15713
15714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15715     {
15716       if (unformat (i, "name %s", &host_if_name))
15717         vec_add1 (host_if_name, 0);
15718       else
15719         break;
15720     }
15721
15722   if (!vec_len (host_if_name))
15723     {
15724       errmsg ("host-interface name must be specified");
15725       return -99;
15726     }
15727
15728   if (vec_len (host_if_name) > 64)
15729     {
15730       errmsg ("host-interface name too long");
15731       return -99;
15732     }
15733
15734   M (AF_PACKET_DELETE, mp);
15735
15736   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15737   vec_free (host_if_name);
15738
15739   S (mp);
15740   W (ret);
15741   return ret;
15742 }
15743
15744 static int
15745 api_policer_add_del (vat_main_t * vam)
15746 {
15747   unformat_input_t *i = vam->input;
15748   vl_api_policer_add_del_t *mp;
15749   u8 is_add = 1;
15750   u8 *name = 0;
15751   u32 cir = 0;
15752   u32 eir = 0;
15753   u64 cb = 0;
15754   u64 eb = 0;
15755   u8 rate_type = 0;
15756   u8 round_type = 0;
15757   u8 type = 0;
15758   u8 color_aware = 0;
15759   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15760   int ret;
15761
15762   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15763   conform_action.dscp = 0;
15764   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15765   exceed_action.dscp = 0;
15766   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15767   violate_action.dscp = 0;
15768
15769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15770     {
15771       if (unformat (i, "del"))
15772         is_add = 0;
15773       else if (unformat (i, "name %s", &name))
15774         vec_add1 (name, 0);
15775       else if (unformat (i, "cir %u", &cir))
15776         ;
15777       else if (unformat (i, "eir %u", &eir))
15778         ;
15779       else if (unformat (i, "cb %u", &cb))
15780         ;
15781       else if (unformat (i, "eb %u", &eb))
15782         ;
15783       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15784                          &rate_type))
15785         ;
15786       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15787                          &round_type))
15788         ;
15789       else if (unformat (i, "type %U", unformat_policer_type, &type))
15790         ;
15791       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15792                          &conform_action))
15793         ;
15794       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15795                          &exceed_action))
15796         ;
15797       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15798                          &violate_action))
15799         ;
15800       else if (unformat (i, "color-aware"))
15801         color_aware = 1;
15802       else
15803         break;
15804     }
15805
15806   if (!vec_len (name))
15807     {
15808       errmsg ("policer name must be specified");
15809       return -99;
15810     }
15811
15812   if (vec_len (name) > 64)
15813     {
15814       errmsg ("policer name too long");
15815       return -99;
15816     }
15817
15818   M (POLICER_ADD_DEL, mp);
15819
15820   clib_memcpy (mp->name, name, vec_len (name));
15821   vec_free (name);
15822   mp->is_add = is_add;
15823   mp->cir = cir;
15824   mp->eir = eir;
15825   mp->cb = cb;
15826   mp->eb = eb;
15827   mp->rate_type = rate_type;
15828   mp->round_type = round_type;
15829   mp->type = type;
15830   mp->conform_action_type = conform_action.action_type;
15831   mp->conform_dscp = conform_action.dscp;
15832   mp->exceed_action_type = exceed_action.action_type;
15833   mp->exceed_dscp = exceed_action.dscp;
15834   mp->violate_action_type = violate_action.action_type;
15835   mp->violate_dscp = violate_action.dscp;
15836   mp->color_aware = color_aware;
15837
15838   S (mp);
15839   W (ret);
15840   return ret;
15841 }
15842
15843 static int
15844 api_policer_dump (vat_main_t * vam)
15845 {
15846   unformat_input_t *i = vam->input;
15847   vl_api_policer_dump_t *mp;
15848   vl_api_control_ping_t *mp_ping;
15849   u8 *match_name = 0;
15850   u8 match_name_valid = 0;
15851   int ret;
15852
15853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15854     {
15855       if (unformat (i, "name %s", &match_name))
15856         {
15857           vec_add1 (match_name, 0);
15858           match_name_valid = 1;
15859         }
15860       else
15861         break;
15862     }
15863
15864   M (POLICER_DUMP, mp);
15865   mp->match_name_valid = match_name_valid;
15866   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15867   vec_free (match_name);
15868   /* send it... */
15869   S (mp);
15870
15871   /* Use a control ping for synchronization */
15872   M (CONTROL_PING, mp_ping);
15873   S (mp_ping);
15874
15875   /* Wait for a reply... */
15876   W (ret);
15877   return ret;
15878 }
15879
15880 static int
15881 api_policer_classify_set_interface (vat_main_t * vam)
15882 {
15883   unformat_input_t *i = vam->input;
15884   vl_api_policer_classify_set_interface_t *mp;
15885   u32 sw_if_index;
15886   int sw_if_index_set;
15887   u32 ip4_table_index = ~0;
15888   u32 ip6_table_index = ~0;
15889   u32 l2_table_index = ~0;
15890   u8 is_add = 1;
15891   int ret;
15892
15893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15894     {
15895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15896         sw_if_index_set = 1;
15897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15898         sw_if_index_set = 1;
15899       else if (unformat (i, "del"))
15900         is_add = 0;
15901       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15902         ;
15903       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15904         ;
15905       else if (unformat (i, "l2-table %d", &l2_table_index))
15906         ;
15907       else
15908         {
15909           clib_warning ("parse error '%U'", format_unformat_error, i);
15910           return -99;
15911         }
15912     }
15913
15914   if (sw_if_index_set == 0)
15915     {
15916       errmsg ("missing interface name or sw_if_index");
15917       return -99;
15918     }
15919
15920   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15921
15922   mp->sw_if_index = ntohl (sw_if_index);
15923   mp->ip4_table_index = ntohl (ip4_table_index);
15924   mp->ip6_table_index = ntohl (ip6_table_index);
15925   mp->l2_table_index = ntohl (l2_table_index);
15926   mp->is_add = is_add;
15927
15928   S (mp);
15929   W (ret);
15930   return ret;
15931 }
15932
15933 static int
15934 api_policer_classify_dump (vat_main_t * vam)
15935 {
15936   unformat_input_t *i = vam->input;
15937   vl_api_policer_classify_dump_t *mp;
15938   vl_api_control_ping_t *mp_ping;
15939   u8 type = POLICER_CLASSIFY_N_TABLES;
15940   int ret;
15941
15942   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15943     ;
15944   else
15945     {
15946       errmsg ("classify table type must be specified");
15947       return -99;
15948     }
15949
15950   if (!vam->json_output)
15951     {
15952       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15953     }
15954
15955   M (POLICER_CLASSIFY_DUMP, mp);
15956   mp->type = type;
15957   /* send it... */
15958   S (mp);
15959
15960   /* Use a control ping for synchronization */
15961   M (CONTROL_PING, mp_ping);
15962   S (mp_ping);
15963
15964   /* Wait for a reply... */
15965   W (ret);
15966   return ret;
15967 }
15968
15969 static int
15970 api_netmap_create (vat_main_t * vam)
15971 {
15972   unformat_input_t *i = vam->input;
15973   vl_api_netmap_create_t *mp;
15974   u8 *if_name = 0;
15975   u8 hw_addr[6];
15976   u8 random_hw_addr = 1;
15977   u8 is_pipe = 0;
15978   u8 is_master = 0;
15979   int ret;
15980
15981   memset (hw_addr, 0, sizeof (hw_addr));
15982
15983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15984     {
15985       if (unformat (i, "name %s", &if_name))
15986         vec_add1 (if_name, 0);
15987       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15988         random_hw_addr = 0;
15989       else if (unformat (i, "pipe"))
15990         is_pipe = 1;
15991       else if (unformat (i, "master"))
15992         is_master = 1;
15993       else if (unformat (i, "slave"))
15994         is_master = 0;
15995       else
15996         break;
15997     }
15998
15999   if (!vec_len (if_name))
16000     {
16001       errmsg ("interface name must be specified");
16002       return -99;
16003     }
16004
16005   if (vec_len (if_name) > 64)
16006     {
16007       errmsg ("interface name too long");
16008       return -99;
16009     }
16010
16011   M (NETMAP_CREATE, mp);
16012
16013   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16014   clib_memcpy (mp->hw_addr, hw_addr, 6);
16015   mp->use_random_hw_addr = random_hw_addr;
16016   mp->is_pipe = is_pipe;
16017   mp->is_master = is_master;
16018   vec_free (if_name);
16019
16020   S (mp);
16021   W (ret);
16022   return ret;
16023 }
16024
16025 static int
16026 api_netmap_delete (vat_main_t * vam)
16027 {
16028   unformat_input_t *i = vam->input;
16029   vl_api_netmap_delete_t *mp;
16030   u8 *if_name = 0;
16031   int ret;
16032
16033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16034     {
16035       if (unformat (i, "name %s", &if_name))
16036         vec_add1 (if_name, 0);
16037       else
16038         break;
16039     }
16040
16041   if (!vec_len (if_name))
16042     {
16043       errmsg ("interface name must be specified");
16044       return -99;
16045     }
16046
16047   if (vec_len (if_name) > 64)
16048     {
16049       errmsg ("interface name too long");
16050       return -99;
16051     }
16052
16053   M (NETMAP_DELETE, mp);
16054
16055   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16056   vec_free (if_name);
16057
16058   S (mp);
16059   W (ret);
16060   return ret;
16061 }
16062
16063 static void vl_api_mpls_tunnel_details_t_handler
16064   (vl_api_mpls_tunnel_details_t * mp)
16065 {
16066   vat_main_t *vam = &vat_main;
16067   i32 len = mp->mt_next_hop_n_labels;
16068   i32 i;
16069
16070   print (vam->ofp, "[%d]: via %U %d labels ",
16071          mp->tunnel_index,
16072          format_ip4_address, mp->mt_next_hop,
16073          ntohl (mp->mt_next_hop_sw_if_index));
16074   for (i = 0; i < len; i++)
16075     {
16076       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
16077     }
16078   print (vam->ofp, "");
16079 }
16080
16081 static void vl_api_mpls_tunnel_details_t_handler_json
16082   (vl_api_mpls_tunnel_details_t * mp)
16083 {
16084   vat_main_t *vam = &vat_main;
16085   vat_json_node_t *node = NULL;
16086   struct in_addr ip4;
16087   i32 i;
16088   i32 len = mp->mt_next_hop_n_labels;
16089
16090   if (VAT_JSON_ARRAY != vam->json_tree.type)
16091     {
16092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16093       vat_json_init_array (&vam->json_tree);
16094     }
16095   node = vat_json_array_add (&vam->json_tree);
16096
16097   vat_json_init_object (node);
16098   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
16099   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
16100   vat_json_object_add_ip4 (node, "next_hop", ip4);
16101   vat_json_object_add_uint (node, "next_hop_sw_if_index",
16102                             ntohl (mp->mt_next_hop_sw_if_index));
16103   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
16104   vat_json_object_add_uint (node, "label_count", len);
16105   for (i = 0; i < len; i++)
16106     {
16107       vat_json_object_add_uint (node, "label",
16108                                 ntohl (mp->mt_next_hop_out_labels[i]));
16109     }
16110 }
16111
16112 static int
16113 api_mpls_tunnel_dump (vat_main_t * vam)
16114 {
16115   vl_api_mpls_tunnel_dump_t *mp;
16116   vl_api_control_ping_t *mp_ping;
16117   i32 index = -1;
16118   int ret;
16119
16120   /* Parse args required to build the message */
16121   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16122     {
16123       if (!unformat (vam->input, "tunnel_index %d", &index))
16124         {
16125           index = -1;
16126           break;
16127         }
16128     }
16129
16130   print (vam->ofp, "  tunnel_index %d", index);
16131
16132   M (MPLS_TUNNEL_DUMP, mp);
16133   mp->tunnel_index = htonl (index);
16134   S (mp);
16135
16136   /* Use a control ping for synchronization */
16137   M (CONTROL_PING, mp_ping);
16138   S (mp_ping);
16139
16140   W (ret);
16141   return ret;
16142 }
16143
16144 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16145 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16146
16147 static void
16148 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16149 {
16150   vat_main_t *vam = &vat_main;
16151   int count = ntohl (mp->count);
16152   vl_api_fib_path2_t *fp;
16153   int i;
16154
16155   print (vam->ofp,
16156          "table-id %d, label %u, ess_bit %u",
16157          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16158   fp = mp->path;
16159   for (i = 0; i < count; i++)
16160     {
16161       if (fp->afi == IP46_TYPE_IP6)
16162         print (vam->ofp,
16163                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16164                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16165                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16166                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16167                format_ip6_address, fp->next_hop);
16168       else if (fp->afi == IP46_TYPE_IP4)
16169         print (vam->ofp,
16170                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16171                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16172                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16173                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16174                format_ip4_address, fp->next_hop);
16175       fp++;
16176     }
16177 }
16178
16179 static void vl_api_mpls_fib_details_t_handler_json
16180   (vl_api_mpls_fib_details_t * mp)
16181 {
16182   vat_main_t *vam = &vat_main;
16183   int count = ntohl (mp->count);
16184   vat_json_node_t *node = NULL;
16185   struct in_addr ip4;
16186   struct in6_addr ip6;
16187   vl_api_fib_path2_t *fp;
16188   int i;
16189
16190   if (VAT_JSON_ARRAY != vam->json_tree.type)
16191     {
16192       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16193       vat_json_init_array (&vam->json_tree);
16194     }
16195   node = vat_json_array_add (&vam->json_tree);
16196
16197   vat_json_init_object (node);
16198   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16199   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16200   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16201   vat_json_object_add_uint (node, "path_count", count);
16202   fp = mp->path;
16203   for (i = 0; i < count; i++)
16204     {
16205       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16206       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16207       vat_json_object_add_uint (node, "is_local", fp->is_local);
16208       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16209       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16210       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16211       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16212       if (fp->afi == IP46_TYPE_IP4)
16213         {
16214           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16215           vat_json_object_add_ip4 (node, "next_hop", ip4);
16216         }
16217       else if (fp->afi == IP46_TYPE_IP6)
16218         {
16219           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16220           vat_json_object_add_ip6 (node, "next_hop", ip6);
16221         }
16222     }
16223 }
16224
16225 static int
16226 api_mpls_fib_dump (vat_main_t * vam)
16227 {
16228   vl_api_mpls_fib_dump_t *mp;
16229   vl_api_control_ping_t *mp_ping;
16230   int ret;
16231
16232   M (MPLS_FIB_DUMP, mp);
16233   S (mp);
16234
16235   /* Use a control ping for synchronization */
16236   M (CONTROL_PING, mp_ping);
16237   S (mp_ping);
16238
16239   W (ret);
16240   return ret;
16241 }
16242
16243 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16244 #define vl_api_ip_fib_details_t_print vl_noop_handler
16245
16246 static void
16247 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16248 {
16249   vat_main_t *vam = &vat_main;
16250   int count = ntohl (mp->count);
16251   vl_api_fib_path_t *fp;
16252   int i;
16253
16254   print (vam->ofp,
16255          "table-id %d, prefix %U/%d",
16256          ntohl (mp->table_id), format_ip4_address, mp->address,
16257          mp->address_length);
16258   fp = mp->path;
16259   for (i = 0; i < count; i++)
16260     {
16261       if (fp->afi == IP46_TYPE_IP6)
16262         print (vam->ofp,
16263                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16264                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16265                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16266                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16267                format_ip6_address, fp->next_hop);
16268       else if (fp->afi == IP46_TYPE_IP4)
16269         print (vam->ofp,
16270                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16271                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16272                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16273                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16274                format_ip4_address, fp->next_hop);
16275       fp++;
16276     }
16277 }
16278
16279 static void vl_api_ip_fib_details_t_handler_json
16280   (vl_api_ip_fib_details_t * mp)
16281 {
16282   vat_main_t *vam = &vat_main;
16283   int count = ntohl (mp->count);
16284   vat_json_node_t *node = NULL;
16285   struct in_addr ip4;
16286   struct in6_addr ip6;
16287   vl_api_fib_path_t *fp;
16288   int i;
16289
16290   if (VAT_JSON_ARRAY != vam->json_tree.type)
16291     {
16292       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16293       vat_json_init_array (&vam->json_tree);
16294     }
16295   node = vat_json_array_add (&vam->json_tree);
16296
16297   vat_json_init_object (node);
16298   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16299   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16300   vat_json_object_add_ip4 (node, "prefix", ip4);
16301   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16302   vat_json_object_add_uint (node, "path_count", count);
16303   fp = mp->path;
16304   for (i = 0; i < count; i++)
16305     {
16306       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16307       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16308       vat_json_object_add_uint (node, "is_local", fp->is_local);
16309       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16310       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16311       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16312       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16313       if (fp->afi == IP46_TYPE_IP4)
16314         {
16315           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16316           vat_json_object_add_ip4 (node, "next_hop", ip4);
16317         }
16318       else if (fp->afi == IP46_TYPE_IP6)
16319         {
16320           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16321           vat_json_object_add_ip6 (node, "next_hop", ip6);
16322         }
16323     }
16324 }
16325
16326 static int
16327 api_ip_fib_dump (vat_main_t * vam)
16328 {
16329   vl_api_ip_fib_dump_t *mp;
16330   vl_api_control_ping_t *mp_ping;
16331   int ret;
16332
16333   M (IP_FIB_DUMP, mp);
16334   S (mp);
16335
16336   /* Use a control ping for synchronization */
16337   M (CONTROL_PING, mp_ping);
16338   S (mp_ping);
16339
16340   W (ret);
16341   return ret;
16342 }
16343
16344 static int
16345 api_ip_mfib_dump (vat_main_t * vam)
16346 {
16347   vl_api_ip_mfib_dump_t *mp;
16348   vl_api_control_ping_t *mp_ping;
16349   int ret;
16350
16351   M (IP_MFIB_DUMP, mp);
16352   S (mp);
16353
16354   /* Use a control ping for synchronization */
16355   M (CONTROL_PING, mp_ping);
16356   S (mp_ping);
16357
16358   W (ret);
16359   return ret;
16360 }
16361
16362 static void vl_api_ip_neighbor_details_t_handler
16363   (vl_api_ip_neighbor_details_t * mp)
16364 {
16365   vat_main_t *vam = &vat_main;
16366
16367   print (vam->ofp, "%c %U %U",
16368          (mp->is_static) ? 'S' : 'D',
16369          format_ethernet_address, &mp->mac_address,
16370          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16371          &mp->ip_address);
16372 }
16373
16374 static void vl_api_ip_neighbor_details_t_handler_json
16375   (vl_api_ip_neighbor_details_t * mp)
16376 {
16377
16378   vat_main_t *vam = &vat_main;
16379   vat_json_node_t *node;
16380   struct in_addr ip4;
16381   struct in6_addr ip6;
16382
16383   if (VAT_JSON_ARRAY != vam->json_tree.type)
16384     {
16385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16386       vat_json_init_array (&vam->json_tree);
16387     }
16388   node = vat_json_array_add (&vam->json_tree);
16389
16390   vat_json_init_object (node);
16391   vat_json_object_add_string_copy (node, "flag",
16392                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16393                                    "dynamic");
16394
16395   vat_json_object_add_string_copy (node, "link_layer",
16396                                    format (0, "%U", format_ethernet_address,
16397                                            &mp->mac_address));
16398
16399   if (mp->is_ipv6)
16400     {
16401       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16402       vat_json_object_add_ip6 (node, "ip_address", ip6);
16403     }
16404   else
16405     {
16406       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16407       vat_json_object_add_ip4 (node, "ip_address", ip4);
16408     }
16409 }
16410
16411 static int
16412 api_ip_neighbor_dump (vat_main_t * vam)
16413 {
16414   unformat_input_t *i = vam->input;
16415   vl_api_ip_neighbor_dump_t *mp;
16416   vl_api_control_ping_t *mp_ping;
16417   u8 is_ipv6 = 0;
16418   u32 sw_if_index = ~0;
16419   int ret;
16420
16421   /* Parse args required to build the message */
16422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16423     {
16424       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16425         ;
16426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16427         ;
16428       else if (unformat (i, "ip6"))
16429         is_ipv6 = 1;
16430       else
16431         break;
16432     }
16433
16434   if (sw_if_index == ~0)
16435     {
16436       errmsg ("missing interface name or sw_if_index");
16437       return -99;
16438     }
16439
16440   M (IP_NEIGHBOR_DUMP, mp);
16441   mp->is_ipv6 = (u8) is_ipv6;
16442   mp->sw_if_index = ntohl (sw_if_index);
16443   S (mp);
16444
16445   /* Use a control ping for synchronization */
16446   M (CONTROL_PING, mp_ping);
16447   S (mp_ping);
16448
16449   W (ret);
16450   return ret;
16451 }
16452
16453 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16454 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16455
16456 static void
16457 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16458 {
16459   vat_main_t *vam = &vat_main;
16460   int count = ntohl (mp->count);
16461   vl_api_fib_path_t *fp;
16462   int i;
16463
16464   print (vam->ofp,
16465          "table-id %d, prefix %U/%d",
16466          ntohl (mp->table_id), format_ip6_address, mp->address,
16467          mp->address_length);
16468   fp = mp->path;
16469   for (i = 0; i < count; i++)
16470     {
16471       if (fp->afi == IP46_TYPE_IP6)
16472         print (vam->ofp,
16473                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16474                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16475                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16476                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16477                format_ip6_address, fp->next_hop);
16478       else if (fp->afi == IP46_TYPE_IP4)
16479         print (vam->ofp,
16480                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16481                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16482                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16483                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16484                format_ip4_address, fp->next_hop);
16485       fp++;
16486     }
16487 }
16488
16489 static void vl_api_ip6_fib_details_t_handler_json
16490   (vl_api_ip6_fib_details_t * mp)
16491 {
16492   vat_main_t *vam = &vat_main;
16493   int count = ntohl (mp->count);
16494   vat_json_node_t *node = NULL;
16495   struct in_addr ip4;
16496   struct in6_addr ip6;
16497   vl_api_fib_path_t *fp;
16498   int i;
16499
16500   if (VAT_JSON_ARRAY != vam->json_tree.type)
16501     {
16502       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16503       vat_json_init_array (&vam->json_tree);
16504     }
16505   node = vat_json_array_add (&vam->json_tree);
16506
16507   vat_json_init_object (node);
16508   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16509   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16510   vat_json_object_add_ip6 (node, "prefix", ip6);
16511   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16512   vat_json_object_add_uint (node, "path_count", count);
16513   fp = mp->path;
16514   for (i = 0; i < count; i++)
16515     {
16516       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16517       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16518       vat_json_object_add_uint (node, "is_local", fp->is_local);
16519       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16520       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16521       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16522       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16523       if (fp->afi == IP46_TYPE_IP4)
16524         {
16525           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16526           vat_json_object_add_ip4 (node, "next_hop", ip4);
16527         }
16528       else if (fp->afi == IP46_TYPE_IP6)
16529         {
16530           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16531           vat_json_object_add_ip6 (node, "next_hop", ip6);
16532         }
16533     }
16534 }
16535
16536 static int
16537 api_ip6_fib_dump (vat_main_t * vam)
16538 {
16539   vl_api_ip6_fib_dump_t *mp;
16540   vl_api_control_ping_t *mp_ping;
16541   int ret;
16542
16543   M (IP6_FIB_DUMP, mp);
16544   S (mp);
16545
16546   /* Use a control ping for synchronization */
16547   M (CONTROL_PING, mp_ping);
16548   S (mp_ping);
16549
16550   W (ret);
16551   return ret;
16552 }
16553
16554 static int
16555 api_ip6_mfib_dump (vat_main_t * vam)
16556 {
16557   vl_api_ip6_mfib_dump_t *mp;
16558   vl_api_control_ping_t *mp_ping;
16559   int ret;
16560
16561   M (IP6_MFIB_DUMP, mp);
16562   S (mp);
16563
16564   /* Use a control ping for synchronization */
16565   M (CONTROL_PING, mp_ping);
16566   S (mp_ping);
16567
16568   W (ret);
16569   return ret;
16570 }
16571
16572 int
16573 api_classify_table_ids (vat_main_t * vam)
16574 {
16575   vl_api_classify_table_ids_t *mp;
16576   int ret;
16577
16578   /* Construct the API message */
16579   M (CLASSIFY_TABLE_IDS, mp);
16580   mp->context = 0;
16581
16582   S (mp);
16583   W (ret);
16584   return ret;
16585 }
16586
16587 int
16588 api_classify_table_by_interface (vat_main_t * vam)
16589 {
16590   unformat_input_t *input = vam->input;
16591   vl_api_classify_table_by_interface_t *mp;
16592
16593   u32 sw_if_index = ~0;
16594   int ret;
16595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16596     {
16597       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16598         ;
16599       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16600         ;
16601       else
16602         break;
16603     }
16604   if (sw_if_index == ~0)
16605     {
16606       errmsg ("missing interface name or sw_if_index");
16607       return -99;
16608     }
16609
16610   /* Construct the API message */
16611   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16612   mp->context = 0;
16613   mp->sw_if_index = ntohl (sw_if_index);
16614
16615   S (mp);
16616   W (ret);
16617   return ret;
16618 }
16619
16620 int
16621 api_classify_table_info (vat_main_t * vam)
16622 {
16623   unformat_input_t *input = vam->input;
16624   vl_api_classify_table_info_t *mp;
16625
16626   u32 table_id = ~0;
16627   int ret;
16628   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16629     {
16630       if (unformat (input, "table_id %d", &table_id))
16631         ;
16632       else
16633         break;
16634     }
16635   if (table_id == ~0)
16636     {
16637       errmsg ("missing table id");
16638       return -99;
16639     }
16640
16641   /* Construct the API message */
16642   M (CLASSIFY_TABLE_INFO, mp);
16643   mp->context = 0;
16644   mp->table_id = ntohl (table_id);
16645
16646   S (mp);
16647   W (ret);
16648   return ret;
16649 }
16650
16651 int
16652 api_classify_session_dump (vat_main_t * vam)
16653 {
16654   unformat_input_t *input = vam->input;
16655   vl_api_classify_session_dump_t *mp;
16656   vl_api_control_ping_t *mp_ping;
16657
16658   u32 table_id = ~0;
16659   int ret;
16660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16661     {
16662       if (unformat (input, "table_id %d", &table_id))
16663         ;
16664       else
16665         break;
16666     }
16667   if (table_id == ~0)
16668     {
16669       errmsg ("missing table id");
16670       return -99;
16671     }
16672
16673   /* Construct the API message */
16674   M (CLASSIFY_SESSION_DUMP, mp);
16675   mp->context = 0;
16676   mp->table_id = ntohl (table_id);
16677   S (mp);
16678
16679   /* Use a control ping for synchronization */
16680   M (CONTROL_PING, mp_ping);
16681   S (mp_ping);
16682
16683   W (ret);
16684   return ret;
16685 }
16686
16687 static void
16688 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16689 {
16690   vat_main_t *vam = &vat_main;
16691
16692   print (vam->ofp, "collector_address %U, collector_port %d, "
16693          "src_address %U, vrf_id %d, path_mtu %u, "
16694          "template_interval %u, udp_checksum %d",
16695          format_ip4_address, mp->collector_address,
16696          ntohs (mp->collector_port),
16697          format_ip4_address, mp->src_address,
16698          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16699          ntohl (mp->template_interval), mp->udp_checksum);
16700
16701   vam->retval = 0;
16702   vam->result_ready = 1;
16703 }
16704
16705 static void
16706   vl_api_ipfix_exporter_details_t_handler_json
16707   (vl_api_ipfix_exporter_details_t * mp)
16708 {
16709   vat_main_t *vam = &vat_main;
16710   vat_json_node_t node;
16711   struct in_addr collector_address;
16712   struct in_addr src_address;
16713
16714   vat_json_init_object (&node);
16715   clib_memcpy (&collector_address, &mp->collector_address,
16716                sizeof (collector_address));
16717   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16718   vat_json_object_add_uint (&node, "collector_port",
16719                             ntohs (mp->collector_port));
16720   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16721   vat_json_object_add_ip4 (&node, "src_address", src_address);
16722   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16723   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16724   vat_json_object_add_uint (&node, "template_interval",
16725                             ntohl (mp->template_interval));
16726   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16727
16728   vat_json_print (vam->ofp, &node);
16729   vat_json_free (&node);
16730   vam->retval = 0;
16731   vam->result_ready = 1;
16732 }
16733
16734 int
16735 api_ipfix_exporter_dump (vat_main_t * vam)
16736 {
16737   vl_api_ipfix_exporter_dump_t *mp;
16738   int ret;
16739
16740   /* Construct the API message */
16741   M (IPFIX_EXPORTER_DUMP, mp);
16742   mp->context = 0;
16743
16744   S (mp);
16745   W (ret);
16746   return ret;
16747 }
16748
16749 static int
16750 api_ipfix_classify_stream_dump (vat_main_t * vam)
16751 {
16752   vl_api_ipfix_classify_stream_dump_t *mp;
16753   int ret;
16754
16755   /* Construct the API message */
16756   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16757   mp->context = 0;
16758
16759   S (mp);
16760   W (ret);
16761   return ret;
16762   /* NOTREACHED */
16763   return 0;
16764 }
16765
16766 static void
16767   vl_api_ipfix_classify_stream_details_t_handler
16768   (vl_api_ipfix_classify_stream_details_t * mp)
16769 {
16770   vat_main_t *vam = &vat_main;
16771   print (vam->ofp, "domain_id %d, src_port %d",
16772          ntohl (mp->domain_id), ntohs (mp->src_port));
16773   vam->retval = 0;
16774   vam->result_ready = 1;
16775 }
16776
16777 static void
16778   vl_api_ipfix_classify_stream_details_t_handler_json
16779   (vl_api_ipfix_classify_stream_details_t * mp)
16780 {
16781   vat_main_t *vam = &vat_main;
16782   vat_json_node_t node;
16783
16784   vat_json_init_object (&node);
16785   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16786   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16787
16788   vat_json_print (vam->ofp, &node);
16789   vat_json_free (&node);
16790   vam->retval = 0;
16791   vam->result_ready = 1;
16792 }
16793
16794 static int
16795 api_ipfix_classify_table_dump (vat_main_t * vam)
16796 {
16797   vl_api_ipfix_classify_table_dump_t *mp;
16798   vl_api_control_ping_t *mp_ping;
16799   int ret;
16800
16801   if (!vam->json_output)
16802     {
16803       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16804              "transport_protocol");
16805     }
16806
16807   /* Construct the API message */
16808   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16809
16810   /* send it... */
16811   S (mp);
16812
16813   /* Use a control ping for synchronization */
16814   M (CONTROL_PING, mp_ping);
16815   S (mp_ping);
16816
16817   W (ret);
16818   return ret;
16819 }
16820
16821 static void
16822   vl_api_ipfix_classify_table_details_t_handler
16823   (vl_api_ipfix_classify_table_details_t * mp)
16824 {
16825   vat_main_t *vam = &vat_main;
16826   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16827          mp->transport_protocol);
16828 }
16829
16830 static void
16831   vl_api_ipfix_classify_table_details_t_handler_json
16832   (vl_api_ipfix_classify_table_details_t * mp)
16833 {
16834   vat_json_node_t *node = NULL;
16835   vat_main_t *vam = &vat_main;
16836
16837   if (VAT_JSON_ARRAY != vam->json_tree.type)
16838     {
16839       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16840       vat_json_init_array (&vam->json_tree);
16841     }
16842
16843   node = vat_json_array_add (&vam->json_tree);
16844   vat_json_init_object (node);
16845
16846   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16847   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16848   vat_json_object_add_uint (node, "transport_protocol",
16849                             mp->transport_protocol);
16850 }
16851
16852 static int
16853 api_sw_interface_span_enable_disable (vat_main_t * vam)
16854 {
16855   unformat_input_t *i = vam->input;
16856   vl_api_sw_interface_span_enable_disable_t *mp;
16857   u32 src_sw_if_index = ~0;
16858   u32 dst_sw_if_index = ~0;
16859   u8 state = 3;
16860   int ret;
16861
16862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16863     {
16864       if (unformat
16865           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16866         ;
16867       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16868         ;
16869       else
16870         if (unformat
16871             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16872         ;
16873       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16874         ;
16875       else if (unformat (i, "disable"))
16876         state = 0;
16877       else if (unformat (i, "rx"))
16878         state = 1;
16879       else if (unformat (i, "tx"))
16880         state = 2;
16881       else if (unformat (i, "both"))
16882         state = 3;
16883       else
16884         break;
16885     }
16886
16887   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16888
16889   mp->sw_if_index_from = htonl (src_sw_if_index);
16890   mp->sw_if_index_to = htonl (dst_sw_if_index);
16891   mp->state = state;
16892
16893   S (mp);
16894   W (ret);
16895   return ret;
16896 }
16897
16898 static void
16899 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16900                                             * mp)
16901 {
16902   vat_main_t *vam = &vat_main;
16903   u8 *sw_if_from_name = 0;
16904   u8 *sw_if_to_name = 0;
16905   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16906   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16907   char *states[] = { "none", "rx", "tx", "both" };
16908   hash_pair_t *p;
16909
16910   /* *INDENT-OFF* */
16911   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16912   ({
16913     if ((u32) p->value[0] == sw_if_index_from)
16914       {
16915         sw_if_from_name = (u8 *)(p->key);
16916         if (sw_if_to_name)
16917           break;
16918       }
16919     if ((u32) p->value[0] == sw_if_index_to)
16920       {
16921         sw_if_to_name = (u8 *)(p->key);
16922         if (sw_if_from_name)
16923           break;
16924       }
16925   }));
16926   /* *INDENT-ON* */
16927   print (vam->ofp, "%20s => %20s (%s)",
16928          sw_if_from_name, sw_if_to_name, states[mp->state]);
16929 }
16930
16931 static void
16932   vl_api_sw_interface_span_details_t_handler_json
16933   (vl_api_sw_interface_span_details_t * mp)
16934 {
16935   vat_main_t *vam = &vat_main;
16936   vat_json_node_t *node = NULL;
16937   u8 *sw_if_from_name = 0;
16938   u8 *sw_if_to_name = 0;
16939   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16940   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16941   hash_pair_t *p;
16942
16943   /* *INDENT-OFF* */
16944   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16945   ({
16946     if ((u32) p->value[0] == sw_if_index_from)
16947       {
16948         sw_if_from_name = (u8 *)(p->key);
16949         if (sw_if_to_name)
16950           break;
16951       }
16952     if ((u32) p->value[0] == sw_if_index_to)
16953       {
16954         sw_if_to_name = (u8 *)(p->key);
16955         if (sw_if_from_name)
16956           break;
16957       }
16958   }));
16959   /* *INDENT-ON* */
16960
16961   if (VAT_JSON_ARRAY != vam->json_tree.type)
16962     {
16963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16964       vat_json_init_array (&vam->json_tree);
16965     }
16966   node = vat_json_array_add (&vam->json_tree);
16967
16968   vat_json_init_object (node);
16969   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16970   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16971   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16972   if (0 != sw_if_to_name)
16973     {
16974       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16975     }
16976   vat_json_object_add_uint (node, "state", mp->state);
16977 }
16978
16979 static int
16980 api_sw_interface_span_dump (vat_main_t * vam)
16981 {
16982   vl_api_sw_interface_span_dump_t *mp;
16983   vl_api_control_ping_t *mp_ping;
16984   int ret;
16985
16986   M (SW_INTERFACE_SPAN_DUMP, mp);
16987   S (mp);
16988
16989   /* Use a control ping for synchronization */
16990   M (CONTROL_PING, mp_ping);
16991   S (mp_ping);
16992
16993   W (ret);
16994   return ret;
16995 }
16996
16997 int
16998 api_pg_create_interface (vat_main_t * vam)
16999 {
17000   unformat_input_t *input = vam->input;
17001   vl_api_pg_create_interface_t *mp;
17002
17003   u32 if_id = ~0;
17004   int ret;
17005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17006     {
17007       if (unformat (input, "if_id %d", &if_id))
17008         ;
17009       else
17010         break;
17011     }
17012   if (if_id == ~0)
17013     {
17014       errmsg ("missing pg interface index");
17015       return -99;
17016     }
17017
17018   /* Construct the API message */
17019   M (PG_CREATE_INTERFACE, mp);
17020   mp->context = 0;
17021   mp->interface_id = ntohl (if_id);
17022
17023   S (mp);
17024   W (ret);
17025   return ret;
17026 }
17027
17028 int
17029 api_pg_capture (vat_main_t * vam)
17030 {
17031   unformat_input_t *input = vam->input;
17032   vl_api_pg_capture_t *mp;
17033
17034   u32 if_id = ~0;
17035   u8 enable = 1;
17036   u32 count = 1;
17037   u8 pcap_file_set = 0;
17038   u8 *pcap_file = 0;
17039   int ret;
17040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17041     {
17042       if (unformat (input, "if_id %d", &if_id))
17043         ;
17044       else if (unformat (input, "pcap %s", &pcap_file))
17045         pcap_file_set = 1;
17046       else if (unformat (input, "count %d", &count))
17047         ;
17048       else if (unformat (input, "disable"))
17049         enable = 0;
17050       else
17051         break;
17052     }
17053   if (if_id == ~0)
17054     {
17055       errmsg ("missing pg interface index");
17056       return -99;
17057     }
17058   if (pcap_file_set > 0)
17059     {
17060       if (vec_len (pcap_file) > 255)
17061         {
17062           errmsg ("pcap file name is too long");
17063           return -99;
17064         }
17065     }
17066
17067   u32 name_len = vec_len (pcap_file);
17068   /* Construct the API message */
17069   M (PG_CAPTURE, mp);
17070   mp->context = 0;
17071   mp->interface_id = ntohl (if_id);
17072   mp->is_enabled = enable;
17073   mp->count = ntohl (count);
17074   mp->pcap_name_length = ntohl (name_len);
17075   if (pcap_file_set != 0)
17076     {
17077       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17078     }
17079   vec_free (pcap_file);
17080
17081   S (mp);
17082   W (ret);
17083   return ret;
17084 }
17085
17086 int
17087 api_pg_enable_disable (vat_main_t * vam)
17088 {
17089   unformat_input_t *input = vam->input;
17090   vl_api_pg_enable_disable_t *mp;
17091
17092   u8 enable = 1;
17093   u8 stream_name_set = 0;
17094   u8 *stream_name = 0;
17095   int ret;
17096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17097     {
17098       if (unformat (input, "stream %s", &stream_name))
17099         stream_name_set = 1;
17100       else if (unformat (input, "disable"))
17101         enable = 0;
17102       else
17103         break;
17104     }
17105
17106   if (stream_name_set > 0)
17107     {
17108       if (vec_len (stream_name) > 255)
17109         {
17110           errmsg ("stream name too long");
17111           return -99;
17112         }
17113     }
17114
17115   u32 name_len = vec_len (stream_name);
17116   /* Construct the API message */
17117   M (PG_ENABLE_DISABLE, mp);
17118   mp->context = 0;
17119   mp->is_enabled = enable;
17120   if (stream_name_set != 0)
17121     {
17122       mp->stream_name_length = ntohl (name_len);
17123       clib_memcpy (mp->stream_name, stream_name, name_len);
17124     }
17125   vec_free (stream_name);
17126
17127   S (mp);
17128   W (ret);
17129   return ret;
17130 }
17131
17132 int
17133 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17134 {
17135   unformat_input_t *input = vam->input;
17136   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17137
17138   u16 *low_ports = 0;
17139   u16 *high_ports = 0;
17140   u16 this_low;
17141   u16 this_hi;
17142   ip4_address_t ip4_addr;
17143   ip6_address_t ip6_addr;
17144   u32 length;
17145   u32 tmp, tmp2;
17146   u8 prefix_set = 0;
17147   u32 vrf_id = ~0;
17148   u8 is_add = 1;
17149   u8 is_ipv6 = 0;
17150   int ret;
17151
17152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17153     {
17154       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17155         {
17156           prefix_set = 1;
17157         }
17158       else
17159         if (unformat
17160             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17161         {
17162           prefix_set = 1;
17163           is_ipv6 = 1;
17164         }
17165       else if (unformat (input, "vrf %d", &vrf_id))
17166         ;
17167       else if (unformat (input, "del"))
17168         is_add = 0;
17169       else if (unformat (input, "port %d", &tmp))
17170         {
17171           if (tmp == 0 || tmp > 65535)
17172             {
17173               errmsg ("port %d out of range", tmp);
17174               return -99;
17175             }
17176           this_low = tmp;
17177           this_hi = this_low + 1;
17178           vec_add1 (low_ports, this_low);
17179           vec_add1 (high_ports, this_hi);
17180         }
17181       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17182         {
17183           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17184             {
17185               errmsg ("incorrect range parameters");
17186               return -99;
17187             }
17188           this_low = tmp;
17189           /* Note: in debug CLI +1 is added to high before
17190              passing to real fn that does "the work"
17191              (ip_source_and_port_range_check_add_del).
17192              This fn is a wrapper around the binary API fn a
17193              control plane will call, which expects this increment
17194              to have occurred. Hence letting the binary API control
17195              plane fn do the increment for consistency between VAT
17196              and other control planes.
17197            */
17198           this_hi = tmp2;
17199           vec_add1 (low_ports, this_low);
17200           vec_add1 (high_ports, this_hi);
17201         }
17202       else
17203         break;
17204     }
17205
17206   if (prefix_set == 0)
17207     {
17208       errmsg ("<address>/<mask> not specified");
17209       return -99;
17210     }
17211
17212   if (vrf_id == ~0)
17213     {
17214       errmsg ("VRF ID required, not specified");
17215       return -99;
17216     }
17217
17218   if (vrf_id == 0)
17219     {
17220       errmsg
17221         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17222       return -99;
17223     }
17224
17225   if (vec_len (low_ports) == 0)
17226     {
17227       errmsg ("At least one port or port range required");
17228       return -99;
17229     }
17230
17231   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17232
17233   mp->is_add = is_add;
17234
17235   if (is_ipv6)
17236     {
17237       mp->is_ipv6 = 1;
17238       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17239     }
17240   else
17241     {
17242       mp->is_ipv6 = 0;
17243       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17244     }
17245
17246   mp->mask_length = length;
17247   mp->number_of_ranges = vec_len (low_ports);
17248
17249   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17250   vec_free (low_ports);
17251
17252   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17253   vec_free (high_ports);
17254
17255   mp->vrf_id = ntohl (vrf_id);
17256
17257   S (mp);
17258   W (ret);
17259   return ret;
17260 }
17261
17262 int
17263 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17264 {
17265   unformat_input_t *input = vam->input;
17266   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17267   u32 sw_if_index = ~0;
17268   int vrf_set = 0;
17269   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17270   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17271   u8 is_add = 1;
17272   int ret;
17273
17274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17275     {
17276       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17277         ;
17278       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17279         ;
17280       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17281         vrf_set = 1;
17282       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17283         vrf_set = 1;
17284       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17285         vrf_set = 1;
17286       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17287         vrf_set = 1;
17288       else if (unformat (input, "del"))
17289         is_add = 0;
17290       else
17291         break;
17292     }
17293
17294   if (sw_if_index == ~0)
17295     {
17296       errmsg ("Interface required but not specified");
17297       return -99;
17298     }
17299
17300   if (vrf_set == 0)
17301     {
17302       errmsg ("VRF ID required but not specified");
17303       return -99;
17304     }
17305
17306   if (tcp_out_vrf_id == 0
17307       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17308     {
17309       errmsg
17310         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17311       return -99;
17312     }
17313
17314   /* Construct the API message */
17315   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17316
17317   mp->sw_if_index = ntohl (sw_if_index);
17318   mp->is_add = is_add;
17319   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17320   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17321   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17322   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17323
17324   /* send it... */
17325   S (mp);
17326
17327   /* Wait for a reply... */
17328   W (ret);
17329   return ret;
17330 }
17331
17332 static int
17333 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17334 {
17335   unformat_input_t *i = vam->input;
17336   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17337   u32 local_sa_id = 0;
17338   u32 remote_sa_id = 0;
17339   ip4_address_t src_address;
17340   ip4_address_t dst_address;
17341   u8 is_add = 1;
17342   int ret;
17343
17344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17345     {
17346       if (unformat (i, "local_sa %d", &local_sa_id))
17347         ;
17348       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17349         ;
17350       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17351         ;
17352       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17353         ;
17354       else if (unformat (i, "del"))
17355         is_add = 0;
17356       else
17357         {
17358           clib_warning ("parse error '%U'", format_unformat_error, i);
17359           return -99;
17360         }
17361     }
17362
17363   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17364
17365   mp->local_sa_id = ntohl (local_sa_id);
17366   mp->remote_sa_id = ntohl (remote_sa_id);
17367   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17368   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17369   mp->is_add = is_add;
17370
17371   S (mp);
17372   W (ret);
17373   return ret;
17374 }
17375
17376 static int
17377 api_punt (vat_main_t * vam)
17378 {
17379   unformat_input_t *i = vam->input;
17380   vl_api_punt_t *mp;
17381   u32 ipv = ~0;
17382   u32 protocol = ~0;
17383   u32 port = ~0;
17384   int is_add = 1;
17385   int ret;
17386
17387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17388     {
17389       if (unformat (i, "ip %d", &ipv))
17390         ;
17391       else if (unformat (i, "protocol %d", &protocol))
17392         ;
17393       else if (unformat (i, "port %d", &port))
17394         ;
17395       else if (unformat (i, "del"))
17396         is_add = 0;
17397       else
17398         {
17399           clib_warning ("parse error '%U'", format_unformat_error, i);
17400           return -99;
17401         }
17402     }
17403
17404   M (PUNT, mp);
17405
17406   mp->is_add = (u8) is_add;
17407   mp->ipv = (u8) ipv;
17408   mp->l4_protocol = (u8) protocol;
17409   mp->l4_port = htons ((u16) port);
17410
17411   S (mp);
17412   W (ret);
17413   return ret;
17414 }
17415
17416 static void vl_api_ipsec_gre_tunnel_details_t_handler
17417   (vl_api_ipsec_gre_tunnel_details_t * mp)
17418 {
17419   vat_main_t *vam = &vat_main;
17420
17421   print (vam->ofp, "%11d%15U%15U%14d%14d",
17422          ntohl (mp->sw_if_index),
17423          format_ip4_address, &mp->src_address,
17424          format_ip4_address, &mp->dst_address,
17425          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17426 }
17427
17428 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17429   (vl_api_ipsec_gre_tunnel_details_t * mp)
17430 {
17431   vat_main_t *vam = &vat_main;
17432   vat_json_node_t *node = NULL;
17433   struct in_addr ip4;
17434
17435   if (VAT_JSON_ARRAY != vam->json_tree.type)
17436     {
17437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17438       vat_json_init_array (&vam->json_tree);
17439     }
17440   node = vat_json_array_add (&vam->json_tree);
17441
17442   vat_json_init_object (node);
17443   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17444   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17445   vat_json_object_add_ip4 (node, "src_address", ip4);
17446   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17447   vat_json_object_add_ip4 (node, "dst_address", ip4);
17448   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17449   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17450 }
17451
17452 static int
17453 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17454 {
17455   unformat_input_t *i = vam->input;
17456   vl_api_ipsec_gre_tunnel_dump_t *mp;
17457   vl_api_control_ping_t *mp_ping;
17458   u32 sw_if_index;
17459   u8 sw_if_index_set = 0;
17460   int ret;
17461
17462   /* Parse args required to build the message */
17463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17464     {
17465       if (unformat (i, "sw_if_index %d", &sw_if_index))
17466         sw_if_index_set = 1;
17467       else
17468         break;
17469     }
17470
17471   if (sw_if_index_set == 0)
17472     {
17473       sw_if_index = ~0;
17474     }
17475
17476   if (!vam->json_output)
17477     {
17478       print (vam->ofp, "%11s%15s%15s%14s%14s",
17479              "sw_if_index", "src_address", "dst_address",
17480              "local_sa_id", "remote_sa_id");
17481     }
17482
17483   /* Get list of gre-tunnel interfaces */
17484   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17485
17486   mp->sw_if_index = htonl (sw_if_index);
17487
17488   S (mp);
17489
17490   /* Use a control ping for synchronization */
17491   M (CONTROL_PING, mp_ping);
17492   S (mp_ping);
17493
17494   W (ret);
17495   return ret;
17496 }
17497
17498 static int
17499 api_delete_subif (vat_main_t * vam)
17500 {
17501   unformat_input_t *i = vam->input;
17502   vl_api_delete_subif_t *mp;
17503   u32 sw_if_index = ~0;
17504   int ret;
17505
17506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17507     {
17508       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17509         ;
17510       if (unformat (i, "sw_if_index %d", &sw_if_index))
17511         ;
17512       else
17513         break;
17514     }
17515
17516   if (sw_if_index == ~0)
17517     {
17518       errmsg ("missing sw_if_index");
17519       return -99;
17520     }
17521
17522   /* Construct the API message */
17523   M (DELETE_SUBIF, mp);
17524   mp->sw_if_index = ntohl (sw_if_index);
17525
17526   S (mp);
17527   W (ret);
17528   return ret;
17529 }
17530
17531 #define foreach_pbb_vtr_op      \
17532 _("disable",  L2_VTR_DISABLED)  \
17533 _("pop",  L2_VTR_POP_2)         \
17534 _("push",  L2_VTR_PUSH_2)
17535
17536 static int
17537 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17538 {
17539   unformat_input_t *i = vam->input;
17540   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17541   u32 sw_if_index = ~0, vtr_op = ~0;
17542   u16 outer_tag = ~0;
17543   u8 dmac[6], smac[6];
17544   u8 dmac_set = 0, smac_set = 0;
17545   u16 vlanid = 0;
17546   u32 sid = ~0;
17547   u32 tmp;
17548   int ret;
17549
17550   /* Shut up coverity */
17551   memset (dmac, 0, sizeof (dmac));
17552   memset (smac, 0, sizeof (smac));
17553
17554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17555     {
17556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17557         ;
17558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17559         ;
17560       else if (unformat (i, "vtr_op %d", &vtr_op))
17561         ;
17562 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17563       foreach_pbb_vtr_op
17564 #undef _
17565         else if (unformat (i, "translate_pbb_stag"))
17566         {
17567           if (unformat (i, "%d", &tmp))
17568             {
17569               vtr_op = L2_VTR_TRANSLATE_2_1;
17570               outer_tag = tmp;
17571             }
17572           else
17573             {
17574               errmsg
17575                 ("translate_pbb_stag operation requires outer tag definition");
17576               return -99;
17577             }
17578         }
17579       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17580         dmac_set++;
17581       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17582         smac_set++;
17583       else if (unformat (i, "sid %d", &sid))
17584         ;
17585       else if (unformat (i, "vlanid %d", &tmp))
17586         vlanid = tmp;
17587       else
17588         {
17589           clib_warning ("parse error '%U'", format_unformat_error, i);
17590           return -99;
17591         }
17592     }
17593
17594   if ((sw_if_index == ~0) || (vtr_op == ~0))
17595     {
17596       errmsg ("missing sw_if_index or vtr operation");
17597       return -99;
17598     }
17599   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17600       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17601     {
17602       errmsg
17603         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17604       return -99;
17605     }
17606
17607   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17608   mp->sw_if_index = ntohl (sw_if_index);
17609   mp->vtr_op = ntohl (vtr_op);
17610   mp->outer_tag = ntohs (outer_tag);
17611   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17612   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17613   mp->b_vlanid = ntohs (vlanid);
17614   mp->i_sid = ntohl (sid);
17615
17616   S (mp);
17617   W (ret);
17618   return ret;
17619 }
17620
17621 static int
17622 api_flow_classify_set_interface (vat_main_t * vam)
17623 {
17624   unformat_input_t *i = vam->input;
17625   vl_api_flow_classify_set_interface_t *mp;
17626   u32 sw_if_index;
17627   int sw_if_index_set;
17628   u32 ip4_table_index = ~0;
17629   u32 ip6_table_index = ~0;
17630   u8 is_add = 1;
17631   int ret;
17632
17633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17634     {
17635       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17636         sw_if_index_set = 1;
17637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17638         sw_if_index_set = 1;
17639       else if (unformat (i, "del"))
17640         is_add = 0;
17641       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17642         ;
17643       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17644         ;
17645       else
17646         {
17647           clib_warning ("parse error '%U'", format_unformat_error, i);
17648           return -99;
17649         }
17650     }
17651
17652   if (sw_if_index_set == 0)
17653     {
17654       errmsg ("missing interface name or sw_if_index");
17655       return -99;
17656     }
17657
17658   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17659
17660   mp->sw_if_index = ntohl (sw_if_index);
17661   mp->ip4_table_index = ntohl (ip4_table_index);
17662   mp->ip6_table_index = ntohl (ip6_table_index);
17663   mp->is_add = is_add;
17664
17665   S (mp);
17666   W (ret);
17667   return ret;
17668 }
17669
17670 static int
17671 api_flow_classify_dump (vat_main_t * vam)
17672 {
17673   unformat_input_t *i = vam->input;
17674   vl_api_flow_classify_dump_t *mp;
17675   vl_api_control_ping_t *mp_ping;
17676   u8 type = FLOW_CLASSIFY_N_TABLES;
17677   int ret;
17678
17679   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17680     ;
17681   else
17682     {
17683       errmsg ("classify table type must be specified");
17684       return -99;
17685     }
17686
17687   if (!vam->json_output)
17688     {
17689       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17690     }
17691
17692   M (FLOW_CLASSIFY_DUMP, mp);
17693   mp->type = type;
17694   /* send it... */
17695   S (mp);
17696
17697   /* Use a control ping for synchronization */
17698   M (CONTROL_PING, mp_ping);
17699   S (mp_ping);
17700
17701   /* Wait for a reply... */
17702   W (ret);
17703   return ret;
17704 }
17705
17706 static int
17707 api_feature_enable_disable (vat_main_t * vam)
17708 {
17709   unformat_input_t *i = vam->input;
17710   vl_api_feature_enable_disable_t *mp;
17711   u8 *arc_name = 0;
17712   u8 *feature_name = 0;
17713   u32 sw_if_index = ~0;
17714   u8 enable = 1;
17715   int ret;
17716
17717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17718     {
17719       if (unformat (i, "arc_name %s", &arc_name))
17720         ;
17721       else if (unformat (i, "feature_name %s", &feature_name))
17722         ;
17723       else
17724         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17725         ;
17726       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17727         ;
17728       else if (unformat (i, "disable"))
17729         enable = 0;
17730       else
17731         break;
17732     }
17733
17734   if (arc_name == 0)
17735     {
17736       errmsg ("missing arc name");
17737       return -99;
17738     }
17739   if (vec_len (arc_name) > 63)
17740     {
17741       errmsg ("arc name too long");
17742     }
17743
17744   if (feature_name == 0)
17745     {
17746       errmsg ("missing feature name");
17747       return -99;
17748     }
17749   if (vec_len (feature_name) > 63)
17750     {
17751       errmsg ("feature name too long");
17752     }
17753
17754   if (sw_if_index == ~0)
17755     {
17756       errmsg ("missing interface name or sw_if_index");
17757       return -99;
17758     }
17759
17760   /* Construct the API message */
17761   M (FEATURE_ENABLE_DISABLE, mp);
17762   mp->sw_if_index = ntohl (sw_if_index);
17763   mp->enable = enable;
17764   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17765   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17766   vec_free (arc_name);
17767   vec_free (feature_name);
17768
17769   S (mp);
17770   W (ret);
17771   return ret;
17772 }
17773
17774 static int
17775 api_sw_interface_tag_add_del (vat_main_t * vam)
17776 {
17777   unformat_input_t *i = vam->input;
17778   vl_api_sw_interface_tag_add_del_t *mp;
17779   u32 sw_if_index = ~0;
17780   u8 *tag = 0;
17781   u8 enable = 1;
17782   int ret;
17783
17784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17785     {
17786       if (unformat (i, "tag %s", &tag))
17787         ;
17788       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17789         ;
17790       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17791         ;
17792       else if (unformat (i, "del"))
17793         enable = 0;
17794       else
17795         break;
17796     }
17797
17798   if (sw_if_index == ~0)
17799     {
17800       errmsg ("missing interface name or sw_if_index");
17801       return -99;
17802     }
17803
17804   if (enable && (tag == 0))
17805     {
17806       errmsg ("no tag specified");
17807       return -99;
17808     }
17809
17810   /* Construct the API message */
17811   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17812   mp->sw_if_index = ntohl (sw_if_index);
17813   mp->is_add = enable;
17814   if (enable)
17815     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17816   vec_free (tag);
17817
17818   S (mp);
17819   W (ret);
17820   return ret;
17821 }
17822
17823 static void vl_api_l2_xconnect_details_t_handler
17824   (vl_api_l2_xconnect_details_t * mp)
17825 {
17826   vat_main_t *vam = &vat_main;
17827
17828   print (vam->ofp, "%15d%15d",
17829          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17830 }
17831
17832 static void vl_api_l2_xconnect_details_t_handler_json
17833   (vl_api_l2_xconnect_details_t * mp)
17834 {
17835   vat_main_t *vam = &vat_main;
17836   vat_json_node_t *node = NULL;
17837
17838   if (VAT_JSON_ARRAY != vam->json_tree.type)
17839     {
17840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17841       vat_json_init_array (&vam->json_tree);
17842     }
17843   node = vat_json_array_add (&vam->json_tree);
17844
17845   vat_json_init_object (node);
17846   vat_json_object_add_uint (node, "rx_sw_if_index",
17847                             ntohl (mp->rx_sw_if_index));
17848   vat_json_object_add_uint (node, "tx_sw_if_index",
17849                             ntohl (mp->tx_sw_if_index));
17850 }
17851
17852 static int
17853 api_l2_xconnect_dump (vat_main_t * vam)
17854 {
17855   vl_api_l2_xconnect_dump_t *mp;
17856   vl_api_control_ping_t *mp_ping;
17857   int ret;
17858
17859   if (!vam->json_output)
17860     {
17861       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17862     }
17863
17864   M (L2_XCONNECT_DUMP, mp);
17865
17866   S (mp);
17867
17868   /* Use a control ping for synchronization */
17869   M (CONTROL_PING, mp_ping);
17870   S (mp_ping);
17871
17872   W (ret);
17873   return ret;
17874 }
17875
17876 static int
17877 api_sw_interface_set_mtu (vat_main_t * vam)
17878 {
17879   unformat_input_t *i = vam->input;
17880   vl_api_sw_interface_set_mtu_t *mp;
17881   u32 sw_if_index = ~0;
17882   u32 mtu = 0;
17883   int ret;
17884
17885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17886     {
17887       if (unformat (i, "mtu %d", &mtu))
17888         ;
17889       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17890         ;
17891       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17892         ;
17893       else
17894         break;
17895     }
17896
17897   if (sw_if_index == ~0)
17898     {
17899       errmsg ("missing interface name or sw_if_index");
17900       return -99;
17901     }
17902
17903   if (mtu == 0)
17904     {
17905       errmsg ("no mtu specified");
17906       return -99;
17907     }
17908
17909   /* Construct the API message */
17910   M (SW_INTERFACE_SET_MTU, mp);
17911   mp->sw_if_index = ntohl (sw_if_index);
17912   mp->mtu = ntohs ((u16) mtu);
17913
17914   S (mp);
17915   W (ret);
17916   return ret;
17917 }
17918
17919
17920 static int
17921 q_or_quit (vat_main_t * vam)
17922 {
17923 #if VPP_API_TEST_BUILTIN == 0
17924   longjmp (vam->jump_buf, 1);
17925 #endif
17926   return 0;                     /* not so much */
17927 }
17928
17929 static int
17930 q (vat_main_t * vam)
17931 {
17932   return q_or_quit (vam);
17933 }
17934
17935 static int
17936 quit (vat_main_t * vam)
17937 {
17938   return q_or_quit (vam);
17939 }
17940
17941 static int
17942 comment (vat_main_t * vam)
17943 {
17944   return 0;
17945 }
17946
17947 static int
17948 cmd_cmp (void *a1, void *a2)
17949 {
17950   u8 **c1 = a1;
17951   u8 **c2 = a2;
17952
17953   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17954 }
17955
17956 static int
17957 help (vat_main_t * vam)
17958 {
17959   u8 **cmds = 0;
17960   u8 *name = 0;
17961   hash_pair_t *p;
17962   unformat_input_t *i = vam->input;
17963   int j;
17964
17965   if (unformat (i, "%s", &name))
17966     {
17967       uword *hs;
17968
17969       vec_add1 (name, 0);
17970
17971       hs = hash_get_mem (vam->help_by_name, name);
17972       if (hs)
17973         print (vam->ofp, "usage: %s %s", name, hs[0]);
17974       else
17975         print (vam->ofp, "No such msg / command '%s'", name);
17976       vec_free (name);
17977       return 0;
17978     }
17979
17980   print (vam->ofp, "Help is available for the following:");
17981
17982     /* *INDENT-OFF* */
17983     hash_foreach_pair (p, vam->function_by_name,
17984     ({
17985       vec_add1 (cmds, (u8 *)(p->key));
17986     }));
17987     /* *INDENT-ON* */
17988
17989   vec_sort_with_function (cmds, cmd_cmp);
17990
17991   for (j = 0; j < vec_len (cmds); j++)
17992     print (vam->ofp, "%s", cmds[j]);
17993
17994   vec_free (cmds);
17995   return 0;
17996 }
17997
17998 static int
17999 set (vat_main_t * vam)
18000 {
18001   u8 *name = 0, *value = 0;
18002   unformat_input_t *i = vam->input;
18003
18004   if (unformat (i, "%s", &name))
18005     {
18006       /* The input buffer is a vector, not a string. */
18007       value = vec_dup (i->buffer);
18008       vec_delete (value, i->index, 0);
18009       /* Almost certainly has a trailing newline */
18010       if (value[vec_len (value) - 1] == '\n')
18011         value[vec_len (value) - 1] = 0;
18012       /* Make sure it's a proper string, one way or the other */
18013       vec_add1 (value, 0);
18014       (void) clib_macro_set_value (&vam->macro_main,
18015                                    (char *) name, (char *) value);
18016     }
18017   else
18018     errmsg ("usage: set <name> <value>");
18019
18020   vec_free (name);
18021   vec_free (value);
18022   return 0;
18023 }
18024
18025 static int
18026 unset (vat_main_t * vam)
18027 {
18028   u8 *name = 0;
18029
18030   if (unformat (vam->input, "%s", &name))
18031     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18032       errmsg ("unset: %s wasn't set", name);
18033   vec_free (name);
18034   return 0;
18035 }
18036
18037 typedef struct
18038 {
18039   u8 *name;
18040   u8 *value;
18041 } macro_sort_t;
18042
18043
18044 static int
18045 macro_sort_cmp (void *a1, void *a2)
18046 {
18047   macro_sort_t *s1 = a1;
18048   macro_sort_t *s2 = a2;
18049
18050   return strcmp ((char *) (s1->name), (char *) (s2->name));
18051 }
18052
18053 static int
18054 dump_macro_table (vat_main_t * vam)
18055 {
18056   macro_sort_t *sort_me = 0, *sm;
18057   int i;
18058   hash_pair_t *p;
18059
18060     /* *INDENT-OFF* */
18061     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18062     ({
18063       vec_add2 (sort_me, sm, 1);
18064       sm->name = (u8 *)(p->key);
18065       sm->value = (u8 *) (p->value[0]);
18066     }));
18067     /* *INDENT-ON* */
18068
18069   vec_sort_with_function (sort_me, macro_sort_cmp);
18070
18071   if (vec_len (sort_me))
18072     print (vam->ofp, "%-15s%s", "Name", "Value");
18073   else
18074     print (vam->ofp, "The macro table is empty...");
18075
18076   for (i = 0; i < vec_len (sort_me); i++)
18077     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18078   return 0;
18079 }
18080
18081 static int
18082 dump_node_table (vat_main_t * vam)
18083 {
18084   int i, j;
18085   vlib_node_t *node, *next_node;
18086
18087   if (vec_len (vam->graph_nodes) == 0)
18088     {
18089       print (vam->ofp, "Node table empty, issue get_node_graph...");
18090       return 0;
18091     }
18092
18093   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18094     {
18095       node = vam->graph_nodes[i];
18096       print (vam->ofp, "[%d] %s", i, node->name);
18097       for (j = 0; j < vec_len (node->next_nodes); j++)
18098         {
18099           if (node->next_nodes[j] != ~0)
18100             {
18101               next_node = vam->graph_nodes[node->next_nodes[j]];
18102               print (vam->ofp, "  [%d] %s", j, next_node->name);
18103             }
18104         }
18105     }
18106   return 0;
18107 }
18108
18109 static int
18110 value_sort_cmp (void *a1, void *a2)
18111 {
18112   name_sort_t *n1 = a1;
18113   name_sort_t *n2 = a2;
18114
18115   if (n1->value < n2->value)
18116     return -1;
18117   if (n1->value > n2->value)
18118     return 1;
18119   return 0;
18120 }
18121
18122
18123 static int
18124 dump_msg_api_table (vat_main_t * vam)
18125 {
18126   api_main_t *am = &api_main;
18127   name_sort_t *nses = 0, *ns;
18128   hash_pair_t *hp;
18129   int i;
18130
18131   /* *INDENT-OFF* */
18132   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18133   ({
18134     vec_add2 (nses, ns, 1);
18135     ns->name = (u8 *)(hp->key);
18136     ns->value = (u32) hp->value[0];
18137   }));
18138   /* *INDENT-ON* */
18139
18140   vec_sort_with_function (nses, value_sort_cmp);
18141
18142   for (i = 0; i < vec_len (nses); i++)
18143     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18144   vec_free (nses);
18145   return 0;
18146 }
18147
18148 static int
18149 get_msg_id (vat_main_t * vam)
18150 {
18151   u8 *name_and_crc;
18152   u32 message_index;
18153
18154   if (unformat (vam->input, "%s", &name_and_crc))
18155     {
18156       message_index = vl_api_get_msg_index (name_and_crc);
18157       if (message_index == ~0)
18158         {
18159           print (vam->ofp, " '%s' not found", name_and_crc);
18160           return 0;
18161         }
18162       print (vam->ofp, " '%s' has message index %d",
18163              name_and_crc, message_index);
18164       return 0;
18165     }
18166   errmsg ("name_and_crc required...");
18167   return 0;
18168 }
18169
18170 static int
18171 search_node_table (vat_main_t * vam)
18172 {
18173   unformat_input_t *line_input = vam->input;
18174   u8 *node_to_find;
18175   int j;
18176   vlib_node_t *node, *next_node;
18177   uword *p;
18178
18179   if (vam->graph_node_index_by_name == 0)
18180     {
18181       print (vam->ofp, "Node table empty, issue get_node_graph...");
18182       return 0;
18183     }
18184
18185   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18186     {
18187       if (unformat (line_input, "%s", &node_to_find))
18188         {
18189           vec_add1 (node_to_find, 0);
18190           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18191           if (p == 0)
18192             {
18193               print (vam->ofp, "%s not found...", node_to_find);
18194               goto out;
18195             }
18196           node = vam->graph_nodes[p[0]];
18197           print (vam->ofp, "[%d] %s", p[0], node->name);
18198           for (j = 0; j < vec_len (node->next_nodes); j++)
18199             {
18200               if (node->next_nodes[j] != ~0)
18201                 {
18202                   next_node = vam->graph_nodes[node->next_nodes[j]];
18203                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18204                 }
18205             }
18206         }
18207
18208       else
18209         {
18210           clib_warning ("parse error '%U'", format_unformat_error,
18211                         line_input);
18212           return -99;
18213         }
18214
18215     out:
18216       vec_free (node_to_find);
18217
18218     }
18219
18220   return 0;
18221 }
18222
18223
18224 static int
18225 script (vat_main_t * vam)
18226 {
18227 #if (VPP_API_TEST_BUILTIN==0)
18228   u8 *s = 0;
18229   char *save_current_file;
18230   unformat_input_t save_input;
18231   jmp_buf save_jump_buf;
18232   u32 save_line_number;
18233
18234   FILE *new_fp, *save_ifp;
18235
18236   if (unformat (vam->input, "%s", &s))
18237     {
18238       new_fp = fopen ((char *) s, "r");
18239       if (new_fp == 0)
18240         {
18241           errmsg ("Couldn't open script file %s", s);
18242           vec_free (s);
18243           return -99;
18244         }
18245     }
18246   else
18247     {
18248       errmsg ("Missing script name");
18249       return -99;
18250     }
18251
18252   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18253   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18254   save_ifp = vam->ifp;
18255   save_line_number = vam->input_line_number;
18256   save_current_file = (char *) vam->current_file;
18257
18258   vam->input_line_number = 0;
18259   vam->ifp = new_fp;
18260   vam->current_file = s;
18261   do_one_file (vam);
18262
18263   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18264   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18265   vam->ifp = save_ifp;
18266   vam->input_line_number = save_line_number;
18267   vam->current_file = (u8 *) save_current_file;
18268   vec_free (s);
18269
18270   return 0;
18271 #else
18272   clib_warning ("use the exec command...");
18273   return -99;
18274 #endif
18275 }
18276
18277 static int
18278 echo (vat_main_t * vam)
18279 {
18280   print (vam->ofp, "%v", vam->input->buffer);
18281   return 0;
18282 }
18283
18284 /* List of API message constructors, CLI names map to api_xxx */
18285 #define foreach_vpe_api_msg                                             \
18286 _(create_loopback,"[mac <mac-addr>]")                                   \
18287 _(sw_interface_dump,"")                                                 \
18288 _(sw_interface_set_flags,                                               \
18289   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18290 _(sw_interface_add_del_address,                                         \
18291   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18292 _(sw_interface_set_table,                                               \
18293   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18294 _(sw_interface_set_mpls_enable,                                         \
18295   "<intfc> | sw_if_index [disable | dis]")                              \
18296 _(sw_interface_set_vpath,                                               \
18297   "<intfc> | sw_if_index <id> enable | disable")                        \
18298 _(sw_interface_set_vxlan_bypass,                                        \
18299   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18300 _(sw_interface_set_l2_xconnect,                                         \
18301   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18302   "enable | disable")                                                   \
18303 _(sw_interface_set_l2_bridge,                                           \
18304   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18305   "[shg <split-horizon-group>] [bvi]\n"                                 \
18306   "enable | disable")                                                   \
18307 _(bridge_domain_add_del,                                                \
18308   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18309 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18310 _(l2fib_add_del,                                                        \
18311   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18312 _(l2_flags,                                                             \
18313   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18314 _(bridge_flags,                                                         \
18315   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18316 _(tap_connect,                                                          \
18317   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18318 _(tap_modify,                                                           \
18319   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18320 _(tap_delete,                                                           \
18321   "<vpp-if-name> | sw_if_index <id>")                                   \
18322 _(sw_interface_tap_dump, "")                                            \
18323 _(ip_add_del_route,                                                     \
18324   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18325   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18326   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18327   "[multipath] [count <n>]")                                            \
18328 _(ip_mroute_add_del,                                                    \
18329   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18330   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18331 _(mpls_route_add_del,                                                   \
18332   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18333   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18334   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18335   "[multipath] [count <n>]")                                            \
18336 _(mpls_ip_bind_unbind,                                                  \
18337   "<label> <addr/len>")                                                 \
18338 _(mpls_tunnel_add_del,                                                  \
18339   " via <addr> [table-id <n>]\n"                                        \
18340   "sw_if_index <id>] [l2]  [del]")                                      \
18341 _(proxy_arp_add_del,                                                    \
18342   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18343 _(proxy_arp_intfc_enable_disable,                                       \
18344   "<intfc> | sw_if_index <id> enable | disable")                        \
18345 _(sw_interface_set_unnumbered,                                          \
18346   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18347 _(ip_neighbor_add_del,                                                  \
18348   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18349   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18350 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18351 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18352 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18353   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18354   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18355   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18356 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18357 _(reset_fib, "vrf <n> [ipv6]")                                          \
18358 _(dhcp_proxy_config,                                                    \
18359   "svr <v46-address> src <v46-address>\n"                               \
18360    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18361 _(dhcp_proxy_set_vss,                                                   \
18362   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18363 _(dhcp_proxy_dump, "ip6")                                               \
18364 _(dhcp_client_config,                                                   \
18365   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18366 _(set_ip_flow_hash,                                                     \
18367   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18368 _(sw_interface_ip6_enable_disable,                                      \
18369   "<intfc> | sw_if_index <id> enable | disable")                        \
18370 _(sw_interface_ip6_set_link_local_address,                              \
18371   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18372 _(sw_interface_ip6nd_ra_prefix,                                         \
18373   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18374   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18375   "[nolink] [isno]")                                                    \
18376 _(sw_interface_ip6nd_ra_config,                                         \
18377   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18378   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18379   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18380 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18381 _(l2_patch_add_del,                                                     \
18382   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18383   "enable | disable")                                                   \
18384 _(sr_tunnel_add_del,                                                    \
18385   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
18386   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
18387   "[policy <policy_name>]")                                             \
18388 _(sr_policy_add_del,                                                    \
18389   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
18390 _(sr_multicast_map_add_del,                                             \
18391   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
18392 _(classify_add_del_table,                                               \
18393   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18394   " [del] [del-chain] mask <mask-value>\n"                              \
18395   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18396   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18397 _(classify_add_del_session,                                             \
18398   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18399   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18400   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18401   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18402 _(classify_set_interface_ip_table,                                      \
18403   "<intfc> | sw_if_index <nn> table <nn>")                              \
18404 _(classify_set_interface_l2_tables,                                     \
18405   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18406   "  [other-table <nn>]")                                               \
18407 _(get_node_index, "node <node-name")                                    \
18408 _(add_node_next, "node <node-name> next <next-node-name>")              \
18409 _(l2tpv3_create_tunnel,                                                 \
18410   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18411   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18412   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18413 _(l2tpv3_set_tunnel_cookies,                                            \
18414   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18415   "[new_remote_cookie <nn>]\n")                                         \
18416 _(l2tpv3_interface_enable_disable,                                      \
18417   "<intfc> | sw_if_index <nn> enable | disable")                        \
18418 _(l2tpv3_set_lookup_key,                                                \
18419   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18420 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18421 _(vxlan_add_del_tunnel,                                                 \
18422   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18423   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18424   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18425 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18426 _(gre_add_del_tunnel,                                                   \
18427   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18428 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18429 _(l2_fib_clear_table, "")                                               \
18430 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18431 _(l2_interface_vlan_tag_rewrite,                                        \
18432   "<intfc> | sw_if_index <nn> \n"                                       \
18433   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18434   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18435 _(create_vhost_user_if,                                                 \
18436         "socket <filename> [server] [renumber <dev_instance>] "         \
18437         "[mac <mac_address>]")                                          \
18438 _(modify_vhost_user_if,                                                 \
18439         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18440         "[server] [renumber <dev_instance>]")                           \
18441 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18442 _(sw_interface_vhost_user_dump, "")                                     \
18443 _(show_version, "")                                                     \
18444 _(vxlan_gpe_add_del_tunnel,                                             \
18445   "local <addr> remote <addr> vni <nn>\n"                               \
18446     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18447   "[next-ethernet] [next-nsh]\n")                                       \
18448 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18449 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18450 _(interface_name_renumber,                                              \
18451   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18452 _(input_acl_set_interface,                                              \
18453   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18454   "  [l2-table <nn>] [del]")                                            \
18455 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18456 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18457 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18458 _(ip_dump, "ipv4 | ipv6")                                               \
18459 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18460 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18461   "  spid_id <n> ")                                                     \
18462 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18463   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18464   "  integ_alg <alg> integ_key <hex>")                                  \
18465 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18466   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18467   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18468   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18469 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18470 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18471 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18472   "(auth_data 0x<data> | auth_data <data>)")                            \
18473 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18474   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18475 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18476   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18477   "(local|remote)")                                                     \
18478 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18479 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18480 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18481 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18482 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18483 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18484 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18485 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18486 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18487 _(delete_loopback,"sw_if_index <nn>")                                   \
18488 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18489 _(map_add_domain,                                                       \
18490   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18491   "ip6-src <ip6addr> "                                                  \
18492   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18493 _(map_del_domain, "index <n>")                                          \
18494 _(map_add_del_rule,                                                     \
18495   "index <n> psid <n> dst <ip6addr> [del]")                             \
18496 _(map_domain_dump, "")                                                  \
18497 _(map_rule_dump, "index <map-domain>")                                  \
18498 _(want_interface_events,  "enable|disable")                             \
18499 _(want_stats,"enable|disable")                                          \
18500 _(get_first_msg_id, "client <name>")                                    \
18501 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18502 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18503   "fib-id <nn> [ip4][ip6][default]")                                    \
18504 _(get_node_graph, " ")                                                  \
18505 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18506 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18507 _(ioam_disable, "")                                                     \
18508 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18509                             " sw_if_index <sw_if_index> p <priority> "  \
18510                             "w <weight>] [del]")                        \
18511 _(one_add_del_locator, "locator-set <locator_name> "                    \
18512                         "iface <intf> | sw_if_index <sw_if_index> "     \
18513                         "p <priority> w <weight> [del]")                \
18514 _(one_add_del_local_eid,"vni <vni> eid "                                \
18515                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18516                          "locator-set <locator_name> [del]"             \
18517                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18518 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18519 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18520 _(one_enable_disable, "enable|disable")                                 \
18521 _(one_map_register_enable_disable, "enable|disable")                    \
18522 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18523 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18524                                "[seid <seid>] "                         \
18525                                "rloc <locator> p <prio> "               \
18526                                "w <weight> [rloc <loc> ... ] "          \
18527                                "action <action> [del-all]")             \
18528 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18529                           "<local-eid>")                                \
18530 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18531 _(one_map_request_mode, "src-dst|dst-only")                             \
18532 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18533 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18534 _(one_locator_set_dump, "[local | remote]")                             \
18535 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18536 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18537                        "[local] | [remote]")                            \
18538 _(one_eid_table_vni_dump, "")                                           \
18539 _(one_eid_table_map_dump, "l2|l3")                                      \
18540 _(one_map_resolver_dump, "")                                            \
18541 _(one_map_server_dump, "")                                              \
18542 _(one_adjacencies_get, "vni <vni>")                                     \
18543 _(show_one_rloc_probe_state, "")                                        \
18544 _(show_one_map_register_state, "")                                      \
18545 _(show_one_status, "")                                                  \
18546 _(one_get_map_request_itr_rlocs, "")                                    \
18547 _(show_one_pitr, "")                                                    \
18548 _(show_one_map_request_mode, "")                                        \
18549 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18550                             " sw_if_index <sw_if_index> p <priority> "  \
18551                             "w <weight>] [del]")                        \
18552 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18553                         "iface <intf> | sw_if_index <sw_if_index> "     \
18554                         "p <priority> w <weight> [del]")                \
18555 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18556                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18557                          "locator-set <locator_name> [del]"             \
18558                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18559 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18560 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18561 _(lisp_enable_disable, "enable|disable")                                \
18562 _(lisp_map_register_enable_disable, "enable|disable")                   \
18563 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18564 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18565                                "[seid <seid>] "                         \
18566                                "rloc <locator> p <prio> "               \
18567                                "w <weight> [rloc <loc> ... ] "          \
18568                                "action <action> [del-all]")             \
18569 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18570                           "<local-eid>")                                \
18571 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18572 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18573 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18574 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18575 _(lisp_locator_set_dump, "[local | remote]")                            \
18576 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18577 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18578                        "[local] | [remote]")                            \
18579 _(lisp_eid_table_vni_dump, "")                                          \
18580 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18581 _(lisp_map_resolver_dump, "")                                           \
18582 _(lisp_map_server_dump, "")                                             \
18583 _(lisp_adjacencies_get, "vni <vni>")                                    \
18584 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18585 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18586 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18587 _(gpe_get_encap_mode, "")                                               \
18588 _(lisp_gpe_add_del_iface, "up|down")                                    \
18589 _(lisp_gpe_enable_disable, "enable|disable")                            \
18590 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18591   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18592 _(show_lisp_rloc_probe_state, "")                                       \
18593 _(show_lisp_map_register_state, "")                                     \
18594 _(show_lisp_status, "")                                                 \
18595 _(lisp_get_map_request_itr_rlocs, "")                                   \
18596 _(show_lisp_pitr, "")                                                   \
18597 _(show_lisp_map_request_mode, "")                                       \
18598 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18599 _(af_packet_delete, "name <host interface name>")                       \
18600 _(policer_add_del, "name <policer name> <params> [del]")                \
18601 _(policer_dump, "[name <policer name>]")                                \
18602 _(policer_classify_set_interface,                                       \
18603   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18604   "  [l2-table <nn>] [del]")                                            \
18605 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18606 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18607     "[master|slave]")                                                   \
18608 _(netmap_delete, "name <interface name>")                               \
18609 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18610 _(mpls_fib_dump, "")                                                    \
18611 _(classify_table_ids, "")                                               \
18612 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18613 _(classify_table_info, "table_id <nn>")                                 \
18614 _(classify_session_dump, "table_id <nn>")                               \
18615 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18616     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18617     "[template_interval <nn>] [udp_checksum]")                          \
18618 _(ipfix_exporter_dump, "")                                              \
18619 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18620 _(ipfix_classify_stream_dump, "")                                       \
18621 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18622 _(ipfix_classify_table_dump, "")                                        \
18623 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18624 _(sw_interface_span_dump, "")                                           \
18625 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18626 _(pg_create_interface, "if_id <nn>")                                    \
18627 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18628 _(pg_enable_disable, "[stream <id>] disable")                           \
18629 _(ip_source_and_port_range_check_add_del,                               \
18630   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18631 _(ip_source_and_port_range_check_interface_add_del,                     \
18632   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18633   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18634 _(ipsec_gre_add_del_tunnel,                                             \
18635   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18636 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18637 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18638 _(l2_interface_pbb_tag_rewrite,                                         \
18639   "<intfc> | sw_if_index <nn> \n"                                       \
18640   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18641   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18642 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18643 _(flow_classify_set_interface,                                          \
18644   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18645 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18646 _(ip_fib_dump, "")                                                      \
18647 _(ip_mfib_dump, "")                                                     \
18648 _(ip6_fib_dump, "")                                                     \
18649 _(ip6_mfib_dump, "")                                                    \
18650 _(feature_enable_disable, "arc_name <arc_name> "                        \
18651   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18652 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18653 "[disable]")                                                            \
18654 _(l2_xconnect_dump, "")                                                 \
18655 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18656 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18657 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18658
18659 #if DPDK > 0
18660 #define foreach_vpe_dpdk_api_msg                                        \
18661 _(sw_interface_set_dpdk_hqos_pipe,                                      \
18662   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18663   "profile <profile-id>\n")                                             \
18664 _(sw_interface_set_dpdk_hqos_subport,                                   \
18665   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
18666   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18667 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
18668   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18669 #endif
18670
18671 /* List of command functions, CLI names map directly to functions */
18672 #define foreach_cli_function                                    \
18673 _(comment, "usage: comment <ignore-rest-of-line>")              \
18674 _(dump_interface_table, "usage: dump_interface_table")          \
18675 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18676 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18677 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18678 _(dump_stats_table, "usage: dump_stats_table")                  \
18679 _(dump_macro_table, "usage: dump_macro_table ")                 \
18680 _(dump_node_table, "usage: dump_node_table")                    \
18681 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18682 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18683 _(echo, "usage: echo <message>")                                \
18684 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18685 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18686 _(help, "usage: help")                                          \
18687 _(q, "usage: quit")                                             \
18688 _(quit, "usage: quit")                                          \
18689 _(search_node_table, "usage: search_node_table <name>...")      \
18690 _(set, "usage: set <variable-name> <value>")                    \
18691 _(script, "usage: script <file-name>")                          \
18692 _(unset, "usage: unset <variable-name>")
18693
18694 #define _(N,n)                                  \
18695     static void vl_api_##n##_t_handler_uni      \
18696     (vl_api_##n##_t * mp)                       \
18697     {                                           \
18698         vat_main_t * vam = &vat_main;           \
18699         if (vam->json_output) {                 \
18700             vl_api_##n##_t_handler_json(mp);    \
18701         } else {                                \
18702             vl_api_##n##_t_handler(mp);         \
18703         }                                       \
18704     }
18705 foreach_vpe_api_reply_msg;
18706 #undef _
18707
18708 #if DPDK > 0
18709 #define _(N,n)                                  \
18710     static void vl_api_##n##_t_handler_uni      \
18711     (vl_api_##n##_t * mp)                       \
18712     {                                           \
18713         vat_main_t * vam = &vat_main;           \
18714         if (vam->json_output) {                 \
18715             vl_api_##n##_t_handler_json(mp);    \
18716         } else {                                \
18717             vl_api_##n##_t_handler(mp);         \
18718         }                                       \
18719     }
18720 foreach_vpe_dpdk_api_reply_msg;
18721 #undef _
18722 #endif
18723
18724 void
18725 vat_api_hookup (vat_main_t * vam)
18726 {
18727 #define _(N,n)                                                  \
18728     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18729                            vl_api_##n##_t_handler_uni,          \
18730                            vl_noop_handler,                     \
18731                            vl_api_##n##_t_endian,               \
18732                            vl_api_##n##_t_print,                \
18733                            sizeof(vl_api_##n##_t), 1);
18734   foreach_vpe_api_reply_msg;
18735 #undef _
18736
18737 #if DPDK > 0
18738 #define _(N,n)                                                  \
18739     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18740                            vl_api_##n##_t_handler_uni,          \
18741                            vl_noop_handler,                     \
18742                            vl_api_##n##_t_endian,               \
18743                            vl_api_##n##_t_print,                \
18744                            sizeof(vl_api_##n##_t), 1);
18745   foreach_vpe_dpdk_api_reply_msg;
18746 #undef _
18747 #endif
18748
18749 #if (VPP_API_TEST_BUILTIN==0)
18750   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18751 #endif
18752
18753   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18754
18755   vam->function_by_name = hash_create_string (0, sizeof (uword));
18756
18757   vam->help_by_name = hash_create_string (0, sizeof (uword));
18758
18759   /* API messages we can send */
18760 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18761   foreach_vpe_api_msg;
18762 #undef _
18763 #if DPDK >0
18764 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18765   foreach_vpe_dpdk_api_msg;
18766 #undef _
18767 #endif
18768
18769   /* Help strings */
18770 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18771   foreach_vpe_api_msg;
18772 #undef _
18773 #if DPDK >0
18774 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18775   foreach_vpe_dpdk_api_msg;
18776 #undef _
18777 #endif
18778
18779   /* CLI functions */
18780 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18781   foreach_cli_function;
18782 #undef _
18783
18784   /* Help strings */
18785 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18786   foreach_cli_function;
18787 #undef _
18788 }
18789
18790 /*
18791  * fd.io coding-style-patch-verification: ON
18792  *
18793  * Local Variables:
18794  * eval: (c-set-style "gnu")
18795  * End:
18796  */