Remove the unused VRF ID parameter from the IP neighbour Add/Del API
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <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 #define _(n)                                    \
3974     static void vl_api_##n##_t_handler          \
3975     (vl_api_##n##_t * mp)                       \
3976     {                                           \
3977         vat_main_t * vam = &vat_main;           \
3978         i32 retval = ntohl(mp->retval);         \
3979         if (vam->async_mode) {                  \
3980             vam->async_errors += (retval < 0);  \
3981         } else {                                \
3982             vam->retval = retval;               \
3983             vam->result_ready = 1;              \
3984         }                                       \
3985     }
3986 foreach_standard_reply_retval_handler;
3987 #undef _
3988
3989 #define _(n)                                    \
3990     static void vl_api_##n##_t_handler_json     \
3991     (vl_api_##n##_t * mp)                       \
3992     {                                           \
3993         vat_main_t * vam = &vat_main;           \
3994         vat_json_node_t node;                   \
3995         vat_json_init_object(&node);            \
3996         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3997         vat_json_print(vam->ofp, &node);        \
3998         vam->retval = ntohl(mp->retval);        \
3999         vam->result_ready = 1;                  \
4000     }
4001 foreach_standard_reply_retval_handler;
4002 #undef _
4003
4004 /*
4005  * Table of message reply handlers, must include boilerplate handlers
4006  * we just generated
4007  */
4008
4009 #define foreach_vpe_api_reply_msg                                       \
4010 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4011 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4012 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4013 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4014 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4015 _(CLI_REPLY, cli_reply)                                                 \
4016 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4017 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4018   sw_interface_add_del_address_reply)                                   \
4019 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4020 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4021 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4022 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4023 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4024   sw_interface_set_l2_xconnect_reply)                                   \
4025 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4026   sw_interface_set_l2_bridge_reply)                                     \
4027 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4028 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4029 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4030 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4031 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4032 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4033 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4034 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4035 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4036 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4037 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4038 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4039 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4040 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4041 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4042 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4043   proxy_arp_intfc_enable_disable_reply)                                 \
4044 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4045 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4046   sw_interface_set_unnumbered_reply)                                    \
4047 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4048 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4049 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4050 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4051 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4052 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4053 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4054 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4055 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4056 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4057 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4058 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4059   sw_interface_ip6_enable_disable_reply)                                \
4060 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4061   sw_interface_ip6_set_link_local_address_reply)                        \
4062 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4063   sw_interface_ip6nd_ra_prefix_reply)                                   \
4064 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4065   sw_interface_ip6nd_ra_config_reply)                                   \
4066 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4067 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4068 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4069 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4070 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4071 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4072 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4073 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4074 classify_set_interface_ip_table_reply)                                  \
4075 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4076   classify_set_interface_l2_tables_reply)                               \
4077 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4078 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4079 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4080 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4081 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4082   l2tpv3_interface_enable_disable_reply)                                \
4083 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4084 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4085 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4086 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4087 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4088 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4089 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4090 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4091 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4092 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4093 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4094 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4095 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4096 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4097 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4098 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4099 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4100 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4101 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4102 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4103 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4104 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4105 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4106 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4107 _(IP_DETAILS, ip_details)                                               \
4108 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4109 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4110 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4111 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4112 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4113 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4114 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4115 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4116 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4117 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4118 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4119 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4120 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4121 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4122 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4123 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4124 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4125 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4126 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4127 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4128 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4129 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4130 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4131 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4132 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4133 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
4134 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4135 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4136 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4137 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4138 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4139 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4140 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4141 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4142 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4143 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4144 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4145 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4146 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4147 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4148 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4149 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4150 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4151 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4152 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4153 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4154 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4155 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4156 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4157   one_map_register_enable_disable_reply)                                \
4158 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4159   one_rloc_probe_enable_disable_reply)                                  \
4160 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4161 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4162 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4163 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4164 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4165 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4166 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4167 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4168 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4169 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4170 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4171 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4172 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4173 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4174 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4175 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4176 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4177 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4178   gpe_fwd_entry_path_details)                                           \
4179 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4180 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4181   one_add_del_map_request_itr_rlocs_reply)                              \
4182 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4183   one_get_map_request_itr_rlocs_reply)                                  \
4184 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4185 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4186 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4187 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4188   show_one_map_register_state_reply)                                    \
4189 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4190 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4191 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4192 _(POLICER_DETAILS, policer_details)                                     \
4193 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4194 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4195 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4196 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4197 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4198 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4199 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4200 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4201 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4202 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4203 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4204 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4205 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4206 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4207 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4208 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4209 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4210 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4211 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4212 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4213 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4214 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4215 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4216 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4217 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4218  ip_source_and_port_range_check_add_del_reply)                          \
4219 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4220  ip_source_and_port_range_check_interface_add_del_reply)                \
4221 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4222 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4223 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4224 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4225 _(PUNT_REPLY, punt_reply)                                               \
4226 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4227 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4228 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4229 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4230 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4231 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4232 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4233 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4234
4235 typedef struct
4236 {
4237   u8 *name;
4238   u32 value;
4239 } name_sort_t;
4240
4241
4242 #define STR_VTR_OP_CASE(op)     \
4243     case L2_VTR_ ## op:         \
4244         return "" # op;
4245
4246 static const char *
4247 str_vtr_op (u32 vtr_op)
4248 {
4249   switch (vtr_op)
4250     {
4251       STR_VTR_OP_CASE (DISABLED);
4252       STR_VTR_OP_CASE (PUSH_1);
4253       STR_VTR_OP_CASE (PUSH_2);
4254       STR_VTR_OP_CASE (POP_1);
4255       STR_VTR_OP_CASE (POP_2);
4256       STR_VTR_OP_CASE (TRANSLATE_1_1);
4257       STR_VTR_OP_CASE (TRANSLATE_1_2);
4258       STR_VTR_OP_CASE (TRANSLATE_2_1);
4259       STR_VTR_OP_CASE (TRANSLATE_2_2);
4260     }
4261
4262   return "UNKNOWN";
4263 }
4264
4265 static int
4266 dump_sub_interface_table (vat_main_t * vam)
4267 {
4268   const sw_interface_subif_t *sub = NULL;
4269
4270   if (vam->json_output)
4271     {
4272       clib_warning
4273         ("JSON output supported only for VPE API calls and dump_stats_table");
4274       return -99;
4275     }
4276
4277   print (vam->ofp,
4278          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4279          "Interface", "sw_if_index",
4280          "sub id", "dot1ad", "tags", "outer id",
4281          "inner id", "exact", "default", "outer any", "inner any");
4282
4283   vec_foreach (sub, vam->sw_if_subif_table)
4284   {
4285     print (vam->ofp,
4286            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4287            sub->interface_name,
4288            sub->sw_if_index,
4289            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4290            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4291            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4292            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4293     if (sub->vtr_op != L2_VTR_DISABLED)
4294       {
4295         print (vam->ofp,
4296                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4297                "tag1: %d tag2: %d ]",
4298                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4299                sub->vtr_tag1, sub->vtr_tag2);
4300       }
4301   }
4302
4303   return 0;
4304 }
4305
4306 static int
4307 name_sort_cmp (void *a1, void *a2)
4308 {
4309   name_sort_t *n1 = a1;
4310   name_sort_t *n2 = a2;
4311
4312   return strcmp ((char *) n1->name, (char *) n2->name);
4313 }
4314
4315 static int
4316 dump_interface_table (vat_main_t * vam)
4317 {
4318   hash_pair_t *p;
4319   name_sort_t *nses = 0, *ns;
4320
4321   if (vam->json_output)
4322     {
4323       clib_warning
4324         ("JSON output supported only for VPE API calls and dump_stats_table");
4325       return -99;
4326     }
4327
4328   /* *INDENT-OFF* */
4329   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4330   ({
4331     vec_add2 (nses, ns, 1);
4332     ns->name = (u8 *)(p->key);
4333     ns->value = (u32) p->value[0];
4334   }));
4335   /* *INDENT-ON* */
4336
4337   vec_sort_with_function (nses, name_sort_cmp);
4338
4339   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4340   vec_foreach (ns, nses)
4341   {
4342     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4343   }
4344   vec_free (nses);
4345   return 0;
4346 }
4347
4348 static int
4349 dump_ip_table (vat_main_t * vam, int is_ipv6)
4350 {
4351   const ip_details_t *det = NULL;
4352   const ip_address_details_t *address = NULL;
4353   u32 i = ~0;
4354
4355   print (vam->ofp, "%-12s", "sw_if_index");
4356
4357   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4358   {
4359     i++;
4360     if (!det->present)
4361       {
4362         continue;
4363       }
4364     print (vam->ofp, "%-12d", i);
4365     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4366     if (!det->addr)
4367       {
4368         continue;
4369       }
4370     vec_foreach (address, det->addr)
4371     {
4372       print (vam->ofp,
4373              "            %-30U%-13d",
4374              is_ipv6 ? format_ip6_address : format_ip4_address,
4375              address->ip, address->prefix_length);
4376     }
4377   }
4378
4379   return 0;
4380 }
4381
4382 static int
4383 dump_ipv4_table (vat_main_t * vam)
4384 {
4385   if (vam->json_output)
4386     {
4387       clib_warning
4388         ("JSON output supported only for VPE API calls and dump_stats_table");
4389       return -99;
4390     }
4391
4392   return dump_ip_table (vam, 0);
4393 }
4394
4395 static int
4396 dump_ipv6_table (vat_main_t * vam)
4397 {
4398   if (vam->json_output)
4399     {
4400       clib_warning
4401         ("JSON output supported only for VPE API calls and dump_stats_table");
4402       return -99;
4403     }
4404
4405   return dump_ip_table (vam, 1);
4406 }
4407
4408 static char *
4409 counter_type_to_str (u8 counter_type, u8 is_combined)
4410 {
4411   if (!is_combined)
4412     {
4413       switch (counter_type)
4414         {
4415         case VNET_INTERFACE_COUNTER_DROP:
4416           return "drop";
4417         case VNET_INTERFACE_COUNTER_PUNT:
4418           return "punt";
4419         case VNET_INTERFACE_COUNTER_IP4:
4420           return "ip4";
4421         case VNET_INTERFACE_COUNTER_IP6:
4422           return "ip6";
4423         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4424           return "rx-no-buf";
4425         case VNET_INTERFACE_COUNTER_RX_MISS:
4426           return "rx-miss";
4427         case VNET_INTERFACE_COUNTER_RX_ERROR:
4428           return "rx-error";
4429         case VNET_INTERFACE_COUNTER_TX_ERROR:
4430           return "tx-error";
4431         default:
4432           return "INVALID-COUNTER-TYPE";
4433         }
4434     }
4435   else
4436     {
4437       switch (counter_type)
4438         {
4439         case VNET_INTERFACE_COUNTER_RX:
4440           return "rx";
4441         case VNET_INTERFACE_COUNTER_TX:
4442           return "tx";
4443         default:
4444           return "INVALID-COUNTER-TYPE";
4445         }
4446     }
4447 }
4448
4449 static int
4450 dump_stats_table (vat_main_t * vam)
4451 {
4452   vat_json_node_t node;
4453   vat_json_node_t *msg_array;
4454   vat_json_node_t *msg;
4455   vat_json_node_t *counter_array;
4456   vat_json_node_t *counter;
4457   interface_counter_t c;
4458   u64 packets;
4459   ip4_fib_counter_t *c4;
4460   ip6_fib_counter_t *c6;
4461   ip4_nbr_counter_t *n4;
4462   ip6_nbr_counter_t *n6;
4463   int i, j;
4464
4465   if (!vam->json_output)
4466     {
4467       clib_warning ("dump_stats_table supported only in JSON format");
4468       return -99;
4469     }
4470
4471   vat_json_init_object (&node);
4472
4473   /* interface counters */
4474   msg_array = vat_json_object_add (&node, "interface_counters");
4475   vat_json_init_array (msg_array);
4476   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4477     {
4478       msg = vat_json_array_add (msg_array);
4479       vat_json_init_object (msg);
4480       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4481                                        (u8 *) counter_type_to_str (i, 0));
4482       vat_json_object_add_int (msg, "is_combined", 0);
4483       counter_array = vat_json_object_add (msg, "data");
4484       vat_json_init_array (counter_array);
4485       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4486         {
4487           packets = vam->simple_interface_counters[i][j];
4488           vat_json_array_add_uint (counter_array, packets);
4489         }
4490     }
4491   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4492     {
4493       msg = vat_json_array_add (msg_array);
4494       vat_json_init_object (msg);
4495       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4496                                        (u8 *) counter_type_to_str (i, 1));
4497       vat_json_object_add_int (msg, "is_combined", 1);
4498       counter_array = vat_json_object_add (msg, "data");
4499       vat_json_init_array (counter_array);
4500       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4501         {
4502           c = vam->combined_interface_counters[i][j];
4503           counter = vat_json_array_add (counter_array);
4504           vat_json_init_object (counter);
4505           vat_json_object_add_uint (counter, "packets", c.packets);
4506           vat_json_object_add_uint (counter, "bytes", c.bytes);
4507         }
4508     }
4509
4510   /* ip4 fib counters */
4511   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4512   vat_json_init_array (msg_array);
4513   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4514     {
4515       msg = vat_json_array_add (msg_array);
4516       vat_json_init_object (msg);
4517       vat_json_object_add_uint (msg, "vrf_id",
4518                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4519       counter_array = vat_json_object_add (msg, "c");
4520       vat_json_init_array (counter_array);
4521       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4522         {
4523           counter = vat_json_array_add (counter_array);
4524           vat_json_init_object (counter);
4525           c4 = &vam->ip4_fib_counters[i][j];
4526           vat_json_object_add_ip4 (counter, "address", c4->address);
4527           vat_json_object_add_uint (counter, "address_length",
4528                                     c4->address_length);
4529           vat_json_object_add_uint (counter, "packets", c4->packets);
4530           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4531         }
4532     }
4533
4534   /* ip6 fib counters */
4535   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4536   vat_json_init_array (msg_array);
4537   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4538     {
4539       msg = vat_json_array_add (msg_array);
4540       vat_json_init_object (msg);
4541       vat_json_object_add_uint (msg, "vrf_id",
4542                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4543       counter_array = vat_json_object_add (msg, "c");
4544       vat_json_init_array (counter_array);
4545       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4546         {
4547           counter = vat_json_array_add (counter_array);
4548           vat_json_init_object (counter);
4549           c6 = &vam->ip6_fib_counters[i][j];
4550           vat_json_object_add_ip6 (counter, "address", c6->address);
4551           vat_json_object_add_uint (counter, "address_length",
4552                                     c6->address_length);
4553           vat_json_object_add_uint (counter, "packets", c6->packets);
4554           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4555         }
4556     }
4557
4558   /* ip4 nbr counters */
4559   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4560   vat_json_init_array (msg_array);
4561   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4562     {
4563       msg = vat_json_array_add (msg_array);
4564       vat_json_init_object (msg);
4565       vat_json_object_add_uint (msg, "sw_if_index", i);
4566       counter_array = vat_json_object_add (msg, "c");
4567       vat_json_init_array (counter_array);
4568       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4569         {
4570           counter = vat_json_array_add (counter_array);
4571           vat_json_init_object (counter);
4572           n4 = &vam->ip4_nbr_counters[i][j];
4573           vat_json_object_add_ip4 (counter, "address", n4->address);
4574           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4575           vat_json_object_add_uint (counter, "packets", n4->packets);
4576           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4577         }
4578     }
4579
4580   /* ip6 nbr counters */
4581   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4582   vat_json_init_array (msg_array);
4583   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4584     {
4585       msg = vat_json_array_add (msg_array);
4586       vat_json_init_object (msg);
4587       vat_json_object_add_uint (msg, "sw_if_index", i);
4588       counter_array = vat_json_object_add (msg, "c");
4589       vat_json_init_array (counter_array);
4590       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4591         {
4592           counter = vat_json_array_add (counter_array);
4593           vat_json_init_object (counter);
4594           n6 = &vam->ip6_nbr_counters[i][j];
4595           vat_json_object_add_ip6 (counter, "address", n6->address);
4596           vat_json_object_add_uint (counter, "packets", n6->packets);
4597           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4598         }
4599     }
4600
4601   vat_json_print (vam->ofp, &node);
4602   vat_json_free (&node);
4603
4604   return 0;
4605 }
4606
4607 int
4608 exec (vat_main_t * vam)
4609 {
4610   api_main_t *am = &api_main;
4611   vl_api_cli_request_t *mp;
4612   f64 timeout;
4613   void *oldheap;
4614   u8 *cmd = 0;
4615   unformat_input_t *i = vam->input;
4616
4617   if (vec_len (i->buffer) == 0)
4618     return -1;
4619
4620   if (vam->exec_mode == 0 && unformat (i, "mode"))
4621     {
4622       vam->exec_mode = 1;
4623       return 0;
4624     }
4625   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4626     {
4627       vam->exec_mode = 0;
4628       return 0;
4629     }
4630
4631
4632   M (CLI_REQUEST, mp);
4633
4634   /*
4635    * Copy cmd into shared memory.
4636    * In order for the CLI command to work, it
4637    * must be a vector ending in \n, not a C-string ending
4638    * in \n\0.
4639    */
4640   pthread_mutex_lock (&am->vlib_rp->mutex);
4641   oldheap = svm_push_data_heap (am->vlib_rp);
4642
4643   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4644   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4645
4646   svm_pop_heap (oldheap);
4647   pthread_mutex_unlock (&am->vlib_rp->mutex);
4648
4649   mp->cmd_in_shmem = (u64) cmd;
4650   S (mp);
4651   timeout = vat_time_now (vam) + 10.0;
4652
4653   while (vat_time_now (vam) < timeout)
4654     {
4655       if (vam->result_ready == 1)
4656         {
4657           u8 *free_me;
4658           if (vam->shmem_result != NULL)
4659             print (vam->ofp, "%s", vam->shmem_result);
4660           pthread_mutex_lock (&am->vlib_rp->mutex);
4661           oldheap = svm_push_data_heap (am->vlib_rp);
4662
4663           free_me = (u8 *) vam->shmem_result;
4664           vec_free (free_me);
4665
4666           svm_pop_heap (oldheap);
4667           pthread_mutex_unlock (&am->vlib_rp->mutex);
4668           return 0;
4669         }
4670     }
4671   return -99;
4672 }
4673
4674 /*
4675  * Future replacement of exec() that passes CLI buffers directly in
4676  * the API messages instead of an additional shared memory area.
4677  */
4678 static int
4679 exec_inband (vat_main_t * vam)
4680 {
4681   vl_api_cli_inband_t *mp;
4682   unformat_input_t *i = vam->input;
4683   int ret;
4684
4685   if (vec_len (i->buffer) == 0)
4686     return -1;
4687
4688   if (vam->exec_mode == 0 && unformat (i, "mode"))
4689     {
4690       vam->exec_mode = 1;
4691       return 0;
4692     }
4693   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4694     {
4695       vam->exec_mode = 0;
4696       return 0;
4697     }
4698
4699   /*
4700    * In order for the CLI command to work, it
4701    * must be a vector ending in \n, not a C-string ending
4702    * in \n\0.
4703    */
4704   u32 len = vec_len (vam->input->buffer);
4705   M2 (CLI_INBAND, mp, len);
4706   clib_memcpy (mp->cmd, vam->input->buffer, len);
4707   mp->length = htonl (len);
4708
4709   S (mp);
4710   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4711   return ret;
4712 }
4713
4714 static int
4715 api_create_loopback (vat_main_t * vam)
4716 {
4717   unformat_input_t *i = vam->input;
4718   vl_api_create_loopback_t *mp;
4719   u8 mac_address[6];
4720   u8 mac_set = 0;
4721   int ret;
4722
4723   memset (mac_address, 0, sizeof (mac_address));
4724
4725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4726     {
4727       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4728         mac_set = 1;
4729       else
4730         break;
4731     }
4732
4733   /* Construct the API message */
4734   M (CREATE_LOOPBACK, mp);
4735   if (mac_set)
4736     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4737
4738   S (mp);
4739   W (ret);
4740   return ret;
4741 }
4742
4743 static int
4744 api_delete_loopback (vat_main_t * vam)
4745 {
4746   unformat_input_t *i = vam->input;
4747   vl_api_delete_loopback_t *mp;
4748   u32 sw_if_index = ~0;
4749   int ret;
4750
4751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4752     {
4753       if (unformat (i, "sw_if_index %d", &sw_if_index))
4754         ;
4755       else
4756         break;
4757     }
4758
4759   if (sw_if_index == ~0)
4760     {
4761       errmsg ("missing sw_if_index");
4762       return -99;
4763     }
4764
4765   /* Construct the API message */
4766   M (DELETE_LOOPBACK, mp);
4767   mp->sw_if_index = ntohl (sw_if_index);
4768
4769   S (mp);
4770   W (ret);
4771   return ret;
4772 }
4773
4774 static int
4775 api_want_stats (vat_main_t * vam)
4776 {
4777   unformat_input_t *i = vam->input;
4778   vl_api_want_stats_t *mp;
4779   int enable = -1;
4780   int ret;
4781
4782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4783     {
4784       if (unformat (i, "enable"))
4785         enable = 1;
4786       else if (unformat (i, "disable"))
4787         enable = 0;
4788       else
4789         break;
4790     }
4791
4792   if (enable == -1)
4793     {
4794       errmsg ("missing enable|disable");
4795       return -99;
4796     }
4797
4798   M (WANT_STATS, mp);
4799   mp->enable_disable = enable;
4800
4801   S (mp);
4802   W (ret);
4803   return ret;
4804 }
4805
4806 static int
4807 api_want_interface_events (vat_main_t * vam)
4808 {
4809   unformat_input_t *i = vam->input;
4810   vl_api_want_interface_events_t *mp;
4811   int enable = -1;
4812   int ret;
4813
4814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4815     {
4816       if (unformat (i, "enable"))
4817         enable = 1;
4818       else if (unformat (i, "disable"))
4819         enable = 0;
4820       else
4821         break;
4822     }
4823
4824   if (enable == -1)
4825     {
4826       errmsg ("missing enable|disable");
4827       return -99;
4828     }
4829
4830   M (WANT_INTERFACE_EVENTS, mp);
4831   mp->enable_disable = enable;
4832
4833   vam->interface_event_display = enable;
4834
4835   S (mp);
4836   W (ret);
4837   return ret;
4838 }
4839
4840
4841 /* Note: non-static, called once to set up the initial intfc table */
4842 int
4843 api_sw_interface_dump (vat_main_t * vam)
4844 {
4845   vl_api_sw_interface_dump_t *mp;
4846   vl_api_control_ping_t *mp_ping;
4847   hash_pair_t *p;
4848   name_sort_t *nses = 0, *ns;
4849   sw_interface_subif_t *sub = NULL;
4850   int ret;
4851
4852   /* Toss the old name table */
4853   /* *INDENT-OFF* */
4854   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4855   ({
4856     vec_add2 (nses, ns, 1);
4857     ns->name = (u8 *)(p->key);
4858     ns->value = (u32) p->value[0];
4859   }));
4860   /* *INDENT-ON* */
4861
4862   hash_free (vam->sw_if_index_by_interface_name);
4863
4864   vec_foreach (ns, nses) vec_free (ns->name);
4865
4866   vec_free (nses);
4867
4868   vec_foreach (sub, vam->sw_if_subif_table)
4869   {
4870     vec_free (sub->interface_name);
4871   }
4872   vec_free (vam->sw_if_subif_table);
4873
4874   /* recreate the interface name hash table */
4875   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4876
4877   /* Get list of ethernets */
4878   M (SW_INTERFACE_DUMP, mp);
4879   mp->name_filter_valid = 1;
4880   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4881   S (mp);
4882
4883   /* and local / loopback interfaces */
4884   M (SW_INTERFACE_DUMP, mp);
4885   mp->name_filter_valid = 1;
4886   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4887   S (mp);
4888
4889   /* and packet-generator interfaces */
4890   M (SW_INTERFACE_DUMP, mp);
4891   mp->name_filter_valid = 1;
4892   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4893   S (mp);
4894
4895   /* and vxlan-gpe tunnel interfaces */
4896   M (SW_INTERFACE_DUMP, mp);
4897   mp->name_filter_valid = 1;
4898   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4899            sizeof (mp->name_filter) - 1);
4900   S (mp);
4901
4902   /* and vxlan tunnel interfaces */
4903   M (SW_INTERFACE_DUMP, mp);
4904   mp->name_filter_valid = 1;
4905   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4906   S (mp);
4907
4908   /* and host (af_packet) interfaces */
4909   M (SW_INTERFACE_DUMP, mp);
4910   mp->name_filter_valid = 1;
4911   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4912   S (mp);
4913
4914   /* and l2tpv3 tunnel interfaces */
4915   M (SW_INTERFACE_DUMP, mp);
4916   mp->name_filter_valid = 1;
4917   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4918            sizeof (mp->name_filter) - 1);
4919   S (mp);
4920
4921   /* and GRE tunnel interfaces */
4922   M (SW_INTERFACE_DUMP, mp);
4923   mp->name_filter_valid = 1;
4924   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4925   S (mp);
4926
4927   /* and LISP-GPE interfaces */
4928   M (SW_INTERFACE_DUMP, mp);
4929   mp->name_filter_valid = 1;
4930   strncpy ((char *) mp->name_filter, "lisp_gpe",
4931            sizeof (mp->name_filter) - 1);
4932   S (mp);
4933
4934   /* and IPSEC tunnel interfaces */
4935   M (SW_INTERFACE_DUMP, mp);
4936   mp->name_filter_valid = 1;
4937   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4938   S (mp);
4939
4940   /* Use a control ping for synchronization */
4941   M (CONTROL_PING, mp_ping);
4942   S (mp_ping);
4943
4944   W (ret);
4945   return ret;
4946 }
4947
4948 static int
4949 api_sw_interface_set_flags (vat_main_t * vam)
4950 {
4951   unformat_input_t *i = vam->input;
4952   vl_api_sw_interface_set_flags_t *mp;
4953   u32 sw_if_index;
4954   u8 sw_if_index_set = 0;
4955   u8 admin_up = 0, link_up = 0;
4956   int ret;
4957
4958   /* Parse args required to build the message */
4959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4960     {
4961       if (unformat (i, "admin-up"))
4962         admin_up = 1;
4963       else if (unformat (i, "admin-down"))
4964         admin_up = 0;
4965       else if (unformat (i, "link-up"))
4966         link_up = 1;
4967       else if (unformat (i, "link-down"))
4968         link_up = 0;
4969       else
4970         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4971         sw_if_index_set = 1;
4972       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4973         sw_if_index_set = 1;
4974       else
4975         break;
4976     }
4977
4978   if (sw_if_index_set == 0)
4979     {
4980       errmsg ("missing interface name or sw_if_index");
4981       return -99;
4982     }
4983
4984   /* Construct the API message */
4985   M (SW_INTERFACE_SET_FLAGS, mp);
4986   mp->sw_if_index = ntohl (sw_if_index);
4987   mp->admin_up_down = admin_up;
4988   mp->link_up_down = link_up;
4989
4990   /* send it... */
4991   S (mp);
4992
4993   /* Wait for a reply, return the good/bad news... */
4994   W (ret);
4995   return ret;
4996 }
4997
4998 static int
4999 api_sw_interface_clear_stats (vat_main_t * vam)
5000 {
5001   unformat_input_t *i = vam->input;
5002   vl_api_sw_interface_clear_stats_t *mp;
5003   u32 sw_if_index;
5004   u8 sw_if_index_set = 0;
5005   int ret;
5006
5007   /* Parse args required to build the message */
5008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5009     {
5010       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5011         sw_if_index_set = 1;
5012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5013         sw_if_index_set = 1;
5014       else
5015         break;
5016     }
5017
5018   /* Construct the API message */
5019   M (SW_INTERFACE_CLEAR_STATS, mp);
5020
5021   if (sw_if_index_set == 1)
5022     mp->sw_if_index = ntohl (sw_if_index);
5023   else
5024     mp->sw_if_index = ~0;
5025
5026   /* send it... */
5027   S (mp);
5028
5029   /* Wait for a reply, return the good/bad news... */
5030   W (ret);
5031   return ret;
5032 }
5033
5034 static int
5035 api_sw_interface_add_del_address (vat_main_t * vam)
5036 {
5037   unformat_input_t *i = vam->input;
5038   vl_api_sw_interface_add_del_address_t *mp;
5039   u32 sw_if_index;
5040   u8 sw_if_index_set = 0;
5041   u8 is_add = 1, del_all = 0;
5042   u32 address_length = 0;
5043   u8 v4_address_set = 0;
5044   u8 v6_address_set = 0;
5045   ip4_address_t v4address;
5046   ip6_address_t v6address;
5047   int ret;
5048
5049   /* Parse args required to build the message */
5050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5051     {
5052       if (unformat (i, "del-all"))
5053         del_all = 1;
5054       else if (unformat (i, "del"))
5055         is_add = 0;
5056       else
5057         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5058         sw_if_index_set = 1;
5059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5060         sw_if_index_set = 1;
5061       else if (unformat (i, "%U/%d",
5062                          unformat_ip4_address, &v4address, &address_length))
5063         v4_address_set = 1;
5064       else if (unformat (i, "%U/%d",
5065                          unformat_ip6_address, &v6address, &address_length))
5066         v6_address_set = 1;
5067       else
5068         break;
5069     }
5070
5071   if (sw_if_index_set == 0)
5072     {
5073       errmsg ("missing interface name or sw_if_index");
5074       return -99;
5075     }
5076   if (v4_address_set && v6_address_set)
5077     {
5078       errmsg ("both v4 and v6 addresses set");
5079       return -99;
5080     }
5081   if (!v4_address_set && !v6_address_set && !del_all)
5082     {
5083       errmsg ("no addresses set");
5084       return -99;
5085     }
5086
5087   /* Construct the API message */
5088   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5089
5090   mp->sw_if_index = ntohl (sw_if_index);
5091   mp->is_add = is_add;
5092   mp->del_all = del_all;
5093   if (v6_address_set)
5094     {
5095       mp->is_ipv6 = 1;
5096       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5097     }
5098   else
5099     {
5100       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5101     }
5102   mp->address_length = address_length;
5103
5104   /* send it... */
5105   S (mp);
5106
5107   /* Wait for a reply, return good/bad news  */
5108   W (ret);
5109   return ret;
5110 }
5111
5112 static int
5113 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5114 {
5115   unformat_input_t *i = vam->input;
5116   vl_api_sw_interface_set_mpls_enable_t *mp;
5117   u32 sw_if_index;
5118   u8 sw_if_index_set = 0;
5119   u8 enable = 1;
5120   int ret;
5121
5122   /* Parse args required to build the message */
5123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5124     {
5125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5126         sw_if_index_set = 1;
5127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5128         sw_if_index_set = 1;
5129       else if (unformat (i, "disable"))
5130         enable = 0;
5131       else if (unformat (i, "dis"))
5132         enable = 0;
5133       else
5134         break;
5135     }
5136
5137   if (sw_if_index_set == 0)
5138     {
5139       errmsg ("missing interface name or sw_if_index");
5140       return -99;
5141     }
5142
5143   /* Construct the API message */
5144   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5145
5146   mp->sw_if_index = ntohl (sw_if_index);
5147   mp->enable = enable;
5148
5149   /* send it... */
5150   S (mp);
5151
5152   /* Wait for a reply... */
5153   W (ret);
5154   return ret;
5155 }
5156
5157 static int
5158 api_sw_interface_set_table (vat_main_t * vam)
5159 {
5160   unformat_input_t *i = vam->input;
5161   vl_api_sw_interface_set_table_t *mp;
5162   u32 sw_if_index, vrf_id = 0;
5163   u8 sw_if_index_set = 0;
5164   u8 is_ipv6 = 0;
5165   int ret;
5166
5167   /* Parse args required to build the message */
5168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5169     {
5170       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5171         sw_if_index_set = 1;
5172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5173         sw_if_index_set = 1;
5174       else if (unformat (i, "vrf %d", &vrf_id))
5175         ;
5176       else if (unformat (i, "ipv6"))
5177         is_ipv6 = 1;
5178       else
5179         break;
5180     }
5181
5182   if (sw_if_index_set == 0)
5183     {
5184       errmsg ("missing interface name or sw_if_index");
5185       return -99;
5186     }
5187
5188   /* Construct the API message */
5189   M (SW_INTERFACE_SET_TABLE, mp);
5190
5191   mp->sw_if_index = ntohl (sw_if_index);
5192   mp->is_ipv6 = is_ipv6;
5193   mp->vrf_id = ntohl (vrf_id);
5194
5195   /* send it... */
5196   S (mp);
5197
5198   /* Wait for a reply... */
5199   W (ret);
5200   return ret;
5201 }
5202
5203 static void vl_api_sw_interface_get_table_reply_t_handler
5204   (vl_api_sw_interface_get_table_reply_t * mp)
5205 {
5206   vat_main_t *vam = &vat_main;
5207
5208   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5209
5210   vam->retval = ntohl (mp->retval);
5211   vam->result_ready = 1;
5212
5213 }
5214
5215 static void vl_api_sw_interface_get_table_reply_t_handler_json
5216   (vl_api_sw_interface_get_table_reply_t * mp)
5217 {
5218   vat_main_t *vam = &vat_main;
5219   vat_json_node_t node;
5220
5221   vat_json_init_object (&node);
5222   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5223   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5224
5225   vat_json_print (vam->ofp, &node);
5226   vat_json_free (&node);
5227
5228   vam->retval = ntohl (mp->retval);
5229   vam->result_ready = 1;
5230 }
5231
5232 static int
5233 api_sw_interface_get_table (vat_main_t * vam)
5234 {
5235   unformat_input_t *i = vam->input;
5236   vl_api_sw_interface_get_table_t *mp;
5237   u32 sw_if_index;
5238   u8 sw_if_index_set = 0;
5239   u8 is_ipv6 = 0;
5240   int ret;
5241
5242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5243     {
5244       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5245         sw_if_index_set = 1;
5246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5247         sw_if_index_set = 1;
5248       else if (unformat (i, "ipv6"))
5249         is_ipv6 = 1;
5250       else
5251         break;
5252     }
5253
5254   if (sw_if_index_set == 0)
5255     {
5256       errmsg ("missing interface name or sw_if_index");
5257       return -99;
5258     }
5259
5260   M (SW_INTERFACE_GET_TABLE, mp);
5261   mp->sw_if_index = htonl (sw_if_index);
5262   mp->is_ipv6 = is_ipv6;
5263
5264   S (mp);
5265   W (ret);
5266   return ret;
5267 }
5268
5269 static int
5270 api_sw_interface_set_vpath (vat_main_t * vam)
5271 {
5272   unformat_input_t *i = vam->input;
5273   vl_api_sw_interface_set_vpath_t *mp;
5274   u32 sw_if_index = 0;
5275   u8 sw_if_index_set = 0;
5276   u8 is_enable = 0;
5277   int ret;
5278
5279   /* Parse args required to build the message */
5280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5281     {
5282       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5283         sw_if_index_set = 1;
5284       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5285         sw_if_index_set = 1;
5286       else if (unformat (i, "enable"))
5287         is_enable = 1;
5288       else if (unformat (i, "disable"))
5289         is_enable = 0;
5290       else
5291         break;
5292     }
5293
5294   if (sw_if_index_set == 0)
5295     {
5296       errmsg ("missing interface name or sw_if_index");
5297       return -99;
5298     }
5299
5300   /* Construct the API message */
5301   M (SW_INTERFACE_SET_VPATH, mp);
5302
5303   mp->sw_if_index = ntohl (sw_if_index);
5304   mp->enable = is_enable;
5305
5306   /* send it... */
5307   S (mp);
5308
5309   /* Wait for a reply... */
5310   W (ret);
5311   return ret;
5312 }
5313
5314 static int
5315 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5316 {
5317   unformat_input_t *i = vam->input;
5318   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5319   u32 sw_if_index = 0;
5320   u8 sw_if_index_set = 0;
5321   u8 is_enable = 1;
5322   u8 is_ipv6 = 0;
5323   int ret;
5324
5325   /* Parse args required to build the message */
5326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5327     {
5328       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5329         sw_if_index_set = 1;
5330       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5331         sw_if_index_set = 1;
5332       else if (unformat (i, "enable"))
5333         is_enable = 1;
5334       else if (unformat (i, "disable"))
5335         is_enable = 0;
5336       else if (unformat (i, "ip4"))
5337         is_ipv6 = 0;
5338       else if (unformat (i, "ip6"))
5339         is_ipv6 = 1;
5340       else
5341         break;
5342     }
5343
5344   if (sw_if_index_set == 0)
5345     {
5346       errmsg ("missing interface name or sw_if_index");
5347       return -99;
5348     }
5349
5350   /* Construct the API message */
5351   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5352
5353   mp->sw_if_index = ntohl (sw_if_index);
5354   mp->enable = is_enable;
5355   mp->is_ipv6 = is_ipv6;
5356
5357   /* send it... */
5358   S (mp);
5359
5360   /* Wait for a reply... */
5361   W (ret);
5362   return ret;
5363 }
5364
5365 static int
5366 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5367 {
5368   unformat_input_t *i = vam->input;
5369   vl_api_sw_interface_set_l2_xconnect_t *mp;
5370   u32 rx_sw_if_index;
5371   u8 rx_sw_if_index_set = 0;
5372   u32 tx_sw_if_index;
5373   u8 tx_sw_if_index_set = 0;
5374   u8 enable = 1;
5375   int ret;
5376
5377   /* Parse args required to build the message */
5378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5379     {
5380       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5381         rx_sw_if_index_set = 1;
5382       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5383         tx_sw_if_index_set = 1;
5384       else if (unformat (i, "rx"))
5385         {
5386           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5387             {
5388               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5389                             &rx_sw_if_index))
5390                 rx_sw_if_index_set = 1;
5391             }
5392           else
5393             break;
5394         }
5395       else if (unformat (i, "tx"))
5396         {
5397           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5398             {
5399               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5400                             &tx_sw_if_index))
5401                 tx_sw_if_index_set = 1;
5402             }
5403           else
5404             break;
5405         }
5406       else if (unformat (i, "enable"))
5407         enable = 1;
5408       else if (unformat (i, "disable"))
5409         enable = 0;
5410       else
5411         break;
5412     }
5413
5414   if (rx_sw_if_index_set == 0)
5415     {
5416       errmsg ("missing rx interface name or rx_sw_if_index");
5417       return -99;
5418     }
5419
5420   if (enable && (tx_sw_if_index_set == 0))
5421     {
5422       errmsg ("missing tx interface name or tx_sw_if_index");
5423       return -99;
5424     }
5425
5426   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5427
5428   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5429   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5430   mp->enable = enable;
5431
5432   S (mp);
5433   W (ret);
5434   return ret;
5435 }
5436
5437 static int
5438 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5439 {
5440   unformat_input_t *i = vam->input;
5441   vl_api_sw_interface_set_l2_bridge_t *mp;
5442   u32 rx_sw_if_index;
5443   u8 rx_sw_if_index_set = 0;
5444   u32 bd_id;
5445   u8 bd_id_set = 0;
5446   u8 bvi = 0;
5447   u32 shg = 0;
5448   u8 enable = 1;
5449   int ret;
5450
5451   /* Parse args required to build the message */
5452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5453     {
5454       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5455         rx_sw_if_index_set = 1;
5456       else if (unformat (i, "bd_id %d", &bd_id))
5457         bd_id_set = 1;
5458       else
5459         if (unformat
5460             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5461         rx_sw_if_index_set = 1;
5462       else if (unformat (i, "shg %d", &shg))
5463         ;
5464       else if (unformat (i, "bvi"))
5465         bvi = 1;
5466       else if (unformat (i, "enable"))
5467         enable = 1;
5468       else if (unformat (i, "disable"))
5469         enable = 0;
5470       else
5471         break;
5472     }
5473
5474   if (rx_sw_if_index_set == 0)
5475     {
5476       errmsg ("missing rx interface name or sw_if_index");
5477       return -99;
5478     }
5479
5480   if (enable && (bd_id_set == 0))
5481     {
5482       errmsg ("missing bridge domain");
5483       return -99;
5484     }
5485
5486   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5487
5488   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5489   mp->bd_id = ntohl (bd_id);
5490   mp->shg = (u8) shg;
5491   mp->bvi = bvi;
5492   mp->enable = enable;
5493
5494   S (mp);
5495   W (ret);
5496   return ret;
5497 }
5498
5499 static int
5500 api_bridge_domain_dump (vat_main_t * vam)
5501 {
5502   unformat_input_t *i = vam->input;
5503   vl_api_bridge_domain_dump_t *mp;
5504   vl_api_control_ping_t *mp_ping;
5505   u32 bd_id = ~0;
5506   int ret;
5507
5508   /* Parse args required to build the message */
5509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5510     {
5511       if (unformat (i, "bd_id %d", &bd_id))
5512         ;
5513       else
5514         break;
5515     }
5516
5517   M (BRIDGE_DOMAIN_DUMP, mp);
5518   mp->bd_id = ntohl (bd_id);
5519   S (mp);
5520
5521   /* Use a control ping for synchronization */
5522   M (CONTROL_PING, mp_ping);
5523   S (mp_ping);
5524
5525   W (ret);
5526   return ret;
5527 }
5528
5529 static int
5530 api_bridge_domain_add_del (vat_main_t * vam)
5531 {
5532   unformat_input_t *i = vam->input;
5533   vl_api_bridge_domain_add_del_t *mp;
5534   u32 bd_id = ~0;
5535   u8 is_add = 1;
5536   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5537   u32 mac_age = 0;
5538   int ret;
5539
5540   /* Parse args required to build the message */
5541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5542     {
5543       if (unformat (i, "bd_id %d", &bd_id))
5544         ;
5545       else if (unformat (i, "flood %d", &flood))
5546         ;
5547       else if (unformat (i, "uu-flood %d", &uu_flood))
5548         ;
5549       else if (unformat (i, "forward %d", &forward))
5550         ;
5551       else if (unformat (i, "learn %d", &learn))
5552         ;
5553       else if (unformat (i, "arp-term %d", &arp_term))
5554         ;
5555       else if (unformat (i, "mac-age %d", &mac_age))
5556         ;
5557       else if (unformat (i, "del"))
5558         {
5559           is_add = 0;
5560           flood = uu_flood = forward = learn = 0;
5561         }
5562       else
5563         break;
5564     }
5565
5566   if (bd_id == ~0)
5567     {
5568       errmsg ("missing bridge domain");
5569       return -99;
5570     }
5571
5572   if (mac_age > 255)
5573     {
5574       errmsg ("mac age must be less than 256 ");
5575       return -99;
5576     }
5577
5578   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5579
5580   mp->bd_id = ntohl (bd_id);
5581   mp->flood = flood;
5582   mp->uu_flood = uu_flood;
5583   mp->forward = forward;
5584   mp->learn = learn;
5585   mp->arp_term = arp_term;
5586   mp->is_add = is_add;
5587   mp->mac_age = (u8) mac_age;
5588
5589   S (mp);
5590   W (ret);
5591   return ret;
5592 }
5593
5594 static int
5595 api_l2fib_add_del (vat_main_t * vam)
5596 {
5597   unformat_input_t *i = vam->input;
5598   vl_api_l2fib_add_del_t *mp;
5599   f64 timeout;
5600   u64 mac = 0;
5601   u8 mac_set = 0;
5602   u32 bd_id;
5603   u8 bd_id_set = 0;
5604   u32 sw_if_index = ~0;
5605   u8 sw_if_index_set = 0;
5606   u8 is_add = 1;
5607   u8 static_mac = 0;
5608   u8 filter_mac = 0;
5609   u8 bvi_mac = 0;
5610   int count = 1;
5611   f64 before = 0;
5612   int j;
5613
5614   /* Parse args required to build the message */
5615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5616     {
5617       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5618         mac_set = 1;
5619       else if (unformat (i, "bd_id %d", &bd_id))
5620         bd_id_set = 1;
5621       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5622         sw_if_index_set = 1;
5623       else if (unformat (i, "sw_if"))
5624         {
5625           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5626             {
5627               if (unformat
5628                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5629                 sw_if_index_set = 1;
5630             }
5631           else
5632             break;
5633         }
5634       else if (unformat (i, "static"))
5635         static_mac = 1;
5636       else if (unformat (i, "filter"))
5637         {
5638           filter_mac = 1;
5639           static_mac = 1;
5640         }
5641       else if (unformat (i, "bvi"))
5642         {
5643           bvi_mac = 1;
5644           static_mac = 1;
5645         }
5646       else if (unformat (i, "del"))
5647         is_add = 0;
5648       else if (unformat (i, "count %d", &count))
5649         ;
5650       else
5651         break;
5652     }
5653
5654   if (mac_set == 0)
5655     {
5656       errmsg ("missing mac address");
5657       return -99;
5658     }
5659
5660   if (bd_id_set == 0)
5661     {
5662       errmsg ("missing bridge domain");
5663       return -99;
5664     }
5665
5666   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5667     {
5668       errmsg ("missing interface name or sw_if_index");
5669       return -99;
5670     }
5671
5672   if (count > 1)
5673     {
5674       /* Turn on async mode */
5675       vam->async_mode = 1;
5676       vam->async_errors = 0;
5677       before = vat_time_now (vam);
5678     }
5679
5680   for (j = 0; j < count; j++)
5681     {
5682       M (L2FIB_ADD_DEL, mp);
5683
5684       mp->mac = mac;
5685       mp->bd_id = ntohl (bd_id);
5686       mp->is_add = is_add;
5687
5688       if (is_add)
5689         {
5690           mp->sw_if_index = ntohl (sw_if_index);
5691           mp->static_mac = static_mac;
5692           mp->filter_mac = filter_mac;
5693           mp->bvi_mac = bvi_mac;
5694         }
5695       increment_mac_address (&mac);
5696       /* send it... */
5697       S (mp);
5698     }
5699
5700   if (count > 1)
5701     {
5702       vl_api_control_ping_t *mp_ping;
5703       f64 after;
5704
5705       /* Shut off async mode */
5706       vam->async_mode = 0;
5707
5708       M (CONTROL_PING, mp_ping);
5709       S (mp_ping);
5710
5711       timeout = vat_time_now (vam) + 1.0;
5712       while (vat_time_now (vam) < timeout)
5713         if (vam->result_ready == 1)
5714           goto out;
5715       vam->retval = -99;
5716
5717     out:
5718       if (vam->retval == -99)
5719         errmsg ("timeout");
5720
5721       if (vam->async_errors > 0)
5722         {
5723           errmsg ("%d asynchronous errors", vam->async_errors);
5724           vam->retval = -98;
5725         }
5726       vam->async_errors = 0;
5727       after = vat_time_now (vam);
5728
5729       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5730              count, after - before, count / (after - before));
5731     }
5732   else
5733     {
5734       int ret;
5735
5736       /* Wait for a reply... */
5737       W (ret);
5738       return ret;
5739     }
5740   /* Return the good/bad news */
5741   return (vam->retval);
5742 }
5743
5744 static int
5745 api_l2_flags (vat_main_t * vam)
5746 {
5747   unformat_input_t *i = vam->input;
5748   vl_api_l2_flags_t *mp;
5749   u32 sw_if_index;
5750   u32 feature_bitmap = 0;
5751   u8 sw_if_index_set = 0;
5752   int ret;
5753
5754   /* Parse args required to build the message */
5755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5756     {
5757       if (unformat (i, "sw_if_index %d", &sw_if_index))
5758         sw_if_index_set = 1;
5759       else if (unformat (i, "sw_if"))
5760         {
5761           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5762             {
5763               if (unformat
5764                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5765                 sw_if_index_set = 1;
5766             }
5767           else
5768             break;
5769         }
5770       else if (unformat (i, "learn"))
5771         feature_bitmap |= L2INPUT_FEAT_LEARN;
5772       else if (unformat (i, "forward"))
5773         feature_bitmap |= L2INPUT_FEAT_FWD;
5774       else if (unformat (i, "flood"))
5775         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5776       else if (unformat (i, "uu-flood"))
5777         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5778       else
5779         break;
5780     }
5781
5782   if (sw_if_index_set == 0)
5783     {
5784       errmsg ("missing interface name or sw_if_index");
5785       return -99;
5786     }
5787
5788   M (L2_FLAGS, mp);
5789
5790   mp->sw_if_index = ntohl (sw_if_index);
5791   mp->feature_bitmap = ntohl (feature_bitmap);
5792
5793   S (mp);
5794   W (ret);
5795   return ret;
5796 }
5797
5798 static int
5799 api_bridge_flags (vat_main_t * vam)
5800 {
5801   unformat_input_t *i = vam->input;
5802   vl_api_bridge_flags_t *mp;
5803   u32 bd_id;
5804   u8 bd_id_set = 0;
5805   u8 is_set = 1;
5806   u32 flags = 0;
5807   int ret;
5808
5809   /* Parse args required to build the message */
5810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5811     {
5812       if (unformat (i, "bd_id %d", &bd_id))
5813         bd_id_set = 1;
5814       else if (unformat (i, "learn"))
5815         flags |= L2_LEARN;
5816       else if (unformat (i, "forward"))
5817         flags |= L2_FWD;
5818       else if (unformat (i, "flood"))
5819         flags |= L2_FLOOD;
5820       else if (unformat (i, "uu-flood"))
5821         flags |= L2_UU_FLOOD;
5822       else if (unformat (i, "arp-term"))
5823         flags |= L2_ARP_TERM;
5824       else if (unformat (i, "off"))
5825         is_set = 0;
5826       else if (unformat (i, "disable"))
5827         is_set = 0;
5828       else
5829         break;
5830     }
5831
5832   if (bd_id_set == 0)
5833     {
5834       errmsg ("missing bridge domain");
5835       return -99;
5836     }
5837
5838   M (BRIDGE_FLAGS, mp);
5839
5840   mp->bd_id = ntohl (bd_id);
5841   mp->feature_bitmap = ntohl (flags);
5842   mp->is_set = is_set;
5843
5844   S (mp);
5845   W (ret);
5846   return ret;
5847 }
5848
5849 static int
5850 api_bd_ip_mac_add_del (vat_main_t * vam)
5851 {
5852   unformat_input_t *i = vam->input;
5853   vl_api_bd_ip_mac_add_del_t *mp;
5854   u32 bd_id;
5855   u8 is_ipv6 = 0;
5856   u8 is_add = 1;
5857   u8 bd_id_set = 0;
5858   u8 ip_set = 0;
5859   u8 mac_set = 0;
5860   ip4_address_t v4addr;
5861   ip6_address_t v6addr;
5862   u8 macaddr[6];
5863   int ret;
5864
5865
5866   /* Parse args required to build the message */
5867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5868     {
5869       if (unformat (i, "bd_id %d", &bd_id))
5870         {
5871           bd_id_set++;
5872         }
5873       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5874         {
5875           ip_set++;
5876         }
5877       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5878         {
5879           ip_set++;
5880           is_ipv6++;
5881         }
5882       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5883         {
5884           mac_set++;
5885         }
5886       else if (unformat (i, "del"))
5887         is_add = 0;
5888       else
5889         break;
5890     }
5891
5892   if (bd_id_set == 0)
5893     {
5894       errmsg ("missing bridge domain");
5895       return -99;
5896     }
5897   else if (ip_set == 0)
5898     {
5899       errmsg ("missing IP address");
5900       return -99;
5901     }
5902   else if (mac_set == 0)
5903     {
5904       errmsg ("missing MAC address");
5905       return -99;
5906     }
5907
5908   M (BD_IP_MAC_ADD_DEL, mp);
5909
5910   mp->bd_id = ntohl (bd_id);
5911   mp->is_ipv6 = is_ipv6;
5912   mp->is_add = is_add;
5913   if (is_ipv6)
5914     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5915   else
5916     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5917   clib_memcpy (mp->mac_address, macaddr, 6);
5918   S (mp);
5919   W (ret);
5920   return ret;
5921 }
5922
5923 static int
5924 api_tap_connect (vat_main_t * vam)
5925 {
5926   unformat_input_t *i = vam->input;
5927   vl_api_tap_connect_t *mp;
5928   u8 mac_address[6];
5929   u8 random_mac = 1;
5930   u8 name_set = 0;
5931   u8 *tap_name;
5932   u8 *tag = 0;
5933   ip4_address_t ip4_address;
5934   u32 ip4_mask_width;
5935   int ip4_address_set = 0;
5936   ip6_address_t ip6_address;
5937   u32 ip6_mask_width;
5938   int ip6_address_set = 0;
5939   int ret;
5940
5941   memset (mac_address, 0, sizeof (mac_address));
5942
5943   /* Parse args required to build the message */
5944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5945     {
5946       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5947         {
5948           random_mac = 0;
5949         }
5950       else if (unformat (i, "random-mac"))
5951         random_mac = 1;
5952       else if (unformat (i, "tapname %s", &tap_name))
5953         name_set = 1;
5954       else if (unformat (i, "tag %s", &tag))
5955         ;
5956       else if (unformat (i, "address %U/%d",
5957                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
5958         ip4_address_set = 1;
5959       else if (unformat (i, "address %U/%d",
5960                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
5961         ip6_address_set = 1;
5962       else
5963         break;
5964     }
5965
5966   if (name_set == 0)
5967     {
5968       errmsg ("missing tap name");
5969       return -99;
5970     }
5971   if (vec_len (tap_name) > 63)
5972     {
5973       errmsg ("tap name too long");
5974       return -99;
5975     }
5976   vec_add1 (tap_name, 0);
5977
5978   if (vec_len (tag) > 63)
5979     {
5980       errmsg ("tag too long");
5981       return -99;
5982     }
5983
5984   /* Construct the API message */
5985   M (TAP_CONNECT, mp);
5986
5987   mp->use_random_mac = random_mac;
5988   clib_memcpy (mp->mac_address, mac_address, 6);
5989   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5990   if (tag)
5991     clib_memcpy (mp->tag, tag, vec_len (tag));
5992
5993   if (ip4_address_set)
5994     {
5995       mp->ip4_address_set = 1;
5996       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
5997       mp->ip4_mask_width = ip4_mask_width;
5998     }
5999   if (ip6_address_set)
6000     {
6001       mp->ip6_address_set = 1;
6002       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6003       mp->ip6_mask_width = ip6_mask_width;
6004     }
6005
6006   vec_free (tap_name);
6007   vec_free (tag);
6008
6009   /* send it... */
6010   S (mp);
6011
6012   /* Wait for a reply... */
6013   W (ret);
6014   return ret;
6015 }
6016
6017 static int
6018 api_tap_modify (vat_main_t * vam)
6019 {
6020   unformat_input_t *i = vam->input;
6021   vl_api_tap_modify_t *mp;
6022   u8 mac_address[6];
6023   u8 random_mac = 1;
6024   u8 name_set = 0;
6025   u8 *tap_name;
6026   u32 sw_if_index = ~0;
6027   u8 sw_if_index_set = 0;
6028   int ret;
6029
6030   memset (mac_address, 0, sizeof (mac_address));
6031
6032   /* Parse args required to build the message */
6033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6034     {
6035       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6036         sw_if_index_set = 1;
6037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6038         sw_if_index_set = 1;
6039       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6040         {
6041           random_mac = 0;
6042         }
6043       else if (unformat (i, "random-mac"))
6044         random_mac = 1;
6045       else if (unformat (i, "tapname %s", &tap_name))
6046         name_set = 1;
6047       else
6048         break;
6049     }
6050
6051   if (sw_if_index_set == 0)
6052     {
6053       errmsg ("missing vpp interface name");
6054       return -99;
6055     }
6056   if (name_set == 0)
6057     {
6058       errmsg ("missing tap name");
6059       return -99;
6060     }
6061   if (vec_len (tap_name) > 63)
6062     {
6063       errmsg ("tap name too long");
6064     }
6065   vec_add1 (tap_name, 0);
6066
6067   /* Construct the API message */
6068   M (TAP_MODIFY, mp);
6069
6070   mp->use_random_mac = random_mac;
6071   mp->sw_if_index = ntohl (sw_if_index);
6072   clib_memcpy (mp->mac_address, mac_address, 6);
6073   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6074   vec_free (tap_name);
6075
6076   /* send it... */
6077   S (mp);
6078
6079   /* Wait for a reply... */
6080   W (ret);
6081   return ret;
6082 }
6083
6084 static int
6085 api_tap_delete (vat_main_t * vam)
6086 {
6087   unformat_input_t *i = vam->input;
6088   vl_api_tap_delete_t *mp;
6089   u32 sw_if_index = ~0;
6090   u8 sw_if_index_set = 0;
6091   int ret;
6092
6093   /* Parse args required to build the message */
6094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6095     {
6096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6097         sw_if_index_set = 1;
6098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6099         sw_if_index_set = 1;
6100       else
6101         break;
6102     }
6103
6104   if (sw_if_index_set == 0)
6105     {
6106       errmsg ("missing vpp interface name");
6107       return -99;
6108     }
6109
6110   /* Construct the API message */
6111   M (TAP_DELETE, mp);
6112
6113   mp->sw_if_index = ntohl (sw_if_index);
6114
6115   /* send it... */
6116   S (mp);
6117
6118   /* Wait for a reply... */
6119   W (ret);
6120   return ret;
6121 }
6122
6123 static int
6124 api_ip_add_del_route (vat_main_t * vam)
6125 {
6126   unformat_input_t *i = vam->input;
6127   vl_api_ip_add_del_route_t *mp;
6128   u32 sw_if_index = ~0, vrf_id = 0;
6129   u8 is_ipv6 = 0;
6130   u8 is_local = 0, is_drop = 0;
6131   u8 is_unreach = 0, is_prohibit = 0;
6132   u8 create_vrf_if_needed = 0;
6133   u8 is_add = 1;
6134   u32 next_hop_weight = 1;
6135   u8 not_last = 0;
6136   u8 is_multipath = 0;
6137   u8 address_set = 0;
6138   u8 address_length_set = 0;
6139   u32 next_hop_table_id = 0;
6140   u32 resolve_attempts = 0;
6141   u32 dst_address_length = 0;
6142   u8 next_hop_set = 0;
6143   ip4_address_t v4_dst_address, v4_next_hop_address;
6144   ip6_address_t v6_dst_address, v6_next_hop_address;
6145   int count = 1;
6146   int j;
6147   f64 before = 0;
6148   u32 random_add_del = 0;
6149   u32 *random_vector = 0;
6150   uword *random_hash;
6151   u32 random_seed = 0xdeaddabe;
6152   u32 classify_table_index = ~0;
6153   u8 is_classify = 0;
6154   u8 resolve_host = 0, resolve_attached = 0;
6155   mpls_label_t *next_hop_out_label_stack = NULL;
6156   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6157   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6158
6159   /* Parse args required to build the message */
6160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6161     {
6162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6163         ;
6164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6165         ;
6166       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6167         {
6168           address_set = 1;
6169           is_ipv6 = 0;
6170         }
6171       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6172         {
6173           address_set = 1;
6174           is_ipv6 = 1;
6175         }
6176       else if (unformat (i, "/%d", &dst_address_length))
6177         {
6178           address_length_set = 1;
6179         }
6180
6181       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6182                                          &v4_next_hop_address))
6183         {
6184           next_hop_set = 1;
6185         }
6186       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6187                                          &v6_next_hop_address))
6188         {
6189           next_hop_set = 1;
6190         }
6191       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6192         ;
6193       else if (unformat (i, "weight %d", &next_hop_weight))
6194         ;
6195       else if (unformat (i, "drop"))
6196         {
6197           is_drop = 1;
6198         }
6199       else if (unformat (i, "null-send-unreach"))
6200         {
6201           is_unreach = 1;
6202         }
6203       else if (unformat (i, "null-send-prohibit"))
6204         {
6205           is_prohibit = 1;
6206         }
6207       else if (unformat (i, "local"))
6208         {
6209           is_local = 1;
6210         }
6211       else if (unformat (i, "classify %d", &classify_table_index))
6212         {
6213           is_classify = 1;
6214         }
6215       else if (unformat (i, "del"))
6216         is_add = 0;
6217       else if (unformat (i, "add"))
6218         is_add = 1;
6219       else if (unformat (i, "not-last"))
6220         not_last = 1;
6221       else if (unformat (i, "resolve-via-host"))
6222         resolve_host = 1;
6223       else if (unformat (i, "resolve-via-attached"))
6224         resolve_attached = 1;
6225       else if (unformat (i, "multipath"))
6226         is_multipath = 1;
6227       else if (unformat (i, "vrf %d", &vrf_id))
6228         ;
6229       else if (unformat (i, "create-vrf"))
6230         create_vrf_if_needed = 1;
6231       else if (unformat (i, "count %d", &count))
6232         ;
6233       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6234         ;
6235       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6236         ;
6237       else if (unformat (i, "out-label %d", &next_hop_out_label))
6238         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6239       else if (unformat (i, "via-label %d", &next_hop_via_label))
6240         ;
6241       else if (unformat (i, "random"))
6242         random_add_del = 1;
6243       else if (unformat (i, "seed %d", &random_seed))
6244         ;
6245       else
6246         {
6247           clib_warning ("parse error '%U'", format_unformat_error, i);
6248           return -99;
6249         }
6250     }
6251
6252   if (!next_hop_set && !is_drop && !is_local &&
6253       !is_classify && !is_unreach && !is_prohibit &&
6254       MPLS_LABEL_INVALID == next_hop_via_label)
6255     {
6256       errmsg
6257         ("next hop / local / drop / unreach / prohibit / classify not set");
6258       return -99;
6259     }
6260
6261   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6262     {
6263       errmsg ("next hop and next-hop via label set");
6264       return -99;
6265     }
6266   if (address_set == 0)
6267     {
6268       errmsg ("missing addresses");
6269       return -99;
6270     }
6271
6272   if (address_length_set == 0)
6273     {
6274       errmsg ("missing address length");
6275       return -99;
6276     }
6277
6278   /* Generate a pile of unique, random routes */
6279   if (random_add_del)
6280     {
6281       u32 this_random_address;
6282       random_hash = hash_create (count, sizeof (uword));
6283
6284       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6285       for (j = 0; j <= count; j++)
6286         {
6287           do
6288             {
6289               this_random_address = random_u32 (&random_seed);
6290               this_random_address =
6291                 clib_host_to_net_u32 (this_random_address);
6292             }
6293           while (hash_get (random_hash, this_random_address));
6294           vec_add1 (random_vector, this_random_address);
6295           hash_set (random_hash, this_random_address, 1);
6296         }
6297       hash_free (random_hash);
6298       v4_dst_address.as_u32 = random_vector[0];
6299     }
6300
6301   if (count > 1)
6302     {
6303       /* Turn on async mode */
6304       vam->async_mode = 1;
6305       vam->async_errors = 0;
6306       before = vat_time_now (vam);
6307     }
6308
6309   for (j = 0; j < count; j++)
6310     {
6311       /* Construct the API message */
6312       M2 (IP_ADD_DEL_ROUTE, mp,
6313           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6314
6315       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6316       mp->table_id = ntohl (vrf_id);
6317       mp->create_vrf_if_needed = create_vrf_if_needed;
6318
6319       mp->is_add = is_add;
6320       mp->is_drop = is_drop;
6321       mp->is_unreach = is_unreach;
6322       mp->is_prohibit = is_prohibit;
6323       mp->is_ipv6 = is_ipv6;
6324       mp->is_local = is_local;
6325       mp->is_classify = is_classify;
6326       mp->is_multipath = is_multipath;
6327       mp->is_resolve_host = resolve_host;
6328       mp->is_resolve_attached = resolve_attached;
6329       mp->not_last = not_last;
6330       mp->next_hop_weight = next_hop_weight;
6331       mp->dst_address_length = dst_address_length;
6332       mp->next_hop_table_id = ntohl (next_hop_table_id);
6333       mp->classify_table_index = ntohl (classify_table_index);
6334       mp->next_hop_via_label = ntohl (next_hop_via_label);
6335       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6336       if (0 != mp->next_hop_n_out_labels)
6337         {
6338           memcpy (mp->next_hop_out_label_stack,
6339                   next_hop_out_label_stack,
6340                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6341           vec_free (next_hop_out_label_stack);
6342         }
6343
6344       if (is_ipv6)
6345         {
6346           clib_memcpy (mp->dst_address, &v6_dst_address,
6347                        sizeof (v6_dst_address));
6348           if (next_hop_set)
6349             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6350                          sizeof (v6_next_hop_address));
6351           increment_v6_address (&v6_dst_address);
6352         }
6353       else
6354         {
6355           clib_memcpy (mp->dst_address, &v4_dst_address,
6356                        sizeof (v4_dst_address));
6357           if (next_hop_set)
6358             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6359                          sizeof (v4_next_hop_address));
6360           if (random_add_del)
6361             v4_dst_address.as_u32 = random_vector[j + 1];
6362           else
6363             increment_v4_address (&v4_dst_address);
6364         }
6365       /* send it... */
6366       S (mp);
6367       /* If we receive SIGTERM, stop now... */
6368       if (vam->do_exit)
6369         break;
6370     }
6371
6372   /* When testing multiple add/del ops, use a control-ping to sync */
6373   if (count > 1)
6374     {
6375       vl_api_control_ping_t *mp_ping;
6376       f64 after;
6377       f64 timeout;
6378
6379       /* Shut off async mode */
6380       vam->async_mode = 0;
6381
6382       M (CONTROL_PING, mp_ping);
6383       S (mp_ping);
6384
6385       timeout = vat_time_now (vam) + 1.0;
6386       while (vat_time_now (vam) < timeout)
6387         if (vam->result_ready == 1)
6388           goto out;
6389       vam->retval = -99;
6390
6391     out:
6392       if (vam->retval == -99)
6393         errmsg ("timeout");
6394
6395       if (vam->async_errors > 0)
6396         {
6397           errmsg ("%d asynchronous errors", vam->async_errors);
6398           vam->retval = -98;
6399         }
6400       vam->async_errors = 0;
6401       after = vat_time_now (vam);
6402
6403       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6404       if (j > 0)
6405         count = j;
6406
6407       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6408              count, after - before, count / (after - before));
6409     }
6410   else
6411     {
6412       int ret;
6413
6414       /* Wait for a reply... */
6415       W (ret);
6416       return ret;
6417     }
6418
6419   /* Return the good/bad news */
6420   return (vam->retval);
6421 }
6422
6423 static int
6424 api_ip_mroute_add_del (vat_main_t * vam)
6425 {
6426   unformat_input_t *i = vam->input;
6427   vl_api_ip_mroute_add_del_t *mp;
6428   u32 sw_if_index = ~0, vrf_id = 0;
6429   u8 is_ipv6 = 0;
6430   u8 is_local = 0;
6431   u8 create_vrf_if_needed = 0;
6432   u8 is_add = 1;
6433   u8 address_set = 0;
6434   u32 grp_address_length = 0;
6435   ip4_address_t v4_grp_address, v4_src_address;
6436   ip6_address_t v6_grp_address, v6_src_address;
6437   mfib_itf_flags_t iflags = 0;
6438   mfib_entry_flags_t eflags = 0;
6439   int ret;
6440
6441   /* Parse args required to build the message */
6442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6443     {
6444       if (unformat (i, "sw_if_index %d", &sw_if_index))
6445         ;
6446       else if (unformat (i, "%U %U",
6447                          unformat_ip4_address, &v4_src_address,
6448                          unformat_ip4_address, &v4_grp_address))
6449         {
6450           grp_address_length = 64;
6451           address_set = 1;
6452           is_ipv6 = 0;
6453         }
6454       else if (unformat (i, "%U %U",
6455                          unformat_ip6_address, &v6_src_address,
6456                          unformat_ip6_address, &v6_grp_address))
6457         {
6458           grp_address_length = 256;
6459           address_set = 1;
6460           is_ipv6 = 1;
6461         }
6462       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6463         {
6464           memset (&v4_src_address, 0, sizeof (v4_src_address));
6465           grp_address_length = 32;
6466           address_set = 1;
6467           is_ipv6 = 0;
6468         }
6469       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6470         {
6471           memset (&v6_src_address, 0, sizeof (v6_src_address));
6472           grp_address_length = 128;
6473           address_set = 1;
6474           is_ipv6 = 1;
6475         }
6476       else if (unformat (i, "/%d", &grp_address_length))
6477         ;
6478       else if (unformat (i, "local"))
6479         {
6480           is_local = 1;
6481         }
6482       else if (unformat (i, "del"))
6483         is_add = 0;
6484       else if (unformat (i, "add"))
6485         is_add = 1;
6486       else if (unformat (i, "vrf %d", &vrf_id))
6487         ;
6488       else if (unformat (i, "create-vrf"))
6489         create_vrf_if_needed = 1;
6490       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6491         ;
6492       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6493         ;
6494       else
6495         {
6496           clib_warning ("parse error '%U'", format_unformat_error, i);
6497           return -99;
6498         }
6499     }
6500
6501   if (address_set == 0)
6502     {
6503       errmsg ("missing addresses\n");
6504       return -99;
6505     }
6506
6507   /* Construct the API message */
6508   M (IP_MROUTE_ADD_DEL, mp);
6509
6510   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6511   mp->table_id = ntohl (vrf_id);
6512   mp->create_vrf_if_needed = create_vrf_if_needed;
6513
6514   mp->is_add = is_add;
6515   mp->is_ipv6 = is_ipv6;
6516   mp->is_local = is_local;
6517   mp->itf_flags = ntohl (iflags);
6518   mp->entry_flags = ntohl (eflags);
6519   mp->grp_address_length = grp_address_length;
6520   mp->grp_address_length = ntohs (mp->grp_address_length);
6521
6522   if (is_ipv6)
6523     {
6524       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6525       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6526     }
6527   else
6528     {
6529       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6530       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6531
6532     }
6533
6534   /* send it... */
6535   S (mp);
6536   /* Wait for a reply... */
6537   W (ret);
6538   return ret;
6539 }
6540
6541 static int
6542 api_mpls_route_add_del (vat_main_t * vam)
6543 {
6544   unformat_input_t *i = vam->input;
6545   vl_api_mpls_route_add_del_t *mp;
6546   u32 sw_if_index = ~0, table_id = 0;
6547   u8 create_table_if_needed = 0;
6548   u8 is_add = 1;
6549   u32 next_hop_weight = 1;
6550   u8 is_multipath = 0;
6551   u32 next_hop_table_id = 0;
6552   u8 next_hop_set = 0;
6553   ip4_address_t v4_next_hop_address = {
6554     .as_u32 = 0,
6555   };
6556   ip6_address_t v6_next_hop_address = { {0} };
6557   int count = 1;
6558   int j;
6559   f64 before = 0;
6560   u32 classify_table_index = ~0;
6561   u8 is_classify = 0;
6562   u8 resolve_host = 0, resolve_attached = 0;
6563   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6564   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6565   mpls_label_t *next_hop_out_label_stack = NULL;
6566   mpls_label_t local_label = MPLS_LABEL_INVALID;
6567   u8 is_eos = 0;
6568   u8 next_hop_proto_is_ip4 = 1;
6569
6570   /* Parse args required to build the message */
6571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6572     {
6573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6574         ;
6575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6576         ;
6577       else if (unformat (i, "%d", &local_label))
6578         ;
6579       else if (unformat (i, "eos"))
6580         is_eos = 1;
6581       else if (unformat (i, "non-eos"))
6582         is_eos = 0;
6583       else if (unformat (i, "via %U", unformat_ip4_address,
6584                          &v4_next_hop_address))
6585         {
6586           next_hop_set = 1;
6587           next_hop_proto_is_ip4 = 1;
6588         }
6589       else if (unformat (i, "via %U", unformat_ip6_address,
6590                          &v6_next_hop_address))
6591         {
6592           next_hop_set = 1;
6593           next_hop_proto_is_ip4 = 0;
6594         }
6595       else if (unformat (i, "weight %d", &next_hop_weight))
6596         ;
6597       else if (unformat (i, "create-table"))
6598         create_table_if_needed = 1;
6599       else if (unformat (i, "classify %d", &classify_table_index))
6600         {
6601           is_classify = 1;
6602         }
6603       else if (unformat (i, "del"))
6604         is_add = 0;
6605       else if (unformat (i, "add"))
6606         is_add = 1;
6607       else if (unformat (i, "resolve-via-host"))
6608         resolve_host = 1;
6609       else if (unformat (i, "resolve-via-attached"))
6610         resolve_attached = 1;
6611       else if (unformat (i, "multipath"))
6612         is_multipath = 1;
6613       else if (unformat (i, "count %d", &count))
6614         ;
6615       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6616         {
6617           next_hop_set = 1;
6618           next_hop_proto_is_ip4 = 1;
6619         }
6620       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6621         {
6622           next_hop_set = 1;
6623           next_hop_proto_is_ip4 = 0;
6624         }
6625       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6626         ;
6627       else if (unformat (i, "via-label %d", &next_hop_via_label))
6628         ;
6629       else if (unformat (i, "out-label %d", &next_hop_out_label))
6630         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6631       else
6632         {
6633           clib_warning ("parse error '%U'", format_unformat_error, i);
6634           return -99;
6635         }
6636     }
6637
6638   if (!next_hop_set && !is_classify)
6639     {
6640       errmsg ("next hop / classify not set");
6641       return -99;
6642     }
6643
6644   if (MPLS_LABEL_INVALID == local_label)
6645     {
6646       errmsg ("missing label");
6647       return -99;
6648     }
6649
6650   if (count > 1)
6651     {
6652       /* Turn on async mode */
6653       vam->async_mode = 1;
6654       vam->async_errors = 0;
6655       before = vat_time_now (vam);
6656     }
6657
6658   for (j = 0; j < count; j++)
6659     {
6660       /* Construct the API message */
6661       M2 (MPLS_ROUTE_ADD_DEL, mp,
6662           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6663
6664       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6665       mp->mr_table_id = ntohl (table_id);
6666       mp->mr_create_table_if_needed = create_table_if_needed;
6667
6668       mp->mr_is_add = is_add;
6669       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6670       mp->mr_is_classify = is_classify;
6671       mp->mr_is_multipath = is_multipath;
6672       mp->mr_is_resolve_host = resolve_host;
6673       mp->mr_is_resolve_attached = resolve_attached;
6674       mp->mr_next_hop_weight = next_hop_weight;
6675       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6676       mp->mr_classify_table_index = ntohl (classify_table_index);
6677       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6678       mp->mr_label = ntohl (local_label);
6679       mp->mr_eos = is_eos;
6680
6681       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6682       if (0 != mp->mr_next_hop_n_out_labels)
6683         {
6684           memcpy (mp->mr_next_hop_out_label_stack,
6685                   next_hop_out_label_stack,
6686                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6687           vec_free (next_hop_out_label_stack);
6688         }
6689
6690       if (next_hop_set)
6691         {
6692           if (next_hop_proto_is_ip4)
6693             {
6694               clib_memcpy (mp->mr_next_hop,
6695                            &v4_next_hop_address,
6696                            sizeof (v4_next_hop_address));
6697             }
6698           else
6699             {
6700               clib_memcpy (mp->mr_next_hop,
6701                            &v6_next_hop_address,
6702                            sizeof (v6_next_hop_address));
6703             }
6704         }
6705       local_label++;
6706
6707       /* send it... */
6708       S (mp);
6709       /* If we receive SIGTERM, stop now... */
6710       if (vam->do_exit)
6711         break;
6712     }
6713
6714   /* When testing multiple add/del ops, use a control-ping to sync */
6715   if (count > 1)
6716     {
6717       vl_api_control_ping_t *mp_ping;
6718       f64 after;
6719       f64 timeout;
6720
6721       /* Shut off async mode */
6722       vam->async_mode = 0;
6723
6724       M (CONTROL_PING, mp_ping);
6725       S (mp_ping);
6726
6727       timeout = vat_time_now (vam) + 1.0;
6728       while (vat_time_now (vam) < timeout)
6729         if (vam->result_ready == 1)
6730           goto out;
6731       vam->retval = -99;
6732
6733     out:
6734       if (vam->retval == -99)
6735         errmsg ("timeout");
6736
6737       if (vam->async_errors > 0)
6738         {
6739           errmsg ("%d asynchronous errors", vam->async_errors);
6740           vam->retval = -98;
6741         }
6742       vam->async_errors = 0;
6743       after = vat_time_now (vam);
6744
6745       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6746       if (j > 0)
6747         count = j;
6748
6749       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6750              count, after - before, count / (after - before));
6751     }
6752   else
6753     {
6754       int ret;
6755
6756       /* Wait for a reply... */
6757       W (ret);
6758       return ret;
6759     }
6760
6761   /* Return the good/bad news */
6762   return (vam->retval);
6763 }
6764
6765 static int
6766 api_mpls_ip_bind_unbind (vat_main_t * vam)
6767 {
6768   unformat_input_t *i = vam->input;
6769   vl_api_mpls_ip_bind_unbind_t *mp;
6770   u32 ip_table_id = 0;
6771   u8 create_table_if_needed = 0;
6772   u8 is_bind = 1;
6773   u8 is_ip4 = 1;
6774   ip4_address_t v4_address;
6775   ip6_address_t v6_address;
6776   u32 address_length;
6777   u8 address_set = 0;
6778   mpls_label_t local_label = MPLS_LABEL_INVALID;
6779   int ret;
6780
6781   /* Parse args required to build the message */
6782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6783     {
6784       if (unformat (i, "%U/%d", unformat_ip4_address,
6785                     &v4_address, &address_length))
6786         {
6787           is_ip4 = 1;
6788           address_set = 1;
6789         }
6790       else if (unformat (i, "%U/%d", unformat_ip6_address,
6791                          &v6_address, &address_length))
6792         {
6793           is_ip4 = 0;
6794           address_set = 1;
6795         }
6796       else if (unformat (i, "%d", &local_label))
6797         ;
6798       else if (unformat (i, "create-table"))
6799         create_table_if_needed = 1;
6800       else if (unformat (i, "table-id %d", &ip_table_id))
6801         ;
6802       else if (unformat (i, "unbind"))
6803         is_bind = 0;
6804       else if (unformat (i, "bind"))
6805         is_bind = 1;
6806       else
6807         {
6808           clib_warning ("parse error '%U'", format_unformat_error, i);
6809           return -99;
6810         }
6811     }
6812
6813   if (!address_set)
6814     {
6815       errmsg ("IP addres not set");
6816       return -99;
6817     }
6818
6819   if (MPLS_LABEL_INVALID == local_label)
6820     {
6821       errmsg ("missing label");
6822       return -99;
6823     }
6824
6825   /* Construct the API message */
6826   M (MPLS_IP_BIND_UNBIND, mp);
6827
6828   mp->mb_create_table_if_needed = create_table_if_needed;
6829   mp->mb_is_bind = is_bind;
6830   mp->mb_is_ip4 = is_ip4;
6831   mp->mb_ip_table_id = ntohl (ip_table_id);
6832   mp->mb_mpls_table_id = 0;
6833   mp->mb_label = ntohl (local_label);
6834   mp->mb_address_length = address_length;
6835
6836   if (is_ip4)
6837     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6838   else
6839     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6840
6841   /* send it... */
6842   S (mp);
6843
6844   /* Wait for a reply... */
6845   W (ret);
6846   return ret;
6847 }
6848
6849 static int
6850 api_proxy_arp_add_del (vat_main_t * vam)
6851 {
6852   unformat_input_t *i = vam->input;
6853   vl_api_proxy_arp_add_del_t *mp;
6854   u32 vrf_id = 0;
6855   u8 is_add = 1;
6856   ip4_address_t lo, hi;
6857   u8 range_set = 0;
6858   int ret;
6859
6860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6861     {
6862       if (unformat (i, "vrf %d", &vrf_id))
6863         ;
6864       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6865                          unformat_ip4_address, &hi))
6866         range_set = 1;
6867       else if (unformat (i, "del"))
6868         is_add = 0;
6869       else
6870         {
6871           clib_warning ("parse error '%U'", format_unformat_error, i);
6872           return -99;
6873         }
6874     }
6875
6876   if (range_set == 0)
6877     {
6878       errmsg ("address range not set");
6879       return -99;
6880     }
6881
6882   M (PROXY_ARP_ADD_DEL, mp);
6883
6884   mp->vrf_id = ntohl (vrf_id);
6885   mp->is_add = is_add;
6886   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6887   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6888
6889   S (mp);
6890   W (ret);
6891   return ret;
6892 }
6893
6894 static int
6895 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6896 {
6897   unformat_input_t *i = vam->input;
6898   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6899   u32 sw_if_index;
6900   u8 enable = 1;
6901   u8 sw_if_index_set = 0;
6902   int ret;
6903
6904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6905     {
6906       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6907         sw_if_index_set = 1;
6908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6909         sw_if_index_set = 1;
6910       else if (unformat (i, "enable"))
6911         enable = 1;
6912       else if (unformat (i, "disable"))
6913         enable = 0;
6914       else
6915         {
6916           clib_warning ("parse error '%U'", format_unformat_error, i);
6917           return -99;
6918         }
6919     }
6920
6921   if (sw_if_index_set == 0)
6922     {
6923       errmsg ("missing interface name or sw_if_index");
6924       return -99;
6925     }
6926
6927   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
6928
6929   mp->sw_if_index = ntohl (sw_if_index);
6930   mp->enable_disable = enable;
6931
6932   S (mp);
6933   W (ret);
6934   return ret;
6935 }
6936
6937 static int
6938 api_mpls_tunnel_add_del (vat_main_t * vam)
6939 {
6940   unformat_input_t *i = vam->input;
6941   vl_api_mpls_tunnel_add_del_t *mp;
6942
6943   u8 is_add = 1;
6944   u8 l2_only = 0;
6945   u32 sw_if_index = ~0;
6946   u32 next_hop_sw_if_index = ~0;
6947   u32 next_hop_proto_is_ip4 = 1;
6948
6949   u32 next_hop_table_id = 0;
6950   ip4_address_t v4_next_hop_address = {
6951     .as_u32 = 0,
6952   };
6953   ip6_address_t v6_next_hop_address = { {0} };
6954   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6955   int ret;
6956
6957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6958     {
6959       if (unformat (i, "add"))
6960         is_add = 1;
6961       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6962         is_add = 0;
6963       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6964         ;
6965       else if (unformat (i, "via %U",
6966                          unformat_ip4_address, &v4_next_hop_address))
6967         {
6968           next_hop_proto_is_ip4 = 1;
6969         }
6970       else if (unformat (i, "via %U",
6971                          unformat_ip6_address, &v6_next_hop_address))
6972         {
6973           next_hop_proto_is_ip4 = 0;
6974         }
6975       else if (unformat (i, "l2-only"))
6976         l2_only = 1;
6977       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6978         ;
6979       else if (unformat (i, "out-label %d", &next_hop_out_label))
6980         vec_add1 (labels, ntohl (next_hop_out_label));
6981       else
6982         {
6983           clib_warning ("parse error '%U'", format_unformat_error, i);
6984           return -99;
6985         }
6986     }
6987
6988   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
6989
6990   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6991   mp->mt_sw_if_index = ntohl (sw_if_index);
6992   mp->mt_is_add = is_add;
6993   mp->mt_l2_only = l2_only;
6994   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6995   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6996
6997   mp->mt_next_hop_n_out_labels = vec_len (labels);
6998
6999   if (0 != mp->mt_next_hop_n_out_labels)
7000     {
7001       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7002                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7003       vec_free (labels);
7004     }
7005
7006   if (next_hop_proto_is_ip4)
7007     {
7008       clib_memcpy (mp->mt_next_hop,
7009                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7010     }
7011   else
7012     {
7013       clib_memcpy (mp->mt_next_hop,
7014                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7015     }
7016
7017   S (mp);
7018   W (ret);
7019   return ret;
7020 }
7021
7022 static int
7023 api_sw_interface_set_unnumbered (vat_main_t * vam)
7024 {
7025   unformat_input_t *i = vam->input;
7026   vl_api_sw_interface_set_unnumbered_t *mp;
7027   u32 sw_if_index;
7028   u32 unnum_sw_index = ~0;
7029   u8 is_add = 1;
7030   u8 sw_if_index_set = 0;
7031   int ret;
7032
7033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7034     {
7035       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7036         sw_if_index_set = 1;
7037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7038         sw_if_index_set = 1;
7039       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7040         ;
7041       else if (unformat (i, "del"))
7042         is_add = 0;
7043       else
7044         {
7045           clib_warning ("parse error '%U'", format_unformat_error, i);
7046           return -99;
7047         }
7048     }
7049
7050   if (sw_if_index_set == 0)
7051     {
7052       errmsg ("missing interface name or sw_if_index");
7053       return -99;
7054     }
7055
7056   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7057
7058   mp->sw_if_index = ntohl (sw_if_index);
7059   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7060   mp->is_add = is_add;
7061
7062   S (mp);
7063   W (ret);
7064   return ret;
7065 }
7066
7067 static int
7068 api_ip_neighbor_add_del (vat_main_t * vam)
7069 {
7070   unformat_input_t *i = vam->input;
7071   vl_api_ip_neighbor_add_del_t *mp;
7072   u32 sw_if_index;
7073   u8 sw_if_index_set = 0;
7074   u8 is_add = 1;
7075   u8 is_static = 0;
7076   u8 mac_address[6];
7077   u8 mac_set = 0;
7078   u8 v4_address_set = 0;
7079   u8 v6_address_set = 0;
7080   ip4_address_t v4address;
7081   ip6_address_t v6address;
7082   int ret;
7083
7084   memset (mac_address, 0, sizeof (mac_address));
7085
7086   /* Parse args required to build the message */
7087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7088     {
7089       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7090         {
7091           mac_set = 1;
7092         }
7093       else if (unformat (i, "del"))
7094         is_add = 0;
7095       else
7096         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7097         sw_if_index_set = 1;
7098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7099         sw_if_index_set = 1;
7100       else if (unformat (i, "is_static"))
7101         is_static = 1;
7102       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7103         v4_address_set = 1;
7104       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7105         v6_address_set = 1;
7106       else
7107         {
7108           clib_warning ("parse error '%U'", format_unformat_error, i);
7109           return -99;
7110         }
7111     }
7112
7113   if (sw_if_index_set == 0)
7114     {
7115       errmsg ("missing interface name or sw_if_index");
7116       return -99;
7117     }
7118   if (v4_address_set && v6_address_set)
7119     {
7120       errmsg ("both v4 and v6 addresses set");
7121       return -99;
7122     }
7123   if (!v4_address_set && !v6_address_set)
7124     {
7125       errmsg ("no address set");
7126       return -99;
7127     }
7128
7129   /* Construct the API message */
7130   M (IP_NEIGHBOR_ADD_DEL, mp);
7131
7132   mp->sw_if_index = ntohl (sw_if_index);
7133   mp->is_add = is_add;
7134   mp->is_static = is_static;
7135   if (mac_set)
7136     clib_memcpy (mp->mac_address, mac_address, 6);
7137   if (v6_address_set)
7138     {
7139       mp->is_ipv6 = 1;
7140       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7141     }
7142   else
7143     {
7144       /* mp->is_ipv6 = 0; via memset in M macro above */
7145       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7146     }
7147
7148   /* send it... */
7149   S (mp);
7150
7151   /* Wait for a reply, return good/bad news  */
7152   W (ret);
7153   return ret;
7154 }
7155
7156 static int
7157 api_reset_vrf (vat_main_t * vam)
7158 {
7159   unformat_input_t *i = vam->input;
7160   vl_api_reset_vrf_t *mp;
7161   u32 vrf_id = 0;
7162   u8 is_ipv6 = 0;
7163   u8 vrf_id_set = 0;
7164   int ret;
7165
7166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7167     {
7168       if (unformat (i, "vrf %d", &vrf_id))
7169         vrf_id_set = 1;
7170       else if (unformat (i, "ipv6"))
7171         is_ipv6 = 1;
7172       else
7173         {
7174           clib_warning ("parse error '%U'", format_unformat_error, i);
7175           return -99;
7176         }
7177     }
7178
7179   if (vrf_id_set == 0)
7180     {
7181       errmsg ("missing vrf id");
7182       return -99;
7183     }
7184
7185   M (RESET_VRF, mp);
7186
7187   mp->vrf_id = ntohl (vrf_id);
7188   mp->is_ipv6 = is_ipv6;
7189
7190   S (mp);
7191   W (ret);
7192   return ret;
7193 }
7194
7195 static int
7196 api_create_vlan_subif (vat_main_t * vam)
7197 {
7198   unformat_input_t *i = vam->input;
7199   vl_api_create_vlan_subif_t *mp;
7200   u32 sw_if_index;
7201   u8 sw_if_index_set = 0;
7202   u32 vlan_id;
7203   u8 vlan_id_set = 0;
7204   int ret;
7205
7206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7207     {
7208       if (unformat (i, "sw_if_index %d", &sw_if_index))
7209         sw_if_index_set = 1;
7210       else
7211         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7212         sw_if_index_set = 1;
7213       else if (unformat (i, "vlan %d", &vlan_id))
7214         vlan_id_set = 1;
7215       else
7216         {
7217           clib_warning ("parse error '%U'", format_unformat_error, i);
7218           return -99;
7219         }
7220     }
7221
7222   if (sw_if_index_set == 0)
7223     {
7224       errmsg ("missing interface name or sw_if_index");
7225       return -99;
7226     }
7227
7228   if (vlan_id_set == 0)
7229     {
7230       errmsg ("missing vlan_id");
7231       return -99;
7232     }
7233   M (CREATE_VLAN_SUBIF, mp);
7234
7235   mp->sw_if_index = ntohl (sw_if_index);
7236   mp->vlan_id = ntohl (vlan_id);
7237
7238   S (mp);
7239   W (ret);
7240   return ret;
7241 }
7242
7243 #define foreach_create_subif_bit                \
7244 _(no_tags)                                      \
7245 _(one_tag)                                      \
7246 _(two_tags)                                     \
7247 _(dot1ad)                                       \
7248 _(exact_match)                                  \
7249 _(default_sub)                                  \
7250 _(outer_vlan_id_any)                            \
7251 _(inner_vlan_id_any)
7252
7253 static int
7254 api_create_subif (vat_main_t * vam)
7255 {
7256   unformat_input_t *i = vam->input;
7257   vl_api_create_subif_t *mp;
7258   u32 sw_if_index;
7259   u8 sw_if_index_set = 0;
7260   u32 sub_id;
7261   u8 sub_id_set = 0;
7262   u32 no_tags = 0;
7263   u32 one_tag = 0;
7264   u32 two_tags = 0;
7265   u32 dot1ad = 0;
7266   u32 exact_match = 0;
7267   u32 default_sub = 0;
7268   u32 outer_vlan_id_any = 0;
7269   u32 inner_vlan_id_any = 0;
7270   u32 tmp;
7271   u16 outer_vlan_id = 0;
7272   u16 inner_vlan_id = 0;
7273   int ret;
7274
7275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7276     {
7277       if (unformat (i, "sw_if_index %d", &sw_if_index))
7278         sw_if_index_set = 1;
7279       else
7280         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7281         sw_if_index_set = 1;
7282       else if (unformat (i, "sub_id %d", &sub_id))
7283         sub_id_set = 1;
7284       else if (unformat (i, "outer_vlan_id %d", &tmp))
7285         outer_vlan_id = tmp;
7286       else if (unformat (i, "inner_vlan_id %d", &tmp))
7287         inner_vlan_id = tmp;
7288
7289 #define _(a) else if (unformat (i, #a)) a = 1 ;
7290       foreach_create_subif_bit
7291 #undef _
7292         else
7293         {
7294           clib_warning ("parse error '%U'", format_unformat_error, i);
7295           return -99;
7296         }
7297     }
7298
7299   if (sw_if_index_set == 0)
7300     {
7301       errmsg ("missing interface name or sw_if_index");
7302       return -99;
7303     }
7304
7305   if (sub_id_set == 0)
7306     {
7307       errmsg ("missing sub_id");
7308       return -99;
7309     }
7310   M (CREATE_SUBIF, mp);
7311
7312   mp->sw_if_index = ntohl (sw_if_index);
7313   mp->sub_id = ntohl (sub_id);
7314
7315 #define _(a) mp->a = a;
7316   foreach_create_subif_bit;
7317 #undef _
7318
7319   mp->outer_vlan_id = ntohs (outer_vlan_id);
7320   mp->inner_vlan_id = ntohs (inner_vlan_id);
7321
7322   S (mp);
7323   W (ret);
7324   return ret;
7325 }
7326
7327 static int
7328 api_oam_add_del (vat_main_t * vam)
7329 {
7330   unformat_input_t *i = vam->input;
7331   vl_api_oam_add_del_t *mp;
7332   u32 vrf_id = 0;
7333   u8 is_add = 1;
7334   ip4_address_t src, dst;
7335   u8 src_set = 0;
7336   u8 dst_set = 0;
7337   int ret;
7338
7339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7340     {
7341       if (unformat (i, "vrf %d", &vrf_id))
7342         ;
7343       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7344         src_set = 1;
7345       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7346         dst_set = 1;
7347       else if (unformat (i, "del"))
7348         is_add = 0;
7349       else
7350         {
7351           clib_warning ("parse error '%U'", format_unformat_error, i);
7352           return -99;
7353         }
7354     }
7355
7356   if (src_set == 0)
7357     {
7358       errmsg ("missing src addr");
7359       return -99;
7360     }
7361
7362   if (dst_set == 0)
7363     {
7364       errmsg ("missing dst addr");
7365       return -99;
7366     }
7367
7368   M (OAM_ADD_DEL, mp);
7369
7370   mp->vrf_id = ntohl (vrf_id);
7371   mp->is_add = is_add;
7372   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7373   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7374
7375   S (mp);
7376   W (ret);
7377   return ret;
7378 }
7379
7380 static int
7381 api_reset_fib (vat_main_t * vam)
7382 {
7383   unformat_input_t *i = vam->input;
7384   vl_api_reset_fib_t *mp;
7385   u32 vrf_id = 0;
7386   u8 is_ipv6 = 0;
7387   u8 vrf_id_set = 0;
7388
7389   int ret;
7390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7391     {
7392       if (unformat (i, "vrf %d", &vrf_id))
7393         vrf_id_set = 1;
7394       else if (unformat (i, "ipv6"))
7395         is_ipv6 = 1;
7396       else
7397         {
7398           clib_warning ("parse error '%U'", format_unformat_error, i);
7399           return -99;
7400         }
7401     }
7402
7403   if (vrf_id_set == 0)
7404     {
7405       errmsg ("missing vrf id");
7406       return -99;
7407     }
7408
7409   M (RESET_FIB, mp);
7410
7411   mp->vrf_id = ntohl (vrf_id);
7412   mp->is_ipv6 = is_ipv6;
7413
7414   S (mp);
7415   W (ret);
7416   return ret;
7417 }
7418
7419 static int
7420 api_dhcp_proxy_config (vat_main_t * vam)
7421 {
7422   unformat_input_t *i = vam->input;
7423   vl_api_dhcp_proxy_config_t *mp;
7424   u32 rx_vrf_id = 0;
7425   u32 server_vrf_id = 0;
7426   u8 is_add = 1;
7427   u8 v4_address_set = 0;
7428   u8 v6_address_set = 0;
7429   ip4_address_t v4address;
7430   ip6_address_t v6address;
7431   u8 v4_src_address_set = 0;
7432   u8 v6_src_address_set = 0;
7433   ip4_address_t v4srcaddress;
7434   ip6_address_t v6srcaddress;
7435   int ret;
7436
7437   /* Parse args required to build the message */
7438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7439     {
7440       if (unformat (i, "del"))
7441         is_add = 0;
7442       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7443         ;
7444       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7445         ;
7446       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7447         v4_address_set = 1;
7448       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7449         v6_address_set = 1;
7450       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7451         v4_src_address_set = 1;
7452       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7453         v6_src_address_set = 1;
7454       else
7455         break;
7456     }
7457
7458   if (v4_address_set && v6_address_set)
7459     {
7460       errmsg ("both v4 and v6 server addresses set");
7461       return -99;
7462     }
7463   if (!v4_address_set && !v6_address_set)
7464     {
7465       errmsg ("no server addresses set");
7466       return -99;
7467     }
7468
7469   if (v4_src_address_set && v6_src_address_set)
7470     {
7471       errmsg ("both v4 and v6  src addresses set");
7472       return -99;
7473     }
7474   if (!v4_src_address_set && !v6_src_address_set)
7475     {
7476       errmsg ("no src addresses set");
7477       return -99;
7478     }
7479
7480   if (!(v4_src_address_set && v4_address_set) &&
7481       !(v6_src_address_set && v6_address_set))
7482     {
7483       errmsg ("no matching server and src addresses set");
7484       return -99;
7485     }
7486
7487   /* Construct the API message */
7488   M (DHCP_PROXY_CONFIG, mp);
7489
7490   mp->is_add = is_add;
7491   mp->rx_vrf_id = ntohl (rx_vrf_id);
7492   mp->server_vrf_id = ntohl (server_vrf_id);
7493   if (v6_address_set)
7494     {
7495       mp->is_ipv6 = 1;
7496       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7497       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7498     }
7499   else
7500     {
7501       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7502       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7503     }
7504
7505   /* send it... */
7506   S (mp);
7507
7508   /* Wait for a reply, return good/bad news  */
7509   W (ret);
7510   return ret;
7511 }
7512
7513 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7514 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7515
7516 static void
7517 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7518 {
7519   vat_main_t *vam = &vat_main;
7520
7521   if (mp->is_ipv6)
7522     print (vam->ofp,
7523            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7524            ntohl (mp->rx_vrf_id),
7525            ntohl (mp->server_vrf_id),
7526            format_ip6_address, mp->dhcp_server,
7527            format_ip6_address, mp->dhcp_src_address,
7528            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7529   else
7530     print (vam->ofp,
7531            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7532            ntohl (mp->rx_vrf_id),
7533            ntohl (mp->server_vrf_id),
7534            format_ip4_address, mp->dhcp_server,
7535            format_ip4_address, mp->dhcp_src_address,
7536            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7537 }
7538
7539 static void vl_api_dhcp_proxy_details_t_handler_json
7540   (vl_api_dhcp_proxy_details_t * mp)
7541 {
7542   vat_main_t *vam = &vat_main;
7543   vat_json_node_t *node = NULL;
7544   struct in_addr ip4;
7545   struct in6_addr ip6;
7546
7547   if (VAT_JSON_ARRAY != vam->json_tree.type)
7548     {
7549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7550       vat_json_init_array (&vam->json_tree);
7551     }
7552   node = vat_json_array_add (&vam->json_tree);
7553
7554   vat_json_init_object (node);
7555   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7556   vat_json_object_add_uint (node, "server-table-id",
7557                             ntohl (mp->server_vrf_id));
7558   if (mp->is_ipv6)
7559     {
7560       clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7561       vat_json_object_add_ip6 (node, "server_address", ip6);
7562       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7563       vat_json_object_add_ip6 (node, "src_address", ip6);
7564     }
7565   else
7566     {
7567       clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7568       vat_json_object_add_ip4 (node, "server_address", ip4);
7569       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7570       vat_json_object_add_ip4 (node, "src_address", ip4);
7571     }
7572   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7573   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7574 }
7575
7576 static int
7577 api_dhcp_proxy_dump (vat_main_t * vam)
7578 {
7579   unformat_input_t *i = vam->input;
7580   vl_api_control_ping_t *mp_ping;
7581   vl_api_dhcp_proxy_dump_t *mp;
7582   u8 is_ipv6 = 0;
7583   int ret;
7584
7585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7586     {
7587       if (unformat (i, "ipv6"))
7588         is_ipv6 = 1;
7589       else
7590         {
7591           clib_warning ("parse error '%U'", format_unformat_error, i);
7592           return -99;
7593         }
7594     }
7595
7596   M (DHCP_PROXY_DUMP, mp);
7597
7598   mp->is_ip6 = is_ipv6;
7599   S (mp);
7600
7601   /* Use a control ping for synchronization */
7602   M (CONTROL_PING, mp_ping);
7603   S (mp_ping);
7604
7605   W (ret);
7606   return ret;
7607 }
7608
7609 static int
7610 api_dhcp_proxy_set_vss (vat_main_t * vam)
7611 {
7612   unformat_input_t *i = vam->input;
7613   vl_api_dhcp_proxy_set_vss_t *mp;
7614   u8 is_ipv6 = 0;
7615   u8 is_add = 1;
7616   u32 tbl_id;
7617   u8 tbl_id_set = 0;
7618   u32 oui;
7619   u8 oui_set = 0;
7620   u32 fib_id;
7621   u8 fib_id_set = 0;
7622   int ret;
7623
7624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7625     {
7626       if (unformat (i, "tbl_id %d", &tbl_id))
7627         tbl_id_set = 1;
7628       if (unformat (i, "fib_id %d", &fib_id))
7629         fib_id_set = 1;
7630       if (unformat (i, "oui %d", &oui))
7631         oui_set = 1;
7632       else if (unformat (i, "ipv6"))
7633         is_ipv6 = 1;
7634       else if (unformat (i, "del"))
7635         is_add = 0;
7636       else
7637         {
7638           clib_warning ("parse error '%U'", format_unformat_error, i);
7639           return -99;
7640         }
7641     }
7642
7643   if (tbl_id_set == 0)
7644     {
7645       errmsg ("missing tbl id");
7646       return -99;
7647     }
7648
7649   if (fib_id_set == 0)
7650     {
7651       errmsg ("missing fib id");
7652       return -99;
7653     }
7654   if (oui_set == 0)
7655     {
7656       errmsg ("missing oui");
7657       return -99;
7658     }
7659
7660   M (DHCP_PROXY_SET_VSS, mp);
7661   mp->tbl_id = ntohl (tbl_id);
7662   mp->fib_id = ntohl (fib_id);
7663   mp->oui = ntohl (oui);
7664   mp->is_ipv6 = is_ipv6;
7665   mp->is_add = is_add;
7666
7667   S (mp);
7668   W (ret);
7669   return ret;
7670 }
7671
7672 static int
7673 api_dhcp_client_config (vat_main_t * vam)
7674 {
7675   unformat_input_t *i = vam->input;
7676   vl_api_dhcp_client_config_t *mp;
7677   u32 sw_if_index;
7678   u8 sw_if_index_set = 0;
7679   u8 is_add = 1;
7680   u8 *hostname = 0;
7681   u8 disable_event = 0;
7682   int ret;
7683
7684   /* Parse args required to build the message */
7685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7686     {
7687       if (unformat (i, "del"))
7688         is_add = 0;
7689       else
7690         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7691         sw_if_index_set = 1;
7692       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7693         sw_if_index_set = 1;
7694       else if (unformat (i, "hostname %s", &hostname))
7695         ;
7696       else if (unformat (i, "disable_event"))
7697         disable_event = 1;
7698       else
7699         break;
7700     }
7701
7702   if (sw_if_index_set == 0)
7703     {
7704       errmsg ("missing interface name or sw_if_index");
7705       return -99;
7706     }
7707
7708   if (vec_len (hostname) > 63)
7709     {
7710       errmsg ("hostname too long");
7711     }
7712   vec_add1 (hostname, 0);
7713
7714   /* Construct the API message */
7715   M (DHCP_CLIENT_CONFIG, mp);
7716
7717   mp->sw_if_index = ntohl (sw_if_index);
7718   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7719   vec_free (hostname);
7720   mp->is_add = is_add;
7721   mp->want_dhcp_event = disable_event ? 0 : 1;
7722   mp->pid = getpid ();
7723
7724   /* send it... */
7725   S (mp);
7726
7727   /* Wait for a reply, return good/bad news  */
7728   W (ret);
7729   return ret;
7730 }
7731
7732 static int
7733 api_set_ip_flow_hash (vat_main_t * vam)
7734 {
7735   unformat_input_t *i = vam->input;
7736   vl_api_set_ip_flow_hash_t *mp;
7737   u32 vrf_id = 0;
7738   u8 is_ipv6 = 0;
7739   u8 vrf_id_set = 0;
7740   u8 src = 0;
7741   u8 dst = 0;
7742   u8 sport = 0;
7743   u8 dport = 0;
7744   u8 proto = 0;
7745   u8 reverse = 0;
7746   int ret;
7747
7748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7749     {
7750       if (unformat (i, "vrf %d", &vrf_id))
7751         vrf_id_set = 1;
7752       else if (unformat (i, "ipv6"))
7753         is_ipv6 = 1;
7754       else if (unformat (i, "src"))
7755         src = 1;
7756       else if (unformat (i, "dst"))
7757         dst = 1;
7758       else if (unformat (i, "sport"))
7759         sport = 1;
7760       else if (unformat (i, "dport"))
7761         dport = 1;
7762       else if (unformat (i, "proto"))
7763         proto = 1;
7764       else if (unformat (i, "reverse"))
7765         reverse = 1;
7766
7767       else
7768         {
7769           clib_warning ("parse error '%U'", format_unformat_error, i);
7770           return -99;
7771         }
7772     }
7773
7774   if (vrf_id_set == 0)
7775     {
7776       errmsg ("missing vrf id");
7777       return -99;
7778     }
7779
7780   M (SET_IP_FLOW_HASH, mp);
7781   mp->src = src;
7782   mp->dst = dst;
7783   mp->sport = sport;
7784   mp->dport = dport;
7785   mp->proto = proto;
7786   mp->reverse = reverse;
7787   mp->vrf_id = ntohl (vrf_id);
7788   mp->is_ipv6 = is_ipv6;
7789
7790   S (mp);
7791   W (ret);
7792   return ret;
7793 }
7794
7795 static int
7796 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7797 {
7798   unformat_input_t *i = vam->input;
7799   vl_api_sw_interface_ip6_enable_disable_t *mp;
7800   u32 sw_if_index;
7801   u8 sw_if_index_set = 0;
7802   u8 enable = 0;
7803   int ret;
7804
7805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7806     {
7807       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7808         sw_if_index_set = 1;
7809       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7810         sw_if_index_set = 1;
7811       else if (unformat (i, "enable"))
7812         enable = 1;
7813       else if (unformat (i, "disable"))
7814         enable = 0;
7815       else
7816         {
7817           clib_warning ("parse error '%U'", format_unformat_error, i);
7818           return -99;
7819         }
7820     }
7821
7822   if (sw_if_index_set == 0)
7823     {
7824       errmsg ("missing interface name or sw_if_index");
7825       return -99;
7826     }
7827
7828   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7829
7830   mp->sw_if_index = ntohl (sw_if_index);
7831   mp->enable = enable;
7832
7833   S (mp);
7834   W (ret);
7835   return ret;
7836 }
7837
7838 static int
7839 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7840 {
7841   unformat_input_t *i = vam->input;
7842   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7843   u32 sw_if_index;
7844   u8 sw_if_index_set = 0;
7845   u8 v6_address_set = 0;
7846   ip6_address_t v6address;
7847   int ret;
7848
7849   /* Parse args required to build the message */
7850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7851     {
7852       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7853         sw_if_index_set = 1;
7854       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7855         sw_if_index_set = 1;
7856       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7857         v6_address_set = 1;
7858       else
7859         break;
7860     }
7861
7862   if (sw_if_index_set == 0)
7863     {
7864       errmsg ("missing interface name or sw_if_index");
7865       return -99;
7866     }
7867   if (!v6_address_set)
7868     {
7869       errmsg ("no address set");
7870       return -99;
7871     }
7872
7873   /* Construct the API message */
7874   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
7875
7876   mp->sw_if_index = ntohl (sw_if_index);
7877   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7878
7879   /* send it... */
7880   S (mp);
7881
7882   /* Wait for a reply, return good/bad news  */
7883   W (ret);
7884   return ret;
7885 }
7886
7887
7888 static int
7889 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7890 {
7891   unformat_input_t *i = vam->input;
7892   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7893   u32 sw_if_index;
7894   u8 sw_if_index_set = 0;
7895   u32 address_length = 0;
7896   u8 v6_address_set = 0;
7897   ip6_address_t v6address;
7898   u8 use_default = 0;
7899   u8 no_advertise = 0;
7900   u8 off_link = 0;
7901   u8 no_autoconfig = 0;
7902   u8 no_onlink = 0;
7903   u8 is_no = 0;
7904   u32 val_lifetime = 0;
7905   u32 pref_lifetime = 0;
7906   int ret;
7907
7908   /* Parse args required to build the message */
7909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7910     {
7911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7912         sw_if_index_set = 1;
7913       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7914         sw_if_index_set = 1;
7915       else if (unformat (i, "%U/%d",
7916                          unformat_ip6_address, &v6address, &address_length))
7917         v6_address_set = 1;
7918       else if (unformat (i, "val_life %d", &val_lifetime))
7919         ;
7920       else if (unformat (i, "pref_life %d", &pref_lifetime))
7921         ;
7922       else if (unformat (i, "def"))
7923         use_default = 1;
7924       else if (unformat (i, "noadv"))
7925         no_advertise = 1;
7926       else if (unformat (i, "offl"))
7927         off_link = 1;
7928       else if (unformat (i, "noauto"))
7929         no_autoconfig = 1;
7930       else if (unformat (i, "nolink"))
7931         no_onlink = 1;
7932       else if (unformat (i, "isno"))
7933         is_no = 1;
7934       else
7935         {
7936           clib_warning ("parse error '%U'", format_unformat_error, i);
7937           return -99;
7938         }
7939     }
7940
7941   if (sw_if_index_set == 0)
7942     {
7943       errmsg ("missing interface name or sw_if_index");
7944       return -99;
7945     }
7946   if (!v6_address_set)
7947     {
7948       errmsg ("no address set");
7949       return -99;
7950     }
7951
7952   /* Construct the API message */
7953   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
7954
7955   mp->sw_if_index = ntohl (sw_if_index);
7956   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7957   mp->address_length = address_length;
7958   mp->use_default = use_default;
7959   mp->no_advertise = no_advertise;
7960   mp->off_link = off_link;
7961   mp->no_autoconfig = no_autoconfig;
7962   mp->no_onlink = no_onlink;
7963   mp->is_no = is_no;
7964   mp->val_lifetime = ntohl (val_lifetime);
7965   mp->pref_lifetime = ntohl (pref_lifetime);
7966
7967   /* send it... */
7968   S (mp);
7969
7970   /* Wait for a reply, return good/bad news  */
7971   W (ret);
7972   return ret;
7973 }
7974
7975 static int
7976 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7977 {
7978   unformat_input_t *i = vam->input;
7979   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7980   u32 sw_if_index;
7981   u8 sw_if_index_set = 0;
7982   u8 suppress = 0;
7983   u8 managed = 0;
7984   u8 other = 0;
7985   u8 ll_option = 0;
7986   u8 send_unicast = 0;
7987   u8 cease = 0;
7988   u8 is_no = 0;
7989   u8 default_router = 0;
7990   u32 max_interval = 0;
7991   u32 min_interval = 0;
7992   u32 lifetime = 0;
7993   u32 initial_count = 0;
7994   u32 initial_interval = 0;
7995   int ret;
7996
7997
7998   /* Parse args required to build the message */
7999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8000     {
8001       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8002         sw_if_index_set = 1;
8003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8004         sw_if_index_set = 1;
8005       else if (unformat (i, "maxint %d", &max_interval))
8006         ;
8007       else if (unformat (i, "minint %d", &min_interval))
8008         ;
8009       else if (unformat (i, "life %d", &lifetime))
8010         ;
8011       else if (unformat (i, "count %d", &initial_count))
8012         ;
8013       else if (unformat (i, "interval %d", &initial_interval))
8014         ;
8015       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8016         suppress = 1;
8017       else if (unformat (i, "managed"))
8018         managed = 1;
8019       else if (unformat (i, "other"))
8020         other = 1;
8021       else if (unformat (i, "ll"))
8022         ll_option = 1;
8023       else if (unformat (i, "send"))
8024         send_unicast = 1;
8025       else if (unformat (i, "cease"))
8026         cease = 1;
8027       else if (unformat (i, "isno"))
8028         is_no = 1;
8029       else if (unformat (i, "def"))
8030         default_router = 1;
8031       else
8032         {
8033           clib_warning ("parse error '%U'", format_unformat_error, i);
8034           return -99;
8035         }
8036     }
8037
8038   if (sw_if_index_set == 0)
8039     {
8040       errmsg ("missing interface name or sw_if_index");
8041       return -99;
8042     }
8043
8044   /* Construct the API message */
8045   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8046
8047   mp->sw_if_index = ntohl (sw_if_index);
8048   mp->max_interval = ntohl (max_interval);
8049   mp->min_interval = ntohl (min_interval);
8050   mp->lifetime = ntohl (lifetime);
8051   mp->initial_count = ntohl (initial_count);
8052   mp->initial_interval = ntohl (initial_interval);
8053   mp->suppress = suppress;
8054   mp->managed = managed;
8055   mp->other = other;
8056   mp->ll_option = ll_option;
8057   mp->send_unicast = send_unicast;
8058   mp->cease = cease;
8059   mp->is_no = is_no;
8060   mp->default_router = default_router;
8061
8062   /* send it... */
8063   S (mp);
8064
8065   /* Wait for a reply, return good/bad news  */
8066   W (ret);
8067   return ret;
8068 }
8069
8070 static int
8071 api_set_arp_neighbor_limit (vat_main_t * vam)
8072 {
8073   unformat_input_t *i = vam->input;
8074   vl_api_set_arp_neighbor_limit_t *mp;
8075   u32 arp_nbr_limit;
8076   u8 limit_set = 0;
8077   u8 is_ipv6 = 0;
8078   int ret;
8079
8080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8081     {
8082       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8083         limit_set = 1;
8084       else if (unformat (i, "ipv6"))
8085         is_ipv6 = 1;
8086       else
8087         {
8088           clib_warning ("parse error '%U'", format_unformat_error, i);
8089           return -99;
8090         }
8091     }
8092
8093   if (limit_set == 0)
8094     {
8095       errmsg ("missing limit value");
8096       return -99;
8097     }
8098
8099   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8100
8101   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8102   mp->is_ipv6 = is_ipv6;
8103
8104   S (mp);
8105   W (ret);
8106   return ret;
8107 }
8108
8109 static int
8110 api_l2_patch_add_del (vat_main_t * vam)
8111 {
8112   unformat_input_t *i = vam->input;
8113   vl_api_l2_patch_add_del_t *mp;
8114   u32 rx_sw_if_index;
8115   u8 rx_sw_if_index_set = 0;
8116   u32 tx_sw_if_index;
8117   u8 tx_sw_if_index_set = 0;
8118   u8 is_add = 1;
8119   int ret;
8120
8121   /* Parse args required to build the message */
8122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8123     {
8124       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8125         rx_sw_if_index_set = 1;
8126       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8127         tx_sw_if_index_set = 1;
8128       else if (unformat (i, "rx"))
8129         {
8130           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8131             {
8132               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8133                             &rx_sw_if_index))
8134                 rx_sw_if_index_set = 1;
8135             }
8136           else
8137             break;
8138         }
8139       else if (unformat (i, "tx"))
8140         {
8141           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8142             {
8143               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8144                             &tx_sw_if_index))
8145                 tx_sw_if_index_set = 1;
8146             }
8147           else
8148             break;
8149         }
8150       else if (unformat (i, "del"))
8151         is_add = 0;
8152       else
8153         break;
8154     }
8155
8156   if (rx_sw_if_index_set == 0)
8157     {
8158       errmsg ("missing rx interface name or rx_sw_if_index");
8159       return -99;
8160     }
8161
8162   if (tx_sw_if_index_set == 0)
8163     {
8164       errmsg ("missing tx interface name or tx_sw_if_index");
8165       return -99;
8166     }
8167
8168   M (L2_PATCH_ADD_DEL, mp);
8169
8170   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8171   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8172   mp->is_add = is_add;
8173
8174   S (mp);
8175   W (ret);
8176   return ret;
8177 }
8178
8179 static int
8180 api_ioam_enable (vat_main_t * vam)
8181 {
8182   unformat_input_t *input = vam->input;
8183   vl_api_ioam_enable_t *mp;
8184   u32 id = 0;
8185   int has_trace_option = 0;
8186   int has_pot_option = 0;
8187   int has_seqno_option = 0;
8188   int has_analyse_option = 0;
8189   int ret;
8190
8191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8192     {
8193       if (unformat (input, "trace"))
8194         has_trace_option = 1;
8195       else if (unformat (input, "pot"))
8196         has_pot_option = 1;
8197       else if (unformat (input, "seqno"))
8198         has_seqno_option = 1;
8199       else if (unformat (input, "analyse"))
8200         has_analyse_option = 1;
8201       else
8202         break;
8203     }
8204   M (IOAM_ENABLE, mp);
8205   mp->id = htons (id);
8206   mp->seqno = has_seqno_option;
8207   mp->analyse = has_analyse_option;
8208   mp->pot_enable = has_pot_option;
8209   mp->trace_enable = has_trace_option;
8210
8211   S (mp);
8212   W (ret);
8213   return ret;
8214 }
8215
8216
8217 static int
8218 api_ioam_disable (vat_main_t * vam)
8219 {
8220   vl_api_ioam_disable_t *mp;
8221   int ret;
8222
8223   M (IOAM_DISABLE, mp);
8224   S (mp);
8225   W (ret);
8226   return ret;
8227 }
8228
8229 static int
8230 api_sr_tunnel_add_del (vat_main_t * vam)
8231 {
8232   unformat_input_t *i = vam->input;
8233   vl_api_sr_tunnel_add_del_t *mp;
8234   int is_del = 0;
8235   int pl_index;
8236   ip6_address_t src_address;
8237   int src_address_set = 0;
8238   ip6_address_t dst_address;
8239   u32 dst_mask_width;
8240   int dst_address_set = 0;
8241   u16 flags = 0;
8242   u32 rx_table_id = 0;
8243   u32 tx_table_id = 0;
8244   ip6_address_t *segments = 0;
8245   ip6_address_t *this_seg;
8246   ip6_address_t *tags = 0;
8247   ip6_address_t *this_tag;
8248   ip6_address_t next_address, tag;
8249   u8 *name = 0;
8250   u8 *policy_name = 0;
8251   int ret;
8252
8253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8254     {
8255       if (unformat (i, "del"))
8256         is_del = 1;
8257       else if (unformat (i, "name %s", &name))
8258         ;
8259       else if (unformat (i, "policy %s", &policy_name))
8260         ;
8261       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8262         ;
8263       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8264         ;
8265       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8266         src_address_set = 1;
8267       else if (unformat (i, "dst %U/%d",
8268                          unformat_ip6_address, &dst_address, &dst_mask_width))
8269         dst_address_set = 1;
8270       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8271         {
8272           vec_add2 (segments, this_seg, 1);
8273           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8274                        sizeof (*this_seg));
8275         }
8276       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8277         {
8278           vec_add2 (tags, this_tag, 1);
8279           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8280         }
8281       else if (unformat (i, "clean"))
8282         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8283       else if (unformat (i, "protected"))
8284         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8285       else if (unformat (i, "InPE %d", &pl_index))
8286         {
8287           if (pl_index <= 0 || pl_index > 4)
8288             {
8289             pl_index_range_error:
8290               errmsg ("pl index %d out of range", pl_index);
8291               return -99;
8292             }
8293           flags |=
8294             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8295         }
8296       else if (unformat (i, "EgPE %d", &pl_index))
8297         {
8298           if (pl_index <= 0 || pl_index > 4)
8299             goto pl_index_range_error;
8300           flags |=
8301             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8302         }
8303       else if (unformat (i, "OrgSrc %d", &pl_index))
8304         {
8305           if (pl_index <= 0 || pl_index > 4)
8306             goto pl_index_range_error;
8307           flags |=
8308             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8309         }
8310       else
8311         break;
8312     }
8313
8314   if (!src_address_set)
8315     {
8316       errmsg ("src address required");
8317       return -99;
8318     }
8319
8320   if (!dst_address_set)
8321     {
8322       errmsg ("dst address required");
8323       return -99;
8324     }
8325
8326   if (!segments)
8327     {
8328       errmsg ("at least one sr segment required");
8329       return -99;
8330     }
8331
8332   M2 (SR_TUNNEL_ADD_DEL, mp,
8333       vec_len (segments) * sizeof (ip6_address_t)
8334       + vec_len (tags) * sizeof (ip6_address_t));
8335
8336   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8337   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8338   mp->dst_mask_width = dst_mask_width;
8339   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8340   mp->n_segments = vec_len (segments);
8341   mp->n_tags = vec_len (tags);
8342   mp->is_add = is_del == 0;
8343   clib_memcpy (mp->segs_and_tags, segments,
8344                vec_len (segments) * sizeof (ip6_address_t));
8345   clib_memcpy (mp->segs_and_tags +
8346                vec_len (segments) * sizeof (ip6_address_t), tags,
8347                vec_len (tags) * sizeof (ip6_address_t));
8348
8349   mp->outer_vrf_id = ntohl (rx_table_id);
8350   mp->inner_vrf_id = ntohl (tx_table_id);
8351   memcpy (mp->name, name, vec_len (name));
8352   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8353
8354   vec_free (segments);
8355   vec_free (tags);
8356
8357   S (mp);
8358   W (ret);
8359   return ret;
8360 }
8361
8362 static int
8363 api_sr_policy_add_del (vat_main_t * vam)
8364 {
8365   unformat_input_t *input = vam->input;
8366   vl_api_sr_policy_add_del_t *mp;
8367   int is_del = 0;
8368   u8 *name = 0;
8369   u8 *tunnel_name = 0;
8370   u8 **tunnel_names = 0;
8371
8372   int name_set = 0;
8373   int tunnel_set = 0;
8374   int j = 0;
8375   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8376   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8377   int ret;
8378
8379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8380     {
8381       if (unformat (input, "del"))
8382         is_del = 1;
8383       else if (unformat (input, "name %s", &name))
8384         name_set = 1;
8385       else if (unformat (input, "tunnel %s", &tunnel_name))
8386         {
8387           if (tunnel_name)
8388             {
8389               vec_add1 (tunnel_names, tunnel_name);
8390               /* For serializer:
8391                  - length = #bytes to store in serial vector
8392                  - +1 = byte to store that length
8393                */
8394               tunnel_names_length += (vec_len (tunnel_name) + 1);
8395               tunnel_set = 1;
8396               tunnel_name = 0;
8397             }
8398         }
8399       else
8400         break;
8401     }
8402
8403   if (!name_set)
8404     {
8405       errmsg ("policy name required");
8406       return -99;
8407     }
8408
8409   if ((!tunnel_set) && (!is_del))
8410     {
8411       errmsg ("tunnel name required");
8412       return -99;
8413     }
8414
8415   M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
8416
8417
8418
8419   mp->is_add = !is_del;
8420
8421   memcpy (mp->name, name, vec_len (name));
8422   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8423   u8 *serial_orig = 0;
8424   vec_validate (serial_orig, tunnel_names_length);
8425   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8426   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8427
8428   for (j = 0; j < vec_len (tunnel_names); j++)
8429     {
8430       tun_name_len = vec_len (tunnel_names[j]);
8431       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8432       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8433       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8434       serial_orig += tun_name_len;      // Advance past the copy
8435     }
8436   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8437
8438   vec_free (tunnel_names);
8439   vec_free (tunnel_name);
8440
8441   S (mp);
8442   W (ret);
8443   return ret;
8444 }
8445
8446 static int
8447 api_sr_multicast_map_add_del (vat_main_t * vam)
8448 {
8449   unformat_input_t *input = vam->input;
8450   vl_api_sr_multicast_map_add_del_t *mp;
8451   int is_del = 0;
8452   ip6_address_t multicast_address;
8453   u8 *policy_name = 0;
8454   int multicast_address_set = 0;
8455   int ret;
8456
8457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8458     {
8459       if (unformat (input, "del"))
8460         is_del = 1;
8461       else
8462         if (unformat
8463             (input, "address %U", unformat_ip6_address, &multicast_address))
8464         multicast_address_set = 1;
8465       else if (unformat (input, "sr-policy %s", &policy_name))
8466         ;
8467       else
8468         break;
8469     }
8470
8471   if (!is_del && !policy_name)
8472     {
8473       errmsg ("sr-policy name required");
8474       return -99;
8475     }
8476
8477
8478   if (!multicast_address_set)
8479     {
8480       errmsg ("address required");
8481       return -99;
8482     }
8483
8484   M (SR_MULTICAST_MAP_ADD_DEL, mp);
8485
8486   mp->is_add = !is_del;
8487   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8488   clib_memcpy (mp->multicast_address, &multicast_address,
8489                sizeof (mp->multicast_address));
8490
8491
8492   vec_free (policy_name);
8493
8494   S (mp);
8495   W (ret);
8496   return ret;
8497 }
8498
8499
8500 #define foreach_tcp_proto_field                 \
8501 _(src_port)                                     \
8502 _(dst_port)
8503
8504 #define foreach_udp_proto_field                 \
8505 _(src_port)                                     \
8506 _(dst_port)
8507
8508 #define foreach_ip4_proto_field                 \
8509 _(src_address)                                  \
8510 _(dst_address)                                  \
8511 _(tos)                                          \
8512 _(length)                                       \
8513 _(fragment_id)                                  \
8514 _(ttl)                                          \
8515 _(protocol)                                     \
8516 _(checksum)
8517
8518 typedef struct
8519 {
8520   u16 src_port, dst_port;
8521 } tcpudp_header_t;
8522
8523 #if VPP_API_TEST_BUILTIN == 0
8524 uword
8525 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8526 {
8527   u8 **maskp = va_arg (*args, u8 **);
8528   u8 *mask = 0;
8529   u8 found_something = 0;
8530   tcp_header_t *tcp;
8531
8532 #define _(a) u8 a=0;
8533   foreach_tcp_proto_field;
8534 #undef _
8535
8536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8537     {
8538       if (0);
8539 #define _(a) else if (unformat (input, #a)) a=1;
8540       foreach_tcp_proto_field
8541 #undef _
8542         else
8543         break;
8544     }
8545
8546 #define _(a) found_something += a;
8547   foreach_tcp_proto_field;
8548 #undef _
8549
8550   if (found_something == 0)
8551     return 0;
8552
8553   vec_validate (mask, sizeof (*tcp) - 1);
8554
8555   tcp = (tcp_header_t *) mask;
8556
8557 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8558   foreach_tcp_proto_field;
8559 #undef _
8560
8561   *maskp = mask;
8562   return 1;
8563 }
8564
8565 uword
8566 unformat_udp_mask (unformat_input_t * input, va_list * args)
8567 {
8568   u8 **maskp = va_arg (*args, u8 **);
8569   u8 *mask = 0;
8570   u8 found_something = 0;
8571   udp_header_t *udp;
8572
8573 #define _(a) u8 a=0;
8574   foreach_udp_proto_field;
8575 #undef _
8576
8577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8578     {
8579       if (0);
8580 #define _(a) else if (unformat (input, #a)) a=1;
8581       foreach_udp_proto_field
8582 #undef _
8583         else
8584         break;
8585     }
8586
8587 #define _(a) found_something += a;
8588   foreach_udp_proto_field;
8589 #undef _
8590
8591   if (found_something == 0)
8592     return 0;
8593
8594   vec_validate (mask, sizeof (*udp) - 1);
8595
8596   udp = (udp_header_t *) mask;
8597
8598 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8599   foreach_udp_proto_field;
8600 #undef _
8601
8602   *maskp = mask;
8603   return 1;
8604 }
8605
8606 uword
8607 unformat_l4_mask (unformat_input_t * input, va_list * args)
8608 {
8609   u8 **maskp = va_arg (*args, u8 **);
8610   u16 src_port = 0, dst_port = 0;
8611   tcpudp_header_t *tcpudp;
8612
8613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8614     {
8615       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8616         return 1;
8617       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8618         return 1;
8619       else if (unformat (input, "src_port"))
8620         src_port = 0xFFFF;
8621       else if (unformat (input, "dst_port"))
8622         dst_port = 0xFFFF;
8623       else
8624         return 0;
8625     }
8626
8627   if (!src_port && !dst_port)
8628     return 0;
8629
8630   u8 *mask = 0;
8631   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8632
8633   tcpudp = (tcpudp_header_t *) mask;
8634   tcpudp->src_port = src_port;
8635   tcpudp->dst_port = dst_port;
8636
8637   *maskp = mask;
8638
8639   return 1;
8640 }
8641
8642 uword
8643 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8644 {
8645   u8 **maskp = va_arg (*args, u8 **);
8646   u8 *mask = 0;
8647   u8 found_something = 0;
8648   ip4_header_t *ip;
8649
8650 #define _(a) u8 a=0;
8651   foreach_ip4_proto_field;
8652 #undef _
8653   u8 version = 0;
8654   u8 hdr_length = 0;
8655
8656
8657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8658     {
8659       if (unformat (input, "version"))
8660         version = 1;
8661       else if (unformat (input, "hdr_length"))
8662         hdr_length = 1;
8663       else if (unformat (input, "src"))
8664         src_address = 1;
8665       else if (unformat (input, "dst"))
8666         dst_address = 1;
8667       else if (unformat (input, "proto"))
8668         protocol = 1;
8669
8670 #define _(a) else if (unformat (input, #a)) a=1;
8671       foreach_ip4_proto_field
8672 #undef _
8673         else
8674         break;
8675     }
8676
8677 #define _(a) found_something += a;
8678   foreach_ip4_proto_field;
8679 #undef _
8680
8681   if (found_something == 0)
8682     return 0;
8683
8684   vec_validate (mask, sizeof (*ip) - 1);
8685
8686   ip = (ip4_header_t *) mask;
8687
8688 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8689   foreach_ip4_proto_field;
8690 #undef _
8691
8692   ip->ip_version_and_header_length = 0;
8693
8694   if (version)
8695     ip->ip_version_and_header_length |= 0xF0;
8696
8697   if (hdr_length)
8698     ip->ip_version_and_header_length |= 0x0F;
8699
8700   *maskp = mask;
8701   return 1;
8702 }
8703
8704 #define foreach_ip6_proto_field                 \
8705 _(src_address)                                  \
8706 _(dst_address)                                  \
8707 _(payload_length)                               \
8708 _(hop_limit)                                    \
8709 _(protocol)
8710
8711 uword
8712 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8713 {
8714   u8 **maskp = va_arg (*args, u8 **);
8715   u8 *mask = 0;
8716   u8 found_something = 0;
8717   ip6_header_t *ip;
8718   u32 ip_version_traffic_class_and_flow_label;
8719
8720 #define _(a) u8 a=0;
8721   foreach_ip6_proto_field;
8722 #undef _
8723   u8 version = 0;
8724   u8 traffic_class = 0;
8725   u8 flow_label = 0;
8726
8727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8728     {
8729       if (unformat (input, "version"))
8730         version = 1;
8731       else if (unformat (input, "traffic-class"))
8732         traffic_class = 1;
8733       else if (unformat (input, "flow-label"))
8734         flow_label = 1;
8735       else if (unformat (input, "src"))
8736         src_address = 1;
8737       else if (unformat (input, "dst"))
8738         dst_address = 1;
8739       else if (unformat (input, "proto"))
8740         protocol = 1;
8741
8742 #define _(a) else if (unformat (input, #a)) a=1;
8743       foreach_ip6_proto_field
8744 #undef _
8745         else
8746         break;
8747     }
8748
8749 #define _(a) found_something += a;
8750   foreach_ip6_proto_field;
8751 #undef _
8752
8753   if (found_something == 0)
8754     return 0;
8755
8756   vec_validate (mask, sizeof (*ip) - 1);
8757
8758   ip = (ip6_header_t *) mask;
8759
8760 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8761   foreach_ip6_proto_field;
8762 #undef _
8763
8764   ip_version_traffic_class_and_flow_label = 0;
8765
8766   if (version)
8767     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8768
8769   if (traffic_class)
8770     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8771
8772   if (flow_label)
8773     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8774
8775   ip->ip_version_traffic_class_and_flow_label =
8776     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8777
8778   *maskp = mask;
8779   return 1;
8780 }
8781
8782 uword
8783 unformat_l3_mask (unformat_input_t * input, va_list * args)
8784 {
8785   u8 **maskp = va_arg (*args, u8 **);
8786
8787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8788     {
8789       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8790         return 1;
8791       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8792         return 1;
8793       else
8794         break;
8795     }
8796   return 0;
8797 }
8798
8799 uword
8800 unformat_l2_mask (unformat_input_t * input, va_list * args)
8801 {
8802   u8 **maskp = va_arg (*args, u8 **);
8803   u8 *mask = 0;
8804   u8 src = 0;
8805   u8 dst = 0;
8806   u8 proto = 0;
8807   u8 tag1 = 0;
8808   u8 tag2 = 0;
8809   u8 ignore_tag1 = 0;
8810   u8 ignore_tag2 = 0;
8811   u8 cos1 = 0;
8812   u8 cos2 = 0;
8813   u8 dot1q = 0;
8814   u8 dot1ad = 0;
8815   int len = 14;
8816
8817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8818     {
8819       if (unformat (input, "src"))
8820         src = 1;
8821       else if (unformat (input, "dst"))
8822         dst = 1;
8823       else if (unformat (input, "proto"))
8824         proto = 1;
8825       else if (unformat (input, "tag1"))
8826         tag1 = 1;
8827       else if (unformat (input, "tag2"))
8828         tag2 = 1;
8829       else if (unformat (input, "ignore-tag1"))
8830         ignore_tag1 = 1;
8831       else if (unformat (input, "ignore-tag2"))
8832         ignore_tag2 = 1;
8833       else if (unformat (input, "cos1"))
8834         cos1 = 1;
8835       else if (unformat (input, "cos2"))
8836         cos2 = 1;
8837       else if (unformat (input, "dot1q"))
8838         dot1q = 1;
8839       else if (unformat (input, "dot1ad"))
8840         dot1ad = 1;
8841       else
8842         break;
8843     }
8844   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8845        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8846     return 0;
8847
8848   if (tag1 || ignore_tag1 || cos1 || dot1q)
8849     len = 18;
8850   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8851     len = 22;
8852
8853   vec_validate (mask, len - 1);
8854
8855   if (dst)
8856     memset (mask, 0xff, 6);
8857
8858   if (src)
8859     memset (mask + 6, 0xff, 6);
8860
8861   if (tag2 || dot1ad)
8862     {
8863       /* inner vlan tag */
8864       if (tag2)
8865         {
8866           mask[19] = 0xff;
8867           mask[18] = 0x0f;
8868         }
8869       if (cos2)
8870         mask[18] |= 0xe0;
8871       if (proto)
8872         mask[21] = mask[20] = 0xff;
8873       if (tag1)
8874         {
8875           mask[15] = 0xff;
8876           mask[14] = 0x0f;
8877         }
8878       if (cos1)
8879         mask[14] |= 0xe0;
8880       *maskp = mask;
8881       return 1;
8882     }
8883   if (tag1 | dot1q)
8884     {
8885       if (tag1)
8886         {
8887           mask[15] = 0xff;
8888           mask[14] = 0x0f;
8889         }
8890       if (cos1)
8891         mask[14] |= 0xe0;
8892       if (proto)
8893         mask[16] = mask[17] = 0xff;
8894
8895       *maskp = mask;
8896       return 1;
8897     }
8898   if (cos2)
8899     mask[18] |= 0xe0;
8900   if (cos1)
8901     mask[14] |= 0xe0;
8902   if (proto)
8903     mask[12] = mask[13] = 0xff;
8904
8905   *maskp = mask;
8906   return 1;
8907 }
8908
8909 uword
8910 unformat_classify_mask (unformat_input_t * input, va_list * args)
8911 {
8912   u8 **maskp = va_arg (*args, u8 **);
8913   u32 *skipp = va_arg (*args, u32 *);
8914   u32 *matchp = va_arg (*args, u32 *);
8915   u32 match;
8916   u8 *mask = 0;
8917   u8 *l2 = 0;
8918   u8 *l3 = 0;
8919   u8 *l4 = 0;
8920   int i;
8921
8922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8923     {
8924       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8925         ;
8926       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8927         ;
8928       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8929         ;
8930       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8931         ;
8932       else
8933         break;
8934     }
8935
8936   if (l4 && !l3)
8937     {
8938       vec_free (mask);
8939       vec_free (l2);
8940       vec_free (l4);
8941       return 0;
8942     }
8943
8944   if (mask || l2 || l3 || l4)
8945     {
8946       if (l2 || l3 || l4)
8947         {
8948           /* "With a free Ethernet header in every package" */
8949           if (l2 == 0)
8950             vec_validate (l2, 13);
8951           mask = l2;
8952           if (vec_len (l3))
8953             {
8954               vec_append (mask, l3);
8955               vec_free (l3);
8956             }
8957           if (vec_len (l4))
8958             {
8959               vec_append (mask, l4);
8960               vec_free (l4);
8961             }
8962         }
8963
8964       /* Scan forward looking for the first significant mask octet */
8965       for (i = 0; i < vec_len (mask); i++)
8966         if (mask[i])
8967           break;
8968
8969       /* compute (skip, match) params */
8970       *skipp = i / sizeof (u32x4);
8971       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8972
8973       /* Pad mask to an even multiple of the vector size */
8974       while (vec_len (mask) % sizeof (u32x4))
8975         vec_add1 (mask, 0);
8976
8977       match = vec_len (mask) / sizeof (u32x4);
8978
8979       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8980         {
8981           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8982           if (*tmp || *(tmp + 1))
8983             break;
8984           match--;
8985         }
8986       if (match == 0)
8987         clib_warning ("BUG: match 0");
8988
8989       _vec_len (mask) = match * sizeof (u32x4);
8990
8991       *matchp = match;
8992       *maskp = mask;
8993
8994       return 1;
8995     }
8996
8997   return 0;
8998 }
8999 #endif /* VPP_API_TEST_BUILTIN */
9000
9001 #define foreach_l2_next                         \
9002 _(drop, DROP)                                   \
9003 _(ethernet, ETHERNET_INPUT)                     \
9004 _(ip4, IP4_INPUT)                               \
9005 _(ip6, IP6_INPUT)
9006
9007 uword
9008 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9009 {
9010   u32 *miss_next_indexp = va_arg (*args, u32 *);
9011   u32 next_index = 0;
9012   u32 tmp;
9013
9014 #define _(n,N) \
9015   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9016   foreach_l2_next;
9017 #undef _
9018
9019   if (unformat (input, "%d", &tmp))
9020     {
9021       next_index = tmp;
9022       goto out;
9023     }
9024
9025   return 0;
9026
9027 out:
9028   *miss_next_indexp = next_index;
9029   return 1;
9030 }
9031
9032 #define foreach_ip_next                         \
9033 _(drop, DROP)                                   \
9034 _(local, LOCAL)                                 \
9035 _(rewrite, REWRITE)
9036
9037 uword
9038 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9039 {
9040   u32 *miss_next_indexp = va_arg (*args, u32 *);
9041   u32 next_index = 0;
9042   u32 tmp;
9043
9044 #define _(n,N) \
9045   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9046   foreach_ip_next;
9047 #undef _
9048
9049   if (unformat (input, "%d", &tmp))
9050     {
9051       next_index = tmp;
9052       goto out;
9053     }
9054
9055   return 0;
9056
9057 out:
9058   *miss_next_indexp = next_index;
9059   return 1;
9060 }
9061
9062 #define foreach_acl_next                        \
9063 _(deny, DENY)
9064
9065 uword
9066 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9067 {
9068   u32 *miss_next_indexp = va_arg (*args, u32 *);
9069   u32 next_index = 0;
9070   u32 tmp;
9071
9072 #define _(n,N) \
9073   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9074   foreach_acl_next;
9075 #undef _
9076
9077   if (unformat (input, "permit"))
9078     {
9079       next_index = ~0;
9080       goto out;
9081     }
9082   else if (unformat (input, "%d", &tmp))
9083     {
9084       next_index = tmp;
9085       goto out;
9086     }
9087
9088   return 0;
9089
9090 out:
9091   *miss_next_indexp = next_index;
9092   return 1;
9093 }
9094
9095 uword
9096 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9097 {
9098   u32 *r = va_arg (*args, u32 *);
9099
9100   if (unformat (input, "conform-color"))
9101     *r = POLICE_CONFORM;
9102   else if (unformat (input, "exceed-color"))
9103     *r = POLICE_EXCEED;
9104   else
9105     return 0;
9106
9107   return 1;
9108 }
9109
9110 static int
9111 api_classify_add_del_table (vat_main_t * vam)
9112 {
9113   unformat_input_t *i = vam->input;
9114   vl_api_classify_add_del_table_t *mp;
9115
9116   u32 nbuckets = 2;
9117   u32 skip = ~0;
9118   u32 match = ~0;
9119   int is_add = 1;
9120   int del_chain = 0;
9121   u32 table_index = ~0;
9122   u32 next_table_index = ~0;
9123   u32 miss_next_index = ~0;
9124   u32 memory_size = 32 << 20;
9125   u8 *mask = 0;
9126   u32 current_data_flag = 0;
9127   int current_data_offset = 0;
9128   int ret;
9129
9130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9131     {
9132       if (unformat (i, "del"))
9133         is_add = 0;
9134       else if (unformat (i, "del-chain"))
9135         {
9136           is_add = 0;
9137           del_chain = 1;
9138         }
9139       else if (unformat (i, "buckets %d", &nbuckets))
9140         ;
9141       else if (unformat (i, "memory_size %d", &memory_size))
9142         ;
9143       else if (unformat (i, "skip %d", &skip))
9144         ;
9145       else if (unformat (i, "match %d", &match))
9146         ;
9147       else if (unformat (i, "table %d", &table_index))
9148         ;
9149       else if (unformat (i, "mask %U", unformat_classify_mask,
9150                          &mask, &skip, &match))
9151         ;
9152       else if (unformat (i, "next-table %d", &next_table_index))
9153         ;
9154       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9155                          &miss_next_index))
9156         ;
9157       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9158                          &miss_next_index))
9159         ;
9160       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9161                          &miss_next_index))
9162         ;
9163       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9164         ;
9165       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9166         ;
9167       else
9168         break;
9169     }
9170
9171   if (is_add && mask == 0)
9172     {
9173       errmsg ("Mask required");
9174       return -99;
9175     }
9176
9177   if (is_add && skip == ~0)
9178     {
9179       errmsg ("skip count required");
9180       return -99;
9181     }
9182
9183   if (is_add && match == ~0)
9184     {
9185       errmsg ("match count required");
9186       return -99;
9187     }
9188
9189   if (!is_add && table_index == ~0)
9190     {
9191       errmsg ("table index required for delete");
9192       return -99;
9193     }
9194
9195   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9196
9197   mp->is_add = is_add;
9198   mp->del_chain = del_chain;
9199   mp->table_index = ntohl (table_index);
9200   mp->nbuckets = ntohl (nbuckets);
9201   mp->memory_size = ntohl (memory_size);
9202   mp->skip_n_vectors = ntohl (skip);
9203   mp->match_n_vectors = ntohl (match);
9204   mp->next_table_index = ntohl (next_table_index);
9205   mp->miss_next_index = ntohl (miss_next_index);
9206   mp->current_data_flag = ntohl (current_data_flag);
9207   mp->current_data_offset = ntohl (current_data_offset);
9208   clib_memcpy (mp->mask, mask, vec_len (mask));
9209
9210   vec_free (mask);
9211
9212   S (mp);
9213   W (ret);
9214   return ret;
9215 }
9216
9217 #if VPP_API_TEST_BUILTIN == 0
9218 uword
9219 unformat_l4_match (unformat_input_t * input, va_list * args)
9220 {
9221   u8 **matchp = va_arg (*args, u8 **);
9222
9223   u8 *proto_header = 0;
9224   int src_port = 0;
9225   int dst_port = 0;
9226
9227   tcpudp_header_t h;
9228
9229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9230     {
9231       if (unformat (input, "src_port %d", &src_port))
9232         ;
9233       else if (unformat (input, "dst_port %d", &dst_port))
9234         ;
9235       else
9236         return 0;
9237     }
9238
9239   h.src_port = clib_host_to_net_u16 (src_port);
9240   h.dst_port = clib_host_to_net_u16 (dst_port);
9241   vec_validate (proto_header, sizeof (h) - 1);
9242   memcpy (proto_header, &h, sizeof (h));
9243
9244   *matchp = proto_header;
9245
9246   return 1;
9247 }
9248
9249 uword
9250 unformat_ip4_match (unformat_input_t * input, va_list * args)
9251 {
9252   u8 **matchp = va_arg (*args, u8 **);
9253   u8 *match = 0;
9254   ip4_header_t *ip;
9255   int version = 0;
9256   u32 version_val;
9257   int hdr_length = 0;
9258   u32 hdr_length_val;
9259   int src = 0, dst = 0;
9260   ip4_address_t src_val, dst_val;
9261   int proto = 0;
9262   u32 proto_val;
9263   int tos = 0;
9264   u32 tos_val;
9265   int length = 0;
9266   u32 length_val;
9267   int fragment_id = 0;
9268   u32 fragment_id_val;
9269   int ttl = 0;
9270   int ttl_val;
9271   int checksum = 0;
9272   u32 checksum_val;
9273
9274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9275     {
9276       if (unformat (input, "version %d", &version_val))
9277         version = 1;
9278       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9279         hdr_length = 1;
9280       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9281         src = 1;
9282       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9283         dst = 1;
9284       else if (unformat (input, "proto %d", &proto_val))
9285         proto = 1;
9286       else if (unformat (input, "tos %d", &tos_val))
9287         tos = 1;
9288       else if (unformat (input, "length %d", &length_val))
9289         length = 1;
9290       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9291         fragment_id = 1;
9292       else if (unformat (input, "ttl %d", &ttl_val))
9293         ttl = 1;
9294       else if (unformat (input, "checksum %d", &checksum_val))
9295         checksum = 1;
9296       else
9297         break;
9298     }
9299
9300   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9301       + ttl + checksum == 0)
9302     return 0;
9303
9304   /*
9305    * Aligned because we use the real comparison functions
9306    */
9307   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9308
9309   ip = (ip4_header_t *) match;
9310
9311   /* These are realistically matched in practice */
9312   if (src)
9313     ip->src_address.as_u32 = src_val.as_u32;
9314
9315   if (dst)
9316     ip->dst_address.as_u32 = dst_val.as_u32;
9317
9318   if (proto)
9319     ip->protocol = proto_val;
9320
9321
9322   /* These are not, but they're included for completeness */
9323   if (version)
9324     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9325
9326   if (hdr_length)
9327     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9328
9329   if (tos)
9330     ip->tos = tos_val;
9331
9332   if (length)
9333     ip->length = clib_host_to_net_u16 (length_val);
9334
9335   if (ttl)
9336     ip->ttl = ttl_val;
9337
9338   if (checksum)
9339     ip->checksum = clib_host_to_net_u16 (checksum_val);
9340
9341   *matchp = match;
9342   return 1;
9343 }
9344
9345 uword
9346 unformat_ip6_match (unformat_input_t * input, va_list * args)
9347 {
9348   u8 **matchp = va_arg (*args, u8 **);
9349   u8 *match = 0;
9350   ip6_header_t *ip;
9351   int version = 0;
9352   u32 version_val;
9353   u8 traffic_class = 0;
9354   u32 traffic_class_val = 0;
9355   u8 flow_label = 0;
9356   u8 flow_label_val;
9357   int src = 0, dst = 0;
9358   ip6_address_t src_val, dst_val;
9359   int proto = 0;
9360   u32 proto_val;
9361   int payload_length = 0;
9362   u32 payload_length_val;
9363   int hop_limit = 0;
9364   int hop_limit_val;
9365   u32 ip_version_traffic_class_and_flow_label;
9366
9367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9368     {
9369       if (unformat (input, "version %d", &version_val))
9370         version = 1;
9371       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9372         traffic_class = 1;
9373       else if (unformat (input, "flow_label %d", &flow_label_val))
9374         flow_label = 1;
9375       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9376         src = 1;
9377       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9378         dst = 1;
9379       else if (unformat (input, "proto %d", &proto_val))
9380         proto = 1;
9381       else if (unformat (input, "payload_length %d", &payload_length_val))
9382         payload_length = 1;
9383       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9384         hop_limit = 1;
9385       else
9386         break;
9387     }
9388
9389   if (version + traffic_class + flow_label + src + dst + proto +
9390       payload_length + hop_limit == 0)
9391     return 0;
9392
9393   /*
9394    * Aligned because we use the real comparison functions
9395    */
9396   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9397
9398   ip = (ip6_header_t *) match;
9399
9400   if (src)
9401     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9402
9403   if (dst)
9404     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9405
9406   if (proto)
9407     ip->protocol = proto_val;
9408
9409   ip_version_traffic_class_and_flow_label = 0;
9410
9411   if (version)
9412     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9413
9414   if (traffic_class)
9415     ip_version_traffic_class_and_flow_label |=
9416       (traffic_class_val & 0xFF) << 20;
9417
9418   if (flow_label)
9419     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9420
9421   ip->ip_version_traffic_class_and_flow_label =
9422     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9423
9424   if (payload_length)
9425     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9426
9427   if (hop_limit)
9428     ip->hop_limit = hop_limit_val;
9429
9430   *matchp = match;
9431   return 1;
9432 }
9433
9434 uword
9435 unformat_l3_match (unformat_input_t * input, va_list * args)
9436 {
9437   u8 **matchp = va_arg (*args, u8 **);
9438
9439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9440     {
9441       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9442         return 1;
9443       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9444         return 1;
9445       else
9446         break;
9447     }
9448   return 0;
9449 }
9450
9451 uword
9452 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9453 {
9454   u8 *tagp = va_arg (*args, u8 *);
9455   u32 tag;
9456
9457   if (unformat (input, "%d", &tag))
9458     {
9459       tagp[0] = (tag >> 8) & 0x0F;
9460       tagp[1] = tag & 0xFF;
9461       return 1;
9462     }
9463
9464   return 0;
9465 }
9466
9467 uword
9468 unformat_l2_match (unformat_input_t * input, va_list * args)
9469 {
9470   u8 **matchp = va_arg (*args, u8 **);
9471   u8 *match = 0;
9472   u8 src = 0;
9473   u8 src_val[6];
9474   u8 dst = 0;
9475   u8 dst_val[6];
9476   u8 proto = 0;
9477   u16 proto_val;
9478   u8 tag1 = 0;
9479   u8 tag1_val[2];
9480   u8 tag2 = 0;
9481   u8 tag2_val[2];
9482   int len = 14;
9483   u8 ignore_tag1 = 0;
9484   u8 ignore_tag2 = 0;
9485   u8 cos1 = 0;
9486   u8 cos2 = 0;
9487   u32 cos1_val = 0;
9488   u32 cos2_val = 0;
9489
9490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9491     {
9492       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9493         src = 1;
9494       else
9495         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9496         dst = 1;
9497       else if (unformat (input, "proto %U",
9498                          unformat_ethernet_type_host_byte_order, &proto_val))
9499         proto = 1;
9500       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9501         tag1 = 1;
9502       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9503         tag2 = 1;
9504       else if (unformat (input, "ignore-tag1"))
9505         ignore_tag1 = 1;
9506       else if (unformat (input, "ignore-tag2"))
9507         ignore_tag2 = 1;
9508       else if (unformat (input, "cos1 %d", &cos1_val))
9509         cos1 = 1;
9510       else if (unformat (input, "cos2 %d", &cos2_val))
9511         cos2 = 1;
9512       else
9513         break;
9514     }
9515   if ((src + dst + proto + tag1 + tag2 +
9516        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9517     return 0;
9518
9519   if (tag1 || ignore_tag1 || cos1)
9520     len = 18;
9521   if (tag2 || ignore_tag2 || cos2)
9522     len = 22;
9523
9524   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9525
9526   if (dst)
9527     clib_memcpy (match, dst_val, 6);
9528
9529   if (src)
9530     clib_memcpy (match + 6, src_val, 6);
9531
9532   if (tag2)
9533     {
9534       /* inner vlan tag */
9535       match[19] = tag2_val[1];
9536       match[18] = tag2_val[0];
9537       if (cos2)
9538         match[18] |= (cos2_val & 0x7) << 5;
9539       if (proto)
9540         {
9541           match[21] = proto_val & 0xff;
9542           match[20] = proto_val >> 8;
9543         }
9544       if (tag1)
9545         {
9546           match[15] = tag1_val[1];
9547           match[14] = tag1_val[0];
9548         }
9549       if (cos1)
9550         match[14] |= (cos1_val & 0x7) << 5;
9551       *matchp = match;
9552       return 1;
9553     }
9554   if (tag1)
9555     {
9556       match[15] = tag1_val[1];
9557       match[14] = tag1_val[0];
9558       if (proto)
9559         {
9560           match[17] = proto_val & 0xff;
9561           match[16] = proto_val >> 8;
9562         }
9563       if (cos1)
9564         match[14] |= (cos1_val & 0x7) << 5;
9565
9566       *matchp = match;
9567       return 1;
9568     }
9569   if (cos2)
9570     match[18] |= (cos2_val & 0x7) << 5;
9571   if (cos1)
9572     match[14] |= (cos1_val & 0x7) << 5;
9573   if (proto)
9574     {
9575       match[13] = proto_val & 0xff;
9576       match[12] = proto_val >> 8;
9577     }
9578
9579   *matchp = match;
9580   return 1;
9581 }
9582 #endif
9583
9584 uword
9585 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9586 {
9587   u8 **matchp = va_arg (*args, u8 **);
9588   u32 skip_n_vectors = va_arg (*args, u32);
9589   u32 match_n_vectors = va_arg (*args, u32);
9590
9591   u8 *match = 0;
9592   u8 *l2 = 0;
9593   u8 *l3 = 0;
9594   u8 *l4 = 0;
9595
9596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9597     {
9598       if (unformat (input, "hex %U", unformat_hex_string, &match))
9599         ;
9600       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9601         ;
9602       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9603         ;
9604       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9605         ;
9606       else
9607         break;
9608     }
9609
9610   if (l4 && !l3)
9611     {
9612       vec_free (match);
9613       vec_free (l2);
9614       vec_free (l4);
9615       return 0;
9616     }
9617
9618   if (match || l2 || l3 || l4)
9619     {
9620       if (l2 || l3 || l4)
9621         {
9622           /* "Win a free Ethernet header in every packet" */
9623           if (l2 == 0)
9624             vec_validate_aligned (l2, 13, sizeof (u32x4));
9625           match = l2;
9626           if (vec_len (l3))
9627             {
9628               vec_append_aligned (match, l3, sizeof (u32x4));
9629               vec_free (l3);
9630             }
9631           if (vec_len (l4))
9632             {
9633               vec_append_aligned (match, l4, sizeof (u32x4));
9634               vec_free (l4);
9635             }
9636         }
9637
9638       /* Make sure the vector is big enough even if key is all 0's */
9639       vec_validate_aligned
9640         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9641          sizeof (u32x4));
9642
9643       /* Set size, include skipped vectors */
9644       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9645
9646       *matchp = match;
9647
9648       return 1;
9649     }
9650
9651   return 0;
9652 }
9653
9654 static int
9655 api_classify_add_del_session (vat_main_t * vam)
9656 {
9657   unformat_input_t *i = vam->input;
9658   vl_api_classify_add_del_session_t *mp;
9659   int is_add = 1;
9660   u32 table_index = ~0;
9661   u32 hit_next_index = ~0;
9662   u32 opaque_index = ~0;
9663   u8 *match = 0;
9664   i32 advance = 0;
9665   u32 skip_n_vectors = 0;
9666   u32 match_n_vectors = 0;
9667   u32 action = 0;
9668   u32 metadata = 0;
9669   int ret;
9670
9671   /*
9672    * Warning: you have to supply skip_n and match_n
9673    * because the API client cant simply look at the classify
9674    * table object.
9675    */
9676
9677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9678     {
9679       if (unformat (i, "del"))
9680         is_add = 0;
9681       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9682                          &hit_next_index))
9683         ;
9684       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9685                          &hit_next_index))
9686         ;
9687       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9688                          &hit_next_index))
9689         ;
9690       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9691         ;
9692       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9693         ;
9694       else if (unformat (i, "opaque-index %d", &opaque_index))
9695         ;
9696       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9697         ;
9698       else if (unformat (i, "match_n %d", &match_n_vectors))
9699         ;
9700       else if (unformat (i, "match %U", api_unformat_classify_match,
9701                          &match, skip_n_vectors, match_n_vectors))
9702         ;
9703       else if (unformat (i, "advance %d", &advance))
9704         ;
9705       else if (unformat (i, "table-index %d", &table_index))
9706         ;
9707       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9708         action = 1;
9709       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9710         action = 2;
9711       else if (unformat (i, "action %d", &action))
9712         ;
9713       else if (unformat (i, "metadata %d", &metadata))
9714         ;
9715       else
9716         break;
9717     }
9718
9719   if (table_index == ~0)
9720     {
9721       errmsg ("Table index required");
9722       return -99;
9723     }
9724
9725   if (is_add && match == 0)
9726     {
9727       errmsg ("Match value required");
9728       return -99;
9729     }
9730
9731   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9732
9733   mp->is_add = is_add;
9734   mp->table_index = ntohl (table_index);
9735   mp->hit_next_index = ntohl (hit_next_index);
9736   mp->opaque_index = ntohl (opaque_index);
9737   mp->advance = ntohl (advance);
9738   mp->action = action;
9739   mp->metadata = ntohl (metadata);
9740   clib_memcpy (mp->match, match, vec_len (match));
9741   vec_free (match);
9742
9743   S (mp);
9744   W (ret);
9745   return ret;
9746 }
9747
9748 static int
9749 api_classify_set_interface_ip_table (vat_main_t * vam)
9750 {
9751   unformat_input_t *i = vam->input;
9752   vl_api_classify_set_interface_ip_table_t *mp;
9753   u32 sw_if_index;
9754   int sw_if_index_set;
9755   u32 table_index = ~0;
9756   u8 is_ipv6 = 0;
9757   int ret;
9758
9759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9760     {
9761       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9762         sw_if_index_set = 1;
9763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9764         sw_if_index_set = 1;
9765       else if (unformat (i, "table %d", &table_index))
9766         ;
9767       else
9768         {
9769           clib_warning ("parse error '%U'", format_unformat_error, i);
9770           return -99;
9771         }
9772     }
9773
9774   if (sw_if_index_set == 0)
9775     {
9776       errmsg ("missing interface name or sw_if_index");
9777       return -99;
9778     }
9779
9780
9781   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9782
9783   mp->sw_if_index = ntohl (sw_if_index);
9784   mp->table_index = ntohl (table_index);
9785   mp->is_ipv6 = is_ipv6;
9786
9787   S (mp);
9788   W (ret);
9789   return ret;
9790 }
9791
9792 static int
9793 api_classify_set_interface_l2_tables (vat_main_t * vam)
9794 {
9795   unformat_input_t *i = vam->input;
9796   vl_api_classify_set_interface_l2_tables_t *mp;
9797   u32 sw_if_index;
9798   int sw_if_index_set;
9799   u32 ip4_table_index = ~0;
9800   u32 ip6_table_index = ~0;
9801   u32 other_table_index = ~0;
9802   u32 is_input = 1;
9803   int ret;
9804
9805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9806     {
9807       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9808         sw_if_index_set = 1;
9809       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9810         sw_if_index_set = 1;
9811       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9812         ;
9813       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9814         ;
9815       else if (unformat (i, "other-table %d", &other_table_index))
9816         ;
9817       else if (unformat (i, "is-input %d", &is_input))
9818         ;
9819       else
9820         {
9821           clib_warning ("parse error '%U'", format_unformat_error, i);
9822           return -99;
9823         }
9824     }
9825
9826   if (sw_if_index_set == 0)
9827     {
9828       errmsg ("missing interface name or sw_if_index");
9829       return -99;
9830     }
9831
9832
9833   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
9834
9835   mp->sw_if_index = ntohl (sw_if_index);
9836   mp->ip4_table_index = ntohl (ip4_table_index);
9837   mp->ip6_table_index = ntohl (ip6_table_index);
9838   mp->other_table_index = ntohl (other_table_index);
9839   mp->is_input = (u8) is_input;
9840
9841   S (mp);
9842   W (ret);
9843   return ret;
9844 }
9845
9846 static int
9847 api_set_ipfix_exporter (vat_main_t * vam)
9848 {
9849   unformat_input_t *i = vam->input;
9850   vl_api_set_ipfix_exporter_t *mp;
9851   ip4_address_t collector_address;
9852   u8 collector_address_set = 0;
9853   u32 collector_port = ~0;
9854   ip4_address_t src_address;
9855   u8 src_address_set = 0;
9856   u32 vrf_id = ~0;
9857   u32 path_mtu = ~0;
9858   u32 template_interval = ~0;
9859   u8 udp_checksum = 0;
9860   int ret;
9861
9862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9863     {
9864       if (unformat (i, "collector_address %U", unformat_ip4_address,
9865                     &collector_address))
9866         collector_address_set = 1;
9867       else if (unformat (i, "collector_port %d", &collector_port))
9868         ;
9869       else if (unformat (i, "src_address %U", unformat_ip4_address,
9870                          &src_address))
9871         src_address_set = 1;
9872       else if (unformat (i, "vrf_id %d", &vrf_id))
9873         ;
9874       else if (unformat (i, "path_mtu %d", &path_mtu))
9875         ;
9876       else if (unformat (i, "template_interval %d", &template_interval))
9877         ;
9878       else if (unformat (i, "udp_checksum"))
9879         udp_checksum = 1;
9880       else
9881         break;
9882     }
9883
9884   if (collector_address_set == 0)
9885     {
9886       errmsg ("collector_address required");
9887       return -99;
9888     }
9889
9890   if (src_address_set == 0)
9891     {
9892       errmsg ("src_address required");
9893       return -99;
9894     }
9895
9896   M (SET_IPFIX_EXPORTER, mp);
9897
9898   memcpy (mp->collector_address, collector_address.data,
9899           sizeof (collector_address.data));
9900   mp->collector_port = htons ((u16) collector_port);
9901   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9902   mp->vrf_id = htonl (vrf_id);
9903   mp->path_mtu = htonl (path_mtu);
9904   mp->template_interval = htonl (template_interval);
9905   mp->udp_checksum = udp_checksum;
9906
9907   S (mp);
9908   W (ret);
9909   return ret;
9910 }
9911
9912 static int
9913 api_set_ipfix_classify_stream (vat_main_t * vam)
9914 {
9915   unformat_input_t *i = vam->input;
9916   vl_api_set_ipfix_classify_stream_t *mp;
9917   u32 domain_id = 0;
9918   u32 src_port = UDP_DST_PORT_ipfix;
9919   int ret;
9920
9921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9922     {
9923       if (unformat (i, "domain %d", &domain_id))
9924         ;
9925       else if (unformat (i, "src_port %d", &src_port))
9926         ;
9927       else
9928         {
9929           errmsg ("unknown input `%U'", format_unformat_error, i);
9930           return -99;
9931         }
9932     }
9933
9934   M (SET_IPFIX_CLASSIFY_STREAM, mp);
9935
9936   mp->domain_id = htonl (domain_id);
9937   mp->src_port = htons ((u16) src_port);
9938
9939   S (mp);
9940   W (ret);
9941   return ret;
9942 }
9943
9944 static int
9945 api_ipfix_classify_table_add_del (vat_main_t * vam)
9946 {
9947   unformat_input_t *i = vam->input;
9948   vl_api_ipfix_classify_table_add_del_t *mp;
9949   int is_add = -1;
9950   u32 classify_table_index = ~0;
9951   u8 ip_version = 0;
9952   u8 transport_protocol = 255;
9953   int ret;
9954
9955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9956     {
9957       if (unformat (i, "add"))
9958         is_add = 1;
9959       else if (unformat (i, "del"))
9960         is_add = 0;
9961       else if (unformat (i, "table %d", &classify_table_index))
9962         ;
9963       else if (unformat (i, "ip4"))
9964         ip_version = 4;
9965       else if (unformat (i, "ip6"))
9966         ip_version = 6;
9967       else if (unformat (i, "tcp"))
9968         transport_protocol = 6;
9969       else if (unformat (i, "udp"))
9970         transport_protocol = 17;
9971       else
9972         {
9973           errmsg ("unknown input `%U'", format_unformat_error, i);
9974           return -99;
9975         }
9976     }
9977
9978   if (is_add == -1)
9979     {
9980       errmsg ("expecting: add|del");
9981       return -99;
9982     }
9983   if (classify_table_index == ~0)
9984     {
9985       errmsg ("classifier table not specified");
9986       return -99;
9987     }
9988   if (ip_version == 0)
9989     {
9990       errmsg ("IP version not specified");
9991       return -99;
9992     }
9993
9994   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9995
9996   mp->is_add = is_add;
9997   mp->table_id = htonl (classify_table_index);
9998   mp->ip_version = ip_version;
9999   mp->transport_protocol = transport_protocol;
10000
10001   S (mp);
10002   W (ret);
10003   return ret;
10004 }
10005
10006 static int
10007 api_get_node_index (vat_main_t * vam)
10008 {
10009   unformat_input_t *i = vam->input;
10010   vl_api_get_node_index_t *mp;
10011   u8 *name = 0;
10012   int ret;
10013
10014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10015     {
10016       if (unformat (i, "node %s", &name))
10017         ;
10018       else
10019         break;
10020     }
10021   if (name == 0)
10022     {
10023       errmsg ("node name required");
10024       return -99;
10025     }
10026   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10027     {
10028       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10029       return -99;
10030     }
10031
10032   M (GET_NODE_INDEX, mp);
10033   clib_memcpy (mp->node_name, name, vec_len (name));
10034   vec_free (name);
10035
10036   S (mp);
10037   W (ret);
10038   return ret;
10039 }
10040
10041 static int
10042 api_get_next_index (vat_main_t * vam)
10043 {
10044   unformat_input_t *i = vam->input;
10045   vl_api_get_next_index_t *mp;
10046   u8 *node_name = 0, *next_node_name = 0;
10047   int ret;
10048
10049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10050     {
10051       if (unformat (i, "node-name %s", &node_name))
10052         ;
10053       else if (unformat (i, "next-node-name %s", &next_node_name))
10054         break;
10055     }
10056
10057   if (node_name == 0)
10058     {
10059       errmsg ("node name required");
10060       return -99;
10061     }
10062   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10063     {
10064       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10065       return -99;
10066     }
10067
10068   if (next_node_name == 0)
10069     {
10070       errmsg ("next node name required");
10071       return -99;
10072     }
10073   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10074     {
10075       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10076       return -99;
10077     }
10078
10079   M (GET_NEXT_INDEX, mp);
10080   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10081   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10082   vec_free (node_name);
10083   vec_free (next_node_name);
10084
10085   S (mp);
10086   W (ret);
10087   return ret;
10088 }
10089
10090 static int
10091 api_add_node_next (vat_main_t * vam)
10092 {
10093   unformat_input_t *i = vam->input;
10094   vl_api_add_node_next_t *mp;
10095   u8 *name = 0;
10096   u8 *next = 0;
10097   int ret;
10098
10099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10100     {
10101       if (unformat (i, "node %s", &name))
10102         ;
10103       else if (unformat (i, "next %s", &next))
10104         ;
10105       else
10106         break;
10107     }
10108   if (name == 0)
10109     {
10110       errmsg ("node name required");
10111       return -99;
10112     }
10113   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10114     {
10115       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10116       return -99;
10117     }
10118   if (next == 0)
10119     {
10120       errmsg ("next node required");
10121       return -99;
10122     }
10123   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10124     {
10125       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10126       return -99;
10127     }
10128
10129   M (ADD_NODE_NEXT, mp);
10130   clib_memcpy (mp->node_name, name, vec_len (name));
10131   clib_memcpy (mp->next_name, next, vec_len (next));
10132   vec_free (name);
10133   vec_free (next);
10134
10135   S (mp);
10136   W (ret);
10137   return ret;
10138 }
10139
10140 static int
10141 api_l2tpv3_create_tunnel (vat_main_t * vam)
10142 {
10143   unformat_input_t *i = vam->input;
10144   ip6_address_t client_address, our_address;
10145   int client_address_set = 0;
10146   int our_address_set = 0;
10147   u32 local_session_id = 0;
10148   u32 remote_session_id = 0;
10149   u64 local_cookie = 0;
10150   u64 remote_cookie = 0;
10151   u8 l2_sublayer_present = 0;
10152   vl_api_l2tpv3_create_tunnel_t *mp;
10153   int ret;
10154
10155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10156     {
10157       if (unformat (i, "client_address %U", unformat_ip6_address,
10158                     &client_address))
10159         client_address_set = 1;
10160       else if (unformat (i, "our_address %U", unformat_ip6_address,
10161                          &our_address))
10162         our_address_set = 1;
10163       else if (unformat (i, "local_session_id %d", &local_session_id))
10164         ;
10165       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10166         ;
10167       else if (unformat (i, "local_cookie %lld", &local_cookie))
10168         ;
10169       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10170         ;
10171       else if (unformat (i, "l2-sublayer-present"))
10172         l2_sublayer_present = 1;
10173       else
10174         break;
10175     }
10176
10177   if (client_address_set == 0)
10178     {
10179       errmsg ("client_address required");
10180       return -99;
10181     }
10182
10183   if (our_address_set == 0)
10184     {
10185       errmsg ("our_address required");
10186       return -99;
10187     }
10188
10189   M (L2TPV3_CREATE_TUNNEL, mp);
10190
10191   clib_memcpy (mp->client_address, client_address.as_u8,
10192                sizeof (mp->client_address));
10193
10194   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10195
10196   mp->local_session_id = ntohl (local_session_id);
10197   mp->remote_session_id = ntohl (remote_session_id);
10198   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10199   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10200   mp->l2_sublayer_present = l2_sublayer_present;
10201   mp->is_ipv6 = 1;
10202
10203   S (mp);
10204   W (ret);
10205   return ret;
10206 }
10207
10208 static int
10209 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10210 {
10211   unformat_input_t *i = vam->input;
10212   u32 sw_if_index;
10213   u8 sw_if_index_set = 0;
10214   u64 new_local_cookie = 0;
10215   u64 new_remote_cookie = 0;
10216   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10217   int ret;
10218
10219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10220     {
10221       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10222         sw_if_index_set = 1;
10223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10224         sw_if_index_set = 1;
10225       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10226         ;
10227       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10228         ;
10229       else
10230         break;
10231     }
10232
10233   if (sw_if_index_set == 0)
10234     {
10235       errmsg ("missing interface name or sw_if_index");
10236       return -99;
10237     }
10238
10239   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10240
10241   mp->sw_if_index = ntohl (sw_if_index);
10242   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10243   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10244
10245   S (mp);
10246   W (ret);
10247   return ret;
10248 }
10249
10250 static int
10251 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10252 {
10253   unformat_input_t *i = vam->input;
10254   vl_api_l2tpv3_interface_enable_disable_t *mp;
10255   u32 sw_if_index;
10256   u8 sw_if_index_set = 0;
10257   u8 enable_disable = 1;
10258   int ret;
10259
10260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10261     {
10262       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10263         sw_if_index_set = 1;
10264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10265         sw_if_index_set = 1;
10266       else if (unformat (i, "enable"))
10267         enable_disable = 1;
10268       else if (unformat (i, "disable"))
10269         enable_disable = 0;
10270       else
10271         break;
10272     }
10273
10274   if (sw_if_index_set == 0)
10275     {
10276       errmsg ("missing interface name or sw_if_index");
10277       return -99;
10278     }
10279
10280   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10281
10282   mp->sw_if_index = ntohl (sw_if_index);
10283   mp->enable_disable = enable_disable;
10284
10285   S (mp);
10286   W (ret);
10287   return ret;
10288 }
10289
10290 static int
10291 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10292 {
10293   unformat_input_t *i = vam->input;
10294   vl_api_l2tpv3_set_lookup_key_t *mp;
10295   u8 key = ~0;
10296   int ret;
10297
10298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10299     {
10300       if (unformat (i, "lookup_v6_src"))
10301         key = L2T_LOOKUP_SRC_ADDRESS;
10302       else if (unformat (i, "lookup_v6_dst"))
10303         key = L2T_LOOKUP_DST_ADDRESS;
10304       else if (unformat (i, "lookup_session_id"))
10305         key = L2T_LOOKUP_SESSION_ID;
10306       else
10307         break;
10308     }
10309
10310   if (key == (u8) ~ 0)
10311     {
10312       errmsg ("l2tp session lookup key unset");
10313       return -99;
10314     }
10315
10316   M (L2TPV3_SET_LOOKUP_KEY, mp);
10317
10318   mp->key = key;
10319
10320   S (mp);
10321   W (ret);
10322   return ret;
10323 }
10324
10325 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10326   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10327 {
10328   vat_main_t *vam = &vat_main;
10329
10330   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10331          format_ip6_address, mp->our_address,
10332          format_ip6_address, mp->client_address,
10333          clib_net_to_host_u32 (mp->sw_if_index));
10334
10335   print (vam->ofp,
10336          "   local cookies %016llx %016llx remote cookie %016llx",
10337          clib_net_to_host_u64 (mp->local_cookie[0]),
10338          clib_net_to_host_u64 (mp->local_cookie[1]),
10339          clib_net_to_host_u64 (mp->remote_cookie));
10340
10341   print (vam->ofp, "   local session-id %d remote session-id %d",
10342          clib_net_to_host_u32 (mp->local_session_id),
10343          clib_net_to_host_u32 (mp->remote_session_id));
10344
10345   print (vam->ofp, "   l2 specific sublayer %s\n",
10346          mp->l2_sublayer_present ? "preset" : "absent");
10347
10348 }
10349
10350 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10351   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10352 {
10353   vat_main_t *vam = &vat_main;
10354   vat_json_node_t *node = NULL;
10355   struct in6_addr addr;
10356
10357   if (VAT_JSON_ARRAY != vam->json_tree.type)
10358     {
10359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10360       vat_json_init_array (&vam->json_tree);
10361     }
10362   node = vat_json_array_add (&vam->json_tree);
10363
10364   vat_json_init_object (node);
10365
10366   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10367   vat_json_object_add_ip6 (node, "our_address", addr);
10368   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10369   vat_json_object_add_ip6 (node, "client_address", addr);
10370
10371   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10372   vat_json_init_array (lc);
10373   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10374   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10375   vat_json_object_add_uint (node, "remote_cookie",
10376                             clib_net_to_host_u64 (mp->remote_cookie));
10377
10378   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10379   vat_json_object_add_uint (node, "local_session_id",
10380                             clib_net_to_host_u32 (mp->local_session_id));
10381   vat_json_object_add_uint (node, "remote_session_id",
10382                             clib_net_to_host_u32 (mp->remote_session_id));
10383   vat_json_object_add_string_copy (node, "l2_sublayer",
10384                                    mp->l2_sublayer_present ? (u8 *) "present"
10385                                    : (u8 *) "absent");
10386 }
10387
10388 static int
10389 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10390 {
10391   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10392   vl_api_control_ping_t *mp_ping;
10393   int ret;
10394
10395   /* Get list of l2tpv3-tunnel interfaces */
10396   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10397   S (mp);
10398
10399   /* Use a control ping for synchronization */
10400   M (CONTROL_PING, mp_ping);
10401   S (mp_ping);
10402
10403   W (ret);
10404   return ret;
10405 }
10406
10407
10408 static void vl_api_sw_interface_tap_details_t_handler
10409   (vl_api_sw_interface_tap_details_t * mp)
10410 {
10411   vat_main_t *vam = &vat_main;
10412
10413   print (vam->ofp, "%-16s %d",
10414          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10415 }
10416
10417 static void vl_api_sw_interface_tap_details_t_handler_json
10418   (vl_api_sw_interface_tap_details_t * mp)
10419 {
10420   vat_main_t *vam = &vat_main;
10421   vat_json_node_t *node = NULL;
10422
10423   if (VAT_JSON_ARRAY != vam->json_tree.type)
10424     {
10425       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10426       vat_json_init_array (&vam->json_tree);
10427     }
10428   node = vat_json_array_add (&vam->json_tree);
10429
10430   vat_json_init_object (node);
10431   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10432   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10433 }
10434
10435 static int
10436 api_sw_interface_tap_dump (vat_main_t * vam)
10437 {
10438   vl_api_sw_interface_tap_dump_t *mp;
10439   vl_api_control_ping_t *mp_ping;
10440   int ret;
10441
10442   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10443   /* Get list of tap interfaces */
10444   M (SW_INTERFACE_TAP_DUMP, mp);
10445   S (mp);
10446
10447   /* Use a control ping for synchronization */
10448   M (CONTROL_PING, mp_ping);
10449   S (mp_ping);
10450
10451   W (ret);
10452   return ret;
10453 }
10454
10455 static uword unformat_vxlan_decap_next
10456   (unformat_input_t * input, va_list * args)
10457 {
10458   u32 *result = va_arg (*args, u32 *);
10459   u32 tmp;
10460
10461   if (unformat (input, "l2"))
10462     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10463   else if (unformat (input, "%d", &tmp))
10464     *result = tmp;
10465   else
10466     return 0;
10467   return 1;
10468 }
10469
10470 static int
10471 api_vxlan_add_del_tunnel (vat_main_t * vam)
10472 {
10473   unformat_input_t *line_input = vam->input;
10474   vl_api_vxlan_add_del_tunnel_t *mp;
10475   ip46_address_t src, dst;
10476   u8 is_add = 1;
10477   u8 ipv4_set = 0, ipv6_set = 0;
10478   u8 src_set = 0;
10479   u8 dst_set = 0;
10480   u8 grp_set = 0;
10481   u32 mcast_sw_if_index = ~0;
10482   u32 encap_vrf_id = 0;
10483   u32 decap_next_index = ~0;
10484   u32 vni = 0;
10485   int ret;
10486
10487   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10488   memset (&src, 0, sizeof src);
10489   memset (&dst, 0, sizeof dst);
10490
10491   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10492     {
10493       if (unformat (line_input, "del"))
10494         is_add = 0;
10495       else
10496         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10497         {
10498           ipv4_set = 1;
10499           src_set = 1;
10500         }
10501       else
10502         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10503         {
10504           ipv4_set = 1;
10505           dst_set = 1;
10506         }
10507       else
10508         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10509         {
10510           ipv6_set = 1;
10511           src_set = 1;
10512         }
10513       else
10514         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10515         {
10516           ipv6_set = 1;
10517           dst_set = 1;
10518         }
10519       else if (unformat (line_input, "group %U %U",
10520                          unformat_ip4_address, &dst.ip4,
10521                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10522         {
10523           grp_set = dst_set = 1;
10524           ipv4_set = 1;
10525         }
10526       else if (unformat (line_input, "group %U",
10527                          unformat_ip4_address, &dst.ip4))
10528         {
10529           grp_set = dst_set = 1;
10530           ipv4_set = 1;
10531         }
10532       else if (unformat (line_input, "group %U %U",
10533                          unformat_ip6_address, &dst.ip6,
10534                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10535         {
10536           grp_set = dst_set = 1;
10537           ipv6_set = 1;
10538         }
10539       else if (unformat (line_input, "group %U",
10540                          unformat_ip6_address, &dst.ip6))
10541         {
10542           grp_set = dst_set = 1;
10543           ipv6_set = 1;
10544         }
10545       else
10546         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10547         ;
10548       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10549         ;
10550       else if (unformat (line_input, "decap-next %U",
10551                          unformat_vxlan_decap_next, &decap_next_index))
10552         ;
10553       else if (unformat (line_input, "vni %d", &vni))
10554         ;
10555       else
10556         {
10557           errmsg ("parse error '%U'", format_unformat_error, line_input);
10558           return -99;
10559         }
10560     }
10561
10562   if (src_set == 0)
10563     {
10564       errmsg ("tunnel src address not specified");
10565       return -99;
10566     }
10567   if (dst_set == 0)
10568     {
10569       errmsg ("tunnel dst address not specified");
10570       return -99;
10571     }
10572
10573   if (grp_set && !ip46_address_is_multicast (&dst))
10574     {
10575       errmsg ("tunnel group address not multicast");
10576       return -99;
10577     }
10578   if (grp_set && mcast_sw_if_index == ~0)
10579     {
10580       errmsg ("tunnel nonexistent multicast device");
10581       return -99;
10582     }
10583   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10584     {
10585       errmsg ("tunnel dst address must be unicast");
10586       return -99;
10587     }
10588
10589
10590   if (ipv4_set && ipv6_set)
10591     {
10592       errmsg ("both IPv4 and IPv6 addresses specified");
10593       return -99;
10594     }
10595
10596   if ((vni == 0) || (vni >> 24))
10597     {
10598       errmsg ("vni not specified or out of range");
10599       return -99;
10600     }
10601
10602   M (VXLAN_ADD_DEL_TUNNEL, mp);
10603
10604   if (ipv6_set)
10605     {
10606       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10607       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10608     }
10609   else
10610     {
10611       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10612       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10613     }
10614   mp->encap_vrf_id = ntohl (encap_vrf_id);
10615   mp->decap_next_index = ntohl (decap_next_index);
10616   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10617   mp->vni = ntohl (vni);
10618   mp->is_add = is_add;
10619   mp->is_ipv6 = ipv6_set;
10620
10621   S (mp);
10622   W (ret);
10623   return ret;
10624 }
10625
10626 static void vl_api_vxlan_tunnel_details_t_handler
10627   (vl_api_vxlan_tunnel_details_t * mp)
10628 {
10629   vat_main_t *vam = &vat_main;
10630   ip46_address_t src, dst;
10631
10632   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10633   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10634
10635   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10636          ntohl (mp->sw_if_index),
10637          format_ip46_address, &src, IP46_TYPE_ANY,
10638          format_ip46_address, &dst, IP46_TYPE_ANY,
10639          ntohl (mp->encap_vrf_id),
10640          ntohl (mp->decap_next_index), ntohl (mp->vni),
10641          ntohl (mp->mcast_sw_if_index));
10642 }
10643
10644 static void vl_api_vxlan_tunnel_details_t_handler_json
10645   (vl_api_vxlan_tunnel_details_t * mp)
10646 {
10647   vat_main_t *vam = &vat_main;
10648   vat_json_node_t *node = NULL;
10649
10650   if (VAT_JSON_ARRAY != vam->json_tree.type)
10651     {
10652       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10653       vat_json_init_array (&vam->json_tree);
10654     }
10655   node = vat_json_array_add (&vam->json_tree);
10656
10657   vat_json_init_object (node);
10658   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10659   if (mp->is_ipv6)
10660     {
10661       struct in6_addr ip6;
10662
10663       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10664       vat_json_object_add_ip6 (node, "src_address", ip6);
10665       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10666       vat_json_object_add_ip6 (node, "dst_address", ip6);
10667     }
10668   else
10669     {
10670       struct in_addr ip4;
10671
10672       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10673       vat_json_object_add_ip4 (node, "src_address", ip4);
10674       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10675       vat_json_object_add_ip4 (node, "dst_address", ip4);
10676     }
10677   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10678   vat_json_object_add_uint (node, "decap_next_index",
10679                             ntohl (mp->decap_next_index));
10680   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10681   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10682   vat_json_object_add_uint (node, "mcast_sw_if_index",
10683                             ntohl (mp->mcast_sw_if_index));
10684 }
10685
10686 static int
10687 api_vxlan_tunnel_dump (vat_main_t * vam)
10688 {
10689   unformat_input_t *i = vam->input;
10690   vl_api_vxlan_tunnel_dump_t *mp;
10691   vl_api_control_ping_t *mp_ping;
10692   u32 sw_if_index;
10693   u8 sw_if_index_set = 0;
10694   int ret;
10695
10696   /* Parse args required to build the message */
10697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10698     {
10699       if (unformat (i, "sw_if_index %d", &sw_if_index))
10700         sw_if_index_set = 1;
10701       else
10702         break;
10703     }
10704
10705   if (sw_if_index_set == 0)
10706     {
10707       sw_if_index = ~0;
10708     }
10709
10710   if (!vam->json_output)
10711     {
10712       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10713              "sw_if_index", "src_address", "dst_address",
10714              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10715     }
10716
10717   /* Get list of vxlan-tunnel interfaces */
10718   M (VXLAN_TUNNEL_DUMP, mp);
10719
10720   mp->sw_if_index = htonl (sw_if_index);
10721
10722   S (mp);
10723
10724   /* Use a control ping for synchronization */
10725   M (CONTROL_PING, mp_ping);
10726   S (mp_ping);
10727
10728   W (ret);
10729   return ret;
10730 }
10731
10732 static int
10733 api_gre_add_del_tunnel (vat_main_t * vam)
10734 {
10735   unformat_input_t *line_input = vam->input;
10736   vl_api_gre_add_del_tunnel_t *mp;
10737   ip4_address_t src4, dst4;
10738   u8 is_add = 1;
10739   u8 teb = 0;
10740   u8 src_set = 0;
10741   u8 dst_set = 0;
10742   u32 outer_fib_id = 0;
10743   int ret;
10744
10745   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10746     {
10747       if (unformat (line_input, "del"))
10748         is_add = 0;
10749       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10750         src_set = 1;
10751       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10752         dst_set = 1;
10753       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10754         ;
10755       else if (unformat (line_input, "teb"))
10756         teb = 1;
10757       else
10758         {
10759           errmsg ("parse error '%U'", format_unformat_error, line_input);
10760           return -99;
10761         }
10762     }
10763
10764   if (src_set == 0)
10765     {
10766       errmsg ("tunnel src address not specified");
10767       return -99;
10768     }
10769   if (dst_set == 0)
10770     {
10771       errmsg ("tunnel dst address not specified");
10772       return -99;
10773     }
10774
10775
10776   M (GRE_ADD_DEL_TUNNEL, mp);
10777
10778   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10779   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10780   mp->outer_fib_id = ntohl (outer_fib_id);
10781   mp->is_add = is_add;
10782   mp->teb = teb;
10783
10784   S (mp);
10785   W (ret);
10786   return ret;
10787 }
10788
10789 static void vl_api_gre_tunnel_details_t_handler
10790   (vl_api_gre_tunnel_details_t * mp)
10791 {
10792   vat_main_t *vam = &vat_main;
10793
10794   print (vam->ofp, "%11d%15U%15U%6d%14d",
10795          ntohl (mp->sw_if_index),
10796          format_ip4_address, &mp->src_address,
10797          format_ip4_address, &mp->dst_address,
10798          mp->teb, ntohl (mp->outer_fib_id));
10799 }
10800
10801 static void vl_api_gre_tunnel_details_t_handler_json
10802   (vl_api_gre_tunnel_details_t * mp)
10803 {
10804   vat_main_t *vam = &vat_main;
10805   vat_json_node_t *node = NULL;
10806   struct in_addr ip4;
10807
10808   if (VAT_JSON_ARRAY != vam->json_tree.type)
10809     {
10810       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10811       vat_json_init_array (&vam->json_tree);
10812     }
10813   node = vat_json_array_add (&vam->json_tree);
10814
10815   vat_json_init_object (node);
10816   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10817   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10818   vat_json_object_add_ip4 (node, "src_address", ip4);
10819   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10820   vat_json_object_add_ip4 (node, "dst_address", ip4);
10821   vat_json_object_add_uint (node, "teb", mp->teb);
10822   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10823 }
10824
10825 static int
10826 api_gre_tunnel_dump (vat_main_t * vam)
10827 {
10828   unformat_input_t *i = vam->input;
10829   vl_api_gre_tunnel_dump_t *mp;
10830   vl_api_control_ping_t *mp_ping;
10831   u32 sw_if_index;
10832   u8 sw_if_index_set = 0;
10833   int ret;
10834
10835   /* Parse args required to build the message */
10836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10837     {
10838       if (unformat (i, "sw_if_index %d", &sw_if_index))
10839         sw_if_index_set = 1;
10840       else
10841         break;
10842     }
10843
10844   if (sw_if_index_set == 0)
10845     {
10846       sw_if_index = ~0;
10847     }
10848
10849   if (!vam->json_output)
10850     {
10851       print (vam->ofp, "%11s%15s%15s%6s%14s",
10852              "sw_if_index", "src_address", "dst_address", "teb",
10853              "outer_fib_id");
10854     }
10855
10856   /* Get list of gre-tunnel interfaces */
10857   M (GRE_TUNNEL_DUMP, mp);
10858
10859   mp->sw_if_index = htonl (sw_if_index);
10860
10861   S (mp);
10862
10863   /* Use a control ping for synchronization */
10864   M (CONTROL_PING, mp_ping);
10865   S (mp_ping);
10866
10867   W (ret);
10868   return ret;
10869 }
10870
10871 static int
10872 api_l2_fib_clear_table (vat_main_t * vam)
10873 {
10874 //  unformat_input_t * i = vam->input;
10875   vl_api_l2_fib_clear_table_t *mp;
10876   int ret;
10877
10878   M (L2_FIB_CLEAR_TABLE, mp);
10879
10880   S (mp);
10881   W (ret);
10882   return ret;
10883 }
10884
10885 static int
10886 api_l2_interface_efp_filter (vat_main_t * vam)
10887 {
10888   unformat_input_t *i = vam->input;
10889   vl_api_l2_interface_efp_filter_t *mp;
10890   u32 sw_if_index;
10891   u8 enable = 1;
10892   u8 sw_if_index_set = 0;
10893   int ret;
10894
10895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10896     {
10897       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10898         sw_if_index_set = 1;
10899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10900         sw_if_index_set = 1;
10901       else if (unformat (i, "enable"))
10902         enable = 1;
10903       else if (unformat (i, "disable"))
10904         enable = 0;
10905       else
10906         {
10907           clib_warning ("parse error '%U'", format_unformat_error, i);
10908           return -99;
10909         }
10910     }
10911
10912   if (sw_if_index_set == 0)
10913     {
10914       errmsg ("missing sw_if_index");
10915       return -99;
10916     }
10917
10918   M (L2_INTERFACE_EFP_FILTER, mp);
10919
10920   mp->sw_if_index = ntohl (sw_if_index);
10921   mp->enable_disable = enable;
10922
10923   S (mp);
10924   W (ret);
10925   return ret;
10926 }
10927
10928 #define foreach_vtr_op                          \
10929 _("disable",  L2_VTR_DISABLED)                  \
10930 _("push-1",  L2_VTR_PUSH_1)                     \
10931 _("push-2",  L2_VTR_PUSH_2)                     \
10932 _("pop-1",  L2_VTR_POP_1)                       \
10933 _("pop-2",  L2_VTR_POP_2)                       \
10934 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10935 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10936 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10937 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10938
10939 static int
10940 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10941 {
10942   unformat_input_t *i = vam->input;
10943   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10944   u32 sw_if_index;
10945   u8 sw_if_index_set = 0;
10946   u8 vtr_op_set = 0;
10947   u32 vtr_op = 0;
10948   u32 push_dot1q = 1;
10949   u32 tag1 = ~0;
10950   u32 tag2 = ~0;
10951   int ret;
10952
10953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10954     {
10955       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10956         sw_if_index_set = 1;
10957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10958         sw_if_index_set = 1;
10959       else if (unformat (i, "vtr_op %d", &vtr_op))
10960         vtr_op_set = 1;
10961 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10962       foreach_vtr_op
10963 #undef _
10964         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10965         ;
10966       else if (unformat (i, "tag1 %d", &tag1))
10967         ;
10968       else if (unformat (i, "tag2 %d", &tag2))
10969         ;
10970       else
10971         {
10972           clib_warning ("parse error '%U'", format_unformat_error, i);
10973           return -99;
10974         }
10975     }
10976
10977   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10978     {
10979       errmsg ("missing vtr operation or sw_if_index");
10980       return -99;
10981     }
10982
10983   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
10984   mp->sw_if_index = ntohl (sw_if_index);
10985   mp->vtr_op = ntohl (vtr_op);
10986   mp->push_dot1q = ntohl (push_dot1q);
10987   mp->tag1 = ntohl (tag1);
10988   mp->tag2 = ntohl (tag2);
10989
10990   S (mp);
10991   W (ret);
10992   return ret;
10993 }
10994
10995 static int
10996 api_create_vhost_user_if (vat_main_t * vam)
10997 {
10998   unformat_input_t *i = vam->input;
10999   vl_api_create_vhost_user_if_t *mp;
11000   u8 *file_name;
11001   u8 is_server = 0;
11002   u8 file_name_set = 0;
11003   u32 custom_dev_instance = ~0;
11004   u8 hwaddr[6];
11005   u8 use_custom_mac = 0;
11006   u8 *tag = 0;
11007   int ret;
11008
11009   /* Shut up coverity */
11010   memset (hwaddr, 0, sizeof (hwaddr));
11011
11012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11013     {
11014       if (unformat (i, "socket %s", &file_name))
11015         {
11016           file_name_set = 1;
11017         }
11018       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11019         ;
11020       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11021         use_custom_mac = 1;
11022       else if (unformat (i, "server"))
11023         is_server = 1;
11024       else if (unformat (i, "tag %s", &tag))
11025         ;
11026       else
11027         break;
11028     }
11029
11030   if (file_name_set == 0)
11031     {
11032       errmsg ("missing socket file name");
11033       return -99;
11034     }
11035
11036   if (vec_len (file_name) > 255)
11037     {
11038       errmsg ("socket file name too long");
11039       return -99;
11040     }
11041   vec_add1 (file_name, 0);
11042
11043   M (CREATE_VHOST_USER_IF, mp);
11044
11045   mp->is_server = is_server;
11046   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11047   vec_free (file_name);
11048   if (custom_dev_instance != ~0)
11049     {
11050       mp->renumber = 1;
11051       mp->custom_dev_instance = ntohl (custom_dev_instance);
11052     }
11053   mp->use_custom_mac = use_custom_mac;
11054   clib_memcpy (mp->mac_address, hwaddr, 6);
11055   if (tag)
11056     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11057   vec_free (tag);
11058
11059   S (mp);
11060   W (ret);
11061   return ret;
11062 }
11063
11064 static int
11065 api_modify_vhost_user_if (vat_main_t * vam)
11066 {
11067   unformat_input_t *i = vam->input;
11068   vl_api_modify_vhost_user_if_t *mp;
11069   u8 *file_name;
11070   u8 is_server = 0;
11071   u8 file_name_set = 0;
11072   u32 custom_dev_instance = ~0;
11073   u8 sw_if_index_set = 0;
11074   u32 sw_if_index = (u32) ~ 0;
11075   int ret;
11076
11077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11078     {
11079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11080         sw_if_index_set = 1;
11081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11082         sw_if_index_set = 1;
11083       else if (unformat (i, "socket %s", &file_name))
11084         {
11085           file_name_set = 1;
11086         }
11087       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11088         ;
11089       else if (unformat (i, "server"))
11090         is_server = 1;
11091       else
11092         break;
11093     }
11094
11095   if (sw_if_index_set == 0)
11096     {
11097       errmsg ("missing sw_if_index or interface name");
11098       return -99;
11099     }
11100
11101   if (file_name_set == 0)
11102     {
11103       errmsg ("missing socket file name");
11104       return -99;
11105     }
11106
11107   if (vec_len (file_name) > 255)
11108     {
11109       errmsg ("socket file name too long");
11110       return -99;
11111     }
11112   vec_add1 (file_name, 0);
11113
11114   M (MODIFY_VHOST_USER_IF, mp);
11115
11116   mp->sw_if_index = ntohl (sw_if_index);
11117   mp->is_server = is_server;
11118   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11119   vec_free (file_name);
11120   if (custom_dev_instance != ~0)
11121     {
11122       mp->renumber = 1;
11123       mp->custom_dev_instance = ntohl (custom_dev_instance);
11124     }
11125
11126   S (mp);
11127   W (ret);
11128   return ret;
11129 }
11130
11131 static int
11132 api_delete_vhost_user_if (vat_main_t * vam)
11133 {
11134   unformat_input_t *i = vam->input;
11135   vl_api_delete_vhost_user_if_t *mp;
11136   u32 sw_if_index = ~0;
11137   u8 sw_if_index_set = 0;
11138   int ret;
11139
11140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11141     {
11142       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11143         sw_if_index_set = 1;
11144       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11145         sw_if_index_set = 1;
11146       else
11147         break;
11148     }
11149
11150   if (sw_if_index_set == 0)
11151     {
11152       errmsg ("missing sw_if_index or interface name");
11153       return -99;
11154     }
11155
11156
11157   M (DELETE_VHOST_USER_IF, mp);
11158
11159   mp->sw_if_index = ntohl (sw_if_index);
11160
11161   S (mp);
11162   W (ret);
11163   return ret;
11164 }
11165
11166 static void vl_api_sw_interface_vhost_user_details_t_handler
11167   (vl_api_sw_interface_vhost_user_details_t * mp)
11168 {
11169   vat_main_t *vam = &vat_main;
11170
11171   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11172          (char *) mp->interface_name,
11173          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11174          clib_net_to_host_u64 (mp->features), mp->is_server,
11175          ntohl (mp->num_regions), (char *) mp->sock_filename);
11176   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11177 }
11178
11179 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11180   (vl_api_sw_interface_vhost_user_details_t * mp)
11181 {
11182   vat_main_t *vam = &vat_main;
11183   vat_json_node_t *node = NULL;
11184
11185   if (VAT_JSON_ARRAY != vam->json_tree.type)
11186     {
11187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11188       vat_json_init_array (&vam->json_tree);
11189     }
11190   node = vat_json_array_add (&vam->json_tree);
11191
11192   vat_json_init_object (node);
11193   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11194   vat_json_object_add_string_copy (node, "interface_name",
11195                                    mp->interface_name);
11196   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11197                             ntohl (mp->virtio_net_hdr_sz));
11198   vat_json_object_add_uint (node, "features",
11199                             clib_net_to_host_u64 (mp->features));
11200   vat_json_object_add_uint (node, "is_server", mp->is_server);
11201   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11202   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11203   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11204 }
11205
11206 static int
11207 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11208 {
11209   vl_api_sw_interface_vhost_user_dump_t *mp;
11210   vl_api_control_ping_t *mp_ping;
11211   int ret;
11212   print (vam->ofp,
11213          "Interface name           idx hdr_sz features server regions filename");
11214
11215   /* Get list of vhost-user interfaces */
11216   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11217   S (mp);
11218
11219   /* Use a control ping for synchronization */
11220   M (CONTROL_PING, mp_ping);
11221   S (mp_ping);
11222
11223   W (ret);
11224   return ret;
11225 }
11226
11227 static int
11228 api_show_version (vat_main_t * vam)
11229 {
11230   vl_api_show_version_t *mp;
11231   int ret;
11232
11233   M (SHOW_VERSION, mp);
11234
11235   S (mp);
11236   W (ret);
11237   return ret;
11238 }
11239
11240
11241 static int
11242 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11243 {
11244   unformat_input_t *line_input = vam->input;
11245   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11246   ip4_address_t local4, remote4;
11247   ip6_address_t local6, remote6;
11248   u8 is_add = 1;
11249   u8 ipv4_set = 0, ipv6_set = 0;
11250   u8 local_set = 0;
11251   u8 remote_set = 0;
11252   u32 encap_vrf_id = 0;
11253   u32 decap_vrf_id = 0;
11254   u8 protocol = ~0;
11255   u32 vni;
11256   u8 vni_set = 0;
11257   int ret;
11258
11259   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11260     {
11261       if (unformat (line_input, "del"))
11262         is_add = 0;
11263       else if (unformat (line_input, "local %U",
11264                          unformat_ip4_address, &local4))
11265         {
11266           local_set = 1;
11267           ipv4_set = 1;
11268         }
11269       else if (unformat (line_input, "remote %U",
11270                          unformat_ip4_address, &remote4))
11271         {
11272           remote_set = 1;
11273           ipv4_set = 1;
11274         }
11275       else if (unformat (line_input, "local %U",
11276                          unformat_ip6_address, &local6))
11277         {
11278           local_set = 1;
11279           ipv6_set = 1;
11280         }
11281       else if (unformat (line_input, "remote %U",
11282                          unformat_ip6_address, &remote6))
11283         {
11284           remote_set = 1;
11285           ipv6_set = 1;
11286         }
11287       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11288         ;
11289       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11290         ;
11291       else if (unformat (line_input, "vni %d", &vni))
11292         vni_set = 1;
11293       else if (unformat (line_input, "next-ip4"))
11294         protocol = 1;
11295       else if (unformat (line_input, "next-ip6"))
11296         protocol = 2;
11297       else if (unformat (line_input, "next-ethernet"))
11298         protocol = 3;
11299       else if (unformat (line_input, "next-nsh"))
11300         protocol = 4;
11301       else
11302         {
11303           errmsg ("parse error '%U'", format_unformat_error, line_input);
11304           return -99;
11305         }
11306     }
11307
11308   if (local_set == 0)
11309     {
11310       errmsg ("tunnel local address not specified");
11311       return -99;
11312     }
11313   if (remote_set == 0)
11314     {
11315       errmsg ("tunnel remote address not specified");
11316       return -99;
11317     }
11318   if (ipv4_set && ipv6_set)
11319     {
11320       errmsg ("both IPv4 and IPv6 addresses specified");
11321       return -99;
11322     }
11323
11324   if (vni_set == 0)
11325     {
11326       errmsg ("vni not specified");
11327       return -99;
11328     }
11329
11330   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11331
11332
11333   if (ipv6_set)
11334     {
11335       clib_memcpy (&mp->local, &local6, sizeof (local6));
11336       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11337     }
11338   else
11339     {
11340       clib_memcpy (&mp->local, &local4, sizeof (local4));
11341       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11342     }
11343
11344   mp->encap_vrf_id = ntohl (encap_vrf_id);
11345   mp->decap_vrf_id = ntohl (decap_vrf_id);
11346   mp->protocol = protocol;
11347   mp->vni = ntohl (vni);
11348   mp->is_add = is_add;
11349   mp->is_ipv6 = ipv6_set;
11350
11351   S (mp);
11352   W (ret);
11353   return ret;
11354 }
11355
11356 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11357   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11358 {
11359   vat_main_t *vam = &vat_main;
11360
11361   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11362          ntohl (mp->sw_if_index),
11363          format_ip46_address, &(mp->local[0]),
11364          format_ip46_address, &(mp->remote[0]),
11365          ntohl (mp->vni),
11366          ntohl (mp->protocol),
11367          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11368 }
11369
11370 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11371   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11372 {
11373   vat_main_t *vam = &vat_main;
11374   vat_json_node_t *node = NULL;
11375   struct in_addr ip4;
11376   struct in6_addr ip6;
11377
11378   if (VAT_JSON_ARRAY != vam->json_tree.type)
11379     {
11380       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11381       vat_json_init_array (&vam->json_tree);
11382     }
11383   node = vat_json_array_add (&vam->json_tree);
11384
11385   vat_json_init_object (node);
11386   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11387   if (mp->is_ipv6)
11388     {
11389       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11390       vat_json_object_add_ip6 (node, "local", ip6);
11391       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11392       vat_json_object_add_ip6 (node, "remote", ip6);
11393     }
11394   else
11395     {
11396       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11397       vat_json_object_add_ip4 (node, "local", ip4);
11398       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11399       vat_json_object_add_ip4 (node, "remote", ip4);
11400     }
11401   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11402   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11403   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11404   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11405   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11406 }
11407
11408 static int
11409 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11410 {
11411   unformat_input_t *i = vam->input;
11412   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11413   vl_api_control_ping_t *mp_ping;
11414   u32 sw_if_index;
11415   u8 sw_if_index_set = 0;
11416   int ret;
11417
11418   /* Parse args required to build the message */
11419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11420     {
11421       if (unformat (i, "sw_if_index %d", &sw_if_index))
11422         sw_if_index_set = 1;
11423       else
11424         break;
11425     }
11426
11427   if (sw_if_index_set == 0)
11428     {
11429       sw_if_index = ~0;
11430     }
11431
11432   if (!vam->json_output)
11433     {
11434       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11435              "sw_if_index", "local", "remote", "vni",
11436              "protocol", "encap_vrf_id", "decap_vrf_id");
11437     }
11438
11439   /* Get list of vxlan-tunnel interfaces */
11440   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11441
11442   mp->sw_if_index = htonl (sw_if_index);
11443
11444   S (mp);
11445
11446   /* Use a control ping for synchronization */
11447   M (CONTROL_PING, mp_ping);
11448   S (mp_ping);
11449
11450   W (ret);
11451   return ret;
11452 }
11453
11454 u8 *
11455 format_l2_fib_mac_address (u8 * s, va_list * args)
11456 {
11457   u8 *a = va_arg (*args, u8 *);
11458
11459   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11460                  a[2], a[3], a[4], a[5], a[6], a[7]);
11461 }
11462
11463 static void vl_api_l2_fib_table_entry_t_handler
11464   (vl_api_l2_fib_table_entry_t * mp)
11465 {
11466   vat_main_t *vam = &vat_main;
11467
11468   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11469          "       %d       %d     %d",
11470          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11471          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11472          mp->bvi_mac);
11473 }
11474
11475 static void vl_api_l2_fib_table_entry_t_handler_json
11476   (vl_api_l2_fib_table_entry_t * mp)
11477 {
11478   vat_main_t *vam = &vat_main;
11479   vat_json_node_t *node = NULL;
11480
11481   if (VAT_JSON_ARRAY != vam->json_tree.type)
11482     {
11483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11484       vat_json_init_array (&vam->json_tree);
11485     }
11486   node = vat_json_array_add (&vam->json_tree);
11487
11488   vat_json_init_object (node);
11489   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11490   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11491   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11492   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11493   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11494   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11495 }
11496
11497 static int
11498 api_l2_fib_table_dump (vat_main_t * vam)
11499 {
11500   unformat_input_t *i = vam->input;
11501   vl_api_l2_fib_table_dump_t *mp;
11502   vl_api_control_ping_t *mp_ping;
11503   u32 bd_id;
11504   u8 bd_id_set = 0;
11505   int ret;
11506
11507   /* Parse args required to build the message */
11508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11509     {
11510       if (unformat (i, "bd_id %d", &bd_id))
11511         bd_id_set = 1;
11512       else
11513         break;
11514     }
11515
11516   if (bd_id_set == 0)
11517     {
11518       errmsg ("missing bridge domain");
11519       return -99;
11520     }
11521
11522   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11523
11524   /* Get list of l2 fib entries */
11525   M (L2_FIB_TABLE_DUMP, mp);
11526
11527   mp->bd_id = ntohl (bd_id);
11528   S (mp);
11529
11530   /* Use a control ping for synchronization */
11531   M (CONTROL_PING, mp_ping);
11532   S (mp_ping);
11533
11534   W (ret);
11535   return ret;
11536 }
11537
11538
11539 static int
11540 api_interface_name_renumber (vat_main_t * vam)
11541 {
11542   unformat_input_t *line_input = vam->input;
11543   vl_api_interface_name_renumber_t *mp;
11544   u32 sw_if_index = ~0;
11545   u32 new_show_dev_instance = ~0;
11546   int ret;
11547
11548   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11549     {
11550       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11551                     &sw_if_index))
11552         ;
11553       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11554         ;
11555       else if (unformat (line_input, "new_show_dev_instance %d",
11556                          &new_show_dev_instance))
11557         ;
11558       else
11559         break;
11560     }
11561
11562   if (sw_if_index == ~0)
11563     {
11564       errmsg ("missing interface name or sw_if_index");
11565       return -99;
11566     }
11567
11568   if (new_show_dev_instance == ~0)
11569     {
11570       errmsg ("missing new_show_dev_instance");
11571       return -99;
11572     }
11573
11574   M (INTERFACE_NAME_RENUMBER, mp);
11575
11576   mp->sw_if_index = ntohl (sw_if_index);
11577   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11578
11579   S (mp);
11580   W (ret);
11581   return ret;
11582 }
11583
11584 static int
11585 api_want_ip4_arp_events (vat_main_t * vam)
11586 {
11587   unformat_input_t *line_input = vam->input;
11588   vl_api_want_ip4_arp_events_t *mp;
11589   ip4_address_t address;
11590   int address_set = 0;
11591   u32 enable_disable = 1;
11592   int ret;
11593
11594   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11595     {
11596       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11597         address_set = 1;
11598       else if (unformat (line_input, "del"))
11599         enable_disable = 0;
11600       else
11601         break;
11602     }
11603
11604   if (address_set == 0)
11605     {
11606       errmsg ("missing addresses");
11607       return -99;
11608     }
11609
11610   M (WANT_IP4_ARP_EVENTS, mp);
11611   mp->enable_disable = enable_disable;
11612   mp->pid = getpid ();
11613   mp->address = address.as_u32;
11614
11615   S (mp);
11616   W (ret);
11617   return ret;
11618 }
11619
11620 static int
11621 api_want_ip6_nd_events (vat_main_t * vam)
11622 {
11623   unformat_input_t *line_input = vam->input;
11624   vl_api_want_ip6_nd_events_t *mp;
11625   ip6_address_t address;
11626   int address_set = 0;
11627   u32 enable_disable = 1;
11628   int ret;
11629
11630   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11631     {
11632       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11633         address_set = 1;
11634       else if (unformat (line_input, "del"))
11635         enable_disable = 0;
11636       else
11637         break;
11638     }
11639
11640   if (address_set == 0)
11641     {
11642       errmsg ("missing addresses");
11643       return -99;
11644     }
11645
11646   M (WANT_IP6_ND_EVENTS, mp);
11647   mp->enable_disable = enable_disable;
11648   mp->pid = getpid ();
11649   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11650
11651   S (mp);
11652   W (ret);
11653   return ret;
11654 }
11655
11656 static int
11657 api_input_acl_set_interface (vat_main_t * vam)
11658 {
11659   unformat_input_t *i = vam->input;
11660   vl_api_input_acl_set_interface_t *mp;
11661   u32 sw_if_index;
11662   int sw_if_index_set;
11663   u32 ip4_table_index = ~0;
11664   u32 ip6_table_index = ~0;
11665   u32 l2_table_index = ~0;
11666   u8 is_add = 1;
11667   int ret;
11668
11669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11670     {
11671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11672         sw_if_index_set = 1;
11673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11674         sw_if_index_set = 1;
11675       else if (unformat (i, "del"))
11676         is_add = 0;
11677       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11678         ;
11679       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11680         ;
11681       else if (unformat (i, "l2-table %d", &l2_table_index))
11682         ;
11683       else
11684         {
11685           clib_warning ("parse error '%U'", format_unformat_error, i);
11686           return -99;
11687         }
11688     }
11689
11690   if (sw_if_index_set == 0)
11691     {
11692       errmsg ("missing interface name or sw_if_index");
11693       return -99;
11694     }
11695
11696   M (INPUT_ACL_SET_INTERFACE, mp);
11697
11698   mp->sw_if_index = ntohl (sw_if_index);
11699   mp->ip4_table_index = ntohl (ip4_table_index);
11700   mp->ip6_table_index = ntohl (ip6_table_index);
11701   mp->l2_table_index = ntohl (l2_table_index);
11702   mp->is_add = is_add;
11703
11704   S (mp);
11705   W (ret);
11706   return ret;
11707 }
11708
11709 static int
11710 api_ip_address_dump (vat_main_t * vam)
11711 {
11712   unformat_input_t *i = vam->input;
11713   vl_api_ip_address_dump_t *mp;
11714   vl_api_control_ping_t *mp_ping;
11715   u32 sw_if_index = ~0;
11716   u8 sw_if_index_set = 0;
11717   u8 ipv4_set = 0;
11718   u8 ipv6_set = 0;
11719   int ret;
11720
11721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11722     {
11723       if (unformat (i, "sw_if_index %d", &sw_if_index))
11724         sw_if_index_set = 1;
11725       else
11726         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11727         sw_if_index_set = 1;
11728       else if (unformat (i, "ipv4"))
11729         ipv4_set = 1;
11730       else if (unformat (i, "ipv6"))
11731         ipv6_set = 1;
11732       else
11733         break;
11734     }
11735
11736   if (ipv4_set && ipv6_set)
11737     {
11738       errmsg ("ipv4 and ipv6 flags cannot be both set");
11739       return -99;
11740     }
11741
11742   if ((!ipv4_set) && (!ipv6_set))
11743     {
11744       errmsg ("no ipv4 nor ipv6 flag set");
11745       return -99;
11746     }
11747
11748   if (sw_if_index_set == 0)
11749     {
11750       errmsg ("missing interface name or sw_if_index");
11751       return -99;
11752     }
11753
11754   vam->current_sw_if_index = sw_if_index;
11755   vam->is_ipv6 = ipv6_set;
11756
11757   M (IP_ADDRESS_DUMP, mp);
11758   mp->sw_if_index = ntohl (sw_if_index);
11759   mp->is_ipv6 = ipv6_set;
11760   S (mp);
11761
11762   /* Use a control ping for synchronization */
11763   M (CONTROL_PING, mp_ping);
11764   S (mp_ping);
11765
11766   W (ret);
11767   return ret;
11768 }
11769
11770 static int
11771 api_ip_dump (vat_main_t * vam)
11772 {
11773   vl_api_ip_dump_t *mp;
11774   vl_api_control_ping_t *mp_ping;
11775   unformat_input_t *in = vam->input;
11776   int ipv4_set = 0;
11777   int ipv6_set = 0;
11778   int is_ipv6;
11779   int i;
11780   int ret;
11781
11782   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11783     {
11784       if (unformat (in, "ipv4"))
11785         ipv4_set = 1;
11786       else if (unformat (in, "ipv6"))
11787         ipv6_set = 1;
11788       else
11789         break;
11790     }
11791
11792   if (ipv4_set && ipv6_set)
11793     {
11794       errmsg ("ipv4 and ipv6 flags cannot be both set");
11795       return -99;
11796     }
11797
11798   if ((!ipv4_set) && (!ipv6_set))
11799     {
11800       errmsg ("no ipv4 nor ipv6 flag set");
11801       return -99;
11802     }
11803
11804   is_ipv6 = ipv6_set;
11805   vam->is_ipv6 = is_ipv6;
11806
11807   /* free old data */
11808   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11809     {
11810       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11811     }
11812   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11813
11814   M (IP_DUMP, mp);
11815   mp->is_ipv6 = ipv6_set;
11816   S (mp);
11817
11818   /* Use a control ping for synchronization */
11819   M (CONTROL_PING, mp_ping);
11820   S (mp_ping);
11821
11822   W (ret);
11823   return ret;
11824 }
11825
11826 static int
11827 api_ipsec_spd_add_del (vat_main_t * vam)
11828 {
11829   unformat_input_t *i = vam->input;
11830   vl_api_ipsec_spd_add_del_t *mp;
11831   u32 spd_id = ~0;
11832   u8 is_add = 1;
11833   int ret;
11834
11835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11836     {
11837       if (unformat (i, "spd_id %d", &spd_id))
11838         ;
11839       else if (unformat (i, "del"))
11840         is_add = 0;
11841       else
11842         {
11843           clib_warning ("parse error '%U'", format_unformat_error, i);
11844           return -99;
11845         }
11846     }
11847   if (spd_id == ~0)
11848     {
11849       errmsg ("spd_id must be set");
11850       return -99;
11851     }
11852
11853   M (IPSEC_SPD_ADD_DEL, mp);
11854
11855   mp->spd_id = ntohl (spd_id);
11856   mp->is_add = is_add;
11857
11858   S (mp);
11859   W (ret);
11860   return ret;
11861 }
11862
11863 static int
11864 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11865 {
11866   unformat_input_t *i = vam->input;
11867   vl_api_ipsec_interface_add_del_spd_t *mp;
11868   u32 sw_if_index;
11869   u8 sw_if_index_set = 0;
11870   u32 spd_id = (u32) ~ 0;
11871   u8 is_add = 1;
11872   int ret;
11873
11874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11875     {
11876       if (unformat (i, "del"))
11877         is_add = 0;
11878       else if (unformat (i, "spd_id %d", &spd_id))
11879         ;
11880       else
11881         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11882         sw_if_index_set = 1;
11883       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11884         sw_if_index_set = 1;
11885       else
11886         {
11887           clib_warning ("parse error '%U'", format_unformat_error, i);
11888           return -99;
11889         }
11890
11891     }
11892
11893   if (spd_id == (u32) ~ 0)
11894     {
11895       errmsg ("spd_id must be set");
11896       return -99;
11897     }
11898
11899   if (sw_if_index_set == 0)
11900     {
11901       errmsg ("missing interface name or sw_if_index");
11902       return -99;
11903     }
11904
11905   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
11906
11907   mp->spd_id = ntohl (spd_id);
11908   mp->sw_if_index = ntohl (sw_if_index);
11909   mp->is_add = is_add;
11910
11911   S (mp);
11912   W (ret);
11913   return ret;
11914 }
11915
11916 static int
11917 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11918 {
11919   unformat_input_t *i = vam->input;
11920   vl_api_ipsec_spd_add_del_entry_t *mp;
11921   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11922   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11923   i32 priority = 0;
11924   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11925   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11926   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11927   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11928   int ret;
11929
11930   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11931   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11932   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11933   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11934   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11935   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11936
11937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11938     {
11939       if (unformat (i, "del"))
11940         is_add = 0;
11941       if (unformat (i, "outbound"))
11942         is_outbound = 1;
11943       if (unformat (i, "inbound"))
11944         is_outbound = 0;
11945       else if (unformat (i, "spd_id %d", &spd_id))
11946         ;
11947       else if (unformat (i, "sa_id %d", &sa_id))
11948         ;
11949       else if (unformat (i, "priority %d", &priority))
11950         ;
11951       else if (unformat (i, "protocol %d", &protocol))
11952         ;
11953       else if (unformat (i, "lport_start %d", &lport_start))
11954         ;
11955       else if (unformat (i, "lport_stop %d", &lport_stop))
11956         ;
11957       else if (unformat (i, "rport_start %d", &rport_start))
11958         ;
11959       else if (unformat (i, "rport_stop %d", &rport_stop))
11960         ;
11961       else
11962         if (unformat
11963             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11964         {
11965           is_ipv6 = 0;
11966           is_ip_any = 0;
11967         }
11968       else
11969         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11970         {
11971           is_ipv6 = 0;
11972           is_ip_any = 0;
11973         }
11974       else
11975         if (unformat
11976             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11977         {
11978           is_ipv6 = 0;
11979           is_ip_any = 0;
11980         }
11981       else
11982         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11983         {
11984           is_ipv6 = 0;
11985           is_ip_any = 0;
11986         }
11987       else
11988         if (unformat
11989             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11990         {
11991           is_ipv6 = 1;
11992           is_ip_any = 0;
11993         }
11994       else
11995         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11996         {
11997           is_ipv6 = 1;
11998           is_ip_any = 0;
11999         }
12000       else
12001         if (unformat
12002             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12003         {
12004           is_ipv6 = 1;
12005           is_ip_any = 0;
12006         }
12007       else
12008         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12009         {
12010           is_ipv6 = 1;
12011           is_ip_any = 0;
12012         }
12013       else
12014         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12015         {
12016           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12017             {
12018               clib_warning ("unsupported action: 'resolve'");
12019               return -99;
12020             }
12021         }
12022       else
12023         {
12024           clib_warning ("parse error '%U'", format_unformat_error, i);
12025           return -99;
12026         }
12027
12028     }
12029
12030   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12031
12032   mp->spd_id = ntohl (spd_id);
12033   mp->priority = ntohl (priority);
12034   mp->is_outbound = is_outbound;
12035
12036   mp->is_ipv6 = is_ipv6;
12037   if (is_ipv6 || is_ip_any)
12038     {
12039       clib_memcpy (mp->remote_address_start, &raddr6_start,
12040                    sizeof (ip6_address_t));
12041       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12042                    sizeof (ip6_address_t));
12043       clib_memcpy (mp->local_address_start, &laddr6_start,
12044                    sizeof (ip6_address_t));
12045       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12046                    sizeof (ip6_address_t));
12047     }
12048   else
12049     {
12050       clib_memcpy (mp->remote_address_start, &raddr4_start,
12051                    sizeof (ip4_address_t));
12052       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12053                    sizeof (ip4_address_t));
12054       clib_memcpy (mp->local_address_start, &laddr4_start,
12055                    sizeof (ip4_address_t));
12056       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12057                    sizeof (ip4_address_t));
12058     }
12059   mp->protocol = (u8) protocol;
12060   mp->local_port_start = ntohs ((u16) lport_start);
12061   mp->local_port_stop = ntohs ((u16) lport_stop);
12062   mp->remote_port_start = ntohs ((u16) rport_start);
12063   mp->remote_port_stop = ntohs ((u16) rport_stop);
12064   mp->policy = (u8) policy;
12065   mp->sa_id = ntohl (sa_id);
12066   mp->is_add = is_add;
12067   mp->is_ip_any = is_ip_any;
12068   S (mp);
12069   W (ret);
12070   return ret;
12071 }
12072
12073 static int
12074 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12075 {
12076   unformat_input_t *i = vam->input;
12077   vl_api_ipsec_sad_add_del_entry_t *mp;
12078   u32 sad_id = 0, spi = 0;
12079   u8 *ck = 0, *ik = 0;
12080   u8 is_add = 1;
12081
12082   u8 protocol = IPSEC_PROTOCOL_AH;
12083   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12084   u32 crypto_alg = 0, integ_alg = 0;
12085   ip4_address_t tun_src4;
12086   ip4_address_t tun_dst4;
12087   ip6_address_t tun_src6;
12088   ip6_address_t tun_dst6;
12089   int ret;
12090
12091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12092     {
12093       if (unformat (i, "del"))
12094         is_add = 0;
12095       else if (unformat (i, "sad_id %d", &sad_id))
12096         ;
12097       else if (unformat (i, "spi %d", &spi))
12098         ;
12099       else if (unformat (i, "esp"))
12100         protocol = IPSEC_PROTOCOL_ESP;
12101       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12102         {
12103           is_tunnel = 1;
12104           is_tunnel_ipv6 = 0;
12105         }
12106       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12107         {
12108           is_tunnel = 1;
12109           is_tunnel_ipv6 = 0;
12110         }
12111       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12112         {
12113           is_tunnel = 1;
12114           is_tunnel_ipv6 = 1;
12115         }
12116       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12117         {
12118           is_tunnel = 1;
12119           is_tunnel_ipv6 = 1;
12120         }
12121       else
12122         if (unformat
12123             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12124         {
12125           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12126               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12127             {
12128               clib_warning ("unsupported crypto-alg: '%U'",
12129                             format_ipsec_crypto_alg, crypto_alg);
12130               return -99;
12131             }
12132         }
12133       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12134         ;
12135       else
12136         if (unformat
12137             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12138         {
12139           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12140               integ_alg >= IPSEC_INTEG_N_ALG)
12141             {
12142               clib_warning ("unsupported integ-alg: '%U'",
12143                             format_ipsec_integ_alg, integ_alg);
12144               return -99;
12145             }
12146         }
12147       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12148         ;
12149       else
12150         {
12151           clib_warning ("parse error '%U'", format_unformat_error, i);
12152           return -99;
12153         }
12154
12155     }
12156
12157   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12158
12159   mp->sad_id = ntohl (sad_id);
12160   mp->is_add = is_add;
12161   mp->protocol = protocol;
12162   mp->spi = ntohl (spi);
12163   mp->is_tunnel = is_tunnel;
12164   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12165   mp->crypto_algorithm = crypto_alg;
12166   mp->integrity_algorithm = integ_alg;
12167   mp->crypto_key_length = vec_len (ck);
12168   mp->integrity_key_length = vec_len (ik);
12169
12170   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12171     mp->crypto_key_length = sizeof (mp->crypto_key);
12172
12173   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12174     mp->integrity_key_length = sizeof (mp->integrity_key);
12175
12176   if (ck)
12177     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12178   if (ik)
12179     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12180
12181   if (is_tunnel)
12182     {
12183       if (is_tunnel_ipv6)
12184         {
12185           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12186                        sizeof (ip6_address_t));
12187           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12188                        sizeof (ip6_address_t));
12189         }
12190       else
12191         {
12192           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12193                        sizeof (ip4_address_t));
12194           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12195                        sizeof (ip4_address_t));
12196         }
12197     }
12198
12199   S (mp);
12200   W (ret);
12201   return ret;
12202 }
12203
12204 static int
12205 api_ipsec_sa_set_key (vat_main_t * vam)
12206 {
12207   unformat_input_t *i = vam->input;
12208   vl_api_ipsec_sa_set_key_t *mp;
12209   u32 sa_id;
12210   u8 *ck = 0, *ik = 0;
12211   int ret;
12212
12213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12214     {
12215       if (unformat (i, "sa_id %d", &sa_id))
12216         ;
12217       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12218         ;
12219       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12220         ;
12221       else
12222         {
12223           clib_warning ("parse error '%U'", format_unformat_error, i);
12224           return -99;
12225         }
12226     }
12227
12228   M (IPSEC_SA_SET_KEY, mp);
12229
12230   mp->sa_id = ntohl (sa_id);
12231   mp->crypto_key_length = vec_len (ck);
12232   mp->integrity_key_length = vec_len (ik);
12233
12234   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12235     mp->crypto_key_length = sizeof (mp->crypto_key);
12236
12237   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12238     mp->integrity_key_length = sizeof (mp->integrity_key);
12239
12240   if (ck)
12241     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12242   if (ik)
12243     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12244
12245   S (mp);
12246   W (ret);
12247   return ret;
12248 }
12249
12250 static int
12251 api_ikev2_profile_add_del (vat_main_t * vam)
12252 {
12253   unformat_input_t *i = vam->input;
12254   vl_api_ikev2_profile_add_del_t *mp;
12255   u8 is_add = 1;
12256   u8 *name = 0;
12257   int ret;
12258
12259   const char *valid_chars = "a-zA-Z0-9_";
12260
12261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12262     {
12263       if (unformat (i, "del"))
12264         is_add = 0;
12265       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12266         vec_add1 (name, 0);
12267       else
12268         {
12269           errmsg ("parse error '%U'", format_unformat_error, i);
12270           return -99;
12271         }
12272     }
12273
12274   if (!vec_len (name))
12275     {
12276       errmsg ("profile name must be specified");
12277       return -99;
12278     }
12279
12280   if (vec_len (name) > 64)
12281     {
12282       errmsg ("profile name too long");
12283       return -99;
12284     }
12285
12286   M (IKEV2_PROFILE_ADD_DEL, mp);
12287
12288   clib_memcpy (mp->name, name, vec_len (name));
12289   mp->is_add = is_add;
12290   vec_free (name);
12291
12292   S (mp);
12293   W (ret);
12294   return ret;
12295 }
12296
12297 static int
12298 api_ikev2_profile_set_auth (vat_main_t * vam)
12299 {
12300   unformat_input_t *i = vam->input;
12301   vl_api_ikev2_profile_set_auth_t *mp;
12302   u8 *name = 0;
12303   u8 *data = 0;
12304   u32 auth_method = 0;
12305   u8 is_hex = 0;
12306   int ret;
12307
12308   const char *valid_chars = "a-zA-Z0-9_";
12309
12310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12311     {
12312       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12313         vec_add1 (name, 0);
12314       else if (unformat (i, "auth_method %U",
12315                          unformat_ikev2_auth_method, &auth_method))
12316         ;
12317       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12318         is_hex = 1;
12319       else if (unformat (i, "auth_data %v", &data))
12320         ;
12321       else
12322         {
12323           errmsg ("parse error '%U'", format_unformat_error, i);
12324           return -99;
12325         }
12326     }
12327
12328   if (!vec_len (name))
12329     {
12330       errmsg ("profile name must be specified");
12331       return -99;
12332     }
12333
12334   if (vec_len (name) > 64)
12335     {
12336       errmsg ("profile name too long");
12337       return -99;
12338     }
12339
12340   if (!vec_len (data))
12341     {
12342       errmsg ("auth_data must be specified");
12343       return -99;
12344     }
12345
12346   if (!auth_method)
12347     {
12348       errmsg ("auth_method must be specified");
12349       return -99;
12350     }
12351
12352   M (IKEV2_PROFILE_SET_AUTH, mp);
12353
12354   mp->is_hex = is_hex;
12355   mp->auth_method = (u8) auth_method;
12356   mp->data_len = vec_len (data);
12357   clib_memcpy (mp->name, name, vec_len (name));
12358   clib_memcpy (mp->data, data, vec_len (data));
12359   vec_free (name);
12360   vec_free (data);
12361
12362   S (mp);
12363   W (ret);
12364   return ret;
12365 }
12366
12367 static int
12368 api_ikev2_profile_set_id (vat_main_t * vam)
12369 {
12370   unformat_input_t *i = vam->input;
12371   vl_api_ikev2_profile_set_id_t *mp;
12372   u8 *name = 0;
12373   u8 *data = 0;
12374   u8 is_local = 0;
12375   u32 id_type = 0;
12376   ip4_address_t ip4;
12377   int ret;
12378
12379   const char *valid_chars = "a-zA-Z0-9_";
12380
12381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12382     {
12383       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12384         vec_add1 (name, 0);
12385       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12386         ;
12387       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12388         {
12389           data = vec_new (u8, 4);
12390           clib_memcpy (data, ip4.as_u8, 4);
12391         }
12392       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12393         ;
12394       else if (unformat (i, "id_data %v", &data))
12395         ;
12396       else if (unformat (i, "local"))
12397         is_local = 1;
12398       else if (unformat (i, "remote"))
12399         is_local = 0;
12400       else
12401         {
12402           errmsg ("parse error '%U'", format_unformat_error, i);
12403           return -99;
12404         }
12405     }
12406
12407   if (!vec_len (name))
12408     {
12409       errmsg ("profile name must be specified");
12410       return -99;
12411     }
12412
12413   if (vec_len (name) > 64)
12414     {
12415       errmsg ("profile name too long");
12416       return -99;
12417     }
12418
12419   if (!vec_len (data))
12420     {
12421       errmsg ("id_data must be specified");
12422       return -99;
12423     }
12424
12425   if (!id_type)
12426     {
12427       errmsg ("id_type must be specified");
12428       return -99;
12429     }
12430
12431   M (IKEV2_PROFILE_SET_ID, mp);
12432
12433   mp->is_local = is_local;
12434   mp->id_type = (u8) id_type;
12435   mp->data_len = vec_len (data);
12436   clib_memcpy (mp->name, name, vec_len (name));
12437   clib_memcpy (mp->data, data, vec_len (data));
12438   vec_free (name);
12439   vec_free (data);
12440
12441   S (mp);
12442   W (ret);
12443   return ret;
12444 }
12445
12446 static int
12447 api_ikev2_profile_set_ts (vat_main_t * vam)
12448 {
12449   unformat_input_t *i = vam->input;
12450   vl_api_ikev2_profile_set_ts_t *mp;
12451   u8 *name = 0;
12452   u8 is_local = 0;
12453   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12454   ip4_address_t start_addr, end_addr;
12455
12456   const char *valid_chars = "a-zA-Z0-9_";
12457   int ret;
12458
12459   start_addr.as_u32 = 0;
12460   end_addr.as_u32 = (u32) ~ 0;
12461
12462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12463     {
12464       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12465         vec_add1 (name, 0);
12466       else if (unformat (i, "protocol %d", &proto))
12467         ;
12468       else if (unformat (i, "start_port %d", &start_port))
12469         ;
12470       else if (unformat (i, "end_port %d", &end_port))
12471         ;
12472       else
12473         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12474         ;
12475       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12476         ;
12477       else if (unformat (i, "local"))
12478         is_local = 1;
12479       else if (unformat (i, "remote"))
12480         is_local = 0;
12481       else
12482         {
12483           errmsg ("parse error '%U'", format_unformat_error, i);
12484           return -99;
12485         }
12486     }
12487
12488   if (!vec_len (name))
12489     {
12490       errmsg ("profile name must be specified");
12491       return -99;
12492     }
12493
12494   if (vec_len (name) > 64)
12495     {
12496       errmsg ("profile name too long");
12497       return -99;
12498     }
12499
12500   M (IKEV2_PROFILE_SET_TS, mp);
12501
12502   mp->is_local = is_local;
12503   mp->proto = (u8) proto;
12504   mp->start_port = (u16) start_port;
12505   mp->end_port = (u16) end_port;
12506   mp->start_addr = start_addr.as_u32;
12507   mp->end_addr = end_addr.as_u32;
12508   clib_memcpy (mp->name, name, vec_len (name));
12509   vec_free (name);
12510
12511   S (mp);
12512   W (ret);
12513   return ret;
12514 }
12515
12516 static int
12517 api_ikev2_set_local_key (vat_main_t * vam)
12518 {
12519   unformat_input_t *i = vam->input;
12520   vl_api_ikev2_set_local_key_t *mp;
12521   u8 *file = 0;
12522   int ret;
12523
12524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12525     {
12526       if (unformat (i, "file %v", &file))
12527         vec_add1 (file, 0);
12528       else
12529         {
12530           errmsg ("parse error '%U'", format_unformat_error, i);
12531           return -99;
12532         }
12533     }
12534
12535   if (!vec_len (file))
12536     {
12537       errmsg ("RSA key file must be specified");
12538       return -99;
12539     }
12540
12541   if (vec_len (file) > 256)
12542     {
12543       errmsg ("file name too long");
12544       return -99;
12545     }
12546
12547   M (IKEV2_SET_LOCAL_KEY, mp);
12548
12549   clib_memcpy (mp->key_file, file, vec_len (file));
12550   vec_free (file);
12551
12552   S (mp);
12553   W (ret);
12554   return ret;
12555 }
12556
12557 static int
12558 api_ikev2_set_responder (vat_main_t * vam)
12559 {
12560   unformat_input_t *i = vam->input;
12561   vl_api_ikev2_set_responder_t *mp;
12562   int ret;
12563   u8 *name = 0;
12564   u32 sw_if_index = ~0;
12565   ip4_address_t address;
12566
12567   const char *valid_chars = "a-zA-Z0-9_";
12568
12569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12570     {
12571       if (unformat
12572           (i, "%U interface %d address %U", unformat_token, valid_chars,
12573            &name, &sw_if_index, unformat_ip4_address, &address))
12574         vec_add1 (name, 0);
12575       else
12576         {
12577           errmsg ("parse error '%U'", format_unformat_error, i);
12578           return -99;
12579         }
12580     }
12581
12582   if (!vec_len (name))
12583     {
12584       errmsg ("profile name must be specified");
12585       return -99;
12586     }
12587
12588   if (vec_len (name) > 64)
12589     {
12590       errmsg ("profile name too long");
12591       return -99;
12592     }
12593
12594   M (IKEV2_SET_RESPONDER, mp);
12595
12596   clib_memcpy (mp->name, name, vec_len (name));
12597   vec_free (name);
12598
12599   mp->sw_if_index = sw_if_index;
12600   clib_memcpy (mp->address, &address, sizeof (address));
12601
12602   S (mp);
12603   W (ret);
12604   return ret;
12605 }
12606
12607 static int
12608 api_ikev2_set_ike_transforms (vat_main_t * vam)
12609 {
12610   unformat_input_t *i = vam->input;
12611   vl_api_ikev2_set_ike_transforms_t *mp;
12612   int ret;
12613   u8 *name = 0;
12614   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12615
12616   const char *valid_chars = "a-zA-Z0-9_";
12617
12618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12619     {
12620       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12621                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12622         vec_add1 (name, 0);
12623       else
12624         {
12625           errmsg ("parse error '%U'", format_unformat_error, i);
12626           return -99;
12627         }
12628     }
12629
12630   if (!vec_len (name))
12631     {
12632       errmsg ("profile name must be specified");
12633       return -99;
12634     }
12635
12636   if (vec_len (name) > 64)
12637     {
12638       errmsg ("profile name too long");
12639       return -99;
12640     }
12641
12642   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12643
12644   clib_memcpy (mp->name, name, vec_len (name));
12645   vec_free (name);
12646   mp->crypto_alg = crypto_alg;
12647   mp->crypto_key_size = crypto_key_size;
12648   mp->integ_alg = integ_alg;
12649   mp->dh_group = dh_group;
12650
12651   S (mp);
12652   W (ret);
12653   return ret;
12654 }
12655
12656
12657 static int
12658 api_ikev2_set_esp_transforms (vat_main_t * vam)
12659 {
12660   unformat_input_t *i = vam->input;
12661   vl_api_ikev2_set_esp_transforms_t *mp;
12662   int ret;
12663   u8 *name = 0;
12664   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12665
12666   const char *valid_chars = "a-zA-Z0-9_";
12667
12668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12669     {
12670       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12671                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12672         vec_add1 (name, 0);
12673       else
12674         {
12675           errmsg ("parse error '%U'", format_unformat_error, i);
12676           return -99;
12677         }
12678     }
12679
12680   if (!vec_len (name))
12681     {
12682       errmsg ("profile name must be specified");
12683       return -99;
12684     }
12685
12686   if (vec_len (name) > 64)
12687     {
12688       errmsg ("profile name too long");
12689       return -99;
12690     }
12691
12692   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12693
12694   clib_memcpy (mp->name, name, vec_len (name));
12695   vec_free (name);
12696   mp->crypto_alg = crypto_alg;
12697   mp->crypto_key_size = crypto_key_size;
12698   mp->integ_alg = integ_alg;
12699   mp->dh_group = dh_group;
12700
12701   S (mp);
12702   W (ret);
12703   return ret;
12704 }
12705
12706 static int
12707 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12708 {
12709   unformat_input_t *i = vam->input;
12710   vl_api_ikev2_set_sa_lifetime_t *mp;
12711   int ret;
12712   u8 *name = 0;
12713   u64 lifetime, lifetime_maxdata;
12714   u32 lifetime_jitter, handover;
12715
12716   const char *valid_chars = "a-zA-Z0-9_";
12717
12718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12719     {
12720       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12721                     &lifetime, &lifetime_jitter, &handover,
12722                     &lifetime_maxdata))
12723         vec_add1 (name, 0);
12724       else
12725         {
12726           errmsg ("parse error '%U'", format_unformat_error, i);
12727           return -99;
12728         }
12729     }
12730
12731   if (!vec_len (name))
12732     {
12733       errmsg ("profile name must be specified");
12734       return -99;
12735     }
12736
12737   if (vec_len (name) > 64)
12738     {
12739       errmsg ("profile name too long");
12740       return -99;
12741     }
12742
12743   M (IKEV2_SET_SA_LIFETIME, mp);
12744
12745   clib_memcpy (mp->name, name, vec_len (name));
12746   vec_free (name);
12747   mp->lifetime = lifetime;
12748   mp->lifetime_jitter = lifetime_jitter;
12749   mp->handover = handover;
12750   mp->lifetime_maxdata = lifetime_maxdata;
12751
12752   S (mp);
12753   W (ret);
12754   return ret;
12755 }
12756
12757 static int
12758 api_ikev2_initiate_sa_init (vat_main_t * vam)
12759 {
12760   unformat_input_t *i = vam->input;
12761   vl_api_ikev2_initiate_sa_init_t *mp;
12762   int ret;
12763   u8 *name = 0;
12764
12765   const char *valid_chars = "a-zA-Z0-9_";
12766
12767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12768     {
12769       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12770         vec_add1 (name, 0);
12771       else
12772         {
12773           errmsg ("parse error '%U'", format_unformat_error, i);
12774           return -99;
12775         }
12776     }
12777
12778   if (!vec_len (name))
12779     {
12780       errmsg ("profile name must be specified");
12781       return -99;
12782     }
12783
12784   if (vec_len (name) > 64)
12785     {
12786       errmsg ("profile name too long");
12787       return -99;
12788     }
12789
12790   M (IKEV2_INITIATE_SA_INIT, mp);
12791
12792   clib_memcpy (mp->name, name, vec_len (name));
12793   vec_free (name);
12794
12795   S (mp);
12796   W (ret);
12797   return ret;
12798 }
12799
12800 static int
12801 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12802 {
12803   unformat_input_t *i = vam->input;
12804   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12805   int ret;
12806   u64 ispi;
12807
12808
12809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12810     {
12811       if (unformat (i, "%lx", &ispi))
12812         ;
12813       else
12814         {
12815           errmsg ("parse error '%U'", format_unformat_error, i);
12816           return -99;
12817         }
12818     }
12819
12820   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12821
12822   mp->ispi = ispi;
12823
12824   S (mp);
12825   W (ret);
12826   return ret;
12827 }
12828
12829 static int
12830 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
12831 {
12832   unformat_input_t *i = vam->input;
12833   vl_api_ikev2_initiate_del_child_sa_t *mp;
12834   int ret;
12835   u32 ispi;
12836
12837
12838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12839     {
12840       if (unformat (i, "%x", &ispi))
12841         ;
12842       else
12843         {
12844           errmsg ("parse error '%U'", format_unformat_error, i);
12845           return -99;
12846         }
12847     }
12848
12849   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
12850
12851   mp->ispi = ispi;
12852
12853   S (mp);
12854   W (ret);
12855   return ret;
12856 }
12857
12858 static int
12859 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
12860 {
12861   unformat_input_t *i = vam->input;
12862   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
12863   int ret;
12864   u32 ispi;
12865
12866
12867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12868     {
12869       if (unformat (i, "%x", &ispi))
12870         ;
12871       else
12872         {
12873           errmsg ("parse error '%U'", format_unformat_error, i);
12874           return -99;
12875         }
12876     }
12877
12878   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
12879
12880   mp->ispi = ispi;
12881
12882   S (mp);
12883   W (ret);
12884   return ret;
12885 }
12886
12887 /*
12888  * MAP
12889  */
12890 static int
12891 api_map_add_domain (vat_main_t * vam)
12892 {
12893   unformat_input_t *i = vam->input;
12894   vl_api_map_add_domain_t *mp;
12895
12896   ip4_address_t ip4_prefix;
12897   ip6_address_t ip6_prefix;
12898   ip6_address_t ip6_src;
12899   u32 num_m_args = 0;
12900   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12901     0, psid_length = 0;
12902   u8 is_translation = 0;
12903   u32 mtu = 0;
12904   u32 ip6_src_len = 128;
12905   int ret;
12906
12907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12908     {
12909       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12910                     &ip4_prefix, &ip4_prefix_len))
12911         num_m_args++;
12912       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12913                          &ip6_prefix, &ip6_prefix_len))
12914         num_m_args++;
12915       else
12916         if (unformat
12917             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12918              &ip6_src_len))
12919         num_m_args++;
12920       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12921         num_m_args++;
12922       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12923         num_m_args++;
12924       else if (unformat (i, "psid-offset %d", &psid_offset))
12925         num_m_args++;
12926       else if (unformat (i, "psid-len %d", &psid_length))
12927         num_m_args++;
12928       else if (unformat (i, "mtu %d", &mtu))
12929         num_m_args++;
12930       else if (unformat (i, "map-t"))
12931         is_translation = 1;
12932       else
12933         {
12934           clib_warning ("parse error '%U'", format_unformat_error, i);
12935           return -99;
12936         }
12937     }
12938
12939   if (num_m_args < 3)
12940     {
12941       errmsg ("mandatory argument(s) missing");
12942       return -99;
12943     }
12944
12945   /* Construct the API message */
12946   M (MAP_ADD_DOMAIN, mp);
12947
12948   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12949   mp->ip4_prefix_len = ip4_prefix_len;
12950
12951   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12952   mp->ip6_prefix_len = ip6_prefix_len;
12953
12954   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12955   mp->ip6_src_prefix_len = ip6_src_len;
12956
12957   mp->ea_bits_len = ea_bits_len;
12958   mp->psid_offset = psid_offset;
12959   mp->psid_length = psid_length;
12960   mp->is_translation = is_translation;
12961   mp->mtu = htons (mtu);
12962
12963   /* send it... */
12964   S (mp);
12965
12966   /* Wait for a reply, return good/bad news  */
12967   W (ret);
12968   return ret;
12969 }
12970
12971 static int
12972 api_map_del_domain (vat_main_t * vam)
12973 {
12974   unformat_input_t *i = vam->input;
12975   vl_api_map_del_domain_t *mp;
12976
12977   u32 num_m_args = 0;
12978   u32 index;
12979   int ret;
12980
12981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12982     {
12983       if (unformat (i, "index %d", &index))
12984         num_m_args++;
12985       else
12986         {
12987           clib_warning ("parse error '%U'", format_unformat_error, i);
12988           return -99;
12989         }
12990     }
12991
12992   if (num_m_args != 1)
12993     {
12994       errmsg ("mandatory argument(s) missing");
12995       return -99;
12996     }
12997
12998   /* Construct the API message */
12999   M (MAP_DEL_DOMAIN, mp);
13000
13001   mp->index = ntohl (index);
13002
13003   /* send it... */
13004   S (mp);
13005
13006   /* Wait for a reply, return good/bad news  */
13007   W (ret);
13008   return ret;
13009 }
13010
13011 static int
13012 api_map_add_del_rule (vat_main_t * vam)
13013 {
13014   unformat_input_t *i = vam->input;
13015   vl_api_map_add_del_rule_t *mp;
13016   u8 is_add = 1;
13017   ip6_address_t ip6_dst;
13018   u32 num_m_args = 0, index, psid = 0;
13019   int ret;
13020
13021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13022     {
13023       if (unformat (i, "index %d", &index))
13024         num_m_args++;
13025       else if (unformat (i, "psid %d", &psid))
13026         num_m_args++;
13027       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13028         num_m_args++;
13029       else if (unformat (i, "del"))
13030         {
13031           is_add = 0;
13032         }
13033       else
13034         {
13035           clib_warning ("parse error '%U'", format_unformat_error, i);
13036           return -99;
13037         }
13038     }
13039
13040   /* Construct the API message */
13041   M (MAP_ADD_DEL_RULE, mp);
13042
13043   mp->index = ntohl (index);
13044   mp->is_add = is_add;
13045   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13046   mp->psid = ntohs (psid);
13047
13048   /* send it... */
13049   S (mp);
13050
13051   /* Wait for a reply, return good/bad news  */
13052   W (ret);
13053   return ret;
13054 }
13055
13056 static int
13057 api_map_domain_dump (vat_main_t * vam)
13058 {
13059   vl_api_map_domain_dump_t *mp;
13060   vl_api_control_ping_t *mp_ping;
13061   int ret;
13062
13063   /* Construct the API message */
13064   M (MAP_DOMAIN_DUMP, mp);
13065
13066   /* send it... */
13067   S (mp);
13068
13069   /* Use a control ping for synchronization */
13070   M (CONTROL_PING, mp_ping);
13071   S (mp_ping);
13072
13073   W (ret);
13074   return ret;
13075 }
13076
13077 static int
13078 api_map_rule_dump (vat_main_t * vam)
13079 {
13080   unformat_input_t *i = vam->input;
13081   vl_api_map_rule_dump_t *mp;
13082   vl_api_control_ping_t *mp_ping;
13083   u32 domain_index = ~0;
13084   int ret;
13085
13086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13087     {
13088       if (unformat (i, "index %u", &domain_index))
13089         ;
13090       else
13091         break;
13092     }
13093
13094   if (domain_index == ~0)
13095     {
13096       clib_warning ("parse error: domain index expected");
13097       return -99;
13098     }
13099
13100   /* Construct the API message */
13101   M (MAP_RULE_DUMP, mp);
13102
13103   mp->domain_index = htonl (domain_index);
13104
13105   /* send it... */
13106   S (mp);
13107
13108   /* Use a control ping for synchronization */
13109   M (CONTROL_PING, mp_ping);
13110   S (mp_ping);
13111
13112   W (ret);
13113   return ret;
13114 }
13115
13116 static void vl_api_map_add_domain_reply_t_handler
13117   (vl_api_map_add_domain_reply_t * mp)
13118 {
13119   vat_main_t *vam = &vat_main;
13120   i32 retval = ntohl (mp->retval);
13121
13122   if (vam->async_mode)
13123     {
13124       vam->async_errors += (retval < 0);
13125     }
13126   else
13127     {
13128       vam->retval = retval;
13129       vam->result_ready = 1;
13130     }
13131 }
13132
13133 static void vl_api_map_add_domain_reply_t_handler_json
13134   (vl_api_map_add_domain_reply_t * mp)
13135 {
13136   vat_main_t *vam = &vat_main;
13137   vat_json_node_t node;
13138
13139   vat_json_init_object (&node);
13140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13141   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13142
13143   vat_json_print (vam->ofp, &node);
13144   vat_json_free (&node);
13145
13146   vam->retval = ntohl (mp->retval);
13147   vam->result_ready = 1;
13148 }
13149
13150 static int
13151 api_get_first_msg_id (vat_main_t * vam)
13152 {
13153   vl_api_get_first_msg_id_t *mp;
13154   unformat_input_t *i = vam->input;
13155   u8 *name;
13156   u8 name_set = 0;
13157   int ret;
13158
13159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13160     {
13161       if (unformat (i, "client %s", &name))
13162         name_set = 1;
13163       else
13164         break;
13165     }
13166
13167   if (name_set == 0)
13168     {
13169       errmsg ("missing client name");
13170       return -99;
13171     }
13172   vec_add1 (name, 0);
13173
13174   if (vec_len (name) > 63)
13175     {
13176       errmsg ("client name too long");
13177       return -99;
13178     }
13179
13180   M (GET_FIRST_MSG_ID, mp);
13181   clib_memcpy (mp->name, name, vec_len (name));
13182   S (mp);
13183   W (ret);
13184   return ret;
13185 }
13186
13187 static int
13188 api_cop_interface_enable_disable (vat_main_t * vam)
13189 {
13190   unformat_input_t *line_input = vam->input;
13191   vl_api_cop_interface_enable_disable_t *mp;
13192   u32 sw_if_index = ~0;
13193   u8 enable_disable = 1;
13194   int ret;
13195
13196   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13197     {
13198       if (unformat (line_input, "disable"))
13199         enable_disable = 0;
13200       if (unformat (line_input, "enable"))
13201         enable_disable = 1;
13202       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13203                          vam, &sw_if_index))
13204         ;
13205       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13206         ;
13207       else
13208         break;
13209     }
13210
13211   if (sw_if_index == ~0)
13212     {
13213       errmsg ("missing interface name or sw_if_index");
13214       return -99;
13215     }
13216
13217   /* Construct the API message */
13218   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13219   mp->sw_if_index = ntohl (sw_if_index);
13220   mp->enable_disable = enable_disable;
13221
13222   /* send it... */
13223   S (mp);
13224   /* Wait for the reply */
13225   W (ret);
13226   return ret;
13227 }
13228
13229 static int
13230 api_cop_whitelist_enable_disable (vat_main_t * vam)
13231 {
13232   unformat_input_t *line_input = vam->input;
13233   vl_api_cop_whitelist_enable_disable_t *mp;
13234   u32 sw_if_index = ~0;
13235   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13236   u32 fib_id = 0;
13237   int ret;
13238
13239   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13240     {
13241       if (unformat (line_input, "ip4"))
13242         ip4 = 1;
13243       else if (unformat (line_input, "ip6"))
13244         ip6 = 1;
13245       else if (unformat (line_input, "default"))
13246         default_cop = 1;
13247       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13248                          vam, &sw_if_index))
13249         ;
13250       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13251         ;
13252       else if (unformat (line_input, "fib-id %d", &fib_id))
13253         ;
13254       else
13255         break;
13256     }
13257
13258   if (sw_if_index == ~0)
13259     {
13260       errmsg ("missing interface name or sw_if_index");
13261       return -99;
13262     }
13263
13264   /* Construct the API message */
13265   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13266   mp->sw_if_index = ntohl (sw_if_index);
13267   mp->fib_id = ntohl (fib_id);
13268   mp->ip4 = ip4;
13269   mp->ip6 = ip6;
13270   mp->default_cop = default_cop;
13271
13272   /* send it... */
13273   S (mp);
13274   /* Wait for the reply */
13275   W (ret);
13276   return ret;
13277 }
13278
13279 static int
13280 api_get_node_graph (vat_main_t * vam)
13281 {
13282   vl_api_get_node_graph_t *mp;
13283   int ret;
13284
13285   M (GET_NODE_GRAPH, mp);
13286
13287   /* send it... */
13288   S (mp);
13289   /* Wait for the reply */
13290   W (ret);
13291   return ret;
13292 }
13293
13294 /* *INDENT-OFF* */
13295 /** Used for parsing LISP eids */
13296 typedef CLIB_PACKED(struct{
13297   u8 addr[16];   /**< eid address */
13298   u32 len;       /**< prefix length if IP */
13299   u8 type;      /**< type of eid */
13300 }) lisp_eid_vat_t;
13301 /* *INDENT-ON* */
13302
13303 static uword
13304 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13305 {
13306   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13307
13308   memset (a, 0, sizeof (a[0]));
13309
13310   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13311     {
13312       a->type = 0;              /* ipv4 type */
13313     }
13314   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13315     {
13316       a->type = 1;              /* ipv6 type */
13317     }
13318   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13319     {
13320       a->type = 2;              /* mac type */
13321     }
13322   else
13323     {
13324       return 0;
13325     }
13326
13327   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13328     {
13329       return 0;
13330     }
13331
13332   return 1;
13333 }
13334
13335 static int
13336 lisp_eid_size_vat (u8 type)
13337 {
13338   switch (type)
13339     {
13340     case 0:
13341       return 4;
13342     case 1:
13343       return 16;
13344     case 2:
13345       return 6;
13346     }
13347   return 0;
13348 }
13349
13350 static void
13351 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13352 {
13353   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13354 }
13355
13356 static int
13357 api_one_add_del_locator_set (vat_main_t * vam)
13358 {
13359   unformat_input_t *input = vam->input;
13360   vl_api_one_add_del_locator_set_t *mp;
13361   u8 is_add = 1;
13362   u8 *locator_set_name = NULL;
13363   u8 locator_set_name_set = 0;
13364   vl_api_local_locator_t locator, *locators = 0;
13365   u32 sw_if_index, priority, weight;
13366   u32 data_len = 0;
13367
13368   int ret;
13369   /* Parse args required to build the message */
13370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13371     {
13372       if (unformat (input, "del"))
13373         {
13374           is_add = 0;
13375         }
13376       else if (unformat (input, "locator-set %s", &locator_set_name))
13377         {
13378           locator_set_name_set = 1;
13379         }
13380       else if (unformat (input, "sw_if_index %u p %u w %u",
13381                          &sw_if_index, &priority, &weight))
13382         {
13383           locator.sw_if_index = htonl (sw_if_index);
13384           locator.priority = priority;
13385           locator.weight = weight;
13386           vec_add1 (locators, locator);
13387         }
13388       else
13389         if (unformat
13390             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13391              &sw_if_index, &priority, &weight))
13392         {
13393           locator.sw_if_index = htonl (sw_if_index);
13394           locator.priority = priority;
13395           locator.weight = weight;
13396           vec_add1 (locators, locator);
13397         }
13398       else
13399         break;
13400     }
13401
13402   if (locator_set_name_set == 0)
13403     {
13404       errmsg ("missing locator-set name");
13405       vec_free (locators);
13406       return -99;
13407     }
13408
13409   if (vec_len (locator_set_name) > 64)
13410     {
13411       errmsg ("locator-set name too long");
13412       vec_free (locator_set_name);
13413       vec_free (locators);
13414       return -99;
13415     }
13416   vec_add1 (locator_set_name, 0);
13417
13418   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13419
13420   /* Construct the API message */
13421   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13422
13423   mp->is_add = is_add;
13424   clib_memcpy (mp->locator_set_name, locator_set_name,
13425                vec_len (locator_set_name));
13426   vec_free (locator_set_name);
13427
13428   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13429   if (locators)
13430     clib_memcpy (mp->locators, locators, data_len);
13431   vec_free (locators);
13432
13433   /* send it... */
13434   S (mp);
13435
13436   /* Wait for a reply... */
13437   W (ret);
13438   return ret;
13439 }
13440
13441 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13442
13443 static int
13444 api_one_add_del_locator (vat_main_t * vam)
13445 {
13446   unformat_input_t *input = vam->input;
13447   vl_api_one_add_del_locator_t *mp;
13448   u32 tmp_if_index = ~0;
13449   u32 sw_if_index = ~0;
13450   u8 sw_if_index_set = 0;
13451   u8 sw_if_index_if_name_set = 0;
13452   u32 priority = ~0;
13453   u8 priority_set = 0;
13454   u32 weight = ~0;
13455   u8 weight_set = 0;
13456   u8 is_add = 1;
13457   u8 *locator_set_name = NULL;
13458   u8 locator_set_name_set = 0;
13459   int ret;
13460
13461   /* Parse args required to build the message */
13462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13463     {
13464       if (unformat (input, "del"))
13465         {
13466           is_add = 0;
13467         }
13468       else if (unformat (input, "locator-set %s", &locator_set_name))
13469         {
13470           locator_set_name_set = 1;
13471         }
13472       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13473                          &tmp_if_index))
13474         {
13475           sw_if_index_if_name_set = 1;
13476           sw_if_index = tmp_if_index;
13477         }
13478       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13479         {
13480           sw_if_index_set = 1;
13481           sw_if_index = tmp_if_index;
13482         }
13483       else if (unformat (input, "p %d", &priority))
13484         {
13485           priority_set = 1;
13486         }
13487       else if (unformat (input, "w %d", &weight))
13488         {
13489           weight_set = 1;
13490         }
13491       else
13492         break;
13493     }
13494
13495   if (locator_set_name_set == 0)
13496     {
13497       errmsg ("missing locator-set name");
13498       return -99;
13499     }
13500
13501   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13502     {
13503       errmsg ("missing sw_if_index");
13504       vec_free (locator_set_name);
13505       return -99;
13506     }
13507
13508   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13509     {
13510       errmsg ("cannot use both params interface name and sw_if_index");
13511       vec_free (locator_set_name);
13512       return -99;
13513     }
13514
13515   if (priority_set == 0)
13516     {
13517       errmsg ("missing locator-set priority");
13518       vec_free (locator_set_name);
13519       return -99;
13520     }
13521
13522   if (weight_set == 0)
13523     {
13524       errmsg ("missing locator-set weight");
13525       vec_free (locator_set_name);
13526       return -99;
13527     }
13528
13529   if (vec_len (locator_set_name) > 64)
13530     {
13531       errmsg ("locator-set name too long");
13532       vec_free (locator_set_name);
13533       return -99;
13534     }
13535   vec_add1 (locator_set_name, 0);
13536
13537   /* Construct the API message */
13538   M (ONE_ADD_DEL_LOCATOR, mp);
13539
13540   mp->is_add = is_add;
13541   mp->sw_if_index = ntohl (sw_if_index);
13542   mp->priority = priority;
13543   mp->weight = weight;
13544   clib_memcpy (mp->locator_set_name, locator_set_name,
13545                vec_len (locator_set_name));
13546   vec_free (locator_set_name);
13547
13548   /* send it... */
13549   S (mp);
13550
13551   /* Wait for a reply... */
13552   W (ret);
13553   return ret;
13554 }
13555
13556 #define api_lisp_add_del_locator api_one_add_del_locator
13557
13558 uword
13559 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13560 {
13561   u32 *key_id = va_arg (*args, u32 *);
13562   u8 *s = 0;
13563
13564   if (unformat (input, "%s", &s))
13565     {
13566       if (!strcmp ((char *) s, "sha1"))
13567         key_id[0] = HMAC_SHA_1_96;
13568       else if (!strcmp ((char *) s, "sha256"))
13569         key_id[0] = HMAC_SHA_256_128;
13570       else
13571         {
13572           clib_warning ("invalid key_id: '%s'", s);
13573           key_id[0] = HMAC_NO_KEY;
13574         }
13575     }
13576   else
13577     return 0;
13578
13579   vec_free (s);
13580   return 1;
13581 }
13582
13583 static int
13584 api_one_add_del_local_eid (vat_main_t * vam)
13585 {
13586   unformat_input_t *input = vam->input;
13587   vl_api_one_add_del_local_eid_t *mp;
13588   u8 is_add = 1;
13589   u8 eid_set = 0;
13590   lisp_eid_vat_t _eid, *eid = &_eid;
13591   u8 *locator_set_name = 0;
13592   u8 locator_set_name_set = 0;
13593   u32 vni = 0;
13594   u16 key_id = 0;
13595   u8 *key = 0;
13596   int ret;
13597
13598   /* Parse args required to build the message */
13599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13600     {
13601       if (unformat (input, "del"))
13602         {
13603           is_add = 0;
13604         }
13605       else if (unformat (input, "vni %d", &vni))
13606         {
13607           ;
13608         }
13609       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13610         {
13611           eid_set = 1;
13612         }
13613       else if (unformat (input, "locator-set %s", &locator_set_name))
13614         {
13615           locator_set_name_set = 1;
13616         }
13617       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13618         ;
13619       else if (unformat (input, "secret-key %_%v%_", &key))
13620         ;
13621       else
13622         break;
13623     }
13624
13625   if (locator_set_name_set == 0)
13626     {
13627       errmsg ("missing locator-set name");
13628       return -99;
13629     }
13630
13631   if (0 == eid_set)
13632     {
13633       errmsg ("EID address not set!");
13634       vec_free (locator_set_name);
13635       return -99;
13636     }
13637
13638   if (key && (0 == key_id))
13639     {
13640       errmsg ("invalid key_id!");
13641       return -99;
13642     }
13643
13644   if (vec_len (key) > 64)
13645     {
13646       errmsg ("key too long");
13647       vec_free (key);
13648       return -99;
13649     }
13650
13651   if (vec_len (locator_set_name) > 64)
13652     {
13653       errmsg ("locator-set name too long");
13654       vec_free (locator_set_name);
13655       return -99;
13656     }
13657   vec_add1 (locator_set_name, 0);
13658
13659   /* Construct the API message */
13660   M (ONE_ADD_DEL_LOCAL_EID, mp);
13661
13662   mp->is_add = is_add;
13663   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13664   mp->eid_type = eid->type;
13665   mp->prefix_len = eid->len;
13666   mp->vni = clib_host_to_net_u32 (vni);
13667   mp->key_id = clib_host_to_net_u16 (key_id);
13668   clib_memcpy (mp->locator_set_name, locator_set_name,
13669                vec_len (locator_set_name));
13670   clib_memcpy (mp->key, key, vec_len (key));
13671
13672   vec_free (locator_set_name);
13673   vec_free (key);
13674
13675   /* send it... */
13676   S (mp);
13677
13678   /* Wait for a reply... */
13679   W (ret);
13680   return ret;
13681 }
13682
13683 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13684
13685 static int
13686 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13687 {
13688   u32 dp_table = 0, vni = 0;;
13689   unformat_input_t *input = vam->input;
13690   vl_api_gpe_add_del_fwd_entry_t *mp;
13691   u8 is_add = 1;
13692   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13693   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13694   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13695   u32 action = ~0, w;
13696   ip4_address_t rmt_rloc4, lcl_rloc4;
13697   ip6_address_t rmt_rloc6, lcl_rloc6;
13698   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13699   int ret;
13700
13701   memset (&rloc, 0, sizeof (rloc));
13702
13703   /* Parse args required to build the message */
13704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13705     {
13706       if (unformat (input, "del"))
13707         is_add = 0;
13708       else if (unformat (input, "add"))
13709         is_add = 1;
13710       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13711         {
13712           rmt_eid_set = 1;
13713         }
13714       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13715         {
13716           lcl_eid_set = 1;
13717         }
13718       else if (unformat (input, "vrf %d", &dp_table))
13719         ;
13720       else if (unformat (input, "bd %d", &dp_table))
13721         ;
13722       else if (unformat (input, "vni %d", &vni))
13723         ;
13724       else if (unformat (input, "w %d", &w))
13725         {
13726           if (!curr_rloc)
13727             {
13728               errmsg ("No RLOC configured for setting priority/weight!");
13729               return -99;
13730             }
13731           curr_rloc->weight = w;
13732         }
13733       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13734                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13735         {
13736           rloc.is_ip4 = 1;
13737
13738           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13739           rloc.weight = 0;
13740           vec_add1 (lcl_locs, rloc);
13741
13742           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13743           vec_add1 (rmt_locs, rloc);
13744           /* weight saved in rmt loc */
13745           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13746         }
13747       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13748                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13749         {
13750           rloc.is_ip4 = 0;
13751           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13752           rloc.weight = 0;
13753           vec_add1 (lcl_locs, rloc);
13754
13755           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13756           vec_add1 (rmt_locs, rloc);
13757           /* weight saved in rmt loc */
13758           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13759         }
13760       else if (unformat (input, "action %d", &action))
13761         {
13762           ;
13763         }
13764       else
13765         {
13766           clib_warning ("parse error '%U'", format_unformat_error, input);
13767           return -99;
13768         }
13769     }
13770
13771   if (!rmt_eid_set)
13772     {
13773       errmsg ("remote eid addresses not set");
13774       return -99;
13775     }
13776
13777   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13778     {
13779       errmsg ("eid types don't match");
13780       return -99;
13781     }
13782
13783   if (0 == rmt_locs && (u32) ~ 0 == action)
13784     {
13785       errmsg ("action not set for negative mapping");
13786       return -99;
13787     }
13788
13789   /* Construct the API message */
13790   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13791       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13792
13793   mp->is_add = is_add;
13794   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13795   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13796   mp->eid_type = rmt_eid->type;
13797   mp->dp_table = clib_host_to_net_u32 (dp_table);
13798   mp->vni = clib_host_to_net_u32 (vni);
13799   mp->rmt_len = rmt_eid->len;
13800   mp->lcl_len = lcl_eid->len;
13801   mp->action = action;
13802
13803   if (0 != rmt_locs && 0 != lcl_locs)
13804     {
13805       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13806       clib_memcpy (mp->locs, lcl_locs,
13807                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13808
13809       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13810       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13811                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13812     }
13813   vec_free (lcl_locs);
13814   vec_free (rmt_locs);
13815
13816   /* send it... */
13817   S (mp);
13818
13819   /* Wait for a reply... */
13820   W (ret);
13821   return ret;
13822 }
13823
13824 static int
13825 api_one_add_del_map_server (vat_main_t * vam)
13826 {
13827   unformat_input_t *input = vam->input;
13828   vl_api_one_add_del_map_server_t *mp;
13829   u8 is_add = 1;
13830   u8 ipv4_set = 0;
13831   u8 ipv6_set = 0;
13832   ip4_address_t ipv4;
13833   ip6_address_t ipv6;
13834   int ret;
13835
13836   /* Parse args required to build the message */
13837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13838     {
13839       if (unformat (input, "del"))
13840         {
13841           is_add = 0;
13842         }
13843       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13844         {
13845           ipv4_set = 1;
13846         }
13847       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13848         {
13849           ipv6_set = 1;
13850         }
13851       else
13852         break;
13853     }
13854
13855   if (ipv4_set && ipv6_set)
13856     {
13857       errmsg ("both eid v4 and v6 addresses set");
13858       return -99;
13859     }
13860
13861   if (!ipv4_set && !ipv6_set)
13862     {
13863       errmsg ("eid addresses not set");
13864       return -99;
13865     }
13866
13867   /* Construct the API message */
13868   M (ONE_ADD_DEL_MAP_SERVER, mp);
13869
13870   mp->is_add = is_add;
13871   if (ipv6_set)
13872     {
13873       mp->is_ipv6 = 1;
13874       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13875     }
13876   else
13877     {
13878       mp->is_ipv6 = 0;
13879       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13880     }
13881
13882   /* send it... */
13883   S (mp);
13884
13885   /* Wait for a reply... */
13886   W (ret);
13887   return ret;
13888 }
13889
13890 #define api_lisp_add_del_map_server api_one_add_del_map_server
13891
13892 static int
13893 api_one_add_del_map_resolver (vat_main_t * vam)
13894 {
13895   unformat_input_t *input = vam->input;
13896   vl_api_one_add_del_map_resolver_t *mp;
13897   u8 is_add = 1;
13898   u8 ipv4_set = 0;
13899   u8 ipv6_set = 0;
13900   ip4_address_t ipv4;
13901   ip6_address_t ipv6;
13902   int ret;
13903
13904   /* Parse args required to build the message */
13905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13906     {
13907       if (unformat (input, "del"))
13908         {
13909           is_add = 0;
13910         }
13911       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13912         {
13913           ipv4_set = 1;
13914         }
13915       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13916         {
13917           ipv6_set = 1;
13918         }
13919       else
13920         break;
13921     }
13922
13923   if (ipv4_set && ipv6_set)
13924     {
13925       errmsg ("both eid v4 and v6 addresses set");
13926       return -99;
13927     }
13928
13929   if (!ipv4_set && !ipv6_set)
13930     {
13931       errmsg ("eid addresses not set");
13932       return -99;
13933     }
13934
13935   /* Construct the API message */
13936   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
13937
13938   mp->is_add = is_add;
13939   if (ipv6_set)
13940     {
13941       mp->is_ipv6 = 1;
13942       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13943     }
13944   else
13945     {
13946       mp->is_ipv6 = 0;
13947       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13948     }
13949
13950   /* send it... */
13951   S (mp);
13952
13953   /* Wait for a reply... */
13954   W (ret);
13955   return ret;
13956 }
13957
13958 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
13959
13960 static int
13961 api_lisp_gpe_enable_disable (vat_main_t * vam)
13962 {
13963   unformat_input_t *input = vam->input;
13964   vl_api_gpe_enable_disable_t *mp;
13965   u8 is_set = 0;
13966   u8 is_en = 1;
13967   int ret;
13968
13969   /* Parse args required to build the message */
13970   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13971     {
13972       if (unformat (input, "enable"))
13973         {
13974           is_set = 1;
13975           is_en = 1;
13976         }
13977       else if (unformat (input, "disable"))
13978         {
13979           is_set = 1;
13980           is_en = 0;
13981         }
13982       else
13983         break;
13984     }
13985
13986   if (is_set == 0)
13987     {
13988       errmsg ("Value not set");
13989       return -99;
13990     }
13991
13992   /* Construct the API message */
13993   M (GPE_ENABLE_DISABLE, mp);
13994
13995   mp->is_en = is_en;
13996
13997   /* send it... */
13998   S (mp);
13999
14000   /* Wait for a reply... */
14001   W (ret);
14002   return ret;
14003 }
14004
14005 static int
14006 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14007 {
14008   unformat_input_t *input = vam->input;
14009   vl_api_one_rloc_probe_enable_disable_t *mp;
14010   u8 is_set = 0;
14011   u8 is_en = 0;
14012   int ret;
14013
14014   /* Parse args required to build the message */
14015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14016     {
14017       if (unformat (input, "enable"))
14018         {
14019           is_set = 1;
14020           is_en = 1;
14021         }
14022       else if (unformat (input, "disable"))
14023         is_set = 1;
14024       else
14025         break;
14026     }
14027
14028   if (!is_set)
14029     {
14030       errmsg ("Value not set");
14031       return -99;
14032     }
14033
14034   /* Construct the API message */
14035   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14036
14037   mp->is_enabled = is_en;
14038
14039   /* send it... */
14040   S (mp);
14041
14042   /* Wait for a reply... */
14043   W (ret);
14044   return ret;
14045 }
14046
14047 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14048
14049 static int
14050 api_one_map_register_enable_disable (vat_main_t * vam)
14051 {
14052   unformat_input_t *input = vam->input;
14053   vl_api_one_map_register_enable_disable_t *mp;
14054   u8 is_set = 0;
14055   u8 is_en = 0;
14056   int ret;
14057
14058   /* Parse args required to build the message */
14059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14060     {
14061       if (unformat (input, "enable"))
14062         {
14063           is_set = 1;
14064           is_en = 1;
14065         }
14066       else if (unformat (input, "disable"))
14067         is_set = 1;
14068       else
14069         break;
14070     }
14071
14072   if (!is_set)
14073     {
14074       errmsg ("Value not set");
14075       return -99;
14076     }
14077
14078   /* Construct the API message */
14079   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14080
14081   mp->is_enabled = is_en;
14082
14083   /* send it... */
14084   S (mp);
14085
14086   /* Wait for a reply... */
14087   W (ret);
14088   return ret;
14089 }
14090
14091 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14092
14093 static int
14094 api_one_enable_disable (vat_main_t * vam)
14095 {
14096   unformat_input_t *input = vam->input;
14097   vl_api_one_enable_disable_t *mp;
14098   u8 is_set = 0;
14099   u8 is_en = 0;
14100   int ret;
14101
14102   /* Parse args required to build the message */
14103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14104     {
14105       if (unformat (input, "enable"))
14106         {
14107           is_set = 1;
14108           is_en = 1;
14109         }
14110       else if (unformat (input, "disable"))
14111         {
14112           is_set = 1;
14113         }
14114       else
14115         break;
14116     }
14117
14118   if (!is_set)
14119     {
14120       errmsg ("Value not set");
14121       return -99;
14122     }
14123
14124   /* Construct the API message */
14125   M (ONE_ENABLE_DISABLE, mp);
14126
14127   mp->is_en = is_en;
14128
14129   /* send it... */
14130   S (mp);
14131
14132   /* Wait for a reply... */
14133   W (ret);
14134   return ret;
14135 }
14136
14137 #define api_lisp_enable_disable api_one_enable_disable
14138
14139 static int
14140 api_show_one_map_register_state (vat_main_t * vam)
14141 {
14142   vl_api_show_one_map_register_state_t *mp;
14143   int ret;
14144
14145   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14146
14147   /* send */
14148   S (mp);
14149
14150   /* wait for reply */
14151   W (ret);
14152   return ret;
14153 }
14154
14155 #define api_show_lisp_map_register_state api_show_one_map_register_state
14156
14157 static int
14158 api_show_one_rloc_probe_state (vat_main_t * vam)
14159 {
14160   vl_api_show_one_rloc_probe_state_t *mp;
14161   int ret;
14162
14163   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14164
14165   /* send */
14166   S (mp);
14167
14168   /* wait for reply */
14169   W (ret);
14170   return ret;
14171 }
14172
14173 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14174
14175 static int
14176 api_show_one_map_request_mode (vat_main_t * vam)
14177 {
14178   vl_api_show_one_map_request_mode_t *mp;
14179   int ret;
14180
14181   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14182
14183   /* send */
14184   S (mp);
14185
14186   /* wait for reply */
14187   W (ret);
14188   return ret;
14189 }
14190
14191 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14192
14193 static int
14194 api_one_map_request_mode (vat_main_t * vam)
14195 {
14196   unformat_input_t *input = vam->input;
14197   vl_api_one_map_request_mode_t *mp;
14198   u8 mode = 0;
14199   int ret;
14200
14201   /* Parse args required to build the message */
14202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14203     {
14204       if (unformat (input, "dst-only"))
14205         mode = 0;
14206       else if (unformat (input, "src-dst"))
14207         mode = 1;
14208       else
14209         {
14210           errmsg ("parse error '%U'", format_unformat_error, input);
14211           return -99;
14212         }
14213     }
14214
14215   M (ONE_MAP_REQUEST_MODE, mp);
14216
14217   mp->mode = mode;
14218
14219   /* send */
14220   S (mp);
14221
14222   /* wait for reply */
14223   W (ret);
14224   return ret;
14225 }
14226
14227 #define api_lisp_map_request_mode api_one_map_request_mode
14228
14229 /**
14230  * Enable/disable ONE proxy ITR.
14231  *
14232  * @param vam vpp API test context
14233  * @return return code
14234  */
14235 static int
14236 api_one_pitr_set_locator_set (vat_main_t * vam)
14237 {
14238   u8 ls_name_set = 0;
14239   unformat_input_t *input = vam->input;
14240   vl_api_one_pitr_set_locator_set_t *mp;
14241   u8 is_add = 1;
14242   u8 *ls_name = 0;
14243   int ret;
14244
14245   /* Parse args required to build the message */
14246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14247     {
14248       if (unformat (input, "del"))
14249         is_add = 0;
14250       else if (unformat (input, "locator-set %s", &ls_name))
14251         ls_name_set = 1;
14252       else
14253         {
14254           errmsg ("parse error '%U'", format_unformat_error, input);
14255           return -99;
14256         }
14257     }
14258
14259   if (!ls_name_set)
14260     {
14261       errmsg ("locator-set name not set!");
14262       return -99;
14263     }
14264
14265   M (ONE_PITR_SET_LOCATOR_SET, mp);
14266
14267   mp->is_add = is_add;
14268   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14269   vec_free (ls_name);
14270
14271   /* send */
14272   S (mp);
14273
14274   /* wait for reply */
14275   W (ret);
14276   return ret;
14277 }
14278
14279 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14280
14281 static int
14282 api_show_one_pitr (vat_main_t * vam)
14283 {
14284   vl_api_show_one_pitr_t *mp;
14285   int ret;
14286
14287   if (!vam->json_output)
14288     {
14289       print (vam->ofp, "%=20s", "lisp status:");
14290     }
14291
14292   M (SHOW_ONE_PITR, mp);
14293   /* send it... */
14294   S (mp);
14295
14296   /* Wait for a reply... */
14297   W (ret);
14298   return ret;
14299 }
14300
14301 #define api_show_lisp_pitr api_show_one_pitr
14302
14303 /**
14304  * Add/delete mapping between vni and vrf
14305  */
14306 static int
14307 api_one_eid_table_add_del_map (vat_main_t * vam)
14308 {
14309   unformat_input_t *input = vam->input;
14310   vl_api_one_eid_table_add_del_map_t *mp;
14311   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14312   u32 vni, vrf, bd_index;
14313   int ret;
14314
14315   /* Parse args required to build the message */
14316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14317     {
14318       if (unformat (input, "del"))
14319         is_add = 0;
14320       else if (unformat (input, "vrf %d", &vrf))
14321         vrf_set = 1;
14322       else if (unformat (input, "bd_index %d", &bd_index))
14323         bd_index_set = 1;
14324       else if (unformat (input, "vni %d", &vni))
14325         vni_set = 1;
14326       else
14327         break;
14328     }
14329
14330   if (!vni_set || (!vrf_set && !bd_index_set))
14331     {
14332       errmsg ("missing arguments!");
14333       return -99;
14334     }
14335
14336   if (vrf_set && bd_index_set)
14337     {
14338       errmsg ("error: both vrf and bd entered!");
14339       return -99;
14340     }
14341
14342   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14343
14344   mp->is_add = is_add;
14345   mp->vni = htonl (vni);
14346   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14347   mp->is_l2 = bd_index_set;
14348
14349   /* send */
14350   S (mp);
14351
14352   /* wait for reply */
14353   W (ret);
14354   return ret;
14355 }
14356
14357 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14358
14359 uword
14360 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14361 {
14362   u32 *action = va_arg (*args, u32 *);
14363   u8 *s = 0;
14364
14365   if (unformat (input, "%s", &s))
14366     {
14367       if (!strcmp ((char *) s, "no-action"))
14368         action[0] = 0;
14369       else if (!strcmp ((char *) s, "natively-forward"))
14370         action[0] = 1;
14371       else if (!strcmp ((char *) s, "send-map-request"))
14372         action[0] = 2;
14373       else if (!strcmp ((char *) s, "drop"))
14374         action[0] = 3;
14375       else
14376         {
14377           clib_warning ("invalid action: '%s'", s);
14378           action[0] = 3;
14379         }
14380     }
14381   else
14382     return 0;
14383
14384   vec_free (s);
14385   return 1;
14386 }
14387
14388 /**
14389  * Add/del remote mapping to/from ONE control plane
14390  *
14391  * @param vam vpp API test context
14392  * @return return code
14393  */
14394 static int
14395 api_one_add_del_remote_mapping (vat_main_t * vam)
14396 {
14397   unformat_input_t *input = vam->input;
14398   vl_api_one_add_del_remote_mapping_t *mp;
14399   u32 vni = 0;
14400   lisp_eid_vat_t _eid, *eid = &_eid;
14401   lisp_eid_vat_t _seid, *seid = &_seid;
14402   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14403   u32 action = ~0, p, w, data_len;
14404   ip4_address_t rloc4;
14405   ip6_address_t rloc6;
14406   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14407   int ret;
14408
14409   memset (&rloc, 0, sizeof (rloc));
14410
14411   /* Parse args required to build the message */
14412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14413     {
14414       if (unformat (input, "del-all"))
14415         {
14416           del_all = 1;
14417         }
14418       else if (unformat (input, "del"))
14419         {
14420           is_add = 0;
14421         }
14422       else if (unformat (input, "add"))
14423         {
14424           is_add = 1;
14425         }
14426       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14427         {
14428           eid_set = 1;
14429         }
14430       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14431         {
14432           seid_set = 1;
14433         }
14434       else if (unformat (input, "vni %d", &vni))
14435         {
14436           ;
14437         }
14438       else if (unformat (input, "p %d w %d", &p, &w))
14439         {
14440           if (!curr_rloc)
14441             {
14442               errmsg ("No RLOC configured for setting priority/weight!");
14443               return -99;
14444             }
14445           curr_rloc->priority = p;
14446           curr_rloc->weight = w;
14447         }
14448       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14449         {
14450           rloc.is_ip4 = 1;
14451           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14452           vec_add1 (rlocs, rloc);
14453           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14454         }
14455       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14456         {
14457           rloc.is_ip4 = 0;
14458           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14459           vec_add1 (rlocs, rloc);
14460           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14461         }
14462       else if (unformat (input, "action %U",
14463                          unformat_negative_mapping_action, &action))
14464         {
14465           ;
14466         }
14467       else
14468         {
14469           clib_warning ("parse error '%U'", format_unformat_error, input);
14470           return -99;
14471         }
14472     }
14473
14474   if (0 == eid_set)
14475     {
14476       errmsg ("missing params!");
14477       return -99;
14478     }
14479
14480   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14481     {
14482       errmsg ("no action set for negative map-reply!");
14483       return -99;
14484     }
14485
14486   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14487
14488   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14489   mp->is_add = is_add;
14490   mp->vni = htonl (vni);
14491   mp->action = (u8) action;
14492   mp->is_src_dst = seid_set;
14493   mp->eid_len = eid->len;
14494   mp->seid_len = seid->len;
14495   mp->del_all = del_all;
14496   mp->eid_type = eid->type;
14497   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14498   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14499
14500   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14501   clib_memcpy (mp->rlocs, rlocs, data_len);
14502   vec_free (rlocs);
14503
14504   /* send it... */
14505   S (mp);
14506
14507   /* Wait for a reply... */
14508   W (ret);
14509   return ret;
14510 }
14511
14512 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14513
14514 /**
14515  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14516  * forwarding entries in data-plane accordingly.
14517  *
14518  * @param vam vpp API test context
14519  * @return return code
14520  */
14521 static int
14522 api_one_add_del_adjacency (vat_main_t * vam)
14523 {
14524   unformat_input_t *input = vam->input;
14525   vl_api_one_add_del_adjacency_t *mp;
14526   u32 vni = 0;
14527   ip4_address_t leid4, reid4;
14528   ip6_address_t leid6, reid6;
14529   u8 reid_mac[6] = { 0 };
14530   u8 leid_mac[6] = { 0 };
14531   u8 reid_type, leid_type;
14532   u32 leid_len = 0, reid_len = 0, len;
14533   u8 is_add = 1;
14534   int ret;
14535
14536   leid_type = reid_type = (u8) ~ 0;
14537
14538   /* Parse args required to build the message */
14539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14540     {
14541       if (unformat (input, "del"))
14542         {
14543           is_add = 0;
14544         }
14545       else if (unformat (input, "add"))
14546         {
14547           is_add = 1;
14548         }
14549       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14550                          &reid4, &len))
14551         {
14552           reid_type = 0;        /* ipv4 */
14553           reid_len = len;
14554         }
14555       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14556                          &reid6, &len))
14557         {
14558           reid_type = 1;        /* ipv6 */
14559           reid_len = len;
14560         }
14561       else if (unformat (input, "reid %U", unformat_ethernet_address,
14562                          reid_mac))
14563         {
14564           reid_type = 2;        /* mac */
14565         }
14566       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14567                          &leid4, &len))
14568         {
14569           leid_type = 0;        /* ipv4 */
14570           leid_len = len;
14571         }
14572       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14573                          &leid6, &len))
14574         {
14575           leid_type = 1;        /* ipv6 */
14576           leid_len = len;
14577         }
14578       else if (unformat (input, "leid %U", unformat_ethernet_address,
14579                          leid_mac))
14580         {
14581           leid_type = 2;        /* mac */
14582         }
14583       else if (unformat (input, "vni %d", &vni))
14584         {
14585           ;
14586         }
14587       else
14588         {
14589           errmsg ("parse error '%U'", format_unformat_error, input);
14590           return -99;
14591         }
14592     }
14593
14594   if ((u8) ~ 0 == reid_type)
14595     {
14596       errmsg ("missing params!");
14597       return -99;
14598     }
14599
14600   if (leid_type != reid_type)
14601     {
14602       errmsg ("remote and local EIDs are of different types!");
14603       return -99;
14604     }
14605
14606   M (ONE_ADD_DEL_ADJACENCY, mp);
14607   mp->is_add = is_add;
14608   mp->vni = htonl (vni);
14609   mp->leid_len = leid_len;
14610   mp->reid_len = reid_len;
14611   mp->eid_type = reid_type;
14612
14613   switch (mp->eid_type)
14614     {
14615     case 0:
14616       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14617       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14618       break;
14619     case 1:
14620       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14621       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14622       break;
14623     case 2:
14624       clib_memcpy (mp->leid, leid_mac, 6);
14625       clib_memcpy (mp->reid, reid_mac, 6);
14626       break;
14627     default:
14628       errmsg ("unknown EID type %d!", mp->eid_type);
14629       return 0;
14630     }
14631
14632   /* send it... */
14633   S (mp);
14634
14635   /* Wait for a reply... */
14636   W (ret);
14637   return ret;
14638 }
14639
14640 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14641
14642 uword
14643 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14644 {
14645   u32 *mode = va_arg (*args, u32 *);
14646
14647   if (unformat (input, "lisp"))
14648     *mode = 0;
14649   else if (unformat (input, "vxlan"))
14650     *mode = 1;
14651   else
14652     return 0;
14653
14654   return 1;
14655 }
14656
14657 static int
14658 api_gpe_get_encap_mode (vat_main_t * vam)
14659 {
14660   vl_api_gpe_get_encap_mode_t *mp;
14661   int ret;
14662
14663   /* Construct the API message */
14664   M (GPE_GET_ENCAP_MODE, mp);
14665
14666   /* send it... */
14667   S (mp);
14668
14669   /* Wait for a reply... */
14670   W (ret);
14671   return ret;
14672 }
14673
14674 static int
14675 api_gpe_set_encap_mode (vat_main_t * vam)
14676 {
14677   unformat_input_t *input = vam->input;
14678   vl_api_gpe_set_encap_mode_t *mp;
14679   int ret;
14680   u32 mode = 0;
14681
14682   /* Parse args required to build the message */
14683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14684     {
14685       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14686         ;
14687       else
14688         break;
14689     }
14690
14691   /* Construct the API message */
14692   M (GPE_SET_ENCAP_MODE, mp);
14693
14694   mp->mode = mode;
14695
14696   /* send it... */
14697   S (mp);
14698
14699   /* Wait for a reply... */
14700   W (ret);
14701   return ret;
14702 }
14703
14704 static int
14705 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14706 {
14707   unformat_input_t *input = vam->input;
14708   vl_api_gpe_add_del_iface_t *mp;
14709   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14710   u32 dp_table = 0, vni = 0;
14711   int ret;
14712
14713   /* Parse args required to build the message */
14714   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14715     {
14716       if (unformat (input, "up"))
14717         {
14718           action_set = 1;
14719           is_add = 1;
14720         }
14721       else if (unformat (input, "down"))
14722         {
14723           action_set = 1;
14724           is_add = 0;
14725         }
14726       else if (unformat (input, "table_id %d", &dp_table))
14727         {
14728           dp_table_set = 1;
14729         }
14730       else if (unformat (input, "bd_id %d", &dp_table))
14731         {
14732           dp_table_set = 1;
14733           is_l2 = 1;
14734         }
14735       else if (unformat (input, "vni %d", &vni))
14736         {
14737           vni_set = 1;
14738         }
14739       else
14740         break;
14741     }
14742
14743   if (action_set == 0)
14744     {
14745       errmsg ("Action not set");
14746       return -99;
14747     }
14748   if (dp_table_set == 0 || vni_set == 0)
14749     {
14750       errmsg ("vni and dp_table must be set");
14751       return -99;
14752     }
14753
14754   /* Construct the API message */
14755   M (GPE_ADD_DEL_IFACE, mp);
14756
14757   mp->is_add = is_add;
14758   mp->dp_table = dp_table;
14759   mp->is_l2 = is_l2;
14760   mp->vni = vni;
14761
14762   /* send it... */
14763   S (mp);
14764
14765   /* Wait for a reply... */
14766   W (ret);
14767   return ret;
14768 }
14769
14770 /**
14771  * Add/del map request itr rlocs from ONE control plane and updates
14772  *
14773  * @param vam vpp API test context
14774  * @return return code
14775  */
14776 static int
14777 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14778 {
14779   unformat_input_t *input = vam->input;
14780   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14781   u8 *locator_set_name = 0;
14782   u8 locator_set_name_set = 0;
14783   u8 is_add = 1;
14784   int ret;
14785
14786   /* Parse args required to build the message */
14787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14788     {
14789       if (unformat (input, "del"))
14790         {
14791           is_add = 0;
14792         }
14793       else if (unformat (input, "%_%v%_", &locator_set_name))
14794         {
14795           locator_set_name_set = 1;
14796         }
14797       else
14798         {
14799           clib_warning ("parse error '%U'", format_unformat_error, input);
14800           return -99;
14801         }
14802     }
14803
14804   if (is_add && !locator_set_name_set)
14805     {
14806       errmsg ("itr-rloc is not set!");
14807       return -99;
14808     }
14809
14810   if (is_add && vec_len (locator_set_name) > 64)
14811     {
14812       errmsg ("itr-rloc locator-set name too long");
14813       vec_free (locator_set_name);
14814       return -99;
14815     }
14816
14817   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14818   mp->is_add = is_add;
14819   if (is_add)
14820     {
14821       clib_memcpy (mp->locator_set_name, locator_set_name,
14822                    vec_len (locator_set_name));
14823     }
14824   else
14825     {
14826       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14827     }
14828   vec_free (locator_set_name);
14829
14830   /* send it... */
14831   S (mp);
14832
14833   /* Wait for a reply... */
14834   W (ret);
14835   return ret;
14836 }
14837
14838 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14839
14840 static int
14841 api_one_locator_dump (vat_main_t * vam)
14842 {
14843   unformat_input_t *input = vam->input;
14844   vl_api_one_locator_dump_t *mp;
14845   vl_api_control_ping_t *mp_ping;
14846   u8 is_index_set = 0, is_name_set = 0;
14847   u8 *ls_name = 0;
14848   u32 ls_index = ~0;
14849   int ret;
14850
14851   /* Parse args required to build the message */
14852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14853     {
14854       if (unformat (input, "ls_name %_%v%_", &ls_name))
14855         {
14856           is_name_set = 1;
14857         }
14858       else if (unformat (input, "ls_index %d", &ls_index))
14859         {
14860           is_index_set = 1;
14861         }
14862       else
14863         {
14864           errmsg ("parse error '%U'", format_unformat_error, input);
14865           return -99;
14866         }
14867     }
14868
14869   if (!is_index_set && !is_name_set)
14870     {
14871       errmsg ("error: expected one of index or name!");
14872       return -99;
14873     }
14874
14875   if (is_index_set && is_name_set)
14876     {
14877       errmsg ("error: only one param expected!");
14878       return -99;
14879     }
14880
14881   if (vec_len (ls_name) > 62)
14882     {
14883       errmsg ("error: locator set name too long!");
14884       return -99;
14885     }
14886
14887   if (!vam->json_output)
14888     {
14889       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14890     }
14891
14892   M (ONE_LOCATOR_DUMP, mp);
14893   mp->is_index_set = is_index_set;
14894
14895   if (is_index_set)
14896     mp->ls_index = clib_host_to_net_u32 (ls_index);
14897   else
14898     {
14899       vec_add1 (ls_name, 0);
14900       strncpy ((char *) mp->ls_name, (char *) ls_name,
14901                sizeof (mp->ls_name) - 1);
14902     }
14903
14904   /* send it... */
14905   S (mp);
14906
14907   /* Use a control ping for synchronization */
14908   M (CONTROL_PING, mp_ping);
14909   S (mp_ping);
14910
14911   /* Wait for a reply... */
14912   W (ret);
14913   return ret;
14914 }
14915
14916 #define api_lisp_locator_dump api_one_locator_dump
14917
14918 static int
14919 api_one_locator_set_dump (vat_main_t * vam)
14920 {
14921   vl_api_one_locator_set_dump_t *mp;
14922   vl_api_control_ping_t *mp_ping;
14923   unformat_input_t *input = vam->input;
14924   u8 filter = 0;
14925   int ret;
14926
14927   /* Parse args required to build the message */
14928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14929     {
14930       if (unformat (input, "local"))
14931         {
14932           filter = 1;
14933         }
14934       else if (unformat (input, "remote"))
14935         {
14936           filter = 2;
14937         }
14938       else
14939         {
14940           errmsg ("parse error '%U'", format_unformat_error, input);
14941           return -99;
14942         }
14943     }
14944
14945   if (!vam->json_output)
14946     {
14947       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14948     }
14949
14950   M (ONE_LOCATOR_SET_DUMP, mp);
14951
14952   mp->filter = filter;
14953
14954   /* send it... */
14955   S (mp);
14956
14957   /* Use a control ping for synchronization */
14958   M (CONTROL_PING, mp_ping);
14959   S (mp_ping);
14960
14961   /* Wait for a reply... */
14962   W (ret);
14963   return ret;
14964 }
14965
14966 #define api_lisp_locator_set_dump api_one_locator_set_dump
14967
14968 static int
14969 api_one_eid_table_map_dump (vat_main_t * vam)
14970 {
14971   u8 is_l2 = 0;
14972   u8 mode_set = 0;
14973   unformat_input_t *input = vam->input;
14974   vl_api_one_eid_table_map_dump_t *mp;
14975   vl_api_control_ping_t *mp_ping;
14976   int ret;
14977
14978   /* Parse args required to build the message */
14979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14980     {
14981       if (unformat (input, "l2"))
14982         {
14983           is_l2 = 1;
14984           mode_set = 1;
14985         }
14986       else if (unformat (input, "l3"))
14987         {
14988           is_l2 = 0;
14989           mode_set = 1;
14990         }
14991       else
14992         {
14993           errmsg ("parse error '%U'", format_unformat_error, input);
14994           return -99;
14995         }
14996     }
14997
14998   if (!mode_set)
14999     {
15000       errmsg ("expected one of 'l2' or 'l3' parameter!");
15001       return -99;
15002     }
15003
15004   if (!vam->json_output)
15005     {
15006       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15007     }
15008
15009   M (ONE_EID_TABLE_MAP_DUMP, mp);
15010   mp->is_l2 = is_l2;
15011
15012   /* send it... */
15013   S (mp);
15014
15015   /* Use a control ping for synchronization */
15016   M (CONTROL_PING, mp_ping);
15017   S (mp_ping);
15018
15019   /* Wait for a reply... */
15020   W (ret);
15021   return ret;
15022 }
15023
15024 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15025
15026 static int
15027 api_one_eid_table_vni_dump (vat_main_t * vam)
15028 {
15029   vl_api_one_eid_table_vni_dump_t *mp;
15030   vl_api_control_ping_t *mp_ping;
15031   int ret;
15032
15033   if (!vam->json_output)
15034     {
15035       print (vam->ofp, "VNI");
15036     }
15037
15038   M (ONE_EID_TABLE_VNI_DUMP, mp);
15039
15040   /* send it... */
15041   S (mp);
15042
15043   /* Use a control ping for synchronization */
15044   M (CONTROL_PING, mp_ping);
15045   S (mp_ping);
15046
15047   /* Wait for a reply... */
15048   W (ret);
15049   return ret;
15050 }
15051
15052 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15053
15054 static int
15055 api_one_eid_table_dump (vat_main_t * vam)
15056 {
15057   unformat_input_t *i = vam->input;
15058   vl_api_one_eid_table_dump_t *mp;
15059   vl_api_control_ping_t *mp_ping;
15060   struct in_addr ip4;
15061   struct in6_addr ip6;
15062   u8 mac[6];
15063   u8 eid_type = ~0, eid_set = 0;
15064   u32 prefix_length = ~0, t, vni = 0;
15065   u8 filter = 0;
15066   int ret;
15067
15068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15069     {
15070       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15071         {
15072           eid_set = 1;
15073           eid_type = 0;
15074           prefix_length = t;
15075         }
15076       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15077         {
15078           eid_set = 1;
15079           eid_type = 1;
15080           prefix_length = t;
15081         }
15082       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15083         {
15084           eid_set = 1;
15085           eid_type = 2;
15086         }
15087       else if (unformat (i, "vni %d", &t))
15088         {
15089           vni = t;
15090         }
15091       else if (unformat (i, "local"))
15092         {
15093           filter = 1;
15094         }
15095       else if (unformat (i, "remote"))
15096         {
15097           filter = 2;
15098         }
15099       else
15100         {
15101           errmsg ("parse error '%U'", format_unformat_error, i);
15102           return -99;
15103         }
15104     }
15105
15106   if (!vam->json_output)
15107     {
15108       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15109              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15110     }
15111
15112   M (ONE_EID_TABLE_DUMP, mp);
15113
15114   mp->filter = filter;
15115   if (eid_set)
15116     {
15117       mp->eid_set = 1;
15118       mp->vni = htonl (vni);
15119       mp->eid_type = eid_type;
15120       switch (eid_type)
15121         {
15122         case 0:
15123           mp->prefix_length = prefix_length;
15124           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15125           break;
15126         case 1:
15127           mp->prefix_length = prefix_length;
15128           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15129           break;
15130         case 2:
15131           clib_memcpy (mp->eid, mac, sizeof (mac));
15132           break;
15133         default:
15134           errmsg ("unknown EID type %d!", eid_type);
15135           return -99;
15136         }
15137     }
15138
15139   /* send it... */
15140   S (mp);
15141
15142   /* Use a control ping for synchronization */
15143   M (CONTROL_PING, mp_ping);
15144   S (mp_ping);
15145
15146   /* Wait for a reply... */
15147   W (ret);
15148   return ret;
15149 }
15150
15151 #define api_lisp_eid_table_dump api_one_eid_table_dump
15152
15153 static int
15154 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15155 {
15156   unformat_input_t *i = vam->input;
15157   vl_api_gpe_fwd_entries_get_t *mp;
15158   u8 vni_set = 0;
15159   u32 vni = ~0;
15160   int ret;
15161
15162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15163     {
15164       if (unformat (i, "vni %d", &vni))
15165         {
15166           vni_set = 1;
15167         }
15168       else
15169         {
15170           errmsg ("parse error '%U'", format_unformat_error, i);
15171           return -99;
15172         }
15173     }
15174
15175   if (!vni_set)
15176     {
15177       errmsg ("vni not set!");
15178       return -99;
15179     }
15180
15181   if (!vam->json_output)
15182     {
15183       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15184              "leid", "reid");
15185     }
15186
15187   M (GPE_FWD_ENTRIES_GET, mp);
15188   mp->vni = clib_host_to_net_u32 (vni);
15189
15190   /* send it... */
15191   S (mp);
15192
15193   /* Wait for a reply... */
15194   W (ret);
15195   return ret;
15196 }
15197
15198 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15199 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15200 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15201 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15202
15203 static int
15204 api_one_adjacencies_get (vat_main_t * vam)
15205 {
15206   unformat_input_t *i = vam->input;
15207   vl_api_one_adjacencies_get_t *mp;
15208   u8 vni_set = 0;
15209   u32 vni = ~0;
15210   int ret;
15211
15212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15213     {
15214       if (unformat (i, "vni %d", &vni))
15215         {
15216           vni_set = 1;
15217         }
15218       else
15219         {
15220           errmsg ("parse error '%U'", format_unformat_error, i);
15221           return -99;
15222         }
15223     }
15224
15225   if (!vni_set)
15226     {
15227       errmsg ("vni not set!");
15228       return -99;
15229     }
15230
15231   if (!vam->json_output)
15232     {
15233       print (vam->ofp, "%s %40s", "leid", "reid");
15234     }
15235
15236   M (ONE_ADJACENCIES_GET, mp);
15237   mp->vni = clib_host_to_net_u32 (vni);
15238
15239   /* send it... */
15240   S (mp);
15241
15242   /* Wait for a reply... */
15243   W (ret);
15244   return ret;
15245 }
15246
15247 #define api_lisp_adjacencies_get api_one_adjacencies_get
15248
15249 static int
15250 api_one_map_server_dump (vat_main_t * vam)
15251 {
15252   vl_api_one_map_server_dump_t *mp;
15253   vl_api_control_ping_t *mp_ping;
15254   int ret;
15255
15256   if (!vam->json_output)
15257     {
15258       print (vam->ofp, "%=20s", "Map server");
15259     }
15260
15261   M (ONE_MAP_SERVER_DUMP, mp);
15262   /* send it... */
15263   S (mp);
15264
15265   /* Use a control ping for synchronization */
15266   M (CONTROL_PING, mp_ping);
15267   S (mp_ping);
15268
15269   /* Wait for a reply... */
15270   W (ret);
15271   return ret;
15272 }
15273
15274 #define api_lisp_map_server_dump api_one_map_server_dump
15275
15276 static int
15277 api_one_map_resolver_dump (vat_main_t * vam)
15278 {
15279   vl_api_one_map_resolver_dump_t *mp;
15280   vl_api_control_ping_t *mp_ping;
15281   int ret;
15282
15283   if (!vam->json_output)
15284     {
15285       print (vam->ofp, "%=20s", "Map resolver");
15286     }
15287
15288   M (ONE_MAP_RESOLVER_DUMP, mp);
15289   /* send it... */
15290   S (mp);
15291
15292   /* Use a control ping for synchronization */
15293   M (CONTROL_PING, mp_ping);
15294   S (mp_ping);
15295
15296   /* Wait for a reply... */
15297   W (ret);
15298   return ret;
15299 }
15300
15301 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15302
15303 static int
15304 api_show_one_status (vat_main_t * vam)
15305 {
15306   vl_api_show_one_status_t *mp;
15307   int ret;
15308
15309   if (!vam->json_output)
15310     {
15311       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15312     }
15313
15314   M (SHOW_ONE_STATUS, mp);
15315   /* send it... */
15316   S (mp);
15317   /* Wait for a reply... */
15318   W (ret);
15319   return ret;
15320 }
15321
15322 #define api_show_lisp_status api_show_one_status
15323
15324 static int
15325 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15326 {
15327   vl_api_gpe_fwd_entry_path_dump_t *mp;
15328   vl_api_control_ping_t *mp_ping;
15329   unformat_input_t *i = vam->input;
15330   u32 fwd_entry_index = ~0;
15331   int ret;
15332
15333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15334     {
15335       if (unformat (i, "index %d", &fwd_entry_index))
15336         ;
15337       else
15338         break;
15339     }
15340
15341   if (~0 == fwd_entry_index)
15342     {
15343       errmsg ("no index specified!");
15344       return -99;
15345     }
15346
15347   if (!vam->json_output)
15348     {
15349       print (vam->ofp, "first line");
15350     }
15351
15352   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15353
15354   /* send it... */
15355   S (mp);
15356   /* Use a control ping for synchronization */
15357   M (CONTROL_PING, mp_ping);
15358   S (mp_ping);
15359
15360   /* Wait for a reply... */
15361   W (ret);
15362   return ret;
15363 }
15364
15365 static int
15366 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15367 {
15368   vl_api_one_get_map_request_itr_rlocs_t *mp;
15369   int ret;
15370
15371   if (!vam->json_output)
15372     {
15373       print (vam->ofp, "%=20s", "itr-rlocs:");
15374     }
15375
15376   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15377   /* send it... */
15378   S (mp);
15379   /* Wait for a reply... */
15380   W (ret);
15381   return ret;
15382 }
15383
15384 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15385
15386 static int
15387 api_af_packet_create (vat_main_t * vam)
15388 {
15389   unformat_input_t *i = vam->input;
15390   vl_api_af_packet_create_t *mp;
15391   u8 *host_if_name = 0;
15392   u8 hw_addr[6];
15393   u8 random_hw_addr = 1;
15394   int ret;
15395
15396   memset (hw_addr, 0, sizeof (hw_addr));
15397
15398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15399     {
15400       if (unformat (i, "name %s", &host_if_name))
15401         vec_add1 (host_if_name, 0);
15402       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15403         random_hw_addr = 0;
15404       else
15405         break;
15406     }
15407
15408   if (!vec_len (host_if_name))
15409     {
15410       errmsg ("host-interface name must be specified");
15411       return -99;
15412     }
15413
15414   if (vec_len (host_if_name) > 64)
15415     {
15416       errmsg ("host-interface name too long");
15417       return -99;
15418     }
15419
15420   M (AF_PACKET_CREATE, mp);
15421
15422   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15423   clib_memcpy (mp->hw_addr, hw_addr, 6);
15424   mp->use_random_hw_addr = random_hw_addr;
15425   vec_free (host_if_name);
15426
15427   S (mp);
15428   W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15429   return ret;
15430 }
15431
15432 static int
15433 api_af_packet_delete (vat_main_t * vam)
15434 {
15435   unformat_input_t *i = vam->input;
15436   vl_api_af_packet_delete_t *mp;
15437   u8 *host_if_name = 0;
15438   int ret;
15439
15440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15441     {
15442       if (unformat (i, "name %s", &host_if_name))
15443         vec_add1 (host_if_name, 0);
15444       else
15445         break;
15446     }
15447
15448   if (!vec_len (host_if_name))
15449     {
15450       errmsg ("host-interface name must be specified");
15451       return -99;
15452     }
15453
15454   if (vec_len (host_if_name) > 64)
15455     {
15456       errmsg ("host-interface name too long");
15457       return -99;
15458     }
15459
15460   M (AF_PACKET_DELETE, mp);
15461
15462   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15463   vec_free (host_if_name);
15464
15465   S (mp);
15466   W (ret);
15467   return ret;
15468 }
15469
15470 static int
15471 api_policer_add_del (vat_main_t * vam)
15472 {
15473   unformat_input_t *i = vam->input;
15474   vl_api_policer_add_del_t *mp;
15475   u8 is_add = 1;
15476   u8 *name = 0;
15477   u32 cir = 0;
15478   u32 eir = 0;
15479   u64 cb = 0;
15480   u64 eb = 0;
15481   u8 rate_type = 0;
15482   u8 round_type = 0;
15483   u8 type = 0;
15484   u8 color_aware = 0;
15485   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15486   int ret;
15487
15488   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15489   conform_action.dscp = 0;
15490   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15491   exceed_action.dscp = 0;
15492   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15493   violate_action.dscp = 0;
15494
15495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15496     {
15497       if (unformat (i, "del"))
15498         is_add = 0;
15499       else if (unformat (i, "name %s", &name))
15500         vec_add1 (name, 0);
15501       else if (unformat (i, "cir %u", &cir))
15502         ;
15503       else if (unformat (i, "eir %u", &eir))
15504         ;
15505       else if (unformat (i, "cb %u", &cb))
15506         ;
15507       else if (unformat (i, "eb %u", &eb))
15508         ;
15509       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15510                          &rate_type))
15511         ;
15512       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15513                          &round_type))
15514         ;
15515       else if (unformat (i, "type %U", unformat_policer_type, &type))
15516         ;
15517       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15518                          &conform_action))
15519         ;
15520       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15521                          &exceed_action))
15522         ;
15523       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15524                          &violate_action))
15525         ;
15526       else if (unformat (i, "color-aware"))
15527         color_aware = 1;
15528       else
15529         break;
15530     }
15531
15532   if (!vec_len (name))
15533     {
15534       errmsg ("policer name must be specified");
15535       return -99;
15536     }
15537
15538   if (vec_len (name) > 64)
15539     {
15540       errmsg ("policer name too long");
15541       return -99;
15542     }
15543
15544   M (POLICER_ADD_DEL, mp);
15545
15546   clib_memcpy (mp->name, name, vec_len (name));
15547   vec_free (name);
15548   mp->is_add = is_add;
15549   mp->cir = cir;
15550   mp->eir = eir;
15551   mp->cb = cb;
15552   mp->eb = eb;
15553   mp->rate_type = rate_type;
15554   mp->round_type = round_type;
15555   mp->type = type;
15556   mp->conform_action_type = conform_action.action_type;
15557   mp->conform_dscp = conform_action.dscp;
15558   mp->exceed_action_type = exceed_action.action_type;
15559   mp->exceed_dscp = exceed_action.dscp;
15560   mp->violate_action_type = violate_action.action_type;
15561   mp->violate_dscp = violate_action.dscp;
15562   mp->color_aware = color_aware;
15563
15564   S (mp);
15565   W (ret);
15566   return ret;
15567 }
15568
15569 static int
15570 api_policer_dump (vat_main_t * vam)
15571 {
15572   unformat_input_t *i = vam->input;
15573   vl_api_policer_dump_t *mp;
15574   vl_api_control_ping_t *mp_ping;
15575   u8 *match_name = 0;
15576   u8 match_name_valid = 0;
15577   int ret;
15578
15579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15580     {
15581       if (unformat (i, "name %s", &match_name))
15582         {
15583           vec_add1 (match_name, 0);
15584           match_name_valid = 1;
15585         }
15586       else
15587         break;
15588     }
15589
15590   M (POLICER_DUMP, mp);
15591   mp->match_name_valid = match_name_valid;
15592   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15593   vec_free (match_name);
15594   /* send it... */
15595   S (mp);
15596
15597   /* Use a control ping for synchronization */
15598   M (CONTROL_PING, mp_ping);
15599   S (mp_ping);
15600
15601   /* Wait for a reply... */
15602   W (ret);
15603   return ret;
15604 }
15605
15606 static int
15607 api_policer_classify_set_interface (vat_main_t * vam)
15608 {
15609   unformat_input_t *i = vam->input;
15610   vl_api_policer_classify_set_interface_t *mp;
15611   u32 sw_if_index;
15612   int sw_if_index_set;
15613   u32 ip4_table_index = ~0;
15614   u32 ip6_table_index = ~0;
15615   u32 l2_table_index = ~0;
15616   u8 is_add = 1;
15617   int ret;
15618
15619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15620     {
15621       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15622         sw_if_index_set = 1;
15623       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15624         sw_if_index_set = 1;
15625       else if (unformat (i, "del"))
15626         is_add = 0;
15627       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15628         ;
15629       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15630         ;
15631       else if (unformat (i, "l2-table %d", &l2_table_index))
15632         ;
15633       else
15634         {
15635           clib_warning ("parse error '%U'", format_unformat_error, i);
15636           return -99;
15637         }
15638     }
15639
15640   if (sw_if_index_set == 0)
15641     {
15642       errmsg ("missing interface name or sw_if_index");
15643       return -99;
15644     }
15645
15646   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15647
15648   mp->sw_if_index = ntohl (sw_if_index);
15649   mp->ip4_table_index = ntohl (ip4_table_index);
15650   mp->ip6_table_index = ntohl (ip6_table_index);
15651   mp->l2_table_index = ntohl (l2_table_index);
15652   mp->is_add = is_add;
15653
15654   S (mp);
15655   W (ret);
15656   return ret;
15657 }
15658
15659 static int
15660 api_policer_classify_dump (vat_main_t * vam)
15661 {
15662   unformat_input_t *i = vam->input;
15663   vl_api_policer_classify_dump_t *mp;
15664   vl_api_control_ping_t *mp_ping;
15665   u8 type = POLICER_CLASSIFY_N_TABLES;
15666   int ret;
15667
15668   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15669     ;
15670   else
15671     {
15672       errmsg ("classify table type must be specified");
15673       return -99;
15674     }
15675
15676   if (!vam->json_output)
15677     {
15678       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15679     }
15680
15681   M (POLICER_CLASSIFY_DUMP, mp);
15682   mp->type = type;
15683   /* send it... */
15684   S (mp);
15685
15686   /* Use a control ping for synchronization */
15687   M (CONTROL_PING, mp_ping);
15688   S (mp_ping);
15689
15690   /* Wait for a reply... */
15691   W (ret);
15692   return ret;
15693 }
15694
15695 static int
15696 api_netmap_create (vat_main_t * vam)
15697 {
15698   unformat_input_t *i = vam->input;
15699   vl_api_netmap_create_t *mp;
15700   u8 *if_name = 0;
15701   u8 hw_addr[6];
15702   u8 random_hw_addr = 1;
15703   u8 is_pipe = 0;
15704   u8 is_master = 0;
15705   int ret;
15706
15707   memset (hw_addr, 0, sizeof (hw_addr));
15708
15709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15710     {
15711       if (unformat (i, "name %s", &if_name))
15712         vec_add1 (if_name, 0);
15713       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15714         random_hw_addr = 0;
15715       else if (unformat (i, "pipe"))
15716         is_pipe = 1;
15717       else if (unformat (i, "master"))
15718         is_master = 1;
15719       else if (unformat (i, "slave"))
15720         is_master = 0;
15721       else
15722         break;
15723     }
15724
15725   if (!vec_len (if_name))
15726     {
15727       errmsg ("interface name must be specified");
15728       return -99;
15729     }
15730
15731   if (vec_len (if_name) > 64)
15732     {
15733       errmsg ("interface name too long");
15734       return -99;
15735     }
15736
15737   M (NETMAP_CREATE, mp);
15738
15739   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15740   clib_memcpy (mp->hw_addr, hw_addr, 6);
15741   mp->use_random_hw_addr = random_hw_addr;
15742   mp->is_pipe = is_pipe;
15743   mp->is_master = is_master;
15744   vec_free (if_name);
15745
15746   S (mp);
15747   W (ret);
15748   return ret;
15749 }
15750
15751 static int
15752 api_netmap_delete (vat_main_t * vam)
15753 {
15754   unformat_input_t *i = vam->input;
15755   vl_api_netmap_delete_t *mp;
15756   u8 *if_name = 0;
15757   int ret;
15758
15759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15760     {
15761       if (unformat (i, "name %s", &if_name))
15762         vec_add1 (if_name, 0);
15763       else
15764         break;
15765     }
15766
15767   if (!vec_len (if_name))
15768     {
15769       errmsg ("interface name must be specified");
15770       return -99;
15771     }
15772
15773   if (vec_len (if_name) > 64)
15774     {
15775       errmsg ("interface name too long");
15776       return -99;
15777     }
15778
15779   M (NETMAP_DELETE, mp);
15780
15781   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15782   vec_free (if_name);
15783
15784   S (mp);
15785   W (ret);
15786   return ret;
15787 }
15788
15789 static void vl_api_mpls_tunnel_details_t_handler
15790   (vl_api_mpls_tunnel_details_t * mp)
15791 {
15792   vat_main_t *vam = &vat_main;
15793   i32 len = mp->mt_next_hop_n_labels;
15794   i32 i;
15795
15796   print (vam->ofp, "[%d]: via %U %d labels ",
15797          mp->tunnel_index,
15798          format_ip4_address, mp->mt_next_hop,
15799          ntohl (mp->mt_next_hop_sw_if_index));
15800   for (i = 0; i < len; i++)
15801     {
15802       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15803     }
15804   print (vam->ofp, "");
15805 }
15806
15807 static void vl_api_mpls_tunnel_details_t_handler_json
15808   (vl_api_mpls_tunnel_details_t * mp)
15809 {
15810   vat_main_t *vam = &vat_main;
15811   vat_json_node_t *node = NULL;
15812   struct in_addr ip4;
15813   i32 i;
15814   i32 len = mp->mt_next_hop_n_labels;
15815
15816   if (VAT_JSON_ARRAY != vam->json_tree.type)
15817     {
15818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15819       vat_json_init_array (&vam->json_tree);
15820     }
15821   node = vat_json_array_add (&vam->json_tree);
15822
15823   vat_json_init_object (node);
15824   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15825   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15826   vat_json_object_add_ip4 (node, "next_hop", ip4);
15827   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15828                             ntohl (mp->mt_next_hop_sw_if_index));
15829   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15830   vat_json_object_add_uint (node, "label_count", len);
15831   for (i = 0; i < len; i++)
15832     {
15833       vat_json_object_add_uint (node, "label",
15834                                 ntohl (mp->mt_next_hop_out_labels[i]));
15835     }
15836 }
15837
15838 static int
15839 api_mpls_tunnel_dump (vat_main_t * vam)
15840 {
15841   vl_api_mpls_tunnel_dump_t *mp;
15842   vl_api_control_ping_t *mp_ping;
15843   i32 index = -1;
15844   int ret;
15845
15846   /* Parse args required to build the message */
15847   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15848     {
15849       if (!unformat (vam->input, "tunnel_index %d", &index))
15850         {
15851           index = -1;
15852           break;
15853         }
15854     }
15855
15856   print (vam->ofp, "  tunnel_index %d", index);
15857
15858   M (MPLS_TUNNEL_DUMP, mp);
15859   mp->tunnel_index = htonl (index);
15860   S (mp);
15861
15862   /* Use a control ping for synchronization */
15863   M (CONTROL_PING, mp_ping);
15864   S (mp_ping);
15865
15866   W (ret);
15867   return ret;
15868 }
15869
15870 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15871 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15872
15873 static void
15874 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15875 {
15876   vat_main_t *vam = &vat_main;
15877   int count = ntohl (mp->count);
15878   vl_api_fib_path2_t *fp;
15879   int i;
15880
15881   print (vam->ofp,
15882          "table-id %d, label %u, ess_bit %u",
15883          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15884   fp = mp->path;
15885   for (i = 0; i < count; i++)
15886     {
15887       if (fp->afi == IP46_TYPE_IP6)
15888         print (vam->ofp,
15889                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15890                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15891                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15892                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15893                format_ip6_address, fp->next_hop);
15894       else if (fp->afi == IP46_TYPE_IP4)
15895         print (vam->ofp,
15896                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15897                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15898                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15899                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15900                format_ip4_address, fp->next_hop);
15901       fp++;
15902     }
15903 }
15904
15905 static void vl_api_mpls_fib_details_t_handler_json
15906   (vl_api_mpls_fib_details_t * mp)
15907 {
15908   vat_main_t *vam = &vat_main;
15909   int count = ntohl (mp->count);
15910   vat_json_node_t *node = NULL;
15911   struct in_addr ip4;
15912   struct in6_addr ip6;
15913   vl_api_fib_path2_t *fp;
15914   int i;
15915
15916   if (VAT_JSON_ARRAY != vam->json_tree.type)
15917     {
15918       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15919       vat_json_init_array (&vam->json_tree);
15920     }
15921   node = vat_json_array_add (&vam->json_tree);
15922
15923   vat_json_init_object (node);
15924   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15925   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15926   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15927   vat_json_object_add_uint (node, "path_count", count);
15928   fp = mp->path;
15929   for (i = 0; i < count; i++)
15930     {
15931       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15932       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15933       vat_json_object_add_uint (node, "is_local", fp->is_local);
15934       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15935       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15936       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15937       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15938       if (fp->afi == IP46_TYPE_IP4)
15939         {
15940           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15941           vat_json_object_add_ip4 (node, "next_hop", ip4);
15942         }
15943       else if (fp->afi == IP46_TYPE_IP6)
15944         {
15945           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15946           vat_json_object_add_ip6 (node, "next_hop", ip6);
15947         }
15948     }
15949 }
15950
15951 static int
15952 api_mpls_fib_dump (vat_main_t * vam)
15953 {
15954   vl_api_mpls_fib_dump_t *mp;
15955   vl_api_control_ping_t *mp_ping;
15956   int ret;
15957
15958   M (MPLS_FIB_DUMP, mp);
15959   S (mp);
15960
15961   /* Use a control ping for synchronization */
15962   M (CONTROL_PING, mp_ping);
15963   S (mp_ping);
15964
15965   W (ret);
15966   return ret;
15967 }
15968
15969 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15970 #define vl_api_ip_fib_details_t_print vl_noop_handler
15971
15972 static void
15973 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15974 {
15975   vat_main_t *vam = &vat_main;
15976   int count = ntohl (mp->count);
15977   vl_api_fib_path_t *fp;
15978   int i;
15979
15980   print (vam->ofp,
15981          "table-id %d, prefix %U/%d",
15982          ntohl (mp->table_id), format_ip4_address, mp->address,
15983          mp->address_length);
15984   fp = mp->path;
15985   for (i = 0; i < count; i++)
15986     {
15987       if (fp->afi == IP46_TYPE_IP6)
15988         print (vam->ofp,
15989                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15990                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15991                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15992                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15993                format_ip6_address, fp->next_hop);
15994       else if (fp->afi == IP46_TYPE_IP4)
15995         print (vam->ofp,
15996                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15997                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15998                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15999                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16000                format_ip4_address, fp->next_hop);
16001       fp++;
16002     }
16003 }
16004
16005 static void vl_api_ip_fib_details_t_handler_json
16006   (vl_api_ip_fib_details_t * mp)
16007 {
16008   vat_main_t *vam = &vat_main;
16009   int count = ntohl (mp->count);
16010   vat_json_node_t *node = NULL;
16011   struct in_addr ip4;
16012   struct in6_addr ip6;
16013   vl_api_fib_path_t *fp;
16014   int i;
16015
16016   if (VAT_JSON_ARRAY != vam->json_tree.type)
16017     {
16018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16019       vat_json_init_array (&vam->json_tree);
16020     }
16021   node = vat_json_array_add (&vam->json_tree);
16022
16023   vat_json_init_object (node);
16024   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16025   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16026   vat_json_object_add_ip4 (node, "prefix", ip4);
16027   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16028   vat_json_object_add_uint (node, "path_count", count);
16029   fp = mp->path;
16030   for (i = 0; i < count; i++)
16031     {
16032       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16033       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16034       vat_json_object_add_uint (node, "is_local", fp->is_local);
16035       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16036       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16037       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16038       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16039       if (fp->afi == IP46_TYPE_IP4)
16040         {
16041           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16042           vat_json_object_add_ip4 (node, "next_hop", ip4);
16043         }
16044       else if (fp->afi == IP46_TYPE_IP6)
16045         {
16046           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16047           vat_json_object_add_ip6 (node, "next_hop", ip6);
16048         }
16049     }
16050 }
16051
16052 static int
16053 api_ip_fib_dump (vat_main_t * vam)
16054 {
16055   vl_api_ip_fib_dump_t *mp;
16056   vl_api_control_ping_t *mp_ping;
16057   int ret;
16058
16059   M (IP_FIB_DUMP, mp);
16060   S (mp);
16061
16062   /* Use a control ping for synchronization */
16063   M (CONTROL_PING, mp_ping);
16064   S (mp_ping);
16065
16066   W (ret);
16067   return ret;
16068 }
16069
16070 static int
16071 api_ip_mfib_dump (vat_main_t * vam)
16072 {
16073   vl_api_ip_mfib_dump_t *mp;
16074   vl_api_control_ping_t *mp_ping;
16075   int ret;
16076
16077   M (IP_MFIB_DUMP, mp);
16078   S (mp);
16079
16080   /* Use a control ping for synchronization */
16081   M (CONTROL_PING, mp_ping);
16082   S (mp_ping);
16083
16084   W (ret);
16085   return ret;
16086 }
16087
16088 static void vl_api_ip_neighbor_details_t_handler
16089   (vl_api_ip_neighbor_details_t * mp)
16090 {
16091   vat_main_t *vam = &vat_main;
16092
16093   print (vam->ofp, "%c %U %U",
16094          (mp->is_static) ? 'S' : 'D',
16095          format_ethernet_address, &mp->mac_address,
16096          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16097          &mp->ip_address);
16098 }
16099
16100 static void vl_api_ip_neighbor_details_t_handler_json
16101   (vl_api_ip_neighbor_details_t * mp)
16102 {
16103
16104   vat_main_t *vam = &vat_main;
16105   vat_json_node_t *node;
16106   struct in_addr ip4;
16107   struct in6_addr ip6;
16108
16109   if (VAT_JSON_ARRAY != vam->json_tree.type)
16110     {
16111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16112       vat_json_init_array (&vam->json_tree);
16113     }
16114   node = vat_json_array_add (&vam->json_tree);
16115
16116   vat_json_init_object (node);
16117   vat_json_object_add_string_copy (node, "flag",
16118                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16119                                    "dynamic");
16120
16121   vat_json_object_add_string_copy (node, "link_layer",
16122                                    format (0, "%U", format_ethernet_address,
16123                                            &mp->mac_address));
16124
16125   if (mp->is_ipv6)
16126     {
16127       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16128       vat_json_object_add_ip6 (node, "ip_address", ip6);
16129     }
16130   else
16131     {
16132       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16133       vat_json_object_add_ip4 (node, "ip_address", ip4);
16134     }
16135 }
16136
16137 static int
16138 api_ip_neighbor_dump (vat_main_t * vam)
16139 {
16140   unformat_input_t *i = vam->input;
16141   vl_api_ip_neighbor_dump_t *mp;
16142   vl_api_control_ping_t *mp_ping;
16143   u8 is_ipv6 = 0;
16144   u32 sw_if_index = ~0;
16145   int ret;
16146
16147   /* Parse args required to build the message */
16148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16149     {
16150       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16151         ;
16152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16153         ;
16154       else if (unformat (i, "ip6"))
16155         is_ipv6 = 1;
16156       else
16157         break;
16158     }
16159
16160   if (sw_if_index == ~0)
16161     {
16162       errmsg ("missing interface name or sw_if_index");
16163       return -99;
16164     }
16165
16166   M (IP_NEIGHBOR_DUMP, mp);
16167   mp->is_ipv6 = (u8) is_ipv6;
16168   mp->sw_if_index = ntohl (sw_if_index);
16169   S (mp);
16170
16171   /* Use a control ping for synchronization */
16172   M (CONTROL_PING, mp_ping);
16173   S (mp_ping);
16174
16175   W (ret);
16176   return ret;
16177 }
16178
16179 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16180 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16181
16182 static void
16183 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16184 {
16185   vat_main_t *vam = &vat_main;
16186   int count = ntohl (mp->count);
16187   vl_api_fib_path_t *fp;
16188   int i;
16189
16190   print (vam->ofp,
16191          "table-id %d, prefix %U/%d",
16192          ntohl (mp->table_id), format_ip6_address, mp->address,
16193          mp->address_length);
16194   fp = mp->path;
16195   for (i = 0; i < count; i++)
16196     {
16197       if (fp->afi == IP46_TYPE_IP6)
16198         print (vam->ofp,
16199                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16200                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16201                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16202                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16203                format_ip6_address, fp->next_hop);
16204       else if (fp->afi == IP46_TYPE_IP4)
16205         print (vam->ofp,
16206                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16207                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16208                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16209                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16210                format_ip4_address, fp->next_hop);
16211       fp++;
16212     }
16213 }
16214
16215 static void vl_api_ip6_fib_details_t_handler_json
16216   (vl_api_ip6_fib_details_t * mp)
16217 {
16218   vat_main_t *vam = &vat_main;
16219   int count = ntohl (mp->count);
16220   vat_json_node_t *node = NULL;
16221   struct in_addr ip4;
16222   struct in6_addr ip6;
16223   vl_api_fib_path_t *fp;
16224   int i;
16225
16226   if (VAT_JSON_ARRAY != vam->json_tree.type)
16227     {
16228       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16229       vat_json_init_array (&vam->json_tree);
16230     }
16231   node = vat_json_array_add (&vam->json_tree);
16232
16233   vat_json_init_object (node);
16234   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16235   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16236   vat_json_object_add_ip6 (node, "prefix", ip6);
16237   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16238   vat_json_object_add_uint (node, "path_count", count);
16239   fp = mp->path;
16240   for (i = 0; i < count; i++)
16241     {
16242       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16243       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16244       vat_json_object_add_uint (node, "is_local", fp->is_local);
16245       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16246       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16247       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16248       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16249       if (fp->afi == IP46_TYPE_IP4)
16250         {
16251           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16252           vat_json_object_add_ip4 (node, "next_hop", ip4);
16253         }
16254       else if (fp->afi == IP46_TYPE_IP6)
16255         {
16256           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16257           vat_json_object_add_ip6 (node, "next_hop", ip6);
16258         }
16259     }
16260 }
16261
16262 static int
16263 api_ip6_fib_dump (vat_main_t * vam)
16264 {
16265   vl_api_ip6_fib_dump_t *mp;
16266   vl_api_control_ping_t *mp_ping;
16267   int ret;
16268
16269   M (IP6_FIB_DUMP, mp);
16270   S (mp);
16271
16272   /* Use a control ping for synchronization */
16273   M (CONTROL_PING, mp_ping);
16274   S (mp_ping);
16275
16276   W (ret);
16277   return ret;
16278 }
16279
16280 static int
16281 api_ip6_mfib_dump (vat_main_t * vam)
16282 {
16283   vl_api_ip6_mfib_dump_t *mp;
16284   vl_api_control_ping_t *mp_ping;
16285   int ret;
16286
16287   M (IP6_MFIB_DUMP, mp);
16288   S (mp);
16289
16290   /* Use a control ping for synchronization */
16291   M (CONTROL_PING, mp_ping);
16292   S (mp_ping);
16293
16294   W (ret);
16295   return ret;
16296 }
16297
16298 int
16299 api_classify_table_ids (vat_main_t * vam)
16300 {
16301   vl_api_classify_table_ids_t *mp;
16302   int ret;
16303
16304   /* Construct the API message */
16305   M (CLASSIFY_TABLE_IDS, mp);
16306   mp->context = 0;
16307
16308   S (mp);
16309   W (ret);
16310   return ret;
16311 }
16312
16313 int
16314 api_classify_table_by_interface (vat_main_t * vam)
16315 {
16316   unformat_input_t *input = vam->input;
16317   vl_api_classify_table_by_interface_t *mp;
16318
16319   u32 sw_if_index = ~0;
16320   int ret;
16321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16322     {
16323       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16324         ;
16325       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16326         ;
16327       else
16328         break;
16329     }
16330   if (sw_if_index == ~0)
16331     {
16332       errmsg ("missing interface name or sw_if_index");
16333       return -99;
16334     }
16335
16336   /* Construct the API message */
16337   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16338   mp->context = 0;
16339   mp->sw_if_index = ntohl (sw_if_index);
16340
16341   S (mp);
16342   W (ret);
16343   return ret;
16344 }
16345
16346 int
16347 api_classify_table_info (vat_main_t * vam)
16348 {
16349   unformat_input_t *input = vam->input;
16350   vl_api_classify_table_info_t *mp;
16351
16352   u32 table_id = ~0;
16353   int ret;
16354   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16355     {
16356       if (unformat (input, "table_id %d", &table_id))
16357         ;
16358       else
16359         break;
16360     }
16361   if (table_id == ~0)
16362     {
16363       errmsg ("missing table id");
16364       return -99;
16365     }
16366
16367   /* Construct the API message */
16368   M (CLASSIFY_TABLE_INFO, mp);
16369   mp->context = 0;
16370   mp->table_id = ntohl (table_id);
16371
16372   S (mp);
16373   W (ret);
16374   return ret;
16375 }
16376
16377 int
16378 api_classify_session_dump (vat_main_t * vam)
16379 {
16380   unformat_input_t *input = vam->input;
16381   vl_api_classify_session_dump_t *mp;
16382   vl_api_control_ping_t *mp_ping;
16383
16384   u32 table_id = ~0;
16385   int ret;
16386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16387     {
16388       if (unformat (input, "table_id %d", &table_id))
16389         ;
16390       else
16391         break;
16392     }
16393   if (table_id == ~0)
16394     {
16395       errmsg ("missing table id");
16396       return -99;
16397     }
16398
16399   /* Construct the API message */
16400   M (CLASSIFY_SESSION_DUMP, mp);
16401   mp->context = 0;
16402   mp->table_id = ntohl (table_id);
16403   S (mp);
16404
16405   /* Use a control ping for synchronization */
16406   M (CONTROL_PING, mp_ping);
16407   S (mp_ping);
16408
16409   W (ret);
16410   return ret;
16411 }
16412
16413 static void
16414 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16415 {
16416   vat_main_t *vam = &vat_main;
16417
16418   print (vam->ofp, "collector_address %U, collector_port %d, "
16419          "src_address %U, vrf_id %d, path_mtu %u, "
16420          "template_interval %u, udp_checksum %d",
16421          format_ip4_address, mp->collector_address,
16422          ntohs (mp->collector_port),
16423          format_ip4_address, mp->src_address,
16424          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16425          ntohl (mp->template_interval), mp->udp_checksum);
16426
16427   vam->retval = 0;
16428   vam->result_ready = 1;
16429 }
16430
16431 static void
16432   vl_api_ipfix_exporter_details_t_handler_json
16433   (vl_api_ipfix_exporter_details_t * mp)
16434 {
16435   vat_main_t *vam = &vat_main;
16436   vat_json_node_t node;
16437   struct in_addr collector_address;
16438   struct in_addr src_address;
16439
16440   vat_json_init_object (&node);
16441   clib_memcpy (&collector_address, &mp->collector_address,
16442                sizeof (collector_address));
16443   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16444   vat_json_object_add_uint (&node, "collector_port",
16445                             ntohs (mp->collector_port));
16446   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16447   vat_json_object_add_ip4 (&node, "src_address", src_address);
16448   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16449   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16450   vat_json_object_add_uint (&node, "template_interval",
16451                             ntohl (mp->template_interval));
16452   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16453
16454   vat_json_print (vam->ofp, &node);
16455   vat_json_free (&node);
16456   vam->retval = 0;
16457   vam->result_ready = 1;
16458 }
16459
16460 int
16461 api_ipfix_exporter_dump (vat_main_t * vam)
16462 {
16463   vl_api_ipfix_exporter_dump_t *mp;
16464   int ret;
16465
16466   /* Construct the API message */
16467   M (IPFIX_EXPORTER_DUMP, mp);
16468   mp->context = 0;
16469
16470   S (mp);
16471   W (ret);
16472   return ret;
16473 }
16474
16475 static int
16476 api_ipfix_classify_stream_dump (vat_main_t * vam)
16477 {
16478   vl_api_ipfix_classify_stream_dump_t *mp;
16479   int ret;
16480
16481   /* Construct the API message */
16482   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16483   mp->context = 0;
16484
16485   S (mp);
16486   W (ret);
16487   return ret;
16488   /* NOTREACHED */
16489   return 0;
16490 }
16491
16492 static void
16493   vl_api_ipfix_classify_stream_details_t_handler
16494   (vl_api_ipfix_classify_stream_details_t * mp)
16495 {
16496   vat_main_t *vam = &vat_main;
16497   print (vam->ofp, "domain_id %d, src_port %d",
16498          ntohl (mp->domain_id), ntohs (mp->src_port));
16499   vam->retval = 0;
16500   vam->result_ready = 1;
16501 }
16502
16503 static void
16504   vl_api_ipfix_classify_stream_details_t_handler_json
16505   (vl_api_ipfix_classify_stream_details_t * mp)
16506 {
16507   vat_main_t *vam = &vat_main;
16508   vat_json_node_t node;
16509
16510   vat_json_init_object (&node);
16511   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16512   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16513
16514   vat_json_print (vam->ofp, &node);
16515   vat_json_free (&node);
16516   vam->retval = 0;
16517   vam->result_ready = 1;
16518 }
16519
16520 static int
16521 api_ipfix_classify_table_dump (vat_main_t * vam)
16522 {
16523   vl_api_ipfix_classify_table_dump_t *mp;
16524   vl_api_control_ping_t *mp_ping;
16525   int ret;
16526
16527   if (!vam->json_output)
16528     {
16529       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16530              "transport_protocol");
16531     }
16532
16533   /* Construct the API message */
16534   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16535
16536   /* send it... */
16537   S (mp);
16538
16539   /* Use a control ping for synchronization */
16540   M (CONTROL_PING, mp_ping);
16541   S (mp_ping);
16542
16543   W (ret);
16544   return ret;
16545 }
16546
16547 static void
16548   vl_api_ipfix_classify_table_details_t_handler
16549   (vl_api_ipfix_classify_table_details_t * mp)
16550 {
16551   vat_main_t *vam = &vat_main;
16552   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16553          mp->transport_protocol);
16554 }
16555
16556 static void
16557   vl_api_ipfix_classify_table_details_t_handler_json
16558   (vl_api_ipfix_classify_table_details_t * mp)
16559 {
16560   vat_json_node_t *node = NULL;
16561   vat_main_t *vam = &vat_main;
16562
16563   if (VAT_JSON_ARRAY != vam->json_tree.type)
16564     {
16565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16566       vat_json_init_array (&vam->json_tree);
16567     }
16568
16569   node = vat_json_array_add (&vam->json_tree);
16570   vat_json_init_object (node);
16571
16572   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16573   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16574   vat_json_object_add_uint (node, "transport_protocol",
16575                             mp->transport_protocol);
16576 }
16577
16578 static int
16579 api_sw_interface_span_enable_disable (vat_main_t * vam)
16580 {
16581   unformat_input_t *i = vam->input;
16582   vl_api_sw_interface_span_enable_disable_t *mp;
16583   u32 src_sw_if_index = ~0;
16584   u32 dst_sw_if_index = ~0;
16585   u8 state = 3;
16586   int ret;
16587
16588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16589     {
16590       if (unformat
16591           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16592         ;
16593       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16594         ;
16595       else
16596         if (unformat
16597             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16598         ;
16599       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16600         ;
16601       else if (unformat (i, "disable"))
16602         state = 0;
16603       else if (unformat (i, "rx"))
16604         state = 1;
16605       else if (unformat (i, "tx"))
16606         state = 2;
16607       else if (unformat (i, "both"))
16608         state = 3;
16609       else
16610         break;
16611     }
16612
16613   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16614
16615   mp->sw_if_index_from = htonl (src_sw_if_index);
16616   mp->sw_if_index_to = htonl (dst_sw_if_index);
16617   mp->state = state;
16618
16619   S (mp);
16620   W (ret);
16621   return ret;
16622 }
16623
16624 static void
16625 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16626                                             * mp)
16627 {
16628   vat_main_t *vam = &vat_main;
16629   u8 *sw_if_from_name = 0;
16630   u8 *sw_if_to_name = 0;
16631   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16632   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16633   char *states[] = { "none", "rx", "tx", "both" };
16634   hash_pair_t *p;
16635
16636   /* *INDENT-OFF* */
16637   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16638   ({
16639     if ((u32) p->value[0] == sw_if_index_from)
16640       {
16641         sw_if_from_name = (u8 *)(p->key);
16642         if (sw_if_to_name)
16643           break;
16644       }
16645     if ((u32) p->value[0] == sw_if_index_to)
16646       {
16647         sw_if_to_name = (u8 *)(p->key);
16648         if (sw_if_from_name)
16649           break;
16650       }
16651   }));
16652   /* *INDENT-ON* */
16653   print (vam->ofp, "%20s => %20s (%s)",
16654          sw_if_from_name, sw_if_to_name, states[mp->state]);
16655 }
16656
16657 static void
16658   vl_api_sw_interface_span_details_t_handler_json
16659   (vl_api_sw_interface_span_details_t * mp)
16660 {
16661   vat_main_t *vam = &vat_main;
16662   vat_json_node_t *node = NULL;
16663   u8 *sw_if_from_name = 0;
16664   u8 *sw_if_to_name = 0;
16665   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16666   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16667   hash_pair_t *p;
16668
16669   /* *INDENT-OFF* */
16670   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16671   ({
16672     if ((u32) p->value[0] == sw_if_index_from)
16673       {
16674         sw_if_from_name = (u8 *)(p->key);
16675         if (sw_if_to_name)
16676           break;
16677       }
16678     if ((u32) p->value[0] == sw_if_index_to)
16679       {
16680         sw_if_to_name = (u8 *)(p->key);
16681         if (sw_if_from_name)
16682           break;
16683       }
16684   }));
16685   /* *INDENT-ON* */
16686
16687   if (VAT_JSON_ARRAY != vam->json_tree.type)
16688     {
16689       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16690       vat_json_init_array (&vam->json_tree);
16691     }
16692   node = vat_json_array_add (&vam->json_tree);
16693
16694   vat_json_init_object (node);
16695   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16696   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16697   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16698   if (0 != sw_if_to_name)
16699     {
16700       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16701     }
16702   vat_json_object_add_uint (node, "state", mp->state);
16703 }
16704
16705 static int
16706 api_sw_interface_span_dump (vat_main_t * vam)
16707 {
16708   vl_api_sw_interface_span_dump_t *mp;
16709   vl_api_control_ping_t *mp_ping;
16710   int ret;
16711
16712   M (SW_INTERFACE_SPAN_DUMP, mp);
16713   S (mp);
16714
16715   /* Use a control ping for synchronization */
16716   M (CONTROL_PING, mp_ping);
16717   S (mp_ping);
16718
16719   W (ret);
16720   return ret;
16721 }
16722
16723 int
16724 api_pg_create_interface (vat_main_t * vam)
16725 {
16726   unformat_input_t *input = vam->input;
16727   vl_api_pg_create_interface_t *mp;
16728
16729   u32 if_id = ~0;
16730   int ret;
16731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16732     {
16733       if (unformat (input, "if_id %d", &if_id))
16734         ;
16735       else
16736         break;
16737     }
16738   if (if_id == ~0)
16739     {
16740       errmsg ("missing pg interface index");
16741       return -99;
16742     }
16743
16744   /* Construct the API message */
16745   M (PG_CREATE_INTERFACE, mp);
16746   mp->context = 0;
16747   mp->interface_id = ntohl (if_id);
16748
16749   S (mp);
16750   W (ret);
16751   return ret;
16752 }
16753
16754 int
16755 api_pg_capture (vat_main_t * vam)
16756 {
16757   unformat_input_t *input = vam->input;
16758   vl_api_pg_capture_t *mp;
16759
16760   u32 if_id = ~0;
16761   u8 enable = 1;
16762   u32 count = 1;
16763   u8 pcap_file_set = 0;
16764   u8 *pcap_file = 0;
16765   int ret;
16766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16767     {
16768       if (unformat (input, "if_id %d", &if_id))
16769         ;
16770       else if (unformat (input, "pcap %s", &pcap_file))
16771         pcap_file_set = 1;
16772       else if (unformat (input, "count %d", &count))
16773         ;
16774       else if (unformat (input, "disable"))
16775         enable = 0;
16776       else
16777         break;
16778     }
16779   if (if_id == ~0)
16780     {
16781       errmsg ("missing pg interface index");
16782       return -99;
16783     }
16784   if (pcap_file_set > 0)
16785     {
16786       if (vec_len (pcap_file) > 255)
16787         {
16788           errmsg ("pcap file name is too long");
16789           return -99;
16790         }
16791     }
16792
16793   u32 name_len = vec_len (pcap_file);
16794   /* Construct the API message */
16795   M (PG_CAPTURE, mp);
16796   mp->context = 0;
16797   mp->interface_id = ntohl (if_id);
16798   mp->is_enabled = enable;
16799   mp->count = ntohl (count);
16800   mp->pcap_name_length = ntohl (name_len);
16801   if (pcap_file_set != 0)
16802     {
16803       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16804     }
16805   vec_free (pcap_file);
16806
16807   S (mp);
16808   W (ret);
16809   return ret;
16810 }
16811
16812 int
16813 api_pg_enable_disable (vat_main_t * vam)
16814 {
16815   unformat_input_t *input = vam->input;
16816   vl_api_pg_enable_disable_t *mp;
16817
16818   u8 enable = 1;
16819   u8 stream_name_set = 0;
16820   u8 *stream_name = 0;
16821   int ret;
16822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16823     {
16824       if (unformat (input, "stream %s", &stream_name))
16825         stream_name_set = 1;
16826       else if (unformat (input, "disable"))
16827         enable = 0;
16828       else
16829         break;
16830     }
16831
16832   if (stream_name_set > 0)
16833     {
16834       if (vec_len (stream_name) > 255)
16835         {
16836           errmsg ("stream name too long");
16837           return -99;
16838         }
16839     }
16840
16841   u32 name_len = vec_len (stream_name);
16842   /* Construct the API message */
16843   M (PG_ENABLE_DISABLE, mp);
16844   mp->context = 0;
16845   mp->is_enabled = enable;
16846   if (stream_name_set != 0)
16847     {
16848       mp->stream_name_length = ntohl (name_len);
16849       clib_memcpy (mp->stream_name, stream_name, name_len);
16850     }
16851   vec_free (stream_name);
16852
16853   S (mp);
16854   W (ret);
16855   return ret;
16856 }
16857
16858 int
16859 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16860 {
16861   unformat_input_t *input = vam->input;
16862   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16863
16864   u16 *low_ports = 0;
16865   u16 *high_ports = 0;
16866   u16 this_low;
16867   u16 this_hi;
16868   ip4_address_t ip4_addr;
16869   ip6_address_t ip6_addr;
16870   u32 length;
16871   u32 tmp, tmp2;
16872   u8 prefix_set = 0;
16873   u32 vrf_id = ~0;
16874   u8 is_add = 1;
16875   u8 is_ipv6 = 0;
16876   int ret;
16877
16878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16879     {
16880       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16881         {
16882           prefix_set = 1;
16883         }
16884       else
16885         if (unformat
16886             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16887         {
16888           prefix_set = 1;
16889           is_ipv6 = 1;
16890         }
16891       else if (unformat (input, "vrf %d", &vrf_id))
16892         ;
16893       else if (unformat (input, "del"))
16894         is_add = 0;
16895       else if (unformat (input, "port %d", &tmp))
16896         {
16897           if (tmp == 0 || tmp > 65535)
16898             {
16899               errmsg ("port %d out of range", tmp);
16900               return -99;
16901             }
16902           this_low = tmp;
16903           this_hi = this_low + 1;
16904           vec_add1 (low_ports, this_low);
16905           vec_add1 (high_ports, this_hi);
16906         }
16907       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16908         {
16909           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16910             {
16911               errmsg ("incorrect range parameters");
16912               return -99;
16913             }
16914           this_low = tmp;
16915           /* Note: in debug CLI +1 is added to high before
16916              passing to real fn that does "the work"
16917              (ip_source_and_port_range_check_add_del).
16918              This fn is a wrapper around the binary API fn a
16919              control plane will call, which expects this increment
16920              to have occurred. Hence letting the binary API control
16921              plane fn do the increment for consistency between VAT
16922              and other control planes.
16923            */
16924           this_hi = tmp2;
16925           vec_add1 (low_ports, this_low);
16926           vec_add1 (high_ports, this_hi);
16927         }
16928       else
16929         break;
16930     }
16931
16932   if (prefix_set == 0)
16933     {
16934       errmsg ("<address>/<mask> not specified");
16935       return -99;
16936     }
16937
16938   if (vrf_id == ~0)
16939     {
16940       errmsg ("VRF ID required, not specified");
16941       return -99;
16942     }
16943
16944   if (vrf_id == 0)
16945     {
16946       errmsg
16947         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16948       return -99;
16949     }
16950
16951   if (vec_len (low_ports) == 0)
16952     {
16953       errmsg ("At least one port or port range required");
16954       return -99;
16955     }
16956
16957   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
16958
16959   mp->is_add = is_add;
16960
16961   if (is_ipv6)
16962     {
16963       mp->is_ipv6 = 1;
16964       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16965     }
16966   else
16967     {
16968       mp->is_ipv6 = 0;
16969       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16970     }
16971
16972   mp->mask_length = length;
16973   mp->number_of_ranges = vec_len (low_ports);
16974
16975   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16976   vec_free (low_ports);
16977
16978   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16979   vec_free (high_ports);
16980
16981   mp->vrf_id = ntohl (vrf_id);
16982
16983   S (mp);
16984   W (ret);
16985   return ret;
16986 }
16987
16988 int
16989 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16990 {
16991   unformat_input_t *input = vam->input;
16992   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16993   u32 sw_if_index = ~0;
16994   int vrf_set = 0;
16995   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16996   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16997   u8 is_add = 1;
16998   int ret;
16999
17000   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17001     {
17002       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17003         ;
17004       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17005         ;
17006       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17007         vrf_set = 1;
17008       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17009         vrf_set = 1;
17010       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17011         vrf_set = 1;
17012       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17013         vrf_set = 1;
17014       else if (unformat (input, "del"))
17015         is_add = 0;
17016       else
17017         break;
17018     }
17019
17020   if (sw_if_index == ~0)
17021     {
17022       errmsg ("Interface required but not specified");
17023       return -99;
17024     }
17025
17026   if (vrf_set == 0)
17027     {
17028       errmsg ("VRF ID required but not specified");
17029       return -99;
17030     }
17031
17032   if (tcp_out_vrf_id == 0
17033       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17034     {
17035       errmsg
17036         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17037       return -99;
17038     }
17039
17040   /* Construct the API message */
17041   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17042
17043   mp->sw_if_index = ntohl (sw_if_index);
17044   mp->is_add = is_add;
17045   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17046   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17047   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17048   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17049
17050   /* send it... */
17051   S (mp);
17052
17053   /* Wait for a reply... */
17054   W (ret);
17055   return ret;
17056 }
17057
17058 static int
17059 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17060 {
17061   unformat_input_t *i = vam->input;
17062   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17063   u32 local_sa_id = 0;
17064   u32 remote_sa_id = 0;
17065   ip4_address_t src_address;
17066   ip4_address_t dst_address;
17067   u8 is_add = 1;
17068   int ret;
17069
17070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17071     {
17072       if (unformat (i, "local_sa %d", &local_sa_id))
17073         ;
17074       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17075         ;
17076       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17077         ;
17078       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17079         ;
17080       else if (unformat (i, "del"))
17081         is_add = 0;
17082       else
17083         {
17084           clib_warning ("parse error '%U'", format_unformat_error, i);
17085           return -99;
17086         }
17087     }
17088
17089   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17090
17091   mp->local_sa_id = ntohl (local_sa_id);
17092   mp->remote_sa_id = ntohl (remote_sa_id);
17093   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17094   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17095   mp->is_add = is_add;
17096
17097   S (mp);
17098   W (ret);
17099   return ret;
17100 }
17101
17102 static int
17103 api_punt (vat_main_t * vam)
17104 {
17105   unformat_input_t *i = vam->input;
17106   vl_api_punt_t *mp;
17107   u32 ipv = ~0;
17108   u32 protocol = ~0;
17109   u32 port = ~0;
17110   int is_add = 1;
17111   int ret;
17112
17113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17114     {
17115       if (unformat (i, "ip %d", &ipv))
17116         ;
17117       else if (unformat (i, "protocol %d", &protocol))
17118         ;
17119       else if (unformat (i, "port %d", &port))
17120         ;
17121       else if (unformat (i, "del"))
17122         is_add = 0;
17123       else
17124         {
17125           clib_warning ("parse error '%U'", format_unformat_error, i);
17126           return -99;
17127         }
17128     }
17129
17130   M (PUNT, mp);
17131
17132   mp->is_add = (u8) is_add;
17133   mp->ipv = (u8) ipv;
17134   mp->l4_protocol = (u8) protocol;
17135   mp->l4_port = htons ((u16) port);
17136
17137   S (mp);
17138   W (ret);
17139   return ret;
17140 }
17141
17142 static void vl_api_ipsec_gre_tunnel_details_t_handler
17143   (vl_api_ipsec_gre_tunnel_details_t * mp)
17144 {
17145   vat_main_t *vam = &vat_main;
17146
17147   print (vam->ofp, "%11d%15U%15U%14d%14d",
17148          ntohl (mp->sw_if_index),
17149          format_ip4_address, &mp->src_address,
17150          format_ip4_address, &mp->dst_address,
17151          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17152 }
17153
17154 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17155   (vl_api_ipsec_gre_tunnel_details_t * mp)
17156 {
17157   vat_main_t *vam = &vat_main;
17158   vat_json_node_t *node = NULL;
17159   struct in_addr ip4;
17160
17161   if (VAT_JSON_ARRAY != vam->json_tree.type)
17162     {
17163       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17164       vat_json_init_array (&vam->json_tree);
17165     }
17166   node = vat_json_array_add (&vam->json_tree);
17167
17168   vat_json_init_object (node);
17169   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17170   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17171   vat_json_object_add_ip4 (node, "src_address", ip4);
17172   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17173   vat_json_object_add_ip4 (node, "dst_address", ip4);
17174   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17175   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17176 }
17177
17178 static int
17179 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17180 {
17181   unformat_input_t *i = vam->input;
17182   vl_api_ipsec_gre_tunnel_dump_t *mp;
17183   vl_api_control_ping_t *mp_ping;
17184   u32 sw_if_index;
17185   u8 sw_if_index_set = 0;
17186   int ret;
17187
17188   /* Parse args required to build the message */
17189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17190     {
17191       if (unformat (i, "sw_if_index %d", &sw_if_index))
17192         sw_if_index_set = 1;
17193       else
17194         break;
17195     }
17196
17197   if (sw_if_index_set == 0)
17198     {
17199       sw_if_index = ~0;
17200     }
17201
17202   if (!vam->json_output)
17203     {
17204       print (vam->ofp, "%11s%15s%15s%14s%14s",
17205              "sw_if_index", "src_address", "dst_address",
17206              "local_sa_id", "remote_sa_id");
17207     }
17208
17209   /* Get list of gre-tunnel interfaces */
17210   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17211
17212   mp->sw_if_index = htonl (sw_if_index);
17213
17214   S (mp);
17215
17216   /* Use a control ping for synchronization */
17217   M (CONTROL_PING, mp_ping);
17218   S (mp_ping);
17219
17220   W (ret);
17221   return ret;
17222 }
17223
17224 static int
17225 api_delete_subif (vat_main_t * vam)
17226 {
17227   unformat_input_t *i = vam->input;
17228   vl_api_delete_subif_t *mp;
17229   u32 sw_if_index = ~0;
17230   int ret;
17231
17232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17233     {
17234       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17235         ;
17236       if (unformat (i, "sw_if_index %d", &sw_if_index))
17237         ;
17238       else
17239         break;
17240     }
17241
17242   if (sw_if_index == ~0)
17243     {
17244       errmsg ("missing sw_if_index");
17245       return -99;
17246     }
17247
17248   /* Construct the API message */
17249   M (DELETE_SUBIF, mp);
17250   mp->sw_if_index = ntohl (sw_if_index);
17251
17252   S (mp);
17253   W (ret);
17254   return ret;
17255 }
17256
17257 #define foreach_pbb_vtr_op      \
17258 _("disable",  L2_VTR_DISABLED)  \
17259 _("pop",  L2_VTR_POP_2)         \
17260 _("push",  L2_VTR_PUSH_2)
17261
17262 static int
17263 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17264 {
17265   unformat_input_t *i = vam->input;
17266   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17267   u32 sw_if_index = ~0, vtr_op = ~0;
17268   u16 outer_tag = ~0;
17269   u8 dmac[6], smac[6];
17270   u8 dmac_set = 0, smac_set = 0;
17271   u16 vlanid = 0;
17272   u32 sid = ~0;
17273   u32 tmp;
17274   int ret;
17275
17276   /* Shut up coverity */
17277   memset (dmac, 0, sizeof (dmac));
17278   memset (smac, 0, sizeof (smac));
17279
17280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17281     {
17282       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17283         ;
17284       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17285         ;
17286       else if (unformat (i, "vtr_op %d", &vtr_op))
17287         ;
17288 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17289       foreach_pbb_vtr_op
17290 #undef _
17291         else if (unformat (i, "translate_pbb_stag"))
17292         {
17293           if (unformat (i, "%d", &tmp))
17294             {
17295               vtr_op = L2_VTR_TRANSLATE_2_1;
17296               outer_tag = tmp;
17297             }
17298           else
17299             {
17300               errmsg
17301                 ("translate_pbb_stag operation requires outer tag definition");
17302               return -99;
17303             }
17304         }
17305       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17306         dmac_set++;
17307       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17308         smac_set++;
17309       else if (unformat (i, "sid %d", &sid))
17310         ;
17311       else if (unformat (i, "vlanid %d", &tmp))
17312         vlanid = tmp;
17313       else
17314         {
17315           clib_warning ("parse error '%U'", format_unformat_error, i);
17316           return -99;
17317         }
17318     }
17319
17320   if ((sw_if_index == ~0) || (vtr_op == ~0))
17321     {
17322       errmsg ("missing sw_if_index or vtr operation");
17323       return -99;
17324     }
17325   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17326       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17327     {
17328       errmsg
17329         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17330       return -99;
17331     }
17332
17333   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17334   mp->sw_if_index = ntohl (sw_if_index);
17335   mp->vtr_op = ntohl (vtr_op);
17336   mp->outer_tag = ntohs (outer_tag);
17337   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17338   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17339   mp->b_vlanid = ntohs (vlanid);
17340   mp->i_sid = ntohl (sid);
17341
17342   S (mp);
17343   W (ret);
17344   return ret;
17345 }
17346
17347 static int
17348 api_flow_classify_set_interface (vat_main_t * vam)
17349 {
17350   unformat_input_t *i = vam->input;
17351   vl_api_flow_classify_set_interface_t *mp;
17352   u32 sw_if_index;
17353   int sw_if_index_set;
17354   u32 ip4_table_index = ~0;
17355   u32 ip6_table_index = ~0;
17356   u8 is_add = 1;
17357   int ret;
17358
17359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17360     {
17361       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17362         sw_if_index_set = 1;
17363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17364         sw_if_index_set = 1;
17365       else if (unformat (i, "del"))
17366         is_add = 0;
17367       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17368         ;
17369       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17370         ;
17371       else
17372         {
17373           clib_warning ("parse error '%U'", format_unformat_error, i);
17374           return -99;
17375         }
17376     }
17377
17378   if (sw_if_index_set == 0)
17379     {
17380       errmsg ("missing interface name or sw_if_index");
17381       return -99;
17382     }
17383
17384   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17385
17386   mp->sw_if_index = ntohl (sw_if_index);
17387   mp->ip4_table_index = ntohl (ip4_table_index);
17388   mp->ip6_table_index = ntohl (ip6_table_index);
17389   mp->is_add = is_add;
17390
17391   S (mp);
17392   W (ret);
17393   return ret;
17394 }
17395
17396 static int
17397 api_flow_classify_dump (vat_main_t * vam)
17398 {
17399   unformat_input_t *i = vam->input;
17400   vl_api_flow_classify_dump_t *mp;
17401   vl_api_control_ping_t *mp_ping;
17402   u8 type = FLOW_CLASSIFY_N_TABLES;
17403   int ret;
17404
17405   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17406     ;
17407   else
17408     {
17409       errmsg ("classify table type must be specified");
17410       return -99;
17411     }
17412
17413   if (!vam->json_output)
17414     {
17415       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17416     }
17417
17418   M (FLOW_CLASSIFY_DUMP, mp);
17419   mp->type = type;
17420   /* send it... */
17421   S (mp);
17422
17423   /* Use a control ping for synchronization */
17424   M (CONTROL_PING, mp_ping);
17425   S (mp_ping);
17426
17427   /* Wait for a reply... */
17428   W (ret);
17429   return ret;
17430 }
17431
17432 static int
17433 api_feature_enable_disable (vat_main_t * vam)
17434 {
17435   unformat_input_t *i = vam->input;
17436   vl_api_feature_enable_disable_t *mp;
17437   u8 *arc_name = 0;
17438   u8 *feature_name = 0;
17439   u32 sw_if_index = ~0;
17440   u8 enable = 1;
17441   int ret;
17442
17443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17444     {
17445       if (unformat (i, "arc_name %s", &arc_name))
17446         ;
17447       else if (unformat (i, "feature_name %s", &feature_name))
17448         ;
17449       else
17450         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17451         ;
17452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17453         ;
17454       else if (unformat (i, "disable"))
17455         enable = 0;
17456       else
17457         break;
17458     }
17459
17460   if (arc_name == 0)
17461     {
17462       errmsg ("missing arc name");
17463       return -99;
17464     }
17465   if (vec_len (arc_name) > 63)
17466     {
17467       errmsg ("arc name too long");
17468     }
17469
17470   if (feature_name == 0)
17471     {
17472       errmsg ("missing feature name");
17473       return -99;
17474     }
17475   if (vec_len (feature_name) > 63)
17476     {
17477       errmsg ("feature name too long");
17478     }
17479
17480   if (sw_if_index == ~0)
17481     {
17482       errmsg ("missing interface name or sw_if_index");
17483       return -99;
17484     }
17485
17486   /* Construct the API message */
17487   M (FEATURE_ENABLE_DISABLE, mp);
17488   mp->sw_if_index = ntohl (sw_if_index);
17489   mp->enable = enable;
17490   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17491   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17492   vec_free (arc_name);
17493   vec_free (feature_name);
17494
17495   S (mp);
17496   W (ret);
17497   return ret;
17498 }
17499
17500 static int
17501 api_sw_interface_tag_add_del (vat_main_t * vam)
17502 {
17503   unformat_input_t *i = vam->input;
17504   vl_api_sw_interface_tag_add_del_t *mp;
17505   u32 sw_if_index = ~0;
17506   u8 *tag = 0;
17507   u8 enable = 1;
17508   int ret;
17509
17510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17511     {
17512       if (unformat (i, "tag %s", &tag))
17513         ;
17514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17515         ;
17516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17517         ;
17518       else if (unformat (i, "del"))
17519         enable = 0;
17520       else
17521         break;
17522     }
17523
17524   if (sw_if_index == ~0)
17525     {
17526       errmsg ("missing interface name or sw_if_index");
17527       return -99;
17528     }
17529
17530   if (enable && (tag == 0))
17531     {
17532       errmsg ("no tag specified");
17533       return -99;
17534     }
17535
17536   /* Construct the API message */
17537   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17538   mp->sw_if_index = ntohl (sw_if_index);
17539   mp->is_add = enable;
17540   if (enable)
17541     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17542   vec_free (tag);
17543
17544   S (mp);
17545   W (ret);
17546   return ret;
17547 }
17548
17549 static void vl_api_l2_xconnect_details_t_handler
17550   (vl_api_l2_xconnect_details_t * mp)
17551 {
17552   vat_main_t *vam = &vat_main;
17553
17554   print (vam->ofp, "%15d%15d",
17555          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17556 }
17557
17558 static void vl_api_l2_xconnect_details_t_handler_json
17559   (vl_api_l2_xconnect_details_t * mp)
17560 {
17561   vat_main_t *vam = &vat_main;
17562   vat_json_node_t *node = NULL;
17563
17564   if (VAT_JSON_ARRAY != vam->json_tree.type)
17565     {
17566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17567       vat_json_init_array (&vam->json_tree);
17568     }
17569   node = vat_json_array_add (&vam->json_tree);
17570
17571   vat_json_init_object (node);
17572   vat_json_object_add_uint (node, "rx_sw_if_index",
17573                             ntohl (mp->rx_sw_if_index));
17574   vat_json_object_add_uint (node, "tx_sw_if_index",
17575                             ntohl (mp->tx_sw_if_index));
17576 }
17577
17578 static int
17579 api_l2_xconnect_dump (vat_main_t * vam)
17580 {
17581   vl_api_l2_xconnect_dump_t *mp;
17582   vl_api_control_ping_t *mp_ping;
17583   int ret;
17584
17585   if (!vam->json_output)
17586     {
17587       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17588     }
17589
17590   M (L2_XCONNECT_DUMP, mp);
17591
17592   S (mp);
17593
17594   /* Use a control ping for synchronization */
17595   M (CONTROL_PING, mp_ping);
17596   S (mp_ping);
17597
17598   W (ret);
17599   return ret;
17600 }
17601
17602 static int
17603 api_sw_interface_set_mtu (vat_main_t * vam)
17604 {
17605   unformat_input_t *i = vam->input;
17606   vl_api_sw_interface_set_mtu_t *mp;
17607   u32 sw_if_index = ~0;
17608   u32 mtu = 0;
17609   int ret;
17610
17611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17612     {
17613       if (unformat (i, "mtu %d", &mtu))
17614         ;
17615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17616         ;
17617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17618         ;
17619       else
17620         break;
17621     }
17622
17623   if (sw_if_index == ~0)
17624     {
17625       errmsg ("missing interface name or sw_if_index");
17626       return -99;
17627     }
17628
17629   if (mtu == 0)
17630     {
17631       errmsg ("no mtu specified");
17632       return -99;
17633     }
17634
17635   /* Construct the API message */
17636   M (SW_INTERFACE_SET_MTU, mp);
17637   mp->sw_if_index = ntohl (sw_if_index);
17638   mp->mtu = ntohs ((u16) mtu);
17639
17640   S (mp);
17641   W (ret);
17642   return ret;
17643 }
17644
17645
17646 static int
17647 q_or_quit (vat_main_t * vam)
17648 {
17649 #if VPP_API_TEST_BUILTIN == 0
17650   longjmp (vam->jump_buf, 1);
17651 #endif
17652   return 0;                     /* not so much */
17653 }
17654
17655 static int
17656 q (vat_main_t * vam)
17657 {
17658   return q_or_quit (vam);
17659 }
17660
17661 static int
17662 quit (vat_main_t * vam)
17663 {
17664   return q_or_quit (vam);
17665 }
17666
17667 static int
17668 comment (vat_main_t * vam)
17669 {
17670   return 0;
17671 }
17672
17673 static int
17674 cmd_cmp (void *a1, void *a2)
17675 {
17676   u8 **c1 = a1;
17677   u8 **c2 = a2;
17678
17679   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17680 }
17681
17682 static int
17683 help (vat_main_t * vam)
17684 {
17685   u8 **cmds = 0;
17686   u8 *name = 0;
17687   hash_pair_t *p;
17688   unformat_input_t *i = vam->input;
17689   int j;
17690
17691   if (unformat (i, "%s", &name))
17692     {
17693       uword *hs;
17694
17695       vec_add1 (name, 0);
17696
17697       hs = hash_get_mem (vam->help_by_name, name);
17698       if (hs)
17699         print (vam->ofp, "usage: %s %s", name, hs[0]);
17700       else
17701         print (vam->ofp, "No such msg / command '%s'", name);
17702       vec_free (name);
17703       return 0;
17704     }
17705
17706   print (vam->ofp, "Help is available for the following:");
17707
17708     /* *INDENT-OFF* */
17709     hash_foreach_pair (p, vam->function_by_name,
17710     ({
17711       vec_add1 (cmds, (u8 *)(p->key));
17712     }));
17713     /* *INDENT-ON* */
17714
17715   vec_sort_with_function (cmds, cmd_cmp);
17716
17717   for (j = 0; j < vec_len (cmds); j++)
17718     print (vam->ofp, "%s", cmds[j]);
17719
17720   vec_free (cmds);
17721   return 0;
17722 }
17723
17724 static int
17725 set (vat_main_t * vam)
17726 {
17727   u8 *name = 0, *value = 0;
17728   unformat_input_t *i = vam->input;
17729
17730   if (unformat (i, "%s", &name))
17731     {
17732       /* The input buffer is a vector, not a string. */
17733       value = vec_dup (i->buffer);
17734       vec_delete (value, i->index, 0);
17735       /* Almost certainly has a trailing newline */
17736       if (value[vec_len (value) - 1] == '\n')
17737         value[vec_len (value) - 1] = 0;
17738       /* Make sure it's a proper string, one way or the other */
17739       vec_add1 (value, 0);
17740       (void) clib_macro_set_value (&vam->macro_main,
17741                                    (char *) name, (char *) value);
17742     }
17743   else
17744     errmsg ("usage: set <name> <value>");
17745
17746   vec_free (name);
17747   vec_free (value);
17748   return 0;
17749 }
17750
17751 static int
17752 unset (vat_main_t * vam)
17753 {
17754   u8 *name = 0;
17755
17756   if (unformat (vam->input, "%s", &name))
17757     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17758       errmsg ("unset: %s wasn't set", name);
17759   vec_free (name);
17760   return 0;
17761 }
17762
17763 typedef struct
17764 {
17765   u8 *name;
17766   u8 *value;
17767 } macro_sort_t;
17768
17769
17770 static int
17771 macro_sort_cmp (void *a1, void *a2)
17772 {
17773   macro_sort_t *s1 = a1;
17774   macro_sort_t *s2 = a2;
17775
17776   return strcmp ((char *) (s1->name), (char *) (s2->name));
17777 }
17778
17779 static int
17780 dump_macro_table (vat_main_t * vam)
17781 {
17782   macro_sort_t *sort_me = 0, *sm;
17783   int i;
17784   hash_pair_t *p;
17785
17786     /* *INDENT-OFF* */
17787     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17788     ({
17789       vec_add2 (sort_me, sm, 1);
17790       sm->name = (u8 *)(p->key);
17791       sm->value = (u8 *) (p->value[0]);
17792     }));
17793     /* *INDENT-ON* */
17794
17795   vec_sort_with_function (sort_me, macro_sort_cmp);
17796
17797   if (vec_len (sort_me))
17798     print (vam->ofp, "%-15s%s", "Name", "Value");
17799   else
17800     print (vam->ofp, "The macro table is empty...");
17801
17802   for (i = 0; i < vec_len (sort_me); i++)
17803     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17804   return 0;
17805 }
17806
17807 static int
17808 dump_node_table (vat_main_t * vam)
17809 {
17810   int i, j;
17811   vlib_node_t *node, *next_node;
17812
17813   if (vec_len (vam->graph_nodes) == 0)
17814     {
17815       print (vam->ofp, "Node table empty, issue get_node_graph...");
17816       return 0;
17817     }
17818
17819   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17820     {
17821       node = vam->graph_nodes[i];
17822       print (vam->ofp, "[%d] %s", i, node->name);
17823       for (j = 0; j < vec_len (node->next_nodes); j++)
17824         {
17825           if (node->next_nodes[j] != ~0)
17826             {
17827               next_node = vam->graph_nodes[node->next_nodes[j]];
17828               print (vam->ofp, "  [%d] %s", j, next_node->name);
17829             }
17830         }
17831     }
17832   return 0;
17833 }
17834
17835 static int
17836 value_sort_cmp (void *a1, void *a2)
17837 {
17838   name_sort_t *n1 = a1;
17839   name_sort_t *n2 = a2;
17840
17841   if (n1->value < n2->value)
17842     return -1;
17843   if (n1->value > n2->value)
17844     return 1;
17845   return 0;
17846 }
17847
17848
17849 static int
17850 dump_msg_api_table (vat_main_t * vam)
17851 {
17852   api_main_t *am = &api_main;
17853   name_sort_t *nses = 0, *ns;
17854   hash_pair_t *hp;
17855   int i;
17856
17857   /* *INDENT-OFF* */
17858   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17859   ({
17860     vec_add2 (nses, ns, 1);
17861     ns->name = (u8 *)(hp->key);
17862     ns->value = (u32) hp->value[0];
17863   }));
17864   /* *INDENT-ON* */
17865
17866   vec_sort_with_function (nses, value_sort_cmp);
17867
17868   for (i = 0; i < vec_len (nses); i++)
17869     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17870   vec_free (nses);
17871   return 0;
17872 }
17873
17874 static int
17875 get_msg_id (vat_main_t * vam)
17876 {
17877   u8 *name_and_crc;
17878   u32 message_index;
17879
17880   if (unformat (vam->input, "%s", &name_and_crc))
17881     {
17882       message_index = vl_api_get_msg_index (name_and_crc);
17883       if (message_index == ~0)
17884         {
17885           print (vam->ofp, " '%s' not found", name_and_crc);
17886           return 0;
17887         }
17888       print (vam->ofp, " '%s' has message index %d",
17889              name_and_crc, message_index);
17890       return 0;
17891     }
17892   errmsg ("name_and_crc required...");
17893   return 0;
17894 }
17895
17896 static int
17897 search_node_table (vat_main_t * vam)
17898 {
17899   unformat_input_t *line_input = vam->input;
17900   u8 *node_to_find;
17901   int j;
17902   vlib_node_t *node, *next_node;
17903   uword *p;
17904
17905   if (vam->graph_node_index_by_name == 0)
17906     {
17907       print (vam->ofp, "Node table empty, issue get_node_graph...");
17908       return 0;
17909     }
17910
17911   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17912     {
17913       if (unformat (line_input, "%s", &node_to_find))
17914         {
17915           vec_add1 (node_to_find, 0);
17916           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17917           if (p == 0)
17918             {
17919               print (vam->ofp, "%s not found...", node_to_find);
17920               goto out;
17921             }
17922           node = vam->graph_nodes[p[0]];
17923           print (vam->ofp, "[%d] %s", p[0], node->name);
17924           for (j = 0; j < vec_len (node->next_nodes); j++)
17925             {
17926               if (node->next_nodes[j] != ~0)
17927                 {
17928                   next_node = vam->graph_nodes[node->next_nodes[j]];
17929                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17930                 }
17931             }
17932         }
17933
17934       else
17935         {
17936           clib_warning ("parse error '%U'", format_unformat_error,
17937                         line_input);
17938           return -99;
17939         }
17940
17941     out:
17942       vec_free (node_to_find);
17943
17944     }
17945
17946   return 0;
17947 }
17948
17949
17950 static int
17951 script (vat_main_t * vam)
17952 {
17953 #if (VPP_API_TEST_BUILTIN==0)
17954   u8 *s = 0;
17955   char *save_current_file;
17956   unformat_input_t save_input;
17957   jmp_buf save_jump_buf;
17958   u32 save_line_number;
17959
17960   FILE *new_fp, *save_ifp;
17961
17962   if (unformat (vam->input, "%s", &s))
17963     {
17964       new_fp = fopen ((char *) s, "r");
17965       if (new_fp == 0)
17966         {
17967           errmsg ("Couldn't open script file %s", s);
17968           vec_free (s);
17969           return -99;
17970         }
17971     }
17972   else
17973     {
17974       errmsg ("Missing script name");
17975       return -99;
17976     }
17977
17978   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17979   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17980   save_ifp = vam->ifp;
17981   save_line_number = vam->input_line_number;
17982   save_current_file = (char *) vam->current_file;
17983
17984   vam->input_line_number = 0;
17985   vam->ifp = new_fp;
17986   vam->current_file = s;
17987   do_one_file (vam);
17988
17989   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17990   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17991   vam->ifp = save_ifp;
17992   vam->input_line_number = save_line_number;
17993   vam->current_file = (u8 *) save_current_file;
17994   vec_free (s);
17995
17996   return 0;
17997 #else
17998   clib_warning ("use the exec command...");
17999   return -99;
18000 #endif
18001 }
18002
18003 static int
18004 echo (vat_main_t * vam)
18005 {
18006   print (vam->ofp, "%v", vam->input->buffer);
18007   return 0;
18008 }
18009
18010 /* List of API message constructors, CLI names map to api_xxx */
18011 #define foreach_vpe_api_msg                                             \
18012 _(create_loopback,"[mac <mac-addr>]")                                   \
18013 _(sw_interface_dump,"")                                                 \
18014 _(sw_interface_set_flags,                                               \
18015   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18016 _(sw_interface_add_del_address,                                         \
18017   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18018 _(sw_interface_set_table,                                               \
18019   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18020 _(sw_interface_set_mpls_enable,                                         \
18021   "<intfc> | sw_if_index [disable | dis]")                              \
18022 _(sw_interface_set_vpath,                                               \
18023   "<intfc> | sw_if_index <id> enable | disable")                        \
18024 _(sw_interface_set_vxlan_bypass,                                        \
18025   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18026 _(sw_interface_set_l2_xconnect,                                         \
18027   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18028   "enable | disable")                                                   \
18029 _(sw_interface_set_l2_bridge,                                           \
18030   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18031   "[shg <split-horizon-group>] [bvi]\n"                                 \
18032   "enable | disable")                                                   \
18033 _(bridge_domain_add_del,                                                \
18034   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18035 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18036 _(l2fib_add_del,                                                        \
18037   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18038 _(l2_flags,                                                             \
18039   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18040 _(bridge_flags,                                                         \
18041   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18042 _(tap_connect,                                                          \
18043   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18044 _(tap_modify,                                                           \
18045   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18046 _(tap_delete,                                                           \
18047   "<vpp-if-name> | sw_if_index <id>")                                   \
18048 _(sw_interface_tap_dump, "")                                            \
18049 _(ip_add_del_route,                                                     \
18050   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18051   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18052   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18053   "[multipath] [count <n>]")                                            \
18054 _(ip_mroute_add_del,                                                    \
18055   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18056   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18057 _(mpls_route_add_del,                                                   \
18058   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18059   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18060   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18061   "[multipath] [count <n>]")                                            \
18062 _(mpls_ip_bind_unbind,                                                  \
18063   "<label> <addr/len>")                                                 \
18064 _(mpls_tunnel_add_del,                                                  \
18065   " via <addr> [table-id <n>]\n"                                        \
18066   "sw_if_index <id>] [l2]  [del]")                                      \
18067 _(proxy_arp_add_del,                                                    \
18068   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18069 _(proxy_arp_intfc_enable_disable,                                       \
18070   "<intfc> | sw_if_index <id> enable | disable")                        \
18071 _(sw_interface_set_unnumbered,                                          \
18072   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18073 _(ip_neighbor_add_del,                                                  \
18074   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18075   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18076 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18077 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18078 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18079   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18080   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18081   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18082 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18083 _(reset_fib, "vrf <n> [ipv6]")                                          \
18084 _(dhcp_proxy_config,                                                    \
18085   "svr <v46-address> src <v46-address>\n"                               \
18086    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18087 _(dhcp_proxy_set_vss,                                                   \
18088   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18089 _(dhcp_proxy_dump, "ip6")                                               \
18090 _(dhcp_client_config,                                                   \
18091   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18092 _(set_ip_flow_hash,                                                     \
18093   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18094 _(sw_interface_ip6_enable_disable,                                      \
18095   "<intfc> | sw_if_index <id> enable | disable")                        \
18096 _(sw_interface_ip6_set_link_local_address,                              \
18097   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18098 _(sw_interface_ip6nd_ra_prefix,                                         \
18099   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18100   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18101   "[nolink] [isno]")                                                    \
18102 _(sw_interface_ip6nd_ra_config,                                         \
18103   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18104   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18105   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18106 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18107 _(l2_patch_add_del,                                                     \
18108   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18109   "enable | disable")                                                   \
18110 _(sr_tunnel_add_del,                                                    \
18111   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
18112   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
18113   "[policy <policy_name>]")                                             \
18114 _(sr_policy_add_del,                                                    \
18115   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
18116 _(sr_multicast_map_add_del,                                             \
18117   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
18118 _(classify_add_del_table,                                               \
18119   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18120   " [del] [del-chain] mask <mask-value>\n"                              \
18121   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18122   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18123 _(classify_add_del_session,                                             \
18124   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18125   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18126   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18127   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18128 _(classify_set_interface_ip_table,                                      \
18129   "<intfc> | sw_if_index <nn> table <nn>")                              \
18130 _(classify_set_interface_l2_tables,                                     \
18131   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18132   "  [other-table <nn>]")                                               \
18133 _(get_node_index, "node <node-name")                                    \
18134 _(add_node_next, "node <node-name> next <next-node-name>")              \
18135 _(l2tpv3_create_tunnel,                                                 \
18136   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18137   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18138   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18139 _(l2tpv3_set_tunnel_cookies,                                            \
18140   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18141   "[new_remote_cookie <nn>]\n")                                         \
18142 _(l2tpv3_interface_enable_disable,                                      \
18143   "<intfc> | sw_if_index <nn> enable | disable")                        \
18144 _(l2tpv3_set_lookup_key,                                                \
18145   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18146 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18147 _(vxlan_add_del_tunnel,                                                 \
18148   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18149   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18150   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18151 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18152 _(gre_add_del_tunnel,                                                   \
18153   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18154 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18155 _(l2_fib_clear_table, "")                                               \
18156 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18157 _(l2_interface_vlan_tag_rewrite,                                        \
18158   "<intfc> | sw_if_index <nn> \n"                                       \
18159   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18160   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18161 _(create_vhost_user_if,                                                 \
18162         "socket <filename> [server] [renumber <dev_instance>] "         \
18163         "[mac <mac_address>]")                                          \
18164 _(modify_vhost_user_if,                                                 \
18165         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18166         "[server] [renumber <dev_instance>]")                           \
18167 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18168 _(sw_interface_vhost_user_dump, "")                                     \
18169 _(show_version, "")                                                     \
18170 _(vxlan_gpe_add_del_tunnel,                                             \
18171   "local <addr> remote <addr> vni <nn>\n"                               \
18172     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18173   "[next-ethernet] [next-nsh]\n")                                       \
18174 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18175 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18176 _(interface_name_renumber,                                              \
18177   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18178 _(input_acl_set_interface,                                              \
18179   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18180   "  [l2-table <nn>] [del]")                                            \
18181 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18182 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18183 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18184 _(ip_dump, "ipv4 | ipv6")                                               \
18185 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18186 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18187   "  spid_id <n> ")                                                     \
18188 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18189   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18190   "  integ_alg <alg> integ_key <hex>")                                  \
18191 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18192   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18193   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18194   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18195 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18196 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18197 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18198   "(auth_data 0x<data> | auth_data <data>)")                            \
18199 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18200   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18201 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18202   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18203   "(local|remote)")                                                     \
18204 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18205 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18206 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18207 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18208 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18209 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18210 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18211 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18212 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18213 _(delete_loopback,"sw_if_index <nn>")                                   \
18214 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18215 _(map_add_domain,                                                       \
18216   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18217   "ip6-src <ip6addr> "                                                  \
18218   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18219 _(map_del_domain, "index <n>")                                          \
18220 _(map_add_del_rule,                                                     \
18221   "index <n> psid <n> dst <ip6addr> [del]")                             \
18222 _(map_domain_dump, "")                                                  \
18223 _(map_rule_dump, "index <map-domain>")                                  \
18224 _(want_interface_events,  "enable|disable")                             \
18225 _(want_stats,"enable|disable")                                          \
18226 _(get_first_msg_id, "client <name>")                                    \
18227 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18228 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18229   "fib-id <nn> [ip4][ip6][default]")                                    \
18230 _(get_node_graph, " ")                                                  \
18231 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18232 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18233 _(ioam_disable, "")                                                     \
18234 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18235                             " sw_if_index <sw_if_index> p <priority> "  \
18236                             "w <weight>] [del]")                        \
18237 _(one_add_del_locator, "locator-set <locator_name> "                    \
18238                         "iface <intf> | sw_if_index <sw_if_index> "     \
18239                         "p <priority> w <weight> [del]")                \
18240 _(one_add_del_local_eid,"vni <vni> eid "                                \
18241                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18242                          "locator-set <locator_name> [del]"             \
18243                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18244 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18245 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18246 _(one_enable_disable, "enable|disable")                                 \
18247 _(one_map_register_enable_disable, "enable|disable")                    \
18248 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18249 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18250                                "[seid <seid>] "                         \
18251                                "rloc <locator> p <prio> "               \
18252                                "w <weight> [rloc <loc> ... ] "          \
18253                                "action <action> [del-all]")             \
18254 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18255                           "<local-eid>")                                \
18256 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18257 _(one_map_request_mode, "src-dst|dst-only")                             \
18258 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18259 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18260 _(one_locator_set_dump, "[local | remote]")                             \
18261 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18262 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18263                        "[local] | [remote]")                            \
18264 _(one_eid_table_vni_dump, "")                                           \
18265 _(one_eid_table_map_dump, "l2|l3")                                      \
18266 _(one_map_resolver_dump, "")                                            \
18267 _(one_map_server_dump, "")                                              \
18268 _(one_adjacencies_get, "vni <vni>")                                     \
18269 _(show_one_rloc_probe_state, "")                                        \
18270 _(show_one_map_register_state, "")                                      \
18271 _(show_one_status, "")                                                  \
18272 _(one_get_map_request_itr_rlocs, "")                                    \
18273 _(show_one_pitr, "")                                                    \
18274 _(show_one_map_request_mode, "")                                        \
18275 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18276                             " sw_if_index <sw_if_index> p <priority> "  \
18277                             "w <weight>] [del]")                        \
18278 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18279                         "iface <intf> | sw_if_index <sw_if_index> "     \
18280                         "p <priority> w <weight> [del]")                \
18281 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18282                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18283                          "locator-set <locator_name> [del]"             \
18284                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18285 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18286 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18287 _(lisp_enable_disable, "enable|disable")                                \
18288 _(lisp_map_register_enable_disable, "enable|disable")                   \
18289 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18290 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18291                                "[seid <seid>] "                         \
18292                                "rloc <locator> p <prio> "               \
18293                                "w <weight> [rloc <loc> ... ] "          \
18294                                "action <action> [del-all]")             \
18295 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18296                           "<local-eid>")                                \
18297 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18298 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18299 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18300 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18301 _(lisp_locator_set_dump, "[local | remote]")                            \
18302 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18303 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18304                        "[local] | [remote]")                            \
18305 _(lisp_eid_table_vni_dump, "")                                          \
18306 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18307 _(lisp_map_resolver_dump, "")                                           \
18308 _(lisp_map_server_dump, "")                                             \
18309 _(lisp_adjacencies_get, "vni <vni>")                                    \
18310 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18311 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18312 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18313 _(gpe_get_encap_mode, "")                                               \
18314 _(lisp_gpe_add_del_iface, "up|down")                                    \
18315 _(lisp_gpe_enable_disable, "enable|disable")                            \
18316 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18317   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18318 _(show_lisp_rloc_probe_state, "")                                       \
18319 _(show_lisp_map_register_state, "")                                     \
18320 _(show_lisp_status, "")                                                 \
18321 _(lisp_get_map_request_itr_rlocs, "")                                   \
18322 _(show_lisp_pitr, "")                                                   \
18323 _(show_lisp_map_request_mode, "")                                       \
18324 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18325 _(af_packet_delete, "name <host interface name>")                       \
18326 _(policer_add_del, "name <policer name> <params> [del]")                \
18327 _(policer_dump, "[name <policer name>]")                                \
18328 _(policer_classify_set_interface,                                       \
18329   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18330   "  [l2-table <nn>] [del]")                                            \
18331 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18332 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18333     "[master|slave]")                                                   \
18334 _(netmap_delete, "name <interface name>")                               \
18335 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18336 _(mpls_fib_dump, "")                                                    \
18337 _(classify_table_ids, "")                                               \
18338 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18339 _(classify_table_info, "table_id <nn>")                                 \
18340 _(classify_session_dump, "table_id <nn>")                               \
18341 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18342     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18343     "[template_interval <nn>] [udp_checksum]")                          \
18344 _(ipfix_exporter_dump, "")                                              \
18345 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18346 _(ipfix_classify_stream_dump, "")                                       \
18347 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18348 _(ipfix_classify_table_dump, "")                                        \
18349 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18350 _(sw_interface_span_dump, "")                                           \
18351 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18352 _(pg_create_interface, "if_id <nn>")                                    \
18353 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18354 _(pg_enable_disable, "[stream <id>] disable")                           \
18355 _(ip_source_and_port_range_check_add_del,                               \
18356   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18357 _(ip_source_and_port_range_check_interface_add_del,                     \
18358   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18359   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18360 _(ipsec_gre_add_del_tunnel,                                             \
18361   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18362 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18363 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18364 _(l2_interface_pbb_tag_rewrite,                                         \
18365   "<intfc> | sw_if_index <nn> \n"                                       \
18366   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18367   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18368 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18369 _(flow_classify_set_interface,                                          \
18370   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18371 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18372 _(ip_fib_dump, "")                                                      \
18373 _(ip_mfib_dump, "")                                                     \
18374 _(ip6_fib_dump, "")                                                     \
18375 _(ip6_mfib_dump, "")                                                    \
18376 _(feature_enable_disable, "arc_name <arc_name> "                        \
18377   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18378 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18379 "[disable]")                                                            \
18380 _(l2_xconnect_dump, "")                                                 \
18381 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18382 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18383 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18384
18385 /* List of command functions, CLI names map directly to functions */
18386 #define foreach_cli_function                                    \
18387 _(comment, "usage: comment <ignore-rest-of-line>")              \
18388 _(dump_interface_table, "usage: dump_interface_table")          \
18389 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18390 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18391 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18392 _(dump_stats_table, "usage: dump_stats_table")                  \
18393 _(dump_macro_table, "usage: dump_macro_table ")                 \
18394 _(dump_node_table, "usage: dump_node_table")                    \
18395 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18396 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18397 _(echo, "usage: echo <message>")                                \
18398 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18399 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18400 _(help, "usage: help")                                          \
18401 _(q, "usage: quit")                                             \
18402 _(quit, "usage: quit")                                          \
18403 _(search_node_table, "usage: search_node_table <name>...")      \
18404 _(set, "usage: set <variable-name> <value>")                    \
18405 _(script, "usage: script <file-name>")                          \
18406 _(unset, "usage: unset <variable-name>")
18407
18408 #define _(N,n)                                  \
18409     static void vl_api_##n##_t_handler_uni      \
18410     (vl_api_##n##_t * mp)                       \
18411     {                                           \
18412         vat_main_t * vam = &vat_main;           \
18413         if (vam->json_output) {                 \
18414             vl_api_##n##_t_handler_json(mp);    \
18415         } else {                                \
18416             vl_api_##n##_t_handler(mp);         \
18417         }                                       \
18418     }
18419 foreach_vpe_api_reply_msg;
18420 #undef _
18421
18422 void
18423 vat_api_hookup (vat_main_t * vam)
18424 {
18425 #define _(N,n)                                                  \
18426     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18427                            vl_api_##n##_t_handler_uni,          \
18428                            vl_noop_handler,                     \
18429                            vl_api_##n##_t_endian,               \
18430                            vl_api_##n##_t_print,                \
18431                            sizeof(vl_api_##n##_t), 1);
18432   foreach_vpe_api_reply_msg;
18433 #undef _
18434
18435 #if (VPP_API_TEST_BUILTIN==0)
18436   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18437 #endif
18438
18439   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18440
18441   vam->function_by_name = hash_create_string (0, sizeof (uword));
18442
18443   vam->help_by_name = hash_create_string (0, sizeof (uword));
18444
18445   /* API messages we can send */
18446 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18447   foreach_vpe_api_msg;
18448 #undef _
18449
18450   /* Help strings */
18451 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18452   foreach_vpe_api_msg;
18453 #undef _
18454
18455   /* CLI functions */
18456 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18457   foreach_cli_function;
18458 #undef _
18459
18460   /* Help strings */
18461 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18462   foreach_cli_function;
18463 #undef _
18464 }
18465
18466 /*
18467  * fd.io coding-style-patch-verification: ON
18468  *
18469  * Local Variables:
18470  * eval: (c-set-style "gnu")
18471  * End:
18472  */