Clean up binary api message handler registration issues
[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 #if VPP_API_TEST_BUILTIN == 0
948 static void vl_api_sw_interface_set_flags_t_handler
949   (vl_api_sw_interface_set_flags_t * mp)
950 {
951   vat_main_t *vam = &vat_main;
952   if (vam->interface_event_display)
953     errmsg ("interface flags: sw_if_index %d %s %s",
954             ntohl (mp->sw_if_index),
955             mp->admin_up_down ? "admin-up" : "admin-down",
956             mp->link_up_down ? "link-up" : "link-down");
957 }
958 #endif
959
960 static void vl_api_sw_interface_set_flags_t_handler_json
961   (vl_api_sw_interface_set_flags_t * mp)
962 {
963   /* JSON output not supported */
964 }
965
966 static void
967 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
968 {
969   vat_main_t *vam = &vat_main;
970   i32 retval = ntohl (mp->retval);
971
972   vam->retval = retval;
973   vam->shmem_result = (u8 *) mp->reply_in_shmem;
974   vam->result_ready = 1;
975 }
976
977 static void
978 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
979 {
980   vat_main_t *vam = &vat_main;
981   vat_json_node_t node;
982   api_main_t *am = &api_main;
983   void *oldheap;
984   u8 *reply;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "reply_in_shmem",
989                             ntohl (mp->reply_in_shmem));
990   /* Toss the shared-memory original... */
991   pthread_mutex_lock (&am->vlib_rp->mutex);
992   oldheap = svm_push_data_heap (am->vlib_rp);
993
994   reply = (u8 *) (mp->reply_in_shmem);
995   vec_free (reply);
996
997   svm_pop_heap (oldheap);
998   pthread_mutex_unlock (&am->vlib_rp->mutex);
999
1000   vat_json_print (vam->ofp, &node);
1001   vat_json_free (&node);
1002
1003   vam->retval = ntohl (mp->retval);
1004   vam->result_ready = 1;
1005 }
1006
1007 static void
1008 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1009 {
1010   vat_main_t *vam = &vat_main;
1011   i32 retval = ntohl (mp->retval);
1012
1013   vam->retval = retval;
1014   vam->cmd_reply = mp->reply;
1015   vam->result_ready = 1;
1016 }
1017
1018 static void
1019 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1020 {
1021   vat_main_t *vam = &vat_main;
1022   vat_json_node_t node;
1023
1024   vat_json_init_object (&node);
1025   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1026   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1027
1028   vat_json_print (vam->ofp, &node);
1029   vat_json_free (&node);
1030
1031   vam->retval = ntohl (mp->retval);
1032   vam->result_ready = 1;
1033 }
1034
1035 static void vl_api_classify_add_del_table_reply_t_handler
1036   (vl_api_classify_add_del_table_reply_t * mp)
1037 {
1038   vat_main_t *vam = &vat_main;
1039   i32 retval = ntohl (mp->retval);
1040   if (vam->async_mode)
1041     {
1042       vam->async_errors += (retval < 0);
1043     }
1044   else
1045     {
1046       vam->retval = retval;
1047       if (retval == 0 &&
1048           ((mp->new_table_index != 0xFFFFFFFF) ||
1049            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1050            (mp->match_n_vectors != 0xFFFFFFFF)))
1051         /*
1052          * Note: this is just barely thread-safe, depends on
1053          * the main thread spinning waiting for an answer...
1054          */
1055         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1056                 ntohl (mp->new_table_index),
1057                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1058       vam->result_ready = 1;
1059     }
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler_json
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   vat_json_node_t node;
1067
1068   vat_json_init_object (&node);
1069   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1070   vat_json_object_add_uint (&node, "new_table_index",
1071                             ntohl (mp->new_table_index));
1072   vat_json_object_add_uint (&node, "skip_n_vectors",
1073                             ntohl (mp->skip_n_vectors));
1074   vat_json_object_add_uint (&node, "match_n_vectors",
1075                             ntohl (mp->match_n_vectors));
1076
1077   vat_json_print (vam->ofp, &node);
1078   vat_json_free (&node);
1079
1080   vam->retval = ntohl (mp->retval);
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_get_node_index_reply_t_handler
1085   (vl_api_get_node_index_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089   if (vam->async_mode)
1090     {
1091       vam->async_errors += (retval < 0);
1092     }
1093   else
1094     {
1095       vam->retval = retval;
1096       if (retval == 0)
1097         errmsg ("node index %d", ntohl (mp->node_index));
1098       vam->result_ready = 1;
1099     }
1100 }
1101
1102 static void vl_api_get_node_index_reply_t_handler_json
1103   (vl_api_get_node_index_reply_t * mp)
1104 {
1105   vat_main_t *vam = &vat_main;
1106   vat_json_node_t node;
1107
1108   vat_json_init_object (&node);
1109   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1110   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1111
1112   vat_json_print (vam->ofp, &node);
1113   vat_json_free (&node);
1114
1115   vam->retval = ntohl (mp->retval);
1116   vam->result_ready = 1;
1117 }
1118
1119 static void vl_api_get_next_index_reply_t_handler
1120   (vl_api_get_next_index_reply_t * mp)
1121 {
1122   vat_main_t *vam = &vat_main;
1123   i32 retval = ntohl (mp->retval);
1124   if (vam->async_mode)
1125     {
1126       vam->async_errors += (retval < 0);
1127     }
1128   else
1129     {
1130       vam->retval = retval;
1131       if (retval == 0)
1132         errmsg ("next node index %d", ntohl (mp->next_index));
1133       vam->result_ready = 1;
1134     }
1135 }
1136
1137 static void vl_api_get_next_index_reply_t_handler_json
1138   (vl_api_get_next_index_reply_t * mp)
1139 {
1140   vat_main_t *vam = &vat_main;
1141   vat_json_node_t node;
1142
1143   vat_json_init_object (&node);
1144   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1145   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1146
1147   vat_json_print (vam->ofp, &node);
1148   vat_json_free (&node);
1149
1150   vam->retval = ntohl (mp->retval);
1151   vam->result_ready = 1;
1152 }
1153
1154 static void vl_api_add_node_next_reply_t_handler
1155   (vl_api_add_node_next_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   i32 retval = ntohl (mp->retval);
1159   if (vam->async_mode)
1160     {
1161       vam->async_errors += (retval < 0);
1162     }
1163   else
1164     {
1165       vam->retval = retval;
1166       if (retval == 0)
1167         errmsg ("next index %d", ntohl (mp->next_index));
1168       vam->result_ready = 1;
1169     }
1170 }
1171
1172 static void vl_api_add_node_next_reply_t_handler_json
1173   (vl_api_add_node_next_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177
1178   vat_json_init_object (&node);
1179   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1180   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1181
1182   vat_json_print (vam->ofp, &node);
1183   vat_json_free (&node);
1184
1185   vam->retval = ntohl (mp->retval);
1186   vam->result_ready = 1;
1187 }
1188
1189 static void vl_api_show_version_reply_t_handler
1190   (vl_api_show_version_reply_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   i32 retval = ntohl (mp->retval);
1194
1195   if (retval >= 0)
1196     {
1197       errmsg ("        program: %s", mp->program);
1198       errmsg ("        version: %s", mp->version);
1199       errmsg ("     build date: %s", mp->build_date);
1200       errmsg ("build directory: %s", mp->build_directory);
1201     }
1202   vam->retval = retval;
1203   vam->result_ready = 1;
1204 }
1205
1206 static void vl_api_show_version_reply_t_handler_json
1207   (vl_api_show_version_reply_t * mp)
1208 {
1209   vat_main_t *vam = &vat_main;
1210   vat_json_node_t node;
1211
1212   vat_json_init_object (&node);
1213   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1214   vat_json_object_add_string_copy (&node, "program", mp->program);
1215   vat_json_object_add_string_copy (&node, "version", mp->version);
1216   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1217   vat_json_object_add_string_copy (&node, "build_directory",
1218                                    mp->build_directory);
1219
1220   vat_json_print (vam->ofp, &node);
1221   vat_json_free (&node);
1222
1223   vam->retval = ntohl (mp->retval);
1224   vam->result_ready = 1;
1225 }
1226
1227 static void
1228 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1229 {
1230   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1231           mp->mac_ip ? "mac/ip binding" : "address resolution",
1232           format_ip4_address, &mp->address,
1233           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1234 }
1235
1236 static void
1237 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1238 {
1239   /* JSON output not supported */
1240 }
1241
1242 static void
1243 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1244 {
1245   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1246           mp->mac_ip ? "mac/ip binding" : "address resolution",
1247           format_ip6_address, mp->address,
1248           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1249 }
1250
1251 static void
1252 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1253 {
1254   /* JSON output not supported */
1255 }
1256
1257 /*
1258  * Special-case: build the bridge domain table, maintain
1259  * the next bd id vbl.
1260  */
1261 static void vl_api_bridge_domain_details_t_handler
1262   (vl_api_bridge_domain_details_t * mp)
1263 {
1264   vat_main_t *vam = &vat_main;
1265   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1266
1267   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1268          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1269
1270   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1271          ntohl (mp->bd_id), mp->learn, mp->forward,
1272          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1273
1274   if (n_sw_ifs)
1275     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1276 }
1277
1278 static void vl_api_bridge_domain_details_t_handler_json
1279   (vl_api_bridge_domain_details_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   vat_json_node_t *node, *array = NULL;
1283
1284   if (VAT_JSON_ARRAY != vam->json_tree.type)
1285     {
1286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1287       vat_json_init_array (&vam->json_tree);
1288     }
1289   node = vat_json_array_add (&vam->json_tree);
1290
1291   vat_json_init_object (node);
1292   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1293   vat_json_object_add_uint (node, "flood", mp->flood);
1294   vat_json_object_add_uint (node, "forward", mp->forward);
1295   vat_json_object_add_uint (node, "learn", mp->learn);
1296   vat_json_object_add_uint (node, "bvi_sw_if_index",
1297                             ntohl (mp->bvi_sw_if_index));
1298   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1299   array = vat_json_object_add (node, "sw_if");
1300   vat_json_init_array (array);
1301 }
1302
1303 /*
1304  * Special-case: build the bridge domain sw if table.
1305  */
1306 static void vl_api_bridge_domain_sw_if_details_t_handler
1307   (vl_api_bridge_domain_sw_if_details_t * mp)
1308 {
1309   vat_main_t *vam = &vat_main;
1310   hash_pair_t *p;
1311   u8 *sw_if_name = 0;
1312   u32 sw_if_index;
1313
1314   sw_if_index = ntohl (mp->sw_if_index);
1315   /* *INDENT-OFF* */
1316   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1317   ({
1318     if ((u32) p->value[0] == sw_if_index)
1319       {
1320         sw_if_name = (u8 *)(p->key);
1321         break;
1322       }
1323   }));
1324   /* *INDENT-ON* */
1325
1326   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1327          mp->shg, sw_if_name ? (char *) sw_if_name :
1328          "sw_if_index not found!");
1329 }
1330
1331 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1332   (vl_api_bridge_domain_sw_if_details_t * mp)
1333 {
1334   vat_main_t *vam = &vat_main;
1335   vat_json_node_t *node = NULL;
1336   uword last_index = 0;
1337
1338   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1339   ASSERT (vec_len (vam->json_tree.array) >= 1);
1340   last_index = vec_len (vam->json_tree.array) - 1;
1341   node = &vam->json_tree.array[last_index];
1342   node = vat_json_object_get_element (node, "sw_if");
1343   ASSERT (NULL != node);
1344   node = vat_json_array_add (node);
1345
1346   vat_json_init_object (node);
1347   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1348   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1349   vat_json_object_add_uint (node, "shg", mp->shg);
1350 }
1351
1352 static void vl_api_control_ping_reply_t_handler
1353   (vl_api_control_ping_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   i32 retval = ntohl (mp->retval);
1357   if (vam->async_mode)
1358     {
1359       vam->async_errors += (retval < 0);
1360     }
1361   else
1362     {
1363       vam->retval = retval;
1364       vam->result_ready = 1;
1365     }
1366 }
1367
1368 static void vl_api_control_ping_reply_t_handler_json
1369   (vl_api_control_ping_reply_t * mp)
1370 {
1371   vat_main_t *vam = &vat_main;
1372   i32 retval = ntohl (mp->retval);
1373
1374   if (VAT_JSON_NONE != vam->json_tree.type)
1375     {
1376       vat_json_print (vam->ofp, &vam->json_tree);
1377       vat_json_free (&vam->json_tree);
1378       vam->json_tree.type = VAT_JSON_NONE;
1379     }
1380   else
1381     {
1382       /* just print [] */
1383       vat_json_init_array (&vam->json_tree);
1384       vat_json_print (vam->ofp, &vam->json_tree);
1385       vam->json_tree.type = VAT_JSON_NONE;
1386     }
1387
1388   vam->retval = retval;
1389   vam->result_ready = 1;
1390 }
1391
1392 static void
1393 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1394 {
1395   vat_main_t *vam = &vat_main;
1396   i32 retval = ntohl (mp->retval);
1397   if (vam->async_mode)
1398     {
1399       vam->async_errors += (retval < 0);
1400     }
1401   else
1402     {
1403       vam->retval = retval;
1404       vam->result_ready = 1;
1405     }
1406 }
1407
1408 static void vl_api_l2_flags_reply_t_handler_json
1409   (vl_api_l2_flags_reply_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t node;
1413
1414   vat_json_init_object (&node);
1415   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1416   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1417                             ntohl (mp->resulting_feature_bitmap));
1418
1419   vat_json_print (vam->ofp, &node);
1420   vat_json_free (&node);
1421
1422   vam->retval = ntohl (mp->retval);
1423   vam->result_ready = 1;
1424 }
1425
1426 static void vl_api_bridge_flags_reply_t_handler
1427   (vl_api_bridge_flags_reply_t * mp)
1428 {
1429   vat_main_t *vam = &vat_main;
1430   i32 retval = ntohl (mp->retval);
1431   if (vam->async_mode)
1432     {
1433       vam->async_errors += (retval < 0);
1434     }
1435   else
1436     {
1437       vam->retval = retval;
1438       vam->result_ready = 1;
1439     }
1440 }
1441
1442 static void vl_api_bridge_flags_reply_t_handler_json
1443   (vl_api_bridge_flags_reply_t * mp)
1444 {
1445   vat_main_t *vam = &vat_main;
1446   vat_json_node_t node;
1447
1448   vat_json_init_object (&node);
1449   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1450   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1451                             ntohl (mp->resulting_feature_bitmap));
1452
1453   vat_json_print (vam->ofp, &node);
1454   vat_json_free (&node);
1455
1456   vam->retval = ntohl (mp->retval);
1457   vam->result_ready = 1;
1458 }
1459
1460 static void vl_api_tap_connect_reply_t_handler
1461   (vl_api_tap_connect_reply_t * mp)
1462 {
1463   vat_main_t *vam = &vat_main;
1464   i32 retval = ntohl (mp->retval);
1465   if (vam->async_mode)
1466     {
1467       vam->async_errors += (retval < 0);
1468     }
1469   else
1470     {
1471       vam->retval = retval;
1472       vam->sw_if_index = ntohl (mp->sw_if_index);
1473       vam->result_ready = 1;
1474     }
1475
1476 }
1477
1478 static void vl_api_tap_connect_reply_t_handler_json
1479   (vl_api_tap_connect_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   vat_json_node_t node;
1483
1484   vat_json_init_object (&node);
1485   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1486   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1487
1488   vat_json_print (vam->ofp, &node);
1489   vat_json_free (&node);
1490
1491   vam->retval = ntohl (mp->retval);
1492   vam->result_ready = 1;
1493
1494 }
1495
1496 static void
1497 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   i32 retval = ntohl (mp->retval);
1501   if (vam->async_mode)
1502     {
1503       vam->async_errors += (retval < 0);
1504     }
1505   else
1506     {
1507       vam->retval = retval;
1508       vam->sw_if_index = ntohl (mp->sw_if_index);
1509       vam->result_ready = 1;
1510     }
1511 }
1512
1513 static void vl_api_tap_modify_reply_t_handler_json
1514   (vl_api_tap_modify_reply_t * mp)
1515 {
1516   vat_main_t *vam = &vat_main;
1517   vat_json_node_t node;
1518
1519   vat_json_init_object (&node);
1520   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1521   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1522
1523   vat_json_print (vam->ofp, &node);
1524   vat_json_free (&node);
1525
1526   vam->retval = ntohl (mp->retval);
1527   vam->result_ready = 1;
1528 }
1529
1530 static void
1531 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1532 {
1533   vat_main_t *vam = &vat_main;
1534   i32 retval = ntohl (mp->retval);
1535   if (vam->async_mode)
1536     {
1537       vam->async_errors += (retval < 0);
1538     }
1539   else
1540     {
1541       vam->retval = retval;
1542       vam->result_ready = 1;
1543     }
1544 }
1545
1546 static void vl_api_tap_delete_reply_t_handler_json
1547   (vl_api_tap_delete_reply_t * mp)
1548 {
1549   vat_main_t *vam = &vat_main;
1550   vat_json_node_t node;
1551
1552   vat_json_init_object (&node);
1553   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560 }
1561
1562 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1563   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   i32 retval = ntohl (mp->retval);
1567   if (vam->async_mode)
1568     {
1569       vam->async_errors += (retval < 0);
1570     }
1571   else
1572     {
1573       vam->retval = retval;
1574       vam->result_ready = 1;
1575     }
1576 }
1577
1578 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1579   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1580 {
1581   vat_main_t *vam = &vat_main;
1582   vat_json_node_t node;
1583
1584   vat_json_init_object (&node);
1585   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1586   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1587                             ntohl (mp->sw_if_index));
1588
1589   vat_json_print (vam->ofp, &node);
1590   vat_json_free (&node);
1591
1592   vam->retval = ntohl (mp->retval);
1593   vam->result_ready = 1;
1594 }
1595
1596 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1597   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   i32 retval = ntohl (mp->retval);
1601   if (vam->async_mode)
1602     {
1603       vam->async_errors += (retval < 0);
1604     }
1605   else
1606     {
1607       vam->retval = retval;
1608       vam->sw_if_index = ntohl (mp->sw_if_index);
1609       vam->result_ready = 1;
1610     }
1611 }
1612
1613 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1614   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1622
1623   vat_json_print (vam->ofp, &node);
1624   vat_json_free (&node);
1625
1626   vam->retval = ntohl (mp->retval);
1627   vam->result_ready = 1;
1628 }
1629
1630
1631 static void vl_api_one_add_del_locator_set_reply_t_handler
1632   (vl_api_one_add_del_locator_set_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1648   (vl_api_one_add_del_locator_set_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1665   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->sw_if_index = ntohl (mp->sw_if_index);
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1682   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_gre_add_del_tunnel_reply_t_handler
1699   (vl_api_gre_add_del_tunnel_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->sw_if_index = ntohl (mp->sw_if_index);
1711       vam->result_ready = 1;
1712     }
1713 }
1714
1715 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1716   (vl_api_gre_add_del_tunnel_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732 static void vl_api_create_vhost_user_if_reply_t_handler
1733   (vl_api_create_vhost_user_if_reply_t * mp)
1734 {
1735   vat_main_t *vam = &vat_main;
1736   i32 retval = ntohl (mp->retval);
1737   if (vam->async_mode)
1738     {
1739       vam->async_errors += (retval < 0);
1740     }
1741   else
1742     {
1743       vam->retval = retval;
1744       vam->sw_if_index = ntohl (mp->sw_if_index);
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_create_vhost_user_if_reply_t_handler_json
1750   (vl_api_create_vhost_user_if_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1758
1759   vat_json_print (vam->ofp, &node);
1760   vat_json_free (&node);
1761
1762   vam->retval = ntohl (mp->retval);
1763   vam->result_ready = 1;
1764 }
1765
1766 static void vl_api_ip_address_details_t_handler
1767   (vl_api_ip_address_details_t * mp)
1768 {
1769   vat_main_t *vam = &vat_main;
1770   static ip_address_details_t empty_ip_address_details = { {0} };
1771   ip_address_details_t *address = NULL;
1772   ip_details_t *current_ip_details = NULL;
1773   ip_details_t *details = NULL;
1774
1775   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1776
1777   if (!details || vam->current_sw_if_index >= vec_len (details)
1778       || !details[vam->current_sw_if_index].present)
1779     {
1780       errmsg ("ip address details arrived but not stored");
1781       errmsg ("ip_dump should be called first");
1782       return;
1783     }
1784
1785   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1786
1787 #define addresses (current_ip_details->addr)
1788
1789   vec_validate_init_empty (addresses, vec_len (addresses),
1790                            empty_ip_address_details);
1791
1792   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1793
1794   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1795   address->prefix_length = mp->prefix_length;
1796 #undef addresses
1797 }
1798
1799 static void vl_api_ip_address_details_t_handler_json
1800   (vl_api_ip_address_details_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   vat_json_node_t *node = NULL;
1804   struct in6_addr ip6;
1805   struct in_addr ip4;
1806
1807   if (VAT_JSON_ARRAY != vam->json_tree.type)
1808     {
1809       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1810       vat_json_init_array (&vam->json_tree);
1811     }
1812   node = vat_json_array_add (&vam->json_tree);
1813
1814   vat_json_init_object (node);
1815   if (vam->is_ipv6)
1816     {
1817       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1818       vat_json_object_add_ip6 (node, "ip", ip6);
1819     }
1820   else
1821     {
1822       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1823       vat_json_object_add_ip4 (node, "ip", ip4);
1824     }
1825   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1826 }
1827
1828 static void
1829 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1830 {
1831   vat_main_t *vam = &vat_main;
1832   static ip_details_t empty_ip_details = { 0 };
1833   ip_details_t *ip = NULL;
1834   u32 sw_if_index = ~0;
1835
1836   sw_if_index = ntohl (mp->sw_if_index);
1837
1838   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1839                            sw_if_index, empty_ip_details);
1840
1841   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1842                          sw_if_index);
1843
1844   ip->present = 1;
1845 }
1846
1847 static void
1848 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1849 {
1850   vat_main_t *vam = &vat_main;
1851
1852   if (VAT_JSON_ARRAY != vam->json_tree.type)
1853     {
1854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1855       vat_json_init_array (&vam->json_tree);
1856     }
1857   vat_json_array_add_uint (&vam->json_tree,
1858                            clib_net_to_host_u32 (mp->sw_if_index));
1859 }
1860
1861 static void vl_api_map_domain_details_t_handler_json
1862   (vl_api_map_domain_details_t * mp)
1863 {
1864   vat_json_node_t *node = NULL;
1865   vat_main_t *vam = &vat_main;
1866   struct in6_addr ip6;
1867   struct in_addr ip4;
1868
1869   if (VAT_JSON_ARRAY != vam->json_tree.type)
1870     {
1871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1872       vat_json_init_array (&vam->json_tree);
1873     }
1874
1875   node = vat_json_array_add (&vam->json_tree);
1876   vat_json_init_object (node);
1877
1878   vat_json_object_add_uint (node, "domain_index",
1879                             clib_net_to_host_u32 (mp->domain_index));
1880   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1881   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1882   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1883   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1884   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1885   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1886   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1887   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1888   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1889   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1890   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1891   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1892   vat_json_object_add_uint (node, "flags", mp->flags);
1893   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1894   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1895 }
1896
1897 static void vl_api_map_domain_details_t_handler
1898   (vl_api_map_domain_details_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901
1902   if (mp->is_translation)
1903     {
1904       print (vam->ofp,
1905              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1906              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1907              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1908              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1909              clib_net_to_host_u32 (mp->domain_index));
1910     }
1911   else
1912     {
1913       print (vam->ofp,
1914              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1915              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1916              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1917              format_ip6_address, mp->ip6_src,
1918              clib_net_to_host_u32 (mp->domain_index));
1919     }
1920   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1921          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1922          mp->is_translation ? "map-t" : "");
1923 }
1924
1925 static void vl_api_map_rule_details_t_handler_json
1926   (vl_api_map_rule_details_t * mp)
1927 {
1928   struct in6_addr ip6;
1929   vat_json_node_t *node = NULL;
1930   vat_main_t *vam = &vat_main;
1931
1932   if (VAT_JSON_ARRAY != vam->json_tree.type)
1933     {
1934       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1935       vat_json_init_array (&vam->json_tree);
1936     }
1937
1938   node = vat_json_array_add (&vam->json_tree);
1939   vat_json_init_object (node);
1940
1941   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1942   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1943   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1944 }
1945
1946 static void
1947 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1948 {
1949   vat_main_t *vam = &vat_main;
1950   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1951          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1952 }
1953
1954 static void
1955 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1956 {
1957   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1958           "router_addr %U host_mac %U",
1959           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1960           format_ip4_address, &mp->host_address,
1961           format_ip4_address, &mp->router_address,
1962           format_ethernet_address, mp->host_mac);
1963 }
1964
1965 static void vl_api_dhcp_compl_event_t_handler_json
1966   (vl_api_dhcp_compl_event_t * mp)
1967 {
1968   /* JSON output not supported */
1969 }
1970
1971 static void
1972 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1973                               u32 counter)
1974 {
1975   vat_main_t *vam = &vat_main;
1976   static u64 default_counter = 0;
1977
1978   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1979                            NULL);
1980   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1981                            sw_if_index, default_counter);
1982   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1983 }
1984
1985 static void
1986 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1987                                 interface_counter_t counter)
1988 {
1989   vat_main_t *vam = &vat_main;
1990   static interface_counter_t default_counter = { 0, };
1991
1992   vec_validate_init_empty (vam->combined_interface_counters,
1993                            vnet_counter_type, NULL);
1994   vec_validate_init_empty (vam->combined_interface_counters
1995                            [vnet_counter_type], sw_if_index, default_counter);
1996   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1997 }
1998
1999 static void vl_api_vnet_interface_counters_t_handler
2000   (vl_api_vnet_interface_counters_t * mp)
2001 {
2002   /* not supported */
2003 }
2004
2005 static void vl_api_vnet_interface_counters_t_handler_json
2006   (vl_api_vnet_interface_counters_t * mp)
2007 {
2008   interface_counter_t counter;
2009   vlib_counter_t *v;
2010   u64 *v_packets;
2011   u64 packets;
2012   u32 count;
2013   u32 first_sw_if_index;
2014   int i;
2015
2016   count = ntohl (mp->count);
2017   first_sw_if_index = ntohl (mp->first_sw_if_index);
2018
2019   if (!mp->is_combined)
2020     {
2021       v_packets = (u64 *) & mp->data;
2022       for (i = 0; i < count; i++)
2023         {
2024           packets =
2025             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2026           set_simple_interface_counter (mp->vnet_counter_type,
2027                                         first_sw_if_index + i, packets);
2028           v_packets++;
2029         }
2030     }
2031   else
2032     {
2033       v = (vlib_counter_t *) & mp->data;
2034       for (i = 0; i < count; i++)
2035         {
2036           counter.packets =
2037             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2038           counter.bytes =
2039             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2040           set_combined_interface_counter (mp->vnet_counter_type,
2041                                           first_sw_if_index + i, counter);
2042           v++;
2043         }
2044     }
2045 }
2046
2047 static u32
2048 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2049 {
2050   vat_main_t *vam = &vat_main;
2051   u32 i;
2052
2053   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2054     {
2055       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2056         {
2057           return i;
2058         }
2059     }
2060   return ~0;
2061 }
2062
2063 static u32
2064 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2065 {
2066   vat_main_t *vam = &vat_main;
2067   u32 i;
2068
2069   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2070     {
2071       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2072         {
2073           return i;
2074         }
2075     }
2076   return ~0;
2077 }
2078
2079 static void vl_api_vnet_ip4_fib_counters_t_handler
2080   (vl_api_vnet_ip4_fib_counters_t * mp)
2081 {
2082   /* not supported */
2083 }
2084
2085 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2086   (vl_api_vnet_ip4_fib_counters_t * mp)
2087 {
2088   vat_main_t *vam = &vat_main;
2089   vl_api_ip4_fib_counter_t *v;
2090   ip4_fib_counter_t *counter;
2091   struct in_addr ip4;
2092   u32 vrf_id;
2093   u32 vrf_index;
2094   u32 count;
2095   int i;
2096
2097   vrf_id = ntohl (mp->vrf_id);
2098   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2099   if (~0 == vrf_index)
2100     {
2101       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2102       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2103       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2104       vec_validate (vam->ip4_fib_counters, vrf_index);
2105       vam->ip4_fib_counters[vrf_index] = NULL;
2106     }
2107
2108   vec_free (vam->ip4_fib_counters[vrf_index]);
2109   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2110   count = ntohl (mp->count);
2111   for (i = 0; i < count; i++)
2112     {
2113       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2114       counter = &vam->ip4_fib_counters[vrf_index][i];
2115       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2116       counter->address = ip4;
2117       counter->address_length = v->address_length;
2118       counter->packets = clib_net_to_host_u64 (v->packets);
2119       counter->bytes = clib_net_to_host_u64 (v->bytes);
2120       v++;
2121     }
2122 }
2123
2124 static void vl_api_vnet_ip4_nbr_counters_t_handler
2125   (vl_api_vnet_ip4_nbr_counters_t * mp)
2126 {
2127   /* not supported */
2128 }
2129
2130 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2131   (vl_api_vnet_ip4_nbr_counters_t * mp)
2132 {
2133   vat_main_t *vam = &vat_main;
2134   vl_api_ip4_nbr_counter_t *v;
2135   ip4_nbr_counter_t *counter;
2136   u32 sw_if_index;
2137   u32 count;
2138   int i;
2139
2140   sw_if_index = ntohl (mp->sw_if_index);
2141   count = ntohl (mp->count);
2142   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2143
2144   if (mp->begin)
2145     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2146
2147   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2148   for (i = 0; i < count; i++)
2149     {
2150       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2151       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2152       counter->address.s_addr = v->address;
2153       counter->packets = clib_net_to_host_u64 (v->packets);
2154       counter->bytes = clib_net_to_host_u64 (v->bytes);
2155       counter->linkt = v->link_type;
2156       v++;
2157     }
2158 }
2159
2160 static void vl_api_vnet_ip6_fib_counters_t_handler
2161   (vl_api_vnet_ip6_fib_counters_t * mp)
2162 {
2163   /* not supported */
2164 }
2165
2166 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2167   (vl_api_vnet_ip6_fib_counters_t * mp)
2168 {
2169   vat_main_t *vam = &vat_main;
2170   vl_api_ip6_fib_counter_t *v;
2171   ip6_fib_counter_t *counter;
2172   struct in6_addr ip6;
2173   u32 vrf_id;
2174   u32 vrf_index;
2175   u32 count;
2176   int i;
2177
2178   vrf_id = ntohl (mp->vrf_id);
2179   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2180   if (~0 == vrf_index)
2181     {
2182       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2183       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2184       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2185       vec_validate (vam->ip6_fib_counters, vrf_index);
2186       vam->ip6_fib_counters[vrf_index] = NULL;
2187     }
2188
2189   vec_free (vam->ip6_fib_counters[vrf_index]);
2190   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2191   count = ntohl (mp->count);
2192   for (i = 0; i < count; i++)
2193     {
2194       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2195       counter = &vam->ip6_fib_counters[vrf_index][i];
2196       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2197       counter->address = ip6;
2198       counter->address_length = v->address_length;
2199       counter->packets = clib_net_to_host_u64 (v->packets);
2200       counter->bytes = clib_net_to_host_u64 (v->bytes);
2201       v++;
2202     }
2203 }
2204
2205 static void vl_api_vnet_ip6_nbr_counters_t_handler
2206   (vl_api_vnet_ip6_nbr_counters_t * mp)
2207 {
2208   /* not supported */
2209 }
2210
2211 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2212   (vl_api_vnet_ip6_nbr_counters_t * mp)
2213 {
2214   vat_main_t *vam = &vat_main;
2215   vl_api_ip6_nbr_counter_t *v;
2216   ip6_nbr_counter_t *counter;
2217   struct in6_addr ip6;
2218   u32 sw_if_index;
2219   u32 count;
2220   int i;
2221
2222   sw_if_index = ntohl (mp->sw_if_index);
2223   count = ntohl (mp->count);
2224   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2225
2226   if (mp->begin)
2227     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2228
2229   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2230   for (i = 0; i < count; i++)
2231     {
2232       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2233       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2234       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2235       counter->address = ip6;
2236       counter->packets = clib_net_to_host_u64 (v->packets);
2237       counter->bytes = clib_net_to_host_u64 (v->bytes);
2238       v++;
2239     }
2240 }
2241
2242 static void vl_api_get_first_msg_id_reply_t_handler
2243   (vl_api_get_first_msg_id_reply_t * mp)
2244 {
2245   vat_main_t *vam = &vat_main;
2246   i32 retval = ntohl (mp->retval);
2247
2248   if (vam->async_mode)
2249     {
2250       vam->async_errors += (retval < 0);
2251     }
2252   else
2253     {
2254       vam->retval = retval;
2255       vam->result_ready = 1;
2256     }
2257   if (retval >= 0)
2258     {
2259       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2260     }
2261 }
2262
2263 static void vl_api_get_first_msg_id_reply_t_handler_json
2264   (vl_api_get_first_msg_id_reply_t * mp)
2265 {
2266   vat_main_t *vam = &vat_main;
2267   vat_json_node_t node;
2268
2269   vat_json_init_object (&node);
2270   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2271   vat_json_object_add_uint (&node, "first_msg_id",
2272                             (uint) ntohs (mp->first_msg_id));
2273
2274   vat_json_print (vam->ofp, &node);
2275   vat_json_free (&node);
2276
2277   vam->retval = ntohl (mp->retval);
2278   vam->result_ready = 1;
2279 }
2280
2281 static void vl_api_get_node_graph_reply_t_handler
2282   (vl_api_get_node_graph_reply_t * mp)
2283 {
2284   vat_main_t *vam = &vat_main;
2285   api_main_t *am = &api_main;
2286   i32 retval = ntohl (mp->retval);
2287   u8 *pvt_copy, *reply;
2288   void *oldheap;
2289   vlib_node_t *node;
2290   int i;
2291
2292   if (vam->async_mode)
2293     {
2294       vam->async_errors += (retval < 0);
2295     }
2296   else
2297     {
2298       vam->retval = retval;
2299       vam->result_ready = 1;
2300     }
2301
2302   /* "Should never happen..." */
2303   if (retval != 0)
2304     return;
2305
2306   reply = (u8 *) (mp->reply_in_shmem);
2307   pvt_copy = vec_dup (reply);
2308
2309   /* Toss the shared-memory original... */
2310   pthread_mutex_lock (&am->vlib_rp->mutex);
2311   oldheap = svm_push_data_heap (am->vlib_rp);
2312
2313   vec_free (reply);
2314
2315   svm_pop_heap (oldheap);
2316   pthread_mutex_unlock (&am->vlib_rp->mutex);
2317
2318   if (vam->graph_nodes)
2319     {
2320       hash_free (vam->graph_node_index_by_name);
2321
2322       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2323         {
2324           node = vam->graph_nodes[i];
2325           vec_free (node->name);
2326           vec_free (node->next_nodes);
2327           vec_free (node);
2328         }
2329       vec_free (vam->graph_nodes);
2330     }
2331
2332   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2333   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2334   vec_free (pvt_copy);
2335
2336   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2337     {
2338       node = vam->graph_nodes[i];
2339       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2340     }
2341 }
2342
2343 static void vl_api_get_node_graph_reply_t_handler_json
2344   (vl_api_get_node_graph_reply_t * mp)
2345 {
2346   vat_main_t *vam = &vat_main;
2347   api_main_t *am = &api_main;
2348   void *oldheap;
2349   vat_json_node_t node;
2350   u8 *reply;
2351
2352   /* $$$$ make this real? */
2353   vat_json_init_object (&node);
2354   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2355   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2356
2357   reply = (u8 *) (mp->reply_in_shmem);
2358
2359   /* Toss the shared-memory original... */
2360   pthread_mutex_lock (&am->vlib_rp->mutex);
2361   oldheap = svm_push_data_heap (am->vlib_rp);
2362
2363   vec_free (reply);
2364
2365   svm_pop_heap (oldheap);
2366   pthread_mutex_unlock (&am->vlib_rp->mutex);
2367
2368   vat_json_print (vam->ofp, &node);
2369   vat_json_free (&node);
2370
2371   vam->retval = ntohl (mp->retval);
2372   vam->result_ready = 1;
2373 }
2374
2375 static void
2376 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2377 {
2378   vat_main_t *vam = &vat_main;
2379   u8 *s = 0;
2380
2381   if (mp->local)
2382     {
2383       s = format (s, "%=16d%=16d%=16d",
2384                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2385     }
2386   else
2387     {
2388       s = format (s, "%=16U%=16d%=16d",
2389                   mp->is_ipv6 ? format_ip6_address :
2390                   format_ip4_address,
2391                   mp->ip_address, mp->priority, mp->weight);
2392     }
2393
2394   print (vam->ofp, "%v", s);
2395   vec_free (s);
2396 }
2397
2398 static void
2399 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t *node = NULL;
2403   struct in6_addr ip6;
2404   struct in_addr ip4;
2405
2406   if (VAT_JSON_ARRAY != vam->json_tree.type)
2407     {
2408       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2409       vat_json_init_array (&vam->json_tree);
2410     }
2411   node = vat_json_array_add (&vam->json_tree);
2412   vat_json_init_object (node);
2413
2414   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2415   vat_json_object_add_uint (node, "priority", mp->priority);
2416   vat_json_object_add_uint (node, "weight", mp->weight);
2417
2418   if (mp->local)
2419     vat_json_object_add_uint (node, "sw_if_index",
2420                               clib_net_to_host_u32 (mp->sw_if_index));
2421   else
2422     {
2423       if (mp->is_ipv6)
2424         {
2425           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2426           vat_json_object_add_ip6 (node, "address", ip6);
2427         }
2428       else
2429         {
2430           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2431           vat_json_object_add_ip4 (node, "address", ip4);
2432         }
2433     }
2434 }
2435
2436 static void
2437 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2438                                           mp)
2439 {
2440   vat_main_t *vam = &vat_main;
2441   u8 *ls_name = 0;
2442
2443   ls_name = format (0, "%s", mp->ls_name);
2444
2445   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2446          ls_name);
2447   vec_free (ls_name);
2448 }
2449
2450 static void
2451   vl_api_one_locator_set_details_t_handler_json
2452   (vl_api_one_locator_set_details_t * mp)
2453 {
2454   vat_main_t *vam = &vat_main;
2455   vat_json_node_t *node = 0;
2456   u8 *ls_name = 0;
2457
2458   ls_name = format (0, "%s", mp->ls_name);
2459   vec_add1 (ls_name, 0);
2460
2461   if (VAT_JSON_ARRAY != vam->json_tree.type)
2462     {
2463       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2464       vat_json_init_array (&vam->json_tree);
2465     }
2466   node = vat_json_array_add (&vam->json_tree);
2467
2468   vat_json_init_object (node);
2469   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2470   vat_json_object_add_uint (node, "ls_index",
2471                             clib_net_to_host_u32 (mp->ls_index));
2472   vec_free (ls_name);
2473 }
2474
2475 static u8 *
2476 format_lisp_flat_eid (u8 * s, va_list * args)
2477 {
2478   u32 type = va_arg (*args, u32);
2479   u8 *eid = va_arg (*args, u8 *);
2480   u32 eid_len = va_arg (*args, u32);
2481
2482   switch (type)
2483     {
2484     case 0:
2485       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2486     case 1:
2487       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2488     case 2:
2489       return format (s, "%U", format_ethernet_address, eid);
2490     }
2491   return 0;
2492 }
2493
2494 static u8 *
2495 format_lisp_eid_vat (u8 * s, va_list * args)
2496 {
2497   u32 type = va_arg (*args, u32);
2498   u8 *eid = va_arg (*args, u8 *);
2499   u32 eid_len = va_arg (*args, u32);
2500   u8 *seid = va_arg (*args, u8 *);
2501   u32 seid_len = va_arg (*args, u32);
2502   u32 is_src_dst = va_arg (*args, u32);
2503
2504   if (is_src_dst)
2505     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2506
2507   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2508
2509   return s;
2510 }
2511
2512 static void
2513 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   u8 *s = 0, *eid = 0;
2517
2518   if (~0 == mp->locator_set_index)
2519     s = format (0, "action: %d", mp->action);
2520   else
2521     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2522
2523   eid = format (0, "%U", format_lisp_eid_vat,
2524                 mp->eid_type,
2525                 mp->eid,
2526                 mp->eid_prefix_len,
2527                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2528   vec_add1 (eid, 0);
2529
2530   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2531          clib_net_to_host_u32 (mp->vni),
2532          eid,
2533          mp->is_local ? "local" : "remote",
2534          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2535          clib_net_to_host_u16 (mp->key_id), mp->key);
2536
2537   vec_free (s);
2538   vec_free (eid);
2539 }
2540
2541 static void
2542 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2543                                              * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   vat_json_node_t *node = 0;
2547   u8 *eid = 0;
2548
2549   if (VAT_JSON_ARRAY != vam->json_tree.type)
2550     {
2551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2552       vat_json_init_array (&vam->json_tree);
2553     }
2554   node = vat_json_array_add (&vam->json_tree);
2555
2556   vat_json_init_object (node);
2557   if (~0 == mp->locator_set_index)
2558     vat_json_object_add_uint (node, "action", mp->action);
2559   else
2560     vat_json_object_add_uint (node, "locator_set_index",
2561                               clib_net_to_host_u32 (mp->locator_set_index));
2562
2563   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2564   eid = format (0, "%U", format_lisp_eid_vat,
2565                 mp->eid_type,
2566                 mp->eid,
2567                 mp->eid_prefix_len,
2568                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2569   vec_add1 (eid, 0);
2570   vat_json_object_add_string_copy (node, "eid", eid);
2571   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2572   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2573   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2574
2575   if (mp->key_id)
2576     {
2577       vat_json_object_add_uint (node, "key_id",
2578                                 clib_net_to_host_u16 (mp->key_id));
2579       vat_json_object_add_string_copy (node, "key", mp->key);
2580     }
2581   vec_free (eid);
2582 }
2583
2584 static void
2585   vl_api_one_eid_table_map_details_t_handler
2586   (vl_api_one_eid_table_map_details_t * mp)
2587 {
2588   vat_main_t *vam = &vat_main;
2589
2590   u8 *line = format (0, "%=10d%=10d",
2591                      clib_net_to_host_u32 (mp->vni),
2592                      clib_net_to_host_u32 (mp->dp_table));
2593   print (vam->ofp, "%v", line);
2594   vec_free (line);
2595 }
2596
2597 static void
2598   vl_api_one_eid_table_map_details_t_handler_json
2599   (vl_api_one_eid_table_map_details_t * mp)
2600 {
2601   vat_main_t *vam = &vat_main;
2602   vat_json_node_t *node = NULL;
2603
2604   if (VAT_JSON_ARRAY != vam->json_tree.type)
2605     {
2606       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2607       vat_json_init_array (&vam->json_tree);
2608     }
2609   node = vat_json_array_add (&vam->json_tree);
2610   vat_json_init_object (node);
2611   vat_json_object_add_uint (node, "dp_table",
2612                             clib_net_to_host_u32 (mp->dp_table));
2613   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2614 }
2615
2616 static void
2617   vl_api_one_eid_table_vni_details_t_handler
2618   (vl_api_one_eid_table_vni_details_t * mp)
2619 {
2620   vat_main_t *vam = &vat_main;
2621
2622   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2623   print (vam->ofp, "%v", line);
2624   vec_free (line);
2625 }
2626
2627 static void
2628   vl_api_one_eid_table_vni_details_t_handler_json
2629   (vl_api_one_eid_table_vni_details_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   vat_json_node_t *node = NULL;
2633
2634   if (VAT_JSON_ARRAY != vam->json_tree.type)
2635     {
2636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2637       vat_json_init_array (&vam->json_tree);
2638     }
2639   node = vat_json_array_add (&vam->json_tree);
2640   vat_json_init_object (node);
2641   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2642 }
2643
2644 static void
2645   vl_api_show_one_map_register_state_reply_t_handler
2646   (vl_api_show_one_map_register_state_reply_t * mp)
2647 {
2648   vat_main_t *vam = &vat_main;
2649   int retval = clib_net_to_host_u32 (mp->retval);
2650
2651   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2652
2653   vam->retval = retval;
2654   vam->result_ready = 1;
2655 }
2656
2657 static void
2658   vl_api_show_one_map_register_state_reply_t_handler_json
2659   (vl_api_show_one_map_register_state_reply_t * mp)
2660 {
2661   vat_main_t *vam = &vat_main;
2662   vat_json_node_t _node, *node = &_node;
2663   int retval = clib_net_to_host_u32 (mp->retval);
2664
2665   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2666
2667   vat_json_init_object (node);
2668   vat_json_object_add_string_copy (node, "state", s);
2669
2670   vat_json_print (vam->ofp, node);
2671   vat_json_free (node);
2672
2673   vam->retval = retval;
2674   vam->result_ready = 1;
2675   vec_free (s);
2676 }
2677
2678 static void
2679   vl_api_show_one_rloc_probe_state_reply_t_handler
2680   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683   int retval = clib_net_to_host_u32 (mp->retval);
2684
2685   if (retval)
2686     goto end;
2687
2688   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2689 end:
2690   vam->retval = retval;
2691   vam->result_ready = 1;
2692 }
2693
2694 static void
2695   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2696   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2697 {
2698   vat_main_t *vam = &vat_main;
2699   vat_json_node_t _node, *node = &_node;
2700   int retval = clib_net_to_host_u32 (mp->retval);
2701
2702   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2703   vat_json_init_object (node);
2704   vat_json_object_add_string_copy (node, "state", s);
2705
2706   vat_json_print (vam->ofp, node);
2707   vat_json_free (node);
2708
2709   vam->retval = retval;
2710   vam->result_ready = 1;
2711   vec_free (s);
2712 }
2713
2714 static void
2715 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2716 {
2717   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2718   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2719 }
2720
2721 static void
2722   gpe_fwd_entries_get_reply_t_net_to_host
2723   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2724 {
2725   u32 i;
2726
2727   mp->count = clib_net_to_host_u32 (mp->count);
2728   for (i = 0; i < mp->count; i++)
2729     {
2730       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2731     }
2732 }
2733
2734 static u8 *
2735 format_gpe_encap_mode (u8 * s, va_list * args)
2736 {
2737   u32 mode = va_arg (*args, u32);
2738
2739   switch (mode)
2740     {
2741     case 0:
2742       return format (s, "lisp");
2743     case 1:
2744       return format (s, "vxlan");
2745     }
2746   return 0;
2747 }
2748
2749 static void
2750   vl_api_gpe_get_encap_mode_reply_t_handler
2751   (vl_api_gpe_get_encap_mode_reply_t * mp)
2752 {
2753   vat_main_t *vam = &vat_main;
2754
2755   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2756   vam->retval = ntohl (mp->retval);
2757   vam->result_ready = 1;
2758 }
2759
2760 static void
2761   vl_api_gpe_get_encap_mode_reply_t_handler_json
2762   (vl_api_gpe_get_encap_mode_reply_t * mp)
2763 {
2764   vat_main_t *vam = &vat_main;
2765   vat_json_node_t node;
2766
2767   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2768   vec_add1 (encap_mode, 0);
2769
2770   vat_json_init_object (&node);
2771   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2772
2773   vec_free (encap_mode);
2774   vat_json_print (vam->ofp, &node);
2775   vat_json_free (&node);
2776
2777   vam->retval = ntohl (mp->retval);
2778   vam->result_ready = 1;
2779 }
2780
2781 static void
2782   vl_api_gpe_fwd_entry_path_details_t_handler
2783   (vl_api_gpe_fwd_entry_path_details_t * mp)
2784 {
2785   vat_main_t *vam = &vat_main;
2786   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2787
2788   if (mp->lcl_loc.is_ip4)
2789     format_ip_address_fcn = format_ip4_address;
2790   else
2791     format_ip_address_fcn = format_ip6_address;
2792
2793   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2794          format_ip_address_fcn, &mp->lcl_loc,
2795          format_ip_address_fcn, &mp->rmt_loc);
2796 }
2797
2798 static void
2799 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2800 {
2801   struct in6_addr ip6;
2802   struct in_addr ip4;
2803
2804   if (loc->is_ip4)
2805     {
2806       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2807       vat_json_object_add_ip4 (n, "address", ip4);
2808     }
2809   else
2810     {
2811       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2812       vat_json_object_add_ip6 (n, "address", ip6);
2813     }
2814   vat_json_object_add_uint (n, "weight", loc->weight);
2815 }
2816
2817 static void
2818   vl_api_gpe_fwd_entry_path_details_t_handler_json
2819   (vl_api_gpe_fwd_entry_path_details_t * mp)
2820 {
2821   vat_main_t *vam = &vat_main;
2822   vat_json_node_t *node = NULL;
2823   vat_json_node_t *loc_node;
2824
2825   if (VAT_JSON_ARRAY != vam->json_tree.type)
2826     {
2827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2828       vat_json_init_array (&vam->json_tree);
2829     }
2830   node = vat_json_array_add (&vam->json_tree);
2831   vat_json_init_object (node);
2832
2833   loc_node = vat_json_object_add (node, "local_locator");
2834   vat_json_init_object (loc_node);
2835   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2836
2837   loc_node = vat_json_object_add (node, "remote_locator");
2838   vat_json_init_object (loc_node);
2839   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2840 }
2841
2842 static void
2843   vl_api_gpe_fwd_entries_get_reply_t_handler
2844   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2845 {
2846   vat_main_t *vam = &vat_main;
2847   u32 i;
2848   int retval = clib_net_to_host_u32 (mp->retval);
2849   vl_api_gpe_fwd_entry_t *e;
2850
2851   if (retval)
2852     goto end;
2853
2854   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2855
2856   for (i = 0; i < mp->count; i++)
2857     {
2858       e = &mp->entries[i];
2859       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2860              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2861              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2862     }
2863
2864 end:
2865   vam->retval = retval;
2866   vam->result_ready = 1;
2867 }
2868
2869 static void
2870   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2871   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2872 {
2873   u8 *s = 0;
2874   vat_main_t *vam = &vat_main;
2875   vat_json_node_t *e = 0, root;
2876   u32 i;
2877   int retval = clib_net_to_host_u32 (mp->retval);
2878   vl_api_gpe_fwd_entry_t *fwd;
2879
2880   if (retval)
2881     goto end;
2882
2883   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2884   vat_json_init_array (&root);
2885
2886   for (i = 0; i < mp->count; i++)
2887     {
2888       e = vat_json_array_add (&root);
2889       fwd = &mp->entries[i];
2890
2891       vat_json_init_object (e);
2892       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2893       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2894
2895       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2896                   fwd->leid_prefix_len);
2897       vec_add1 (s, 0);
2898       vat_json_object_add_string_copy (e, "leid", s);
2899       vec_free (s);
2900
2901       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2902                   fwd->reid_prefix_len);
2903       vec_add1 (s, 0);
2904       vat_json_object_add_string_copy (e, "reid", s);
2905       vec_free (s);
2906     }
2907
2908   vat_json_print (vam->ofp, &root);
2909   vat_json_free (&root);
2910
2911 end:
2912   vam->retval = retval;
2913   vam->result_ready = 1;
2914 }
2915
2916 static void
2917   vl_api_one_adjacencies_get_reply_t_handler
2918   (vl_api_one_adjacencies_get_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   u32 i, n;
2922   int retval = clib_net_to_host_u32 (mp->retval);
2923   vl_api_one_adjacency_t *a;
2924
2925   if (retval)
2926     goto end;
2927
2928   n = clib_net_to_host_u32 (mp->count);
2929
2930   for (i = 0; i < n; i++)
2931     {
2932       a = &mp->adjacencies[i];
2933       print (vam->ofp, "%U %40U",
2934              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2935              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2936     }
2937
2938 end:
2939   vam->retval = retval;
2940   vam->result_ready = 1;
2941 }
2942
2943 static void
2944   vl_api_one_adjacencies_get_reply_t_handler_json
2945   (vl_api_one_adjacencies_get_reply_t * mp)
2946 {
2947   u8 *s = 0;
2948   vat_main_t *vam = &vat_main;
2949   vat_json_node_t *e = 0, root;
2950   u32 i, n;
2951   int retval = clib_net_to_host_u32 (mp->retval);
2952   vl_api_one_adjacency_t *a;
2953
2954   if (retval)
2955     goto end;
2956
2957   n = clib_net_to_host_u32 (mp->count);
2958   vat_json_init_array (&root);
2959
2960   for (i = 0; i < n; i++)
2961     {
2962       e = vat_json_array_add (&root);
2963       a = &mp->adjacencies[i];
2964
2965       vat_json_init_object (e);
2966       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2967                   a->leid_prefix_len);
2968       vec_add1 (s, 0);
2969       vat_json_object_add_string_copy (e, "leid", s);
2970       vec_free (s);
2971
2972       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2973                   a->reid_prefix_len);
2974       vec_add1 (s, 0);
2975       vat_json_object_add_string_copy (e, "reid", s);
2976       vec_free (s);
2977     }
2978
2979   vat_json_print (vam->ofp, &root);
2980   vat_json_free (&root);
2981
2982 end:
2983   vam->retval = retval;
2984   vam->result_ready = 1;
2985 }
2986
2987 static void
2988 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
2989 {
2990   vat_main_t *vam = &vat_main;
2991
2992   print (vam->ofp, "%=20U",
2993          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2994          mp->ip_address);
2995 }
2996
2997 static void
2998   vl_api_one_map_server_details_t_handler_json
2999   (vl_api_one_map_server_details_t * mp)
3000 {
3001   vat_main_t *vam = &vat_main;
3002   vat_json_node_t *node = NULL;
3003   struct in6_addr ip6;
3004   struct in_addr ip4;
3005
3006   if (VAT_JSON_ARRAY != vam->json_tree.type)
3007     {
3008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3009       vat_json_init_array (&vam->json_tree);
3010     }
3011   node = vat_json_array_add (&vam->json_tree);
3012
3013   vat_json_init_object (node);
3014   if (mp->is_ipv6)
3015     {
3016       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3017       vat_json_object_add_ip6 (node, "map-server", ip6);
3018     }
3019   else
3020     {
3021       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3022       vat_json_object_add_ip4 (node, "map-server", ip4);
3023     }
3024 }
3025
3026 static void
3027 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3028                                            * mp)
3029 {
3030   vat_main_t *vam = &vat_main;
3031
3032   print (vam->ofp, "%=20U",
3033          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3034          mp->ip_address);
3035 }
3036
3037 static void
3038   vl_api_one_map_resolver_details_t_handler_json
3039   (vl_api_one_map_resolver_details_t * mp)
3040 {
3041   vat_main_t *vam = &vat_main;
3042   vat_json_node_t *node = NULL;
3043   struct in6_addr ip6;
3044   struct in_addr ip4;
3045
3046   if (VAT_JSON_ARRAY != vam->json_tree.type)
3047     {
3048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3049       vat_json_init_array (&vam->json_tree);
3050     }
3051   node = vat_json_array_add (&vam->json_tree);
3052
3053   vat_json_init_object (node);
3054   if (mp->is_ipv6)
3055     {
3056       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3057       vat_json_object_add_ip6 (node, "map resolver", ip6);
3058     }
3059   else
3060     {
3061       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3062       vat_json_object_add_ip4 (node, "map resolver", ip4);
3063     }
3064 }
3065
3066 static void
3067 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   i32 retval = ntohl (mp->retval);
3071
3072   if (0 <= retval)
3073     {
3074       print (vam->ofp, "feature: %s\ngpe: %s",
3075              mp->feature_status ? "enabled" : "disabled",
3076              mp->gpe_status ? "enabled" : "disabled");
3077     }
3078
3079   vam->retval = retval;
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_show_one_status_reply_t_handler_json
3085   (vl_api_show_one_status_reply_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   vat_json_node_t node;
3089   u8 *gpe_status = NULL;
3090   u8 *feature_status = NULL;
3091
3092   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3093   feature_status = format (0, "%s",
3094                            mp->feature_status ? "enabled" : "disabled");
3095   vec_add1 (gpe_status, 0);
3096   vec_add1 (feature_status, 0);
3097
3098   vat_json_init_object (&node);
3099   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3100   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3101
3102   vec_free (gpe_status);
3103   vec_free (feature_status);
3104
3105   vat_json_print (vam->ofp, &node);
3106   vat_json_free (&node);
3107
3108   vam->retval = ntohl (mp->retval);
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3114   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   i32 retval = ntohl (mp->retval);
3118
3119   if (retval >= 0)
3120     {
3121       print (vam->ofp, "%=20s", mp->locator_set_name);
3122     }
3123
3124   vam->retval = retval;
3125   vam->result_ready = 1;
3126 }
3127
3128 static void
3129   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3130   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3131 {
3132   vat_main_t *vam = &vat_main;
3133   vat_json_node_t *node = NULL;
3134
3135   if (VAT_JSON_ARRAY != vam->json_tree.type)
3136     {
3137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3138       vat_json_init_array (&vam->json_tree);
3139     }
3140   node = vat_json_array_add (&vam->json_tree);
3141
3142   vat_json_init_object (node);
3143   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3144
3145   vat_json_print (vam->ofp, node);
3146   vat_json_free (node);
3147
3148   vam->retval = ntohl (mp->retval);
3149   vam->result_ready = 1;
3150 }
3151
3152 static u8 *
3153 format_lisp_map_request_mode (u8 * s, va_list * args)
3154 {
3155   u32 mode = va_arg (*args, u32);
3156
3157   switch (mode)
3158     {
3159     case 0:
3160       return format (0, "dst-only");
3161     case 1:
3162       return format (0, "src-dst");
3163     }
3164   return 0;
3165 }
3166
3167 static void
3168   vl_api_show_one_map_request_mode_reply_t_handler
3169   (vl_api_show_one_map_request_mode_reply_t * mp)
3170 {
3171   vat_main_t *vam = &vat_main;
3172   i32 retval = ntohl (mp->retval);
3173
3174   if (0 <= retval)
3175     {
3176       u32 mode = mp->mode;
3177       print (vam->ofp, "map_request_mode: %U",
3178              format_lisp_map_request_mode, mode);
3179     }
3180
3181   vam->retval = retval;
3182   vam->result_ready = 1;
3183 }
3184
3185 static void
3186   vl_api_show_one_map_request_mode_reply_t_handler_json
3187   (vl_api_show_one_map_request_mode_reply_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   vat_json_node_t node;
3191   u8 *s = 0;
3192   u32 mode;
3193
3194   mode = mp->mode;
3195   s = format (0, "%U", format_lisp_map_request_mode, mode);
3196   vec_add1 (s, 0);
3197
3198   vat_json_init_object (&node);
3199   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3200   vat_json_print (vam->ofp, &node);
3201   vat_json_free (&node);
3202
3203   vec_free (s);
3204   vam->retval = ntohl (mp->retval);
3205   vam->result_ready = 1;
3206 }
3207
3208 static void
3209 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   i32 retval = ntohl (mp->retval);
3213
3214   if (0 <= retval)
3215     {
3216       print (vam->ofp, "%-20s%-16s",
3217              mp->status ? "enabled" : "disabled",
3218              mp->status ? (char *) mp->locator_set_name : "");
3219     }
3220
3221   vam->retval = retval;
3222   vam->result_ready = 1;
3223 }
3224
3225 static void
3226 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229   vat_json_node_t node;
3230   u8 *status = 0;
3231
3232   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3233   vec_add1 (status, 0);
3234
3235   vat_json_init_object (&node);
3236   vat_json_object_add_string_copy (&node, "status", status);
3237   if (mp->status)
3238     {
3239       vat_json_object_add_string_copy (&node, "locator_set",
3240                                        mp->locator_set_name);
3241     }
3242
3243   vec_free (status);
3244
3245   vat_json_print (vam->ofp, &node);
3246   vat_json_free (&node);
3247
3248   vam->retval = ntohl (mp->retval);
3249   vam->result_ready = 1;
3250 }
3251
3252 static u8 *
3253 format_policer_type (u8 * s, va_list * va)
3254 {
3255   u32 i = va_arg (*va, u32);
3256
3257   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3258     s = format (s, "1r2c");
3259   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3260     s = format (s, "1r3c");
3261   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3262     s = format (s, "2r3c-2698");
3263   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3264     s = format (s, "2r3c-4115");
3265   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3266     s = format (s, "2r3c-mef5cf1");
3267   else
3268     s = format (s, "ILLEGAL");
3269   return s;
3270 }
3271
3272 static u8 *
3273 format_policer_rate_type (u8 * s, va_list * va)
3274 {
3275   u32 i = va_arg (*va, u32);
3276
3277   if (i == SSE2_QOS_RATE_KBPS)
3278     s = format (s, "kbps");
3279   else if (i == SSE2_QOS_RATE_PPS)
3280     s = format (s, "pps");
3281   else
3282     s = format (s, "ILLEGAL");
3283   return s;
3284 }
3285
3286 static u8 *
3287 format_policer_round_type (u8 * s, va_list * va)
3288 {
3289   u32 i = va_arg (*va, u32);
3290
3291   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3292     s = format (s, "closest");
3293   else if (i == SSE2_QOS_ROUND_TO_UP)
3294     s = format (s, "up");
3295   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3296     s = format (s, "down");
3297   else
3298     s = format (s, "ILLEGAL");
3299   return s;
3300 }
3301
3302 static u8 *
3303 format_policer_action_type (u8 * s, va_list * va)
3304 {
3305   u32 i = va_arg (*va, u32);
3306
3307   if (i == SSE2_QOS_ACTION_DROP)
3308     s = format (s, "drop");
3309   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3310     s = format (s, "transmit");
3311   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3312     s = format (s, "mark-and-transmit");
3313   else
3314     s = format (s, "ILLEGAL");
3315   return s;
3316 }
3317
3318 static u8 *
3319 format_dscp (u8 * s, va_list * va)
3320 {
3321   u32 i = va_arg (*va, u32);
3322   char *t = 0;
3323
3324   switch (i)
3325     {
3326 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3327       foreach_vnet_dscp
3328 #undef _
3329     default:
3330       return format (s, "ILLEGAL");
3331     }
3332   s = format (s, "%s", t);
3333   return s;
3334 }
3335
3336 static void
3337 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3338 {
3339   vat_main_t *vam = &vat_main;
3340   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3341
3342   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3343     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3344   else
3345     conform_dscp_str = format (0, "");
3346
3347   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3348     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3349   else
3350     exceed_dscp_str = format (0, "");
3351
3352   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3353     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3354   else
3355     violate_dscp_str = format (0, "");
3356
3357   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3358          "rate type %U, round type %U, %s rate, %s color-aware, "
3359          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3360          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3361          "conform action %U%s, exceed action %U%s, violate action %U%s",
3362          mp->name,
3363          format_policer_type, mp->type,
3364          ntohl (mp->cir),
3365          ntohl (mp->eir),
3366          clib_net_to_host_u64 (mp->cb),
3367          clib_net_to_host_u64 (mp->eb),
3368          format_policer_rate_type, mp->rate_type,
3369          format_policer_round_type, mp->round_type,
3370          mp->single_rate ? "single" : "dual",
3371          mp->color_aware ? "is" : "not",
3372          ntohl (mp->cir_tokens_per_period),
3373          ntohl (mp->pir_tokens_per_period),
3374          ntohl (mp->scale),
3375          ntohl (mp->current_limit),
3376          ntohl (mp->current_bucket),
3377          ntohl (mp->extended_limit),
3378          ntohl (mp->extended_bucket),
3379          clib_net_to_host_u64 (mp->last_update_time),
3380          format_policer_action_type, mp->conform_action_type,
3381          conform_dscp_str,
3382          format_policer_action_type, mp->exceed_action_type,
3383          exceed_dscp_str,
3384          format_policer_action_type, mp->violate_action_type,
3385          violate_dscp_str);
3386
3387   vec_free (conform_dscp_str);
3388   vec_free (exceed_dscp_str);
3389   vec_free (violate_dscp_str);
3390 }
3391
3392 static void vl_api_policer_details_t_handler_json
3393   (vl_api_policer_details_t * mp)
3394 {
3395   vat_main_t *vam = &vat_main;
3396   vat_json_node_t *node;
3397   u8 *rate_type_str, *round_type_str, *type_str;
3398   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3399
3400   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3401   round_type_str =
3402     format (0, "%U", format_policer_round_type, mp->round_type);
3403   type_str = format (0, "%U", format_policer_type, mp->type);
3404   conform_action_str = format (0, "%U", format_policer_action_type,
3405                                mp->conform_action_type);
3406   exceed_action_str = format (0, "%U", format_policer_action_type,
3407                               mp->exceed_action_type);
3408   violate_action_str = format (0, "%U", format_policer_action_type,
3409                                mp->violate_action_type);
3410
3411   if (VAT_JSON_ARRAY != vam->json_tree.type)
3412     {
3413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3414       vat_json_init_array (&vam->json_tree);
3415     }
3416   node = vat_json_array_add (&vam->json_tree);
3417
3418   vat_json_init_object (node);
3419   vat_json_object_add_string_copy (node, "name", mp->name);
3420   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3421   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3422   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3423   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3424   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3425   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3426   vat_json_object_add_string_copy (node, "type", type_str);
3427   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3428   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3429   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3430   vat_json_object_add_uint (node, "cir_tokens_per_period",
3431                             ntohl (mp->cir_tokens_per_period));
3432   vat_json_object_add_uint (node, "eir_tokens_per_period",
3433                             ntohl (mp->pir_tokens_per_period));
3434   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3435   vat_json_object_add_uint (node, "current_bucket",
3436                             ntohl (mp->current_bucket));
3437   vat_json_object_add_uint (node, "extended_limit",
3438                             ntohl (mp->extended_limit));
3439   vat_json_object_add_uint (node, "extended_bucket",
3440                             ntohl (mp->extended_bucket));
3441   vat_json_object_add_uint (node, "last_update_time",
3442                             ntohl (mp->last_update_time));
3443   vat_json_object_add_string_copy (node, "conform_action",
3444                                    conform_action_str);
3445   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3446     {
3447       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3448       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3449       vec_free (dscp_str);
3450     }
3451   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3452   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3453     {
3454       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3455       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3456       vec_free (dscp_str);
3457     }
3458   vat_json_object_add_string_copy (node, "violate_action",
3459                                    violate_action_str);
3460   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3461     {
3462       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3463       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3464       vec_free (dscp_str);
3465     }
3466
3467   vec_free (rate_type_str);
3468   vec_free (round_type_str);
3469   vec_free (type_str);
3470   vec_free (conform_action_str);
3471   vec_free (exceed_action_str);
3472   vec_free (violate_action_str);
3473 }
3474
3475 static void
3476 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3477                                            mp)
3478 {
3479   vat_main_t *vam = &vat_main;
3480   int i, count = ntohl (mp->count);
3481
3482   if (count > 0)
3483     print (vam->ofp, "classify table ids (%d) : ", count);
3484   for (i = 0; i < count; i++)
3485     {
3486       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3487       print (vam->ofp, (i < count - 1) ? "," : "");
3488     }
3489   vam->retval = ntohl (mp->retval);
3490   vam->result_ready = 1;
3491 }
3492
3493 static void
3494   vl_api_classify_table_ids_reply_t_handler_json
3495   (vl_api_classify_table_ids_reply_t * mp)
3496 {
3497   vat_main_t *vam = &vat_main;
3498   int i, count = ntohl (mp->count);
3499
3500   if (count > 0)
3501     {
3502       vat_json_node_t node;
3503
3504       vat_json_init_object (&node);
3505       for (i = 0; i < count; i++)
3506         {
3507           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3508         }
3509       vat_json_print (vam->ofp, &node);
3510       vat_json_free (&node);
3511     }
3512   vam->retval = ntohl (mp->retval);
3513   vam->result_ready = 1;
3514 }
3515
3516 static void
3517   vl_api_classify_table_by_interface_reply_t_handler
3518   (vl_api_classify_table_by_interface_reply_t * mp)
3519 {
3520   vat_main_t *vam = &vat_main;
3521   u32 table_id;
3522
3523   table_id = ntohl (mp->l2_table_id);
3524   if (table_id != ~0)
3525     print (vam->ofp, "l2 table id : %d", table_id);
3526   else
3527     print (vam->ofp, "l2 table id : No input ACL tables configured");
3528   table_id = ntohl (mp->ip4_table_id);
3529   if (table_id != ~0)
3530     print (vam->ofp, "ip4 table id : %d", table_id);
3531   else
3532     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3533   table_id = ntohl (mp->ip6_table_id);
3534   if (table_id != ~0)
3535     print (vam->ofp, "ip6 table id : %d", table_id);
3536   else
3537     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3538   vam->retval = ntohl (mp->retval);
3539   vam->result_ready = 1;
3540 }
3541
3542 static void
3543   vl_api_classify_table_by_interface_reply_t_handler_json
3544   (vl_api_classify_table_by_interface_reply_t * mp)
3545 {
3546   vat_main_t *vam = &vat_main;
3547   vat_json_node_t node;
3548
3549   vat_json_init_object (&node);
3550
3551   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3552   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3553   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3554
3555   vat_json_print (vam->ofp, &node);
3556   vat_json_free (&node);
3557
3558   vam->retval = ntohl (mp->retval);
3559   vam->result_ready = 1;
3560 }
3561
3562 static void vl_api_policer_add_del_reply_t_handler
3563   (vl_api_policer_add_del_reply_t * mp)
3564 {
3565   vat_main_t *vam = &vat_main;
3566   i32 retval = ntohl (mp->retval);
3567   if (vam->async_mode)
3568     {
3569       vam->async_errors += (retval < 0);
3570     }
3571   else
3572     {
3573       vam->retval = retval;
3574       vam->result_ready = 1;
3575       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3576         /*
3577          * Note: this is just barely thread-safe, depends on
3578          * the main thread spinning waiting for an answer...
3579          */
3580         errmsg ("policer index %d", ntohl (mp->policer_index));
3581     }
3582 }
3583
3584 static void vl_api_policer_add_del_reply_t_handler_json
3585   (vl_api_policer_add_del_reply_t * mp)
3586 {
3587   vat_main_t *vam = &vat_main;
3588   vat_json_node_t node;
3589
3590   vat_json_init_object (&node);
3591   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3592   vat_json_object_add_uint (&node, "policer_index",
3593                             ntohl (mp->policer_index));
3594
3595   vat_json_print (vam->ofp, &node);
3596   vat_json_free (&node);
3597
3598   vam->retval = ntohl (mp->retval);
3599   vam->result_ready = 1;
3600 }
3601
3602 /* Format hex dump. */
3603 u8 *
3604 format_hex_bytes (u8 * s, va_list * va)
3605 {
3606   u8 *bytes = va_arg (*va, u8 *);
3607   int n_bytes = va_arg (*va, int);
3608   uword i;
3609
3610   /* Print short or long form depending on byte count. */
3611   uword short_form = n_bytes <= 32;
3612   uword indent = format_get_indent (s);
3613
3614   if (n_bytes == 0)
3615     return s;
3616
3617   for (i = 0; i < n_bytes; i++)
3618     {
3619       if (!short_form && (i % 32) == 0)
3620         s = format (s, "%08x: ", i);
3621       s = format (s, "%02x", bytes[i]);
3622       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3623         s = format (s, "\n%U", format_white_space, indent);
3624     }
3625
3626   return s;
3627 }
3628
3629 static void
3630 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3631                                             * mp)
3632 {
3633   vat_main_t *vam = &vat_main;
3634   i32 retval = ntohl (mp->retval);
3635   if (retval == 0)
3636     {
3637       print (vam->ofp, "classify table info :");
3638       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3639              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3640              ntohl (mp->miss_next_index));
3641       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3642              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3643              ntohl (mp->match_n_vectors));
3644       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3645              ntohl (mp->mask_length));
3646     }
3647   vam->retval = retval;
3648   vam->result_ready = 1;
3649 }
3650
3651 static void
3652   vl_api_classify_table_info_reply_t_handler_json
3653   (vl_api_classify_table_info_reply_t * mp)
3654 {
3655   vat_main_t *vam = &vat_main;
3656   vat_json_node_t node;
3657
3658   i32 retval = ntohl (mp->retval);
3659   if (retval == 0)
3660     {
3661       vat_json_init_object (&node);
3662
3663       vat_json_object_add_int (&node, "sessions",
3664                                ntohl (mp->active_sessions));
3665       vat_json_object_add_int (&node, "nexttbl",
3666                                ntohl (mp->next_table_index));
3667       vat_json_object_add_int (&node, "nextnode",
3668                                ntohl (mp->miss_next_index));
3669       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3670       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3671       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3672       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3673                       ntohl (mp->mask_length), 0);
3674       vat_json_object_add_string_copy (&node, "mask", s);
3675
3676       vat_json_print (vam->ofp, &node);
3677       vat_json_free (&node);
3678     }
3679   vam->retval = ntohl (mp->retval);
3680   vam->result_ready = 1;
3681 }
3682
3683 static void
3684 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3685                                            mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688
3689   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3690          ntohl (mp->hit_next_index), ntohl (mp->advance),
3691          ntohl (mp->opaque_index));
3692   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3693          ntohl (mp->match_length));
3694 }
3695
3696 static void
3697   vl_api_classify_session_details_t_handler_json
3698   (vl_api_classify_session_details_t * mp)
3699 {
3700   vat_main_t *vam = &vat_main;
3701   vat_json_node_t *node = NULL;
3702
3703   if (VAT_JSON_ARRAY != vam->json_tree.type)
3704     {
3705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3706       vat_json_init_array (&vam->json_tree);
3707     }
3708   node = vat_json_array_add (&vam->json_tree);
3709
3710   vat_json_init_object (node);
3711   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3712   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3713   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3714   u8 *s =
3715     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3716             0);
3717   vat_json_object_add_string_copy (node, "match", s);
3718 }
3719
3720 static void vl_api_pg_create_interface_reply_t_handler
3721   (vl_api_pg_create_interface_reply_t * mp)
3722 {
3723   vat_main_t *vam = &vat_main;
3724
3725   vam->retval = ntohl (mp->retval);
3726   vam->result_ready = 1;
3727 }
3728
3729 static void vl_api_pg_create_interface_reply_t_handler_json
3730   (vl_api_pg_create_interface_reply_t * mp)
3731 {
3732   vat_main_t *vam = &vat_main;
3733   vat_json_node_t node;
3734
3735   i32 retval = ntohl (mp->retval);
3736   if (retval == 0)
3737     {
3738       vat_json_init_object (&node);
3739
3740       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3741
3742       vat_json_print (vam->ofp, &node);
3743       vat_json_free (&node);
3744     }
3745   vam->retval = ntohl (mp->retval);
3746   vam->result_ready = 1;
3747 }
3748
3749 static void vl_api_policer_classify_details_t_handler
3750   (vl_api_policer_classify_details_t * mp)
3751 {
3752   vat_main_t *vam = &vat_main;
3753
3754   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3755          ntohl (mp->table_index));
3756 }
3757
3758 static void vl_api_policer_classify_details_t_handler_json
3759   (vl_api_policer_classify_details_t * mp)
3760 {
3761   vat_main_t *vam = &vat_main;
3762   vat_json_node_t *node;
3763
3764   if (VAT_JSON_ARRAY != vam->json_tree.type)
3765     {
3766       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3767       vat_json_init_array (&vam->json_tree);
3768     }
3769   node = vat_json_array_add (&vam->json_tree);
3770
3771   vat_json_init_object (node);
3772   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3773   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3774 }
3775
3776 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3777   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3778 {
3779   vat_main_t *vam = &vat_main;
3780   i32 retval = ntohl (mp->retval);
3781   if (vam->async_mode)
3782     {
3783       vam->async_errors += (retval < 0);
3784     }
3785   else
3786     {
3787       vam->retval = retval;
3788       vam->sw_if_index = ntohl (mp->sw_if_index);
3789       vam->result_ready = 1;
3790     }
3791 }
3792
3793 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3794   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3795 {
3796   vat_main_t *vam = &vat_main;
3797   vat_json_node_t node;
3798
3799   vat_json_init_object (&node);
3800   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3801   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3802
3803   vat_json_print (vam->ofp, &node);
3804   vat_json_free (&node);
3805
3806   vam->retval = ntohl (mp->retval);
3807   vam->result_ready = 1;
3808 }
3809
3810 static void vl_api_flow_classify_details_t_handler
3811   (vl_api_flow_classify_details_t * mp)
3812 {
3813   vat_main_t *vam = &vat_main;
3814
3815   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3816          ntohl (mp->table_index));
3817 }
3818
3819 static void vl_api_flow_classify_details_t_handler_json
3820   (vl_api_flow_classify_details_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   vat_json_node_t *node;
3824
3825   if (VAT_JSON_ARRAY != vam->json_tree.type)
3826     {
3827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3828       vat_json_init_array (&vam->json_tree);
3829     }
3830   node = vat_json_array_add (&vam->json_tree);
3831
3832   vat_json_init_object (node);
3833   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3834   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3835 }
3836
3837
3838
3839 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3840 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3841 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3842 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3843 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3844 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3845 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3846 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3847 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3848 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3849
3850 /*
3851  * Generate boilerplate reply handlers, which
3852  * dig the return value out of the xxx_reply_t API message,
3853  * stick it into vam->retval, and set vam->result_ready
3854  *
3855  * Could also do this by pointing N message decode slots at
3856  * a single function, but that could break in subtle ways.
3857  */
3858
3859 #define foreach_standard_reply_retval_handler           \
3860 _(sw_interface_set_flags_reply)                         \
3861 _(sw_interface_add_del_address_reply)                   \
3862 _(sw_interface_set_table_reply)                         \
3863 _(sw_interface_set_mpls_enable_reply)                   \
3864 _(sw_interface_set_vpath_reply)                         \
3865 _(sw_interface_set_vxlan_bypass_reply)                  \
3866 _(sw_interface_set_l2_bridge_reply)                     \
3867 _(bridge_domain_add_del_reply)                          \
3868 _(sw_interface_set_l2_xconnect_reply)                   \
3869 _(l2fib_add_del_reply)                                  \
3870 _(ip_add_del_route_reply)                               \
3871 _(ip_mroute_add_del_reply)                              \
3872 _(mpls_route_add_del_reply)                             \
3873 _(mpls_ip_bind_unbind_reply)                            \
3874 _(proxy_arp_add_del_reply)                              \
3875 _(proxy_arp_intfc_enable_disable_reply)                 \
3876 _(sw_interface_set_unnumbered_reply)                    \
3877 _(ip_neighbor_add_del_reply)                            \
3878 _(reset_vrf_reply)                                      \
3879 _(oam_add_del_reply)                                    \
3880 _(reset_fib_reply)                                      \
3881 _(dhcp_proxy_config_reply)                              \
3882 _(dhcp_proxy_set_vss_reply)                             \
3883 _(dhcp_client_config_reply)                             \
3884 _(set_ip_flow_hash_reply)                               \
3885 _(sw_interface_ip6_enable_disable_reply)                \
3886 _(sw_interface_ip6_set_link_local_address_reply)        \
3887 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3888 _(sw_interface_ip6nd_ra_config_reply)                   \
3889 _(set_arp_neighbor_limit_reply)                         \
3890 _(l2_patch_add_del_reply)                               \
3891 _(sr_tunnel_add_del_reply)                              \
3892 _(sr_policy_add_del_reply)                              \
3893 _(sr_multicast_map_add_del_reply)                       \
3894 _(classify_add_del_session_reply)                       \
3895 _(classify_set_interface_ip_table_reply)                \
3896 _(classify_set_interface_l2_tables_reply)               \
3897 _(l2tpv3_set_tunnel_cookies_reply)                      \
3898 _(l2tpv3_interface_enable_disable_reply)                \
3899 _(l2tpv3_set_lookup_key_reply)                          \
3900 _(l2_fib_clear_table_reply)                             \
3901 _(l2_interface_efp_filter_reply)                        \
3902 _(l2_interface_vlan_tag_rewrite_reply)                  \
3903 _(modify_vhost_user_if_reply)                           \
3904 _(delete_vhost_user_if_reply)                           \
3905 _(want_ip4_arp_events_reply)                            \
3906 _(want_ip6_nd_events_reply)                             \
3907 _(input_acl_set_interface_reply)                        \
3908 _(ipsec_spd_add_del_reply)                              \
3909 _(ipsec_interface_add_del_spd_reply)                    \
3910 _(ipsec_spd_add_del_entry_reply)                        \
3911 _(ipsec_sad_add_del_entry_reply)                        \
3912 _(ipsec_sa_set_key_reply)                               \
3913 _(ikev2_profile_add_del_reply)                          \
3914 _(ikev2_profile_set_auth_reply)                         \
3915 _(ikev2_profile_set_id_reply)                           \
3916 _(ikev2_profile_set_ts_reply)                           \
3917 _(ikev2_set_local_key_reply)                            \
3918 _(ikev2_set_responder_reply)                            \
3919 _(ikev2_set_ike_transforms_reply)                       \
3920 _(ikev2_set_esp_transforms_reply)                       \
3921 _(ikev2_set_sa_lifetime_reply)                          \
3922 _(ikev2_initiate_sa_init_reply)                         \
3923 _(ikev2_initiate_del_ike_sa_reply)                      \
3924 _(ikev2_initiate_del_child_sa_reply)                    \
3925 _(ikev2_initiate_rekey_child_sa_reply)                  \
3926 _(delete_loopback_reply)                                \
3927 _(bd_ip_mac_add_del_reply)                              \
3928 _(map_del_domain_reply)                                 \
3929 _(map_add_del_rule_reply)                               \
3930 _(want_interface_events_reply)                          \
3931 _(want_stats_reply)                                     \
3932 _(cop_interface_enable_disable_reply)                   \
3933 _(cop_whitelist_enable_disable_reply)                   \
3934 _(sw_interface_clear_stats_reply)                       \
3935 _(ioam_enable_reply)                              \
3936 _(ioam_disable_reply)                              \
3937 _(one_add_del_locator_reply)                            \
3938 _(one_add_del_local_eid_reply)                          \
3939 _(one_add_del_remote_mapping_reply)                     \
3940 _(one_add_del_adjacency_reply)                          \
3941 _(one_add_del_map_resolver_reply)                       \
3942 _(one_add_del_map_server_reply)                         \
3943 _(one_enable_disable_reply)                             \
3944 _(one_rloc_probe_enable_disable_reply)                  \
3945 _(one_map_register_enable_disable_reply)                \
3946 _(one_pitr_set_locator_set_reply)                       \
3947 _(one_map_request_mode_reply)                           \
3948 _(one_add_del_map_request_itr_rlocs_reply)              \
3949 _(one_eid_table_add_del_map_reply)                      \
3950 _(gpe_add_del_fwd_entry_reply)                          \
3951 _(gpe_enable_disable_reply)                             \
3952 _(gpe_set_encap_mode_reply)                             \
3953 _(gpe_add_del_iface_reply)                              \
3954 _(vxlan_gpe_add_del_tunnel_reply)                       \
3955 _(af_packet_delete_reply)                               \
3956 _(policer_classify_set_interface_reply)                 \
3957 _(netmap_create_reply)                                  \
3958 _(netmap_delete_reply)                                  \
3959 _(set_ipfix_exporter_reply)                             \
3960 _(set_ipfix_classify_stream_reply)                      \
3961 _(ipfix_classify_table_add_del_reply)                   \
3962 _(flow_classify_set_interface_reply)                    \
3963 _(sw_interface_span_enable_disable_reply)               \
3964 _(pg_capture_reply)                                     \
3965 _(pg_enable_disable_reply)                              \
3966 _(ip_source_and_port_range_check_add_del_reply)         \
3967 _(ip_source_and_port_range_check_interface_add_del_reply)\
3968 _(delete_subif_reply)                                   \
3969 _(l2_interface_pbb_tag_rewrite_reply)                   \
3970 _(punt_reply)                                           \
3971 _(feature_enable_disable_reply)                         \
3972 _(sw_interface_tag_add_del_reply)                       \
3973 _(sw_interface_set_mtu_reply)
3974
3975 #define _(n)                                    \
3976     static void vl_api_##n##_t_handler          \
3977     (vl_api_##n##_t * mp)                       \
3978     {                                           \
3979         vat_main_t * vam = &vat_main;           \
3980         i32 retval = ntohl(mp->retval);         \
3981         if (vam->async_mode) {                  \
3982             vam->async_errors += (retval < 0);  \
3983         } else {                                \
3984             vam->retval = retval;               \
3985             vam->result_ready = 1;              \
3986         }                                       \
3987     }
3988 foreach_standard_reply_retval_handler;
3989 #undef _
3990
3991 #define _(n)                                    \
3992     static void vl_api_##n##_t_handler_json     \
3993     (vl_api_##n##_t * mp)                       \
3994     {                                           \
3995         vat_main_t * vam = &vat_main;           \
3996         vat_json_node_t node;                   \
3997         vat_json_init_object(&node);            \
3998         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3999         vat_json_print(vam->ofp, &node);        \
4000         vam->retval = ntohl(mp->retval);        \
4001         vam->result_ready = 1;                  \
4002     }
4003 foreach_standard_reply_retval_handler;
4004 #undef _
4005
4006 /*
4007  * Table of message reply handlers, must include boilerplate handlers
4008  * we just generated
4009  */
4010
4011 #define foreach_vpe_api_reply_msg                                       \
4012 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4013 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4014 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4015 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4016 _(CLI_REPLY, cli_reply)                                                 \
4017 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4018 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4019   sw_interface_add_del_address_reply)                                   \
4020 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4021 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4022 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4023 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4024 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4025   sw_interface_set_l2_xconnect_reply)                                   \
4026 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4027   sw_interface_set_l2_bridge_reply)                                     \
4028 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4029 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4030 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4031 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4032 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4033 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4034 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4035 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4036 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4037 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4038 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4039 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4040 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4041 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4042 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4043 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4044   proxy_arp_intfc_enable_disable_reply)                                 \
4045 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4046 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4047   sw_interface_set_unnumbered_reply)                                    \
4048 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4049 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4050 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4051 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4052 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4053 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4054 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4055 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4056 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4057 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4058 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4059 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4060   sw_interface_ip6_enable_disable_reply)                                \
4061 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4062   sw_interface_ip6_set_link_local_address_reply)                        \
4063 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4064   sw_interface_ip6nd_ra_prefix_reply)                                   \
4065 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4066   sw_interface_ip6nd_ra_config_reply)                                   \
4067 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4068 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4069 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4070 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4071 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4072 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4073 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4074 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4075 classify_set_interface_ip_table_reply)                                  \
4076 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4077   classify_set_interface_l2_tables_reply)                               \
4078 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4079 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4080 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4081 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4082 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4083   l2tpv3_interface_enable_disable_reply)                                \
4084 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4085 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4086 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4087 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4088 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4089 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4090 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4091 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4092 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4093 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4094 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4095 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4096 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4097 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4098 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4099 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4100 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4101 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4102 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4103 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4104 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4105 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4106 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4107 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4108 _(IP_DETAILS, ip_details)                                               \
4109 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4110 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4111 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4112 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4113 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4114 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4115 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4116 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4117 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4118 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4119 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4120 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4121 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4122 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4123 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4124 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4125 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4126 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4127 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4128 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4129 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4130 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4131 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4132 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4133 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4134 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4135 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4136 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4137 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4138 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4139 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4140 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4141 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4142 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4143 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4144 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4145 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4146 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4147 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4148 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4149 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4150 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4151 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4152 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4153   one_map_register_enable_disable_reply)                                \
4154 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4155   one_rloc_probe_enable_disable_reply)                                  \
4156 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4157 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4158 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4159 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4160 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4161 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4162 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4163 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4164 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4165 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4166 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4167 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4168 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4169 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4170 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4171 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4172 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4173 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4174   gpe_fwd_entry_path_details)                                           \
4175 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4176 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4177   one_add_del_map_request_itr_rlocs_reply)                              \
4178 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4179   one_get_map_request_itr_rlocs_reply)                                  \
4180 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4181 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4182 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4183 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4184   show_one_map_register_state_reply)                                    \
4185 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4186 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4187 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4188 _(POLICER_DETAILS, policer_details)                                     \
4189 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4190 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4191 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4192 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4193 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4194 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4195 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4196 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4197 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4198 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4199 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4200 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4201 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4202 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4203 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4204 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4205 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4206 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4207 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4208 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4209 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4210 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4211 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4212 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4213 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4214  ip_source_and_port_range_check_add_del_reply)                          \
4215 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4216  ip_source_and_port_range_check_interface_add_del_reply)                \
4217 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4218 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4219 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4220 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4221 _(PUNT_REPLY, punt_reply)                                               \
4222 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4223 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4224 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4225 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4226 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4227 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4228 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4229 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4230
4231 #define foreach_standalone_reply_msg                                    \
4232 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4233 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4234 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4235 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4236 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4237 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4238
4239 typedef struct
4240 {
4241   u8 *name;
4242   u32 value;
4243 } name_sort_t;
4244
4245
4246 #define STR_VTR_OP_CASE(op)     \
4247     case L2_VTR_ ## op:         \
4248         return "" # op;
4249
4250 static const char *
4251 str_vtr_op (u32 vtr_op)
4252 {
4253   switch (vtr_op)
4254     {
4255       STR_VTR_OP_CASE (DISABLED);
4256       STR_VTR_OP_CASE (PUSH_1);
4257       STR_VTR_OP_CASE (PUSH_2);
4258       STR_VTR_OP_CASE (POP_1);
4259       STR_VTR_OP_CASE (POP_2);
4260       STR_VTR_OP_CASE (TRANSLATE_1_1);
4261       STR_VTR_OP_CASE (TRANSLATE_1_2);
4262       STR_VTR_OP_CASE (TRANSLATE_2_1);
4263       STR_VTR_OP_CASE (TRANSLATE_2_2);
4264     }
4265
4266   return "UNKNOWN";
4267 }
4268
4269 static int
4270 dump_sub_interface_table (vat_main_t * vam)
4271 {
4272   const sw_interface_subif_t *sub = NULL;
4273
4274   if (vam->json_output)
4275     {
4276       clib_warning
4277         ("JSON output supported only for VPE API calls and dump_stats_table");
4278       return -99;
4279     }
4280
4281   print (vam->ofp,
4282          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4283          "Interface", "sw_if_index",
4284          "sub id", "dot1ad", "tags", "outer id",
4285          "inner id", "exact", "default", "outer any", "inner any");
4286
4287   vec_foreach (sub, vam->sw_if_subif_table)
4288   {
4289     print (vam->ofp,
4290            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4291            sub->interface_name,
4292            sub->sw_if_index,
4293            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4294            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4295            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4296            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4297     if (sub->vtr_op != L2_VTR_DISABLED)
4298       {
4299         print (vam->ofp,
4300                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4301                "tag1: %d tag2: %d ]",
4302                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4303                sub->vtr_tag1, sub->vtr_tag2);
4304       }
4305   }
4306
4307   return 0;
4308 }
4309
4310 static int
4311 name_sort_cmp (void *a1, void *a2)
4312 {
4313   name_sort_t *n1 = a1;
4314   name_sort_t *n2 = a2;
4315
4316   return strcmp ((char *) n1->name, (char *) n2->name);
4317 }
4318
4319 static int
4320 dump_interface_table (vat_main_t * vam)
4321 {
4322   hash_pair_t *p;
4323   name_sort_t *nses = 0, *ns;
4324
4325   if (vam->json_output)
4326     {
4327       clib_warning
4328         ("JSON output supported only for VPE API calls and dump_stats_table");
4329       return -99;
4330     }
4331
4332   /* *INDENT-OFF* */
4333   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4334   ({
4335     vec_add2 (nses, ns, 1);
4336     ns->name = (u8 *)(p->key);
4337     ns->value = (u32) p->value[0];
4338   }));
4339   /* *INDENT-ON* */
4340
4341   vec_sort_with_function (nses, name_sort_cmp);
4342
4343   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4344   vec_foreach (ns, nses)
4345   {
4346     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4347   }
4348   vec_free (nses);
4349   return 0;
4350 }
4351
4352 static int
4353 dump_ip_table (vat_main_t * vam, int is_ipv6)
4354 {
4355   const ip_details_t *det = NULL;
4356   const ip_address_details_t *address = NULL;
4357   u32 i = ~0;
4358
4359   print (vam->ofp, "%-12s", "sw_if_index");
4360
4361   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4362   {
4363     i++;
4364     if (!det->present)
4365       {
4366         continue;
4367       }
4368     print (vam->ofp, "%-12d", i);
4369     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4370     if (!det->addr)
4371       {
4372         continue;
4373       }
4374     vec_foreach (address, det->addr)
4375     {
4376       print (vam->ofp,
4377              "            %-30U%-13d",
4378              is_ipv6 ? format_ip6_address : format_ip4_address,
4379              address->ip, address->prefix_length);
4380     }
4381   }
4382
4383   return 0;
4384 }
4385
4386 static int
4387 dump_ipv4_table (vat_main_t * vam)
4388 {
4389   if (vam->json_output)
4390     {
4391       clib_warning
4392         ("JSON output supported only for VPE API calls and dump_stats_table");
4393       return -99;
4394     }
4395
4396   return dump_ip_table (vam, 0);
4397 }
4398
4399 static int
4400 dump_ipv6_table (vat_main_t * vam)
4401 {
4402   if (vam->json_output)
4403     {
4404       clib_warning
4405         ("JSON output supported only for VPE API calls and dump_stats_table");
4406       return -99;
4407     }
4408
4409   return dump_ip_table (vam, 1);
4410 }
4411
4412 static char *
4413 counter_type_to_str (u8 counter_type, u8 is_combined)
4414 {
4415   if (!is_combined)
4416     {
4417       switch (counter_type)
4418         {
4419         case VNET_INTERFACE_COUNTER_DROP:
4420           return "drop";
4421         case VNET_INTERFACE_COUNTER_PUNT:
4422           return "punt";
4423         case VNET_INTERFACE_COUNTER_IP4:
4424           return "ip4";
4425         case VNET_INTERFACE_COUNTER_IP6:
4426           return "ip6";
4427         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4428           return "rx-no-buf";
4429         case VNET_INTERFACE_COUNTER_RX_MISS:
4430           return "rx-miss";
4431         case VNET_INTERFACE_COUNTER_RX_ERROR:
4432           return "rx-error";
4433         case VNET_INTERFACE_COUNTER_TX_ERROR:
4434           return "tx-error";
4435         default:
4436           return "INVALID-COUNTER-TYPE";
4437         }
4438     }
4439   else
4440     {
4441       switch (counter_type)
4442         {
4443         case VNET_INTERFACE_COUNTER_RX:
4444           return "rx";
4445         case VNET_INTERFACE_COUNTER_TX:
4446           return "tx";
4447         default:
4448           return "INVALID-COUNTER-TYPE";
4449         }
4450     }
4451 }
4452
4453 static int
4454 dump_stats_table (vat_main_t * vam)
4455 {
4456   vat_json_node_t node;
4457   vat_json_node_t *msg_array;
4458   vat_json_node_t *msg;
4459   vat_json_node_t *counter_array;
4460   vat_json_node_t *counter;
4461   interface_counter_t c;
4462   u64 packets;
4463   ip4_fib_counter_t *c4;
4464   ip6_fib_counter_t *c6;
4465   ip4_nbr_counter_t *n4;
4466   ip6_nbr_counter_t *n6;
4467   int i, j;
4468
4469   if (!vam->json_output)
4470     {
4471       clib_warning ("dump_stats_table supported only in JSON format");
4472       return -99;
4473     }
4474
4475   vat_json_init_object (&node);
4476
4477   /* interface counters */
4478   msg_array = vat_json_object_add (&node, "interface_counters");
4479   vat_json_init_array (msg_array);
4480   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4481     {
4482       msg = vat_json_array_add (msg_array);
4483       vat_json_init_object (msg);
4484       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4485                                        (u8 *) counter_type_to_str (i, 0));
4486       vat_json_object_add_int (msg, "is_combined", 0);
4487       counter_array = vat_json_object_add (msg, "data");
4488       vat_json_init_array (counter_array);
4489       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4490         {
4491           packets = vam->simple_interface_counters[i][j];
4492           vat_json_array_add_uint (counter_array, packets);
4493         }
4494     }
4495   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4496     {
4497       msg = vat_json_array_add (msg_array);
4498       vat_json_init_object (msg);
4499       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4500                                        (u8 *) counter_type_to_str (i, 1));
4501       vat_json_object_add_int (msg, "is_combined", 1);
4502       counter_array = vat_json_object_add (msg, "data");
4503       vat_json_init_array (counter_array);
4504       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4505         {
4506           c = vam->combined_interface_counters[i][j];
4507           counter = vat_json_array_add (counter_array);
4508           vat_json_init_object (counter);
4509           vat_json_object_add_uint (counter, "packets", c.packets);
4510           vat_json_object_add_uint (counter, "bytes", c.bytes);
4511         }
4512     }
4513
4514   /* ip4 fib counters */
4515   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4516   vat_json_init_array (msg_array);
4517   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4518     {
4519       msg = vat_json_array_add (msg_array);
4520       vat_json_init_object (msg);
4521       vat_json_object_add_uint (msg, "vrf_id",
4522                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4523       counter_array = vat_json_object_add (msg, "c");
4524       vat_json_init_array (counter_array);
4525       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4526         {
4527           counter = vat_json_array_add (counter_array);
4528           vat_json_init_object (counter);
4529           c4 = &vam->ip4_fib_counters[i][j];
4530           vat_json_object_add_ip4 (counter, "address", c4->address);
4531           vat_json_object_add_uint (counter, "address_length",
4532                                     c4->address_length);
4533           vat_json_object_add_uint (counter, "packets", c4->packets);
4534           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4535         }
4536     }
4537
4538   /* ip6 fib counters */
4539   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4540   vat_json_init_array (msg_array);
4541   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4542     {
4543       msg = vat_json_array_add (msg_array);
4544       vat_json_init_object (msg);
4545       vat_json_object_add_uint (msg, "vrf_id",
4546                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4547       counter_array = vat_json_object_add (msg, "c");
4548       vat_json_init_array (counter_array);
4549       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4550         {
4551           counter = vat_json_array_add (counter_array);
4552           vat_json_init_object (counter);
4553           c6 = &vam->ip6_fib_counters[i][j];
4554           vat_json_object_add_ip6 (counter, "address", c6->address);
4555           vat_json_object_add_uint (counter, "address_length",
4556                                     c6->address_length);
4557           vat_json_object_add_uint (counter, "packets", c6->packets);
4558           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4559         }
4560     }
4561
4562   /* ip4 nbr counters */
4563   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4564   vat_json_init_array (msg_array);
4565   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4566     {
4567       msg = vat_json_array_add (msg_array);
4568       vat_json_init_object (msg);
4569       vat_json_object_add_uint (msg, "sw_if_index", i);
4570       counter_array = vat_json_object_add (msg, "c");
4571       vat_json_init_array (counter_array);
4572       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4573         {
4574           counter = vat_json_array_add (counter_array);
4575           vat_json_init_object (counter);
4576           n4 = &vam->ip4_nbr_counters[i][j];
4577           vat_json_object_add_ip4 (counter, "address", n4->address);
4578           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4579           vat_json_object_add_uint (counter, "packets", n4->packets);
4580           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4581         }
4582     }
4583
4584   /* ip6 nbr counters */
4585   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4586   vat_json_init_array (msg_array);
4587   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4588     {
4589       msg = vat_json_array_add (msg_array);
4590       vat_json_init_object (msg);
4591       vat_json_object_add_uint (msg, "sw_if_index", i);
4592       counter_array = vat_json_object_add (msg, "c");
4593       vat_json_init_array (counter_array);
4594       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4595         {
4596           counter = vat_json_array_add (counter_array);
4597           vat_json_init_object (counter);
4598           n6 = &vam->ip6_nbr_counters[i][j];
4599           vat_json_object_add_ip6 (counter, "address", n6->address);
4600           vat_json_object_add_uint (counter, "packets", n6->packets);
4601           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4602         }
4603     }
4604
4605   vat_json_print (vam->ofp, &node);
4606   vat_json_free (&node);
4607
4608   return 0;
4609 }
4610
4611 int
4612 exec (vat_main_t * vam)
4613 {
4614   api_main_t *am = &api_main;
4615   vl_api_cli_request_t *mp;
4616   f64 timeout;
4617   void *oldheap;
4618   u8 *cmd = 0;
4619   unformat_input_t *i = vam->input;
4620
4621   if (vec_len (i->buffer) == 0)
4622     return -1;
4623
4624   if (vam->exec_mode == 0 && unformat (i, "mode"))
4625     {
4626       vam->exec_mode = 1;
4627       return 0;
4628     }
4629   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4630     {
4631       vam->exec_mode = 0;
4632       return 0;
4633     }
4634
4635
4636   M (CLI_REQUEST, mp);
4637
4638   /*
4639    * Copy cmd into shared memory.
4640    * In order for the CLI command to work, it
4641    * must be a vector ending in \n, not a C-string ending
4642    * in \n\0.
4643    */
4644   pthread_mutex_lock (&am->vlib_rp->mutex);
4645   oldheap = svm_push_data_heap (am->vlib_rp);
4646
4647   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4648   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4649
4650   svm_pop_heap (oldheap);
4651   pthread_mutex_unlock (&am->vlib_rp->mutex);
4652
4653   mp->cmd_in_shmem = (u64) cmd;
4654   S (mp);
4655   timeout = vat_time_now (vam) + 10.0;
4656
4657   while (vat_time_now (vam) < timeout)
4658     {
4659       if (vam->result_ready == 1)
4660         {
4661           u8 *free_me;
4662           if (vam->shmem_result != NULL)
4663             print (vam->ofp, "%s", vam->shmem_result);
4664           pthread_mutex_lock (&am->vlib_rp->mutex);
4665           oldheap = svm_push_data_heap (am->vlib_rp);
4666
4667           free_me = (u8 *) vam->shmem_result;
4668           vec_free (free_me);
4669
4670           svm_pop_heap (oldheap);
4671           pthread_mutex_unlock (&am->vlib_rp->mutex);
4672           return 0;
4673         }
4674     }
4675   return -99;
4676 }
4677
4678 /*
4679  * Future replacement of exec() that passes CLI buffers directly in
4680  * the API messages instead of an additional shared memory area.
4681  */
4682 static int
4683 exec_inband (vat_main_t * vam)
4684 {
4685   vl_api_cli_inband_t *mp;
4686   unformat_input_t *i = vam->input;
4687   int ret;
4688
4689   if (vec_len (i->buffer) == 0)
4690     return -1;
4691
4692   if (vam->exec_mode == 0 && unformat (i, "mode"))
4693     {
4694       vam->exec_mode = 1;
4695       return 0;
4696     }
4697   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4698     {
4699       vam->exec_mode = 0;
4700       return 0;
4701     }
4702
4703   /*
4704    * In order for the CLI command to work, it
4705    * must be a vector ending in \n, not a C-string ending
4706    * in \n\0.
4707    */
4708   u32 len = vec_len (vam->input->buffer);
4709   M2 (CLI_INBAND, mp, len);
4710   clib_memcpy (mp->cmd, vam->input->buffer, len);
4711   mp->length = htonl (len);
4712
4713   S (mp);
4714   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4715   return ret;
4716 }
4717
4718 static int
4719 api_create_loopback (vat_main_t * vam)
4720 {
4721   unformat_input_t *i = vam->input;
4722   vl_api_create_loopback_t *mp;
4723   u8 mac_address[6];
4724   u8 mac_set = 0;
4725   int ret;
4726
4727   memset (mac_address, 0, sizeof (mac_address));
4728
4729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4730     {
4731       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4732         mac_set = 1;
4733       else
4734         break;
4735     }
4736
4737   /* Construct the API message */
4738   M (CREATE_LOOPBACK, mp);
4739   if (mac_set)
4740     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4741
4742   S (mp);
4743   W (ret);
4744   return ret;
4745 }
4746
4747 static int
4748 api_delete_loopback (vat_main_t * vam)
4749 {
4750   unformat_input_t *i = vam->input;
4751   vl_api_delete_loopback_t *mp;
4752   u32 sw_if_index = ~0;
4753   int ret;
4754
4755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4756     {
4757       if (unformat (i, "sw_if_index %d", &sw_if_index))
4758         ;
4759       else
4760         break;
4761     }
4762
4763   if (sw_if_index == ~0)
4764     {
4765       errmsg ("missing sw_if_index");
4766       return -99;
4767     }
4768
4769   /* Construct the API message */
4770   M (DELETE_LOOPBACK, mp);
4771   mp->sw_if_index = ntohl (sw_if_index);
4772
4773   S (mp);
4774   W (ret);
4775   return ret;
4776 }
4777
4778 static int
4779 api_want_stats (vat_main_t * vam)
4780 {
4781   unformat_input_t *i = vam->input;
4782   vl_api_want_stats_t *mp;
4783   int enable = -1;
4784   int ret;
4785
4786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4787     {
4788       if (unformat (i, "enable"))
4789         enable = 1;
4790       else if (unformat (i, "disable"))
4791         enable = 0;
4792       else
4793         break;
4794     }
4795
4796   if (enable == -1)
4797     {
4798       errmsg ("missing enable|disable");
4799       return -99;
4800     }
4801
4802   M (WANT_STATS, mp);
4803   mp->enable_disable = enable;
4804
4805   S (mp);
4806   W (ret);
4807   return ret;
4808 }
4809
4810 static int
4811 api_want_interface_events (vat_main_t * vam)
4812 {
4813   unformat_input_t *i = vam->input;
4814   vl_api_want_interface_events_t *mp;
4815   int enable = -1;
4816   int ret;
4817
4818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4819     {
4820       if (unformat (i, "enable"))
4821         enable = 1;
4822       else if (unformat (i, "disable"))
4823         enable = 0;
4824       else
4825         break;
4826     }
4827
4828   if (enable == -1)
4829     {
4830       errmsg ("missing enable|disable");
4831       return -99;
4832     }
4833
4834   M (WANT_INTERFACE_EVENTS, mp);
4835   mp->enable_disable = enable;
4836
4837   vam->interface_event_display = enable;
4838
4839   S (mp);
4840   W (ret);
4841   return ret;
4842 }
4843
4844
4845 /* Note: non-static, called once to set up the initial intfc table */
4846 int
4847 api_sw_interface_dump (vat_main_t * vam)
4848 {
4849   vl_api_sw_interface_dump_t *mp;
4850   vl_api_control_ping_t *mp_ping;
4851   hash_pair_t *p;
4852   name_sort_t *nses = 0, *ns;
4853   sw_interface_subif_t *sub = NULL;
4854   int ret;
4855
4856   /* Toss the old name table */
4857   /* *INDENT-OFF* */
4858   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4859   ({
4860     vec_add2 (nses, ns, 1);
4861     ns->name = (u8 *)(p->key);
4862     ns->value = (u32) p->value[0];
4863   }));
4864   /* *INDENT-ON* */
4865
4866   hash_free (vam->sw_if_index_by_interface_name);
4867
4868   vec_foreach (ns, nses) vec_free (ns->name);
4869
4870   vec_free (nses);
4871
4872   vec_foreach (sub, vam->sw_if_subif_table)
4873   {
4874     vec_free (sub->interface_name);
4875   }
4876   vec_free (vam->sw_if_subif_table);
4877
4878   /* recreate the interface name hash table */
4879   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4880
4881   /* Get list of ethernets */
4882   M (SW_INTERFACE_DUMP, mp);
4883   mp->name_filter_valid = 1;
4884   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4885   S (mp);
4886
4887   /* and local / loopback interfaces */
4888   M (SW_INTERFACE_DUMP, mp);
4889   mp->name_filter_valid = 1;
4890   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4891   S (mp);
4892
4893   /* and packet-generator interfaces */
4894   M (SW_INTERFACE_DUMP, mp);
4895   mp->name_filter_valid = 1;
4896   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4897   S (mp);
4898
4899   /* and vxlan-gpe tunnel interfaces */
4900   M (SW_INTERFACE_DUMP, mp);
4901   mp->name_filter_valid = 1;
4902   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4903            sizeof (mp->name_filter) - 1);
4904   S (mp);
4905
4906   /* and vxlan tunnel interfaces */
4907   M (SW_INTERFACE_DUMP, mp);
4908   mp->name_filter_valid = 1;
4909   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4910   S (mp);
4911
4912   /* and host (af_packet) interfaces */
4913   M (SW_INTERFACE_DUMP, mp);
4914   mp->name_filter_valid = 1;
4915   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4916   S (mp);
4917
4918   /* and l2tpv3 tunnel interfaces */
4919   M (SW_INTERFACE_DUMP, mp);
4920   mp->name_filter_valid = 1;
4921   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4922            sizeof (mp->name_filter) - 1);
4923   S (mp);
4924
4925   /* and GRE tunnel interfaces */
4926   M (SW_INTERFACE_DUMP, mp);
4927   mp->name_filter_valid = 1;
4928   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4929   S (mp);
4930
4931   /* and LISP-GPE interfaces */
4932   M (SW_INTERFACE_DUMP, mp);
4933   mp->name_filter_valid = 1;
4934   strncpy ((char *) mp->name_filter, "lisp_gpe",
4935            sizeof (mp->name_filter) - 1);
4936   S (mp);
4937
4938   /* and IPSEC tunnel interfaces */
4939   M (SW_INTERFACE_DUMP, mp);
4940   mp->name_filter_valid = 1;
4941   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4942   S (mp);
4943
4944   /* Use a control ping for synchronization */
4945   M (CONTROL_PING, mp_ping);
4946   S (mp_ping);
4947
4948   W (ret);
4949   return ret;
4950 }
4951
4952 static int
4953 api_sw_interface_set_flags (vat_main_t * vam)
4954 {
4955   unformat_input_t *i = vam->input;
4956   vl_api_sw_interface_set_flags_t *mp;
4957   u32 sw_if_index;
4958   u8 sw_if_index_set = 0;
4959   u8 admin_up = 0, link_up = 0;
4960   int ret;
4961
4962   /* Parse args required to build the message */
4963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4964     {
4965       if (unformat (i, "admin-up"))
4966         admin_up = 1;
4967       else if (unformat (i, "admin-down"))
4968         admin_up = 0;
4969       else if (unformat (i, "link-up"))
4970         link_up = 1;
4971       else if (unformat (i, "link-down"))
4972         link_up = 0;
4973       else
4974         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4975         sw_if_index_set = 1;
4976       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4977         sw_if_index_set = 1;
4978       else
4979         break;
4980     }
4981
4982   if (sw_if_index_set == 0)
4983     {
4984       errmsg ("missing interface name or sw_if_index");
4985       return -99;
4986     }
4987
4988   /* Construct the API message */
4989   M (SW_INTERFACE_SET_FLAGS, mp);
4990   mp->sw_if_index = ntohl (sw_if_index);
4991   mp->admin_up_down = admin_up;
4992   mp->link_up_down = link_up;
4993
4994   /* send it... */
4995   S (mp);
4996
4997   /* Wait for a reply, return the good/bad news... */
4998   W (ret);
4999   return ret;
5000 }
5001
5002 static int
5003 api_sw_interface_clear_stats (vat_main_t * vam)
5004 {
5005   unformat_input_t *i = vam->input;
5006   vl_api_sw_interface_clear_stats_t *mp;
5007   u32 sw_if_index;
5008   u8 sw_if_index_set = 0;
5009   int ret;
5010
5011   /* Parse args required to build the message */
5012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5013     {
5014       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5015         sw_if_index_set = 1;
5016       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5017         sw_if_index_set = 1;
5018       else
5019         break;
5020     }
5021
5022   /* Construct the API message */
5023   M (SW_INTERFACE_CLEAR_STATS, mp);
5024
5025   if (sw_if_index_set == 1)
5026     mp->sw_if_index = ntohl (sw_if_index);
5027   else
5028     mp->sw_if_index = ~0;
5029
5030   /* send it... */
5031   S (mp);
5032
5033   /* Wait for a reply, return the good/bad news... */
5034   W (ret);
5035   return ret;
5036 }
5037
5038 static int
5039 api_sw_interface_add_del_address (vat_main_t * vam)
5040 {
5041   unformat_input_t *i = vam->input;
5042   vl_api_sw_interface_add_del_address_t *mp;
5043   u32 sw_if_index;
5044   u8 sw_if_index_set = 0;
5045   u8 is_add = 1, del_all = 0;
5046   u32 address_length = 0;
5047   u8 v4_address_set = 0;
5048   u8 v6_address_set = 0;
5049   ip4_address_t v4address;
5050   ip6_address_t v6address;
5051   int ret;
5052
5053   /* Parse args required to build the message */
5054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5055     {
5056       if (unformat (i, "del-all"))
5057         del_all = 1;
5058       else if (unformat (i, "del"))
5059         is_add = 0;
5060       else
5061         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5062         sw_if_index_set = 1;
5063       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5064         sw_if_index_set = 1;
5065       else if (unformat (i, "%U/%d",
5066                          unformat_ip4_address, &v4address, &address_length))
5067         v4_address_set = 1;
5068       else if (unformat (i, "%U/%d",
5069                          unformat_ip6_address, &v6address, &address_length))
5070         v6_address_set = 1;
5071       else
5072         break;
5073     }
5074
5075   if (sw_if_index_set == 0)
5076     {
5077       errmsg ("missing interface name or sw_if_index");
5078       return -99;
5079     }
5080   if (v4_address_set && v6_address_set)
5081     {
5082       errmsg ("both v4 and v6 addresses set");
5083       return -99;
5084     }
5085   if (!v4_address_set && !v6_address_set && !del_all)
5086     {
5087       errmsg ("no addresses set");
5088       return -99;
5089     }
5090
5091   /* Construct the API message */
5092   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5093
5094   mp->sw_if_index = ntohl (sw_if_index);
5095   mp->is_add = is_add;
5096   mp->del_all = del_all;
5097   if (v6_address_set)
5098     {
5099       mp->is_ipv6 = 1;
5100       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5101     }
5102   else
5103     {
5104       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5105     }
5106   mp->address_length = address_length;
5107
5108   /* send it... */
5109   S (mp);
5110
5111   /* Wait for a reply, return good/bad news  */
5112   W (ret);
5113   return ret;
5114 }
5115
5116 static int
5117 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5118 {
5119   unformat_input_t *i = vam->input;
5120   vl_api_sw_interface_set_mpls_enable_t *mp;
5121   u32 sw_if_index;
5122   u8 sw_if_index_set = 0;
5123   u8 enable = 1;
5124   int ret;
5125
5126   /* Parse args required to build the message */
5127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5128     {
5129       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5130         sw_if_index_set = 1;
5131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5132         sw_if_index_set = 1;
5133       else if (unformat (i, "disable"))
5134         enable = 0;
5135       else if (unformat (i, "dis"))
5136         enable = 0;
5137       else
5138         break;
5139     }
5140
5141   if (sw_if_index_set == 0)
5142     {
5143       errmsg ("missing interface name or sw_if_index");
5144       return -99;
5145     }
5146
5147   /* Construct the API message */
5148   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5149
5150   mp->sw_if_index = ntohl (sw_if_index);
5151   mp->enable = enable;
5152
5153   /* send it... */
5154   S (mp);
5155
5156   /* Wait for a reply... */
5157   W (ret);
5158   return ret;
5159 }
5160
5161 static int
5162 api_sw_interface_set_table (vat_main_t * vam)
5163 {
5164   unformat_input_t *i = vam->input;
5165   vl_api_sw_interface_set_table_t *mp;
5166   u32 sw_if_index, vrf_id = 0;
5167   u8 sw_if_index_set = 0;
5168   u8 is_ipv6 = 0;
5169   int ret;
5170
5171   /* Parse args required to build the message */
5172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5173     {
5174       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5175         sw_if_index_set = 1;
5176       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5177         sw_if_index_set = 1;
5178       else if (unformat (i, "vrf %d", &vrf_id))
5179         ;
5180       else if (unformat (i, "ipv6"))
5181         is_ipv6 = 1;
5182       else
5183         break;
5184     }
5185
5186   if (sw_if_index_set == 0)
5187     {
5188       errmsg ("missing interface name or sw_if_index");
5189       return -99;
5190     }
5191
5192   /* Construct the API message */
5193   M (SW_INTERFACE_SET_TABLE, mp);
5194
5195   mp->sw_if_index = ntohl (sw_if_index);
5196   mp->is_ipv6 = is_ipv6;
5197   mp->vrf_id = ntohl (vrf_id);
5198
5199   /* send it... */
5200   S (mp);
5201
5202   /* Wait for a reply... */
5203   W (ret);
5204   return ret;
5205 }
5206
5207 static void vl_api_sw_interface_get_table_reply_t_handler
5208   (vl_api_sw_interface_get_table_reply_t * mp)
5209 {
5210   vat_main_t *vam = &vat_main;
5211
5212   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5213
5214   vam->retval = ntohl (mp->retval);
5215   vam->result_ready = 1;
5216
5217 }
5218
5219 static void vl_api_sw_interface_get_table_reply_t_handler_json
5220   (vl_api_sw_interface_get_table_reply_t * mp)
5221 {
5222   vat_main_t *vam = &vat_main;
5223   vat_json_node_t node;
5224
5225   vat_json_init_object (&node);
5226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5227   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5228
5229   vat_json_print (vam->ofp, &node);
5230   vat_json_free (&node);
5231
5232   vam->retval = ntohl (mp->retval);
5233   vam->result_ready = 1;
5234 }
5235
5236 static int
5237 api_sw_interface_get_table (vat_main_t * vam)
5238 {
5239   unformat_input_t *i = vam->input;
5240   vl_api_sw_interface_get_table_t *mp;
5241   u32 sw_if_index;
5242   u8 sw_if_index_set = 0;
5243   u8 is_ipv6 = 0;
5244   int ret;
5245
5246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5247     {
5248       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5249         sw_if_index_set = 1;
5250       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5251         sw_if_index_set = 1;
5252       else if (unformat (i, "ipv6"))
5253         is_ipv6 = 1;
5254       else
5255         break;
5256     }
5257
5258   if (sw_if_index_set == 0)
5259     {
5260       errmsg ("missing interface name or sw_if_index");
5261       return -99;
5262     }
5263
5264   M (SW_INTERFACE_GET_TABLE, mp);
5265   mp->sw_if_index = htonl (sw_if_index);
5266   mp->is_ipv6 = is_ipv6;
5267
5268   S (mp);
5269   W (ret);
5270   return ret;
5271 }
5272
5273 static int
5274 api_sw_interface_set_vpath (vat_main_t * vam)
5275 {
5276   unformat_input_t *i = vam->input;
5277   vl_api_sw_interface_set_vpath_t *mp;
5278   u32 sw_if_index = 0;
5279   u8 sw_if_index_set = 0;
5280   u8 is_enable = 0;
5281   int ret;
5282
5283   /* Parse args required to build the message */
5284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5285     {
5286       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5287         sw_if_index_set = 1;
5288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5289         sw_if_index_set = 1;
5290       else if (unformat (i, "enable"))
5291         is_enable = 1;
5292       else if (unformat (i, "disable"))
5293         is_enable = 0;
5294       else
5295         break;
5296     }
5297
5298   if (sw_if_index_set == 0)
5299     {
5300       errmsg ("missing interface name or sw_if_index");
5301       return -99;
5302     }
5303
5304   /* Construct the API message */
5305   M (SW_INTERFACE_SET_VPATH, mp);
5306
5307   mp->sw_if_index = ntohl (sw_if_index);
5308   mp->enable = is_enable;
5309
5310   /* send it... */
5311   S (mp);
5312
5313   /* Wait for a reply... */
5314   W (ret);
5315   return ret;
5316 }
5317
5318 static int
5319 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5320 {
5321   unformat_input_t *i = vam->input;
5322   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5323   u32 sw_if_index = 0;
5324   u8 sw_if_index_set = 0;
5325   u8 is_enable = 1;
5326   u8 is_ipv6 = 0;
5327   int ret;
5328
5329   /* Parse args required to build the message */
5330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5331     {
5332       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5333         sw_if_index_set = 1;
5334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5335         sw_if_index_set = 1;
5336       else if (unformat (i, "enable"))
5337         is_enable = 1;
5338       else if (unformat (i, "disable"))
5339         is_enable = 0;
5340       else if (unformat (i, "ip4"))
5341         is_ipv6 = 0;
5342       else if (unformat (i, "ip6"))
5343         is_ipv6 = 1;
5344       else
5345         break;
5346     }
5347
5348   if (sw_if_index_set == 0)
5349     {
5350       errmsg ("missing interface name or sw_if_index");
5351       return -99;
5352     }
5353
5354   /* Construct the API message */
5355   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5356
5357   mp->sw_if_index = ntohl (sw_if_index);
5358   mp->enable = is_enable;
5359   mp->is_ipv6 = is_ipv6;
5360
5361   /* send it... */
5362   S (mp);
5363
5364   /* Wait for a reply... */
5365   W (ret);
5366   return ret;
5367 }
5368
5369 static int
5370 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5371 {
5372   unformat_input_t *i = vam->input;
5373   vl_api_sw_interface_set_l2_xconnect_t *mp;
5374   u32 rx_sw_if_index;
5375   u8 rx_sw_if_index_set = 0;
5376   u32 tx_sw_if_index;
5377   u8 tx_sw_if_index_set = 0;
5378   u8 enable = 1;
5379   int ret;
5380
5381   /* Parse args required to build the message */
5382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5383     {
5384       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5385         rx_sw_if_index_set = 1;
5386       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5387         tx_sw_if_index_set = 1;
5388       else if (unformat (i, "rx"))
5389         {
5390           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5391             {
5392               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5393                             &rx_sw_if_index))
5394                 rx_sw_if_index_set = 1;
5395             }
5396           else
5397             break;
5398         }
5399       else if (unformat (i, "tx"))
5400         {
5401           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5402             {
5403               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5404                             &tx_sw_if_index))
5405                 tx_sw_if_index_set = 1;
5406             }
5407           else
5408             break;
5409         }
5410       else if (unformat (i, "enable"))
5411         enable = 1;
5412       else if (unformat (i, "disable"))
5413         enable = 0;
5414       else
5415         break;
5416     }
5417
5418   if (rx_sw_if_index_set == 0)
5419     {
5420       errmsg ("missing rx interface name or rx_sw_if_index");
5421       return -99;
5422     }
5423
5424   if (enable && (tx_sw_if_index_set == 0))
5425     {
5426       errmsg ("missing tx interface name or tx_sw_if_index");
5427       return -99;
5428     }
5429
5430   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5431
5432   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5433   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5434   mp->enable = enable;
5435
5436   S (mp);
5437   W (ret);
5438   return ret;
5439 }
5440
5441 static int
5442 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5443 {
5444   unformat_input_t *i = vam->input;
5445   vl_api_sw_interface_set_l2_bridge_t *mp;
5446   u32 rx_sw_if_index;
5447   u8 rx_sw_if_index_set = 0;
5448   u32 bd_id;
5449   u8 bd_id_set = 0;
5450   u8 bvi = 0;
5451   u32 shg = 0;
5452   u8 enable = 1;
5453   int ret;
5454
5455   /* Parse args required to build the message */
5456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5457     {
5458       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5459         rx_sw_if_index_set = 1;
5460       else if (unformat (i, "bd_id %d", &bd_id))
5461         bd_id_set = 1;
5462       else
5463         if (unformat
5464             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5465         rx_sw_if_index_set = 1;
5466       else if (unformat (i, "shg %d", &shg))
5467         ;
5468       else if (unformat (i, "bvi"))
5469         bvi = 1;
5470       else if (unformat (i, "enable"))
5471         enable = 1;
5472       else if (unformat (i, "disable"))
5473         enable = 0;
5474       else
5475         break;
5476     }
5477
5478   if (rx_sw_if_index_set == 0)
5479     {
5480       errmsg ("missing rx interface name or sw_if_index");
5481       return -99;
5482     }
5483
5484   if (enable && (bd_id_set == 0))
5485     {
5486       errmsg ("missing bridge domain");
5487       return -99;
5488     }
5489
5490   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5491
5492   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5493   mp->bd_id = ntohl (bd_id);
5494   mp->shg = (u8) shg;
5495   mp->bvi = bvi;
5496   mp->enable = enable;
5497
5498   S (mp);
5499   W (ret);
5500   return ret;
5501 }
5502
5503 static int
5504 api_bridge_domain_dump (vat_main_t * vam)
5505 {
5506   unformat_input_t *i = vam->input;
5507   vl_api_bridge_domain_dump_t *mp;
5508   vl_api_control_ping_t *mp_ping;
5509   u32 bd_id = ~0;
5510   int ret;
5511
5512   /* Parse args required to build the message */
5513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5514     {
5515       if (unformat (i, "bd_id %d", &bd_id))
5516         ;
5517       else
5518         break;
5519     }
5520
5521   M (BRIDGE_DOMAIN_DUMP, mp);
5522   mp->bd_id = ntohl (bd_id);
5523   S (mp);
5524
5525   /* Use a control ping for synchronization */
5526   M (CONTROL_PING, mp_ping);
5527   S (mp_ping);
5528
5529   W (ret);
5530   return ret;
5531 }
5532
5533 static int
5534 api_bridge_domain_add_del (vat_main_t * vam)
5535 {
5536   unformat_input_t *i = vam->input;
5537   vl_api_bridge_domain_add_del_t *mp;
5538   u32 bd_id = ~0;
5539   u8 is_add = 1;
5540   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5541   u32 mac_age = 0;
5542   int ret;
5543
5544   /* Parse args required to build the message */
5545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5546     {
5547       if (unformat (i, "bd_id %d", &bd_id))
5548         ;
5549       else if (unformat (i, "flood %d", &flood))
5550         ;
5551       else if (unformat (i, "uu-flood %d", &uu_flood))
5552         ;
5553       else if (unformat (i, "forward %d", &forward))
5554         ;
5555       else if (unformat (i, "learn %d", &learn))
5556         ;
5557       else if (unformat (i, "arp-term %d", &arp_term))
5558         ;
5559       else if (unformat (i, "mac-age %d", &mac_age))
5560         ;
5561       else if (unformat (i, "del"))
5562         {
5563           is_add = 0;
5564           flood = uu_flood = forward = learn = 0;
5565         }
5566       else
5567         break;
5568     }
5569
5570   if (bd_id == ~0)
5571     {
5572       errmsg ("missing bridge domain");
5573       return -99;
5574     }
5575
5576   if (mac_age > 255)
5577     {
5578       errmsg ("mac age must be less than 256 ");
5579       return -99;
5580     }
5581
5582   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5583
5584   mp->bd_id = ntohl (bd_id);
5585   mp->flood = flood;
5586   mp->uu_flood = uu_flood;
5587   mp->forward = forward;
5588   mp->learn = learn;
5589   mp->arp_term = arp_term;
5590   mp->is_add = is_add;
5591   mp->mac_age = (u8) mac_age;
5592
5593   S (mp);
5594   W (ret);
5595   return ret;
5596 }
5597
5598 static int
5599 api_l2fib_add_del (vat_main_t * vam)
5600 {
5601   unformat_input_t *i = vam->input;
5602   vl_api_l2fib_add_del_t *mp;
5603   f64 timeout;
5604   u64 mac = 0;
5605   u8 mac_set = 0;
5606   u32 bd_id;
5607   u8 bd_id_set = 0;
5608   u32 sw_if_index = ~0;
5609   u8 sw_if_index_set = 0;
5610   u8 is_add = 1;
5611   u8 static_mac = 0;
5612   u8 filter_mac = 0;
5613   u8 bvi_mac = 0;
5614   int count = 1;
5615   f64 before = 0;
5616   int j;
5617
5618   /* Parse args required to build the message */
5619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5620     {
5621       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5622         mac_set = 1;
5623       else if (unformat (i, "bd_id %d", &bd_id))
5624         bd_id_set = 1;
5625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5626         sw_if_index_set = 1;
5627       else if (unformat (i, "sw_if"))
5628         {
5629           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5630             {
5631               if (unformat
5632                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5633                 sw_if_index_set = 1;
5634             }
5635           else
5636             break;
5637         }
5638       else if (unformat (i, "static"))
5639         static_mac = 1;
5640       else if (unformat (i, "filter"))
5641         {
5642           filter_mac = 1;
5643           static_mac = 1;
5644         }
5645       else if (unformat (i, "bvi"))
5646         {
5647           bvi_mac = 1;
5648           static_mac = 1;
5649         }
5650       else if (unformat (i, "del"))
5651         is_add = 0;
5652       else if (unformat (i, "count %d", &count))
5653         ;
5654       else
5655         break;
5656     }
5657
5658   if (mac_set == 0)
5659     {
5660       errmsg ("missing mac address");
5661       return -99;
5662     }
5663
5664   if (bd_id_set == 0)
5665     {
5666       errmsg ("missing bridge domain");
5667       return -99;
5668     }
5669
5670   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5671     {
5672       errmsg ("missing interface name or sw_if_index");
5673       return -99;
5674     }
5675
5676   if (count > 1)
5677     {
5678       /* Turn on async mode */
5679       vam->async_mode = 1;
5680       vam->async_errors = 0;
5681       before = vat_time_now (vam);
5682     }
5683
5684   for (j = 0; j < count; j++)
5685     {
5686       M (L2FIB_ADD_DEL, mp);
5687
5688       mp->mac = mac;
5689       mp->bd_id = ntohl (bd_id);
5690       mp->is_add = is_add;
5691
5692       if (is_add)
5693         {
5694           mp->sw_if_index = ntohl (sw_if_index);
5695           mp->static_mac = static_mac;
5696           mp->filter_mac = filter_mac;
5697           mp->bvi_mac = bvi_mac;
5698         }
5699       increment_mac_address (&mac);
5700       /* send it... */
5701       S (mp);
5702     }
5703
5704   if (count > 1)
5705     {
5706       vl_api_control_ping_t *mp_ping;
5707       f64 after;
5708
5709       /* Shut off async mode */
5710       vam->async_mode = 0;
5711
5712       M (CONTROL_PING, mp_ping);
5713       S (mp_ping);
5714
5715       timeout = vat_time_now (vam) + 1.0;
5716       while (vat_time_now (vam) < timeout)
5717         if (vam->result_ready == 1)
5718           goto out;
5719       vam->retval = -99;
5720
5721     out:
5722       if (vam->retval == -99)
5723         errmsg ("timeout");
5724
5725       if (vam->async_errors > 0)
5726         {
5727           errmsg ("%d asynchronous errors", vam->async_errors);
5728           vam->retval = -98;
5729         }
5730       vam->async_errors = 0;
5731       after = vat_time_now (vam);
5732
5733       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5734              count, after - before, count / (after - before));
5735     }
5736   else
5737     {
5738       int ret;
5739
5740       /* Wait for a reply... */
5741       W (ret);
5742       return ret;
5743     }
5744   /* Return the good/bad news */
5745   return (vam->retval);
5746 }
5747
5748 static int
5749 api_l2_flags (vat_main_t * vam)
5750 {
5751   unformat_input_t *i = vam->input;
5752   vl_api_l2_flags_t *mp;
5753   u32 sw_if_index;
5754   u32 feature_bitmap = 0;
5755   u8 sw_if_index_set = 0;
5756   int ret;
5757
5758   /* Parse args required to build the message */
5759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5760     {
5761       if (unformat (i, "sw_if_index %d", &sw_if_index))
5762         sw_if_index_set = 1;
5763       else if (unformat (i, "sw_if"))
5764         {
5765           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5766             {
5767               if (unformat
5768                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5769                 sw_if_index_set = 1;
5770             }
5771           else
5772             break;
5773         }
5774       else if (unformat (i, "learn"))
5775         feature_bitmap |= L2INPUT_FEAT_LEARN;
5776       else if (unformat (i, "forward"))
5777         feature_bitmap |= L2INPUT_FEAT_FWD;
5778       else if (unformat (i, "flood"))
5779         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5780       else if (unformat (i, "uu-flood"))
5781         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5782       else
5783         break;
5784     }
5785
5786   if (sw_if_index_set == 0)
5787     {
5788       errmsg ("missing interface name or sw_if_index");
5789       return -99;
5790     }
5791
5792   M (L2_FLAGS, mp);
5793
5794   mp->sw_if_index = ntohl (sw_if_index);
5795   mp->feature_bitmap = ntohl (feature_bitmap);
5796
5797   S (mp);
5798   W (ret);
5799   return ret;
5800 }
5801
5802 static int
5803 api_bridge_flags (vat_main_t * vam)
5804 {
5805   unformat_input_t *i = vam->input;
5806   vl_api_bridge_flags_t *mp;
5807   u32 bd_id;
5808   u8 bd_id_set = 0;
5809   u8 is_set = 1;
5810   u32 flags = 0;
5811   int ret;
5812
5813   /* Parse args required to build the message */
5814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5815     {
5816       if (unformat (i, "bd_id %d", &bd_id))
5817         bd_id_set = 1;
5818       else if (unformat (i, "learn"))
5819         flags |= L2_LEARN;
5820       else if (unformat (i, "forward"))
5821         flags |= L2_FWD;
5822       else if (unformat (i, "flood"))
5823         flags |= L2_FLOOD;
5824       else if (unformat (i, "uu-flood"))
5825         flags |= L2_UU_FLOOD;
5826       else if (unformat (i, "arp-term"))
5827         flags |= L2_ARP_TERM;
5828       else if (unformat (i, "off"))
5829         is_set = 0;
5830       else if (unformat (i, "disable"))
5831         is_set = 0;
5832       else
5833         break;
5834     }
5835
5836   if (bd_id_set == 0)
5837     {
5838       errmsg ("missing bridge domain");
5839       return -99;
5840     }
5841
5842   M (BRIDGE_FLAGS, mp);
5843
5844   mp->bd_id = ntohl (bd_id);
5845   mp->feature_bitmap = ntohl (flags);
5846   mp->is_set = is_set;
5847
5848   S (mp);
5849   W (ret);
5850   return ret;
5851 }
5852
5853 static int
5854 api_bd_ip_mac_add_del (vat_main_t * vam)
5855 {
5856   unformat_input_t *i = vam->input;
5857   vl_api_bd_ip_mac_add_del_t *mp;
5858   u32 bd_id;
5859   u8 is_ipv6 = 0;
5860   u8 is_add = 1;
5861   u8 bd_id_set = 0;
5862   u8 ip_set = 0;
5863   u8 mac_set = 0;
5864   ip4_address_t v4addr;
5865   ip6_address_t v6addr;
5866   u8 macaddr[6];
5867   int ret;
5868
5869
5870   /* Parse args required to build the message */
5871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5872     {
5873       if (unformat (i, "bd_id %d", &bd_id))
5874         {
5875           bd_id_set++;
5876         }
5877       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5878         {
5879           ip_set++;
5880         }
5881       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5882         {
5883           ip_set++;
5884           is_ipv6++;
5885         }
5886       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5887         {
5888           mac_set++;
5889         }
5890       else if (unformat (i, "del"))
5891         is_add = 0;
5892       else
5893         break;
5894     }
5895
5896   if (bd_id_set == 0)
5897     {
5898       errmsg ("missing bridge domain");
5899       return -99;
5900     }
5901   else if (ip_set == 0)
5902     {
5903       errmsg ("missing IP address");
5904       return -99;
5905     }
5906   else if (mac_set == 0)
5907     {
5908       errmsg ("missing MAC address");
5909       return -99;
5910     }
5911
5912   M (BD_IP_MAC_ADD_DEL, mp);
5913
5914   mp->bd_id = ntohl (bd_id);
5915   mp->is_ipv6 = is_ipv6;
5916   mp->is_add = is_add;
5917   if (is_ipv6)
5918     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5919   else
5920     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5921   clib_memcpy (mp->mac_address, macaddr, 6);
5922   S (mp);
5923   W (ret);
5924   return ret;
5925 }
5926
5927 static int
5928 api_tap_connect (vat_main_t * vam)
5929 {
5930   unformat_input_t *i = vam->input;
5931   vl_api_tap_connect_t *mp;
5932   u8 mac_address[6];
5933   u8 random_mac = 1;
5934   u8 name_set = 0;
5935   u8 *tap_name;
5936   u8 *tag = 0;
5937   ip4_address_t ip4_address;
5938   u32 ip4_mask_width;
5939   int ip4_address_set = 0;
5940   ip6_address_t ip6_address;
5941   u32 ip6_mask_width;
5942   int ip6_address_set = 0;
5943   int ret;
5944
5945   memset (mac_address, 0, sizeof (mac_address));
5946
5947   /* Parse args required to build the message */
5948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5949     {
5950       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5951         {
5952           random_mac = 0;
5953         }
5954       else if (unformat (i, "random-mac"))
5955         random_mac = 1;
5956       else if (unformat (i, "tapname %s", &tap_name))
5957         name_set = 1;
5958       else if (unformat (i, "tag %s", &tag))
5959         ;
5960       else if (unformat (i, "address %U/%d",
5961                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
5962         ip4_address_set = 1;
5963       else if (unformat (i, "address %U/%d",
5964                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
5965         ip6_address_set = 1;
5966       else
5967         break;
5968     }
5969
5970   if (name_set == 0)
5971     {
5972       errmsg ("missing tap name");
5973       return -99;
5974     }
5975   if (vec_len (tap_name) > 63)
5976     {
5977       errmsg ("tap name too long");
5978       return -99;
5979     }
5980   vec_add1 (tap_name, 0);
5981
5982   if (vec_len (tag) > 63)
5983     {
5984       errmsg ("tag too long");
5985       return -99;
5986     }
5987
5988   /* Construct the API message */
5989   M (TAP_CONNECT, mp);
5990
5991   mp->use_random_mac = random_mac;
5992   clib_memcpy (mp->mac_address, mac_address, 6);
5993   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5994   if (tag)
5995     clib_memcpy (mp->tag, tag, vec_len (tag));
5996
5997   if (ip4_address_set)
5998     {
5999       mp->ip4_address_set = 1;
6000       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6001       mp->ip4_mask_width = ip4_mask_width;
6002     }
6003   if (ip6_address_set)
6004     {
6005       mp->ip6_address_set = 1;
6006       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6007       mp->ip6_mask_width = ip6_mask_width;
6008     }
6009
6010   vec_free (tap_name);
6011   vec_free (tag);
6012
6013   /* send it... */
6014   S (mp);
6015
6016   /* Wait for a reply... */
6017   W (ret);
6018   return ret;
6019 }
6020
6021 static int
6022 api_tap_modify (vat_main_t * vam)
6023 {
6024   unformat_input_t *i = vam->input;
6025   vl_api_tap_modify_t *mp;
6026   u8 mac_address[6];
6027   u8 random_mac = 1;
6028   u8 name_set = 0;
6029   u8 *tap_name;
6030   u32 sw_if_index = ~0;
6031   u8 sw_if_index_set = 0;
6032   int ret;
6033
6034   memset (mac_address, 0, sizeof (mac_address));
6035
6036   /* Parse args required to build the message */
6037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6038     {
6039       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6040         sw_if_index_set = 1;
6041       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6042         sw_if_index_set = 1;
6043       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6044         {
6045           random_mac = 0;
6046         }
6047       else if (unformat (i, "random-mac"))
6048         random_mac = 1;
6049       else if (unformat (i, "tapname %s", &tap_name))
6050         name_set = 1;
6051       else
6052         break;
6053     }
6054
6055   if (sw_if_index_set == 0)
6056     {
6057       errmsg ("missing vpp interface name");
6058       return -99;
6059     }
6060   if (name_set == 0)
6061     {
6062       errmsg ("missing tap name");
6063       return -99;
6064     }
6065   if (vec_len (tap_name) > 63)
6066     {
6067       errmsg ("tap name too long");
6068     }
6069   vec_add1 (tap_name, 0);
6070
6071   /* Construct the API message */
6072   M (TAP_MODIFY, mp);
6073
6074   mp->use_random_mac = random_mac;
6075   mp->sw_if_index = ntohl (sw_if_index);
6076   clib_memcpy (mp->mac_address, mac_address, 6);
6077   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6078   vec_free (tap_name);
6079
6080   /* send it... */
6081   S (mp);
6082
6083   /* Wait for a reply... */
6084   W (ret);
6085   return ret;
6086 }
6087
6088 static int
6089 api_tap_delete (vat_main_t * vam)
6090 {
6091   unformat_input_t *i = vam->input;
6092   vl_api_tap_delete_t *mp;
6093   u32 sw_if_index = ~0;
6094   u8 sw_if_index_set = 0;
6095   int ret;
6096
6097   /* Parse args required to build the message */
6098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6099     {
6100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6101         sw_if_index_set = 1;
6102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6103         sw_if_index_set = 1;
6104       else
6105         break;
6106     }
6107
6108   if (sw_if_index_set == 0)
6109     {
6110       errmsg ("missing vpp interface name");
6111       return -99;
6112     }
6113
6114   /* Construct the API message */
6115   M (TAP_DELETE, mp);
6116
6117   mp->sw_if_index = ntohl (sw_if_index);
6118
6119   /* send it... */
6120   S (mp);
6121
6122   /* Wait for a reply... */
6123   W (ret);
6124   return ret;
6125 }
6126
6127 static int
6128 api_ip_add_del_route (vat_main_t * vam)
6129 {
6130   unformat_input_t *i = vam->input;
6131   vl_api_ip_add_del_route_t *mp;
6132   u32 sw_if_index = ~0, vrf_id = 0;
6133   u8 is_ipv6 = 0;
6134   u8 is_local = 0, is_drop = 0;
6135   u8 is_unreach = 0, is_prohibit = 0;
6136   u8 create_vrf_if_needed = 0;
6137   u8 is_add = 1;
6138   u32 next_hop_weight = 1;
6139   u8 not_last = 0;
6140   u8 is_multipath = 0;
6141   u8 address_set = 0;
6142   u8 address_length_set = 0;
6143   u32 next_hop_table_id = 0;
6144   u32 resolve_attempts = 0;
6145   u32 dst_address_length = 0;
6146   u8 next_hop_set = 0;
6147   ip4_address_t v4_dst_address, v4_next_hop_address;
6148   ip6_address_t v6_dst_address, v6_next_hop_address;
6149   int count = 1;
6150   int j;
6151   f64 before = 0;
6152   u32 random_add_del = 0;
6153   u32 *random_vector = 0;
6154   uword *random_hash;
6155   u32 random_seed = 0xdeaddabe;
6156   u32 classify_table_index = ~0;
6157   u8 is_classify = 0;
6158   u8 resolve_host = 0, resolve_attached = 0;
6159   mpls_label_t *next_hop_out_label_stack = NULL;
6160   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6161   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6162
6163   /* Parse args required to build the message */
6164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6165     {
6166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6167         ;
6168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6169         ;
6170       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6171         {
6172           address_set = 1;
6173           is_ipv6 = 0;
6174         }
6175       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6176         {
6177           address_set = 1;
6178           is_ipv6 = 1;
6179         }
6180       else if (unformat (i, "/%d", &dst_address_length))
6181         {
6182           address_length_set = 1;
6183         }
6184
6185       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6186                                          &v4_next_hop_address))
6187         {
6188           next_hop_set = 1;
6189         }
6190       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6191                                          &v6_next_hop_address))
6192         {
6193           next_hop_set = 1;
6194         }
6195       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6196         ;
6197       else if (unformat (i, "weight %d", &next_hop_weight))
6198         ;
6199       else if (unformat (i, "drop"))
6200         {
6201           is_drop = 1;
6202         }
6203       else if (unformat (i, "null-send-unreach"))
6204         {
6205           is_unreach = 1;
6206         }
6207       else if (unformat (i, "null-send-prohibit"))
6208         {
6209           is_prohibit = 1;
6210         }
6211       else if (unformat (i, "local"))
6212         {
6213           is_local = 1;
6214         }
6215       else if (unformat (i, "classify %d", &classify_table_index))
6216         {
6217           is_classify = 1;
6218         }
6219       else if (unformat (i, "del"))
6220         is_add = 0;
6221       else if (unformat (i, "add"))
6222         is_add = 1;
6223       else if (unformat (i, "not-last"))
6224         not_last = 1;
6225       else if (unformat (i, "resolve-via-host"))
6226         resolve_host = 1;
6227       else if (unformat (i, "resolve-via-attached"))
6228         resolve_attached = 1;
6229       else if (unformat (i, "multipath"))
6230         is_multipath = 1;
6231       else if (unformat (i, "vrf %d", &vrf_id))
6232         ;
6233       else if (unformat (i, "create-vrf"))
6234         create_vrf_if_needed = 1;
6235       else if (unformat (i, "count %d", &count))
6236         ;
6237       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6238         ;
6239       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6240         ;
6241       else if (unformat (i, "out-label %d", &next_hop_out_label))
6242         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6243       else if (unformat (i, "via-label %d", &next_hop_via_label))
6244         ;
6245       else if (unformat (i, "random"))
6246         random_add_del = 1;
6247       else if (unformat (i, "seed %d", &random_seed))
6248         ;
6249       else
6250         {
6251           clib_warning ("parse error '%U'", format_unformat_error, i);
6252           return -99;
6253         }
6254     }
6255
6256   if (!next_hop_set && !is_drop && !is_local &&
6257       !is_classify && !is_unreach && !is_prohibit &&
6258       MPLS_LABEL_INVALID == next_hop_via_label)
6259     {
6260       errmsg
6261         ("next hop / local / drop / unreach / prohibit / classify not set");
6262       return -99;
6263     }
6264
6265   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6266     {
6267       errmsg ("next hop and next-hop via label set");
6268       return -99;
6269     }
6270   if (address_set == 0)
6271     {
6272       errmsg ("missing addresses");
6273       return -99;
6274     }
6275
6276   if (address_length_set == 0)
6277     {
6278       errmsg ("missing address length");
6279       return -99;
6280     }
6281
6282   /* Generate a pile of unique, random routes */
6283   if (random_add_del)
6284     {
6285       u32 this_random_address;
6286       random_hash = hash_create (count, sizeof (uword));
6287
6288       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6289       for (j = 0; j <= count; j++)
6290         {
6291           do
6292             {
6293               this_random_address = random_u32 (&random_seed);
6294               this_random_address =
6295                 clib_host_to_net_u32 (this_random_address);
6296             }
6297           while (hash_get (random_hash, this_random_address));
6298           vec_add1 (random_vector, this_random_address);
6299           hash_set (random_hash, this_random_address, 1);
6300         }
6301       hash_free (random_hash);
6302       v4_dst_address.as_u32 = random_vector[0];
6303     }
6304
6305   if (count > 1)
6306     {
6307       /* Turn on async mode */
6308       vam->async_mode = 1;
6309       vam->async_errors = 0;
6310       before = vat_time_now (vam);
6311     }
6312
6313   for (j = 0; j < count; j++)
6314     {
6315       /* Construct the API message */
6316       M2 (IP_ADD_DEL_ROUTE, mp,
6317           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6318
6319       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6320       mp->table_id = ntohl (vrf_id);
6321       mp->create_vrf_if_needed = create_vrf_if_needed;
6322
6323       mp->is_add = is_add;
6324       mp->is_drop = is_drop;
6325       mp->is_unreach = is_unreach;
6326       mp->is_prohibit = is_prohibit;
6327       mp->is_ipv6 = is_ipv6;
6328       mp->is_local = is_local;
6329       mp->is_classify = is_classify;
6330       mp->is_multipath = is_multipath;
6331       mp->is_resolve_host = resolve_host;
6332       mp->is_resolve_attached = resolve_attached;
6333       mp->not_last = not_last;
6334       mp->next_hop_weight = next_hop_weight;
6335       mp->dst_address_length = dst_address_length;
6336       mp->next_hop_table_id = ntohl (next_hop_table_id);
6337       mp->classify_table_index = ntohl (classify_table_index);
6338       mp->next_hop_via_label = ntohl (next_hop_via_label);
6339       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6340       if (0 != mp->next_hop_n_out_labels)
6341         {
6342           memcpy (mp->next_hop_out_label_stack,
6343                   next_hop_out_label_stack,
6344                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6345           vec_free (next_hop_out_label_stack);
6346         }
6347
6348       if (is_ipv6)
6349         {
6350           clib_memcpy (mp->dst_address, &v6_dst_address,
6351                        sizeof (v6_dst_address));
6352           if (next_hop_set)
6353             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6354                          sizeof (v6_next_hop_address));
6355           increment_v6_address (&v6_dst_address);
6356         }
6357       else
6358         {
6359           clib_memcpy (mp->dst_address, &v4_dst_address,
6360                        sizeof (v4_dst_address));
6361           if (next_hop_set)
6362             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6363                          sizeof (v4_next_hop_address));
6364           if (random_add_del)
6365             v4_dst_address.as_u32 = random_vector[j + 1];
6366           else
6367             increment_v4_address (&v4_dst_address);
6368         }
6369       /* send it... */
6370       S (mp);
6371       /* If we receive SIGTERM, stop now... */
6372       if (vam->do_exit)
6373         break;
6374     }
6375
6376   /* When testing multiple add/del ops, use a control-ping to sync */
6377   if (count > 1)
6378     {
6379       vl_api_control_ping_t *mp_ping;
6380       f64 after;
6381       f64 timeout;
6382
6383       /* Shut off async mode */
6384       vam->async_mode = 0;
6385
6386       M (CONTROL_PING, mp_ping);
6387       S (mp_ping);
6388
6389       timeout = vat_time_now (vam) + 1.0;
6390       while (vat_time_now (vam) < timeout)
6391         if (vam->result_ready == 1)
6392           goto out;
6393       vam->retval = -99;
6394
6395     out:
6396       if (vam->retval == -99)
6397         errmsg ("timeout");
6398
6399       if (vam->async_errors > 0)
6400         {
6401           errmsg ("%d asynchronous errors", vam->async_errors);
6402           vam->retval = -98;
6403         }
6404       vam->async_errors = 0;
6405       after = vat_time_now (vam);
6406
6407       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6408       if (j > 0)
6409         count = j;
6410
6411       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6412              count, after - before, count / (after - before));
6413     }
6414   else
6415     {
6416       int ret;
6417
6418       /* Wait for a reply... */
6419       W (ret);
6420       return ret;
6421     }
6422
6423   /* Return the good/bad news */
6424   return (vam->retval);
6425 }
6426
6427 static int
6428 api_ip_mroute_add_del (vat_main_t * vam)
6429 {
6430   unformat_input_t *i = vam->input;
6431   vl_api_ip_mroute_add_del_t *mp;
6432   u32 sw_if_index = ~0, vrf_id = 0;
6433   u8 is_ipv6 = 0;
6434   u8 is_local = 0;
6435   u8 create_vrf_if_needed = 0;
6436   u8 is_add = 1;
6437   u8 address_set = 0;
6438   u32 grp_address_length = 0;
6439   ip4_address_t v4_grp_address, v4_src_address;
6440   ip6_address_t v6_grp_address, v6_src_address;
6441   mfib_itf_flags_t iflags = 0;
6442   mfib_entry_flags_t eflags = 0;
6443   int ret;
6444
6445   /* Parse args required to build the message */
6446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6447     {
6448       if (unformat (i, "sw_if_index %d", &sw_if_index))
6449         ;
6450       else if (unformat (i, "%U %U",
6451                          unformat_ip4_address, &v4_src_address,
6452                          unformat_ip4_address, &v4_grp_address))
6453         {
6454           grp_address_length = 64;
6455           address_set = 1;
6456           is_ipv6 = 0;
6457         }
6458       else if (unformat (i, "%U %U",
6459                          unformat_ip6_address, &v6_src_address,
6460                          unformat_ip6_address, &v6_grp_address))
6461         {
6462           grp_address_length = 256;
6463           address_set = 1;
6464           is_ipv6 = 1;
6465         }
6466       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6467         {
6468           memset (&v4_src_address, 0, sizeof (v4_src_address));
6469           grp_address_length = 32;
6470           address_set = 1;
6471           is_ipv6 = 0;
6472         }
6473       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6474         {
6475           memset (&v6_src_address, 0, sizeof (v6_src_address));
6476           grp_address_length = 128;
6477           address_set = 1;
6478           is_ipv6 = 1;
6479         }
6480       else if (unformat (i, "/%d", &grp_address_length))
6481         ;
6482       else if (unformat (i, "local"))
6483         {
6484           is_local = 1;
6485         }
6486       else if (unformat (i, "del"))
6487         is_add = 0;
6488       else if (unformat (i, "add"))
6489         is_add = 1;
6490       else if (unformat (i, "vrf %d", &vrf_id))
6491         ;
6492       else if (unformat (i, "create-vrf"))
6493         create_vrf_if_needed = 1;
6494       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6495         ;
6496       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6497         ;
6498       else
6499         {
6500           clib_warning ("parse error '%U'", format_unformat_error, i);
6501           return -99;
6502         }
6503     }
6504
6505   if (address_set == 0)
6506     {
6507       errmsg ("missing addresses\n");
6508       return -99;
6509     }
6510
6511   /* Construct the API message */
6512   M (IP_MROUTE_ADD_DEL, mp);
6513
6514   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6515   mp->table_id = ntohl (vrf_id);
6516   mp->create_vrf_if_needed = create_vrf_if_needed;
6517
6518   mp->is_add = is_add;
6519   mp->is_ipv6 = is_ipv6;
6520   mp->is_local = is_local;
6521   mp->itf_flags = ntohl (iflags);
6522   mp->entry_flags = ntohl (eflags);
6523   mp->grp_address_length = grp_address_length;
6524   mp->grp_address_length = ntohs (mp->grp_address_length);
6525
6526   if (is_ipv6)
6527     {
6528       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6529       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6530     }
6531   else
6532     {
6533       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6534       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6535
6536     }
6537
6538   /* send it... */
6539   S (mp);
6540   /* Wait for a reply... */
6541   W (ret);
6542   return ret;
6543 }
6544
6545 static int
6546 api_mpls_route_add_del (vat_main_t * vam)
6547 {
6548   unformat_input_t *i = vam->input;
6549   vl_api_mpls_route_add_del_t *mp;
6550   u32 sw_if_index = ~0, table_id = 0;
6551   u8 create_table_if_needed = 0;
6552   u8 is_add = 1;
6553   u32 next_hop_weight = 1;
6554   u8 is_multipath = 0;
6555   u32 next_hop_table_id = 0;
6556   u8 next_hop_set = 0;
6557   ip4_address_t v4_next_hop_address = {
6558     .as_u32 = 0,
6559   };
6560   ip6_address_t v6_next_hop_address = { {0} };
6561   int count = 1;
6562   int j;
6563   f64 before = 0;
6564   u32 classify_table_index = ~0;
6565   u8 is_classify = 0;
6566   u8 resolve_host = 0, resolve_attached = 0;
6567   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6568   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6569   mpls_label_t *next_hop_out_label_stack = NULL;
6570   mpls_label_t local_label = MPLS_LABEL_INVALID;
6571   u8 is_eos = 0;
6572   u8 next_hop_proto_is_ip4 = 1;
6573
6574   /* Parse args required to build the message */
6575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6576     {
6577       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6578         ;
6579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6580         ;
6581       else if (unformat (i, "%d", &local_label))
6582         ;
6583       else if (unformat (i, "eos"))
6584         is_eos = 1;
6585       else if (unformat (i, "non-eos"))
6586         is_eos = 0;
6587       else if (unformat (i, "via %U", unformat_ip4_address,
6588                          &v4_next_hop_address))
6589         {
6590           next_hop_set = 1;
6591           next_hop_proto_is_ip4 = 1;
6592         }
6593       else if (unformat (i, "via %U", unformat_ip6_address,
6594                          &v6_next_hop_address))
6595         {
6596           next_hop_set = 1;
6597           next_hop_proto_is_ip4 = 0;
6598         }
6599       else if (unformat (i, "weight %d", &next_hop_weight))
6600         ;
6601       else if (unformat (i, "create-table"))
6602         create_table_if_needed = 1;
6603       else if (unformat (i, "classify %d", &classify_table_index))
6604         {
6605           is_classify = 1;
6606         }
6607       else if (unformat (i, "del"))
6608         is_add = 0;
6609       else if (unformat (i, "add"))
6610         is_add = 1;
6611       else if (unformat (i, "resolve-via-host"))
6612         resolve_host = 1;
6613       else if (unformat (i, "resolve-via-attached"))
6614         resolve_attached = 1;
6615       else if (unformat (i, "multipath"))
6616         is_multipath = 1;
6617       else if (unformat (i, "count %d", &count))
6618         ;
6619       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6620         {
6621           next_hop_set = 1;
6622           next_hop_proto_is_ip4 = 1;
6623         }
6624       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6625         {
6626           next_hop_set = 1;
6627           next_hop_proto_is_ip4 = 0;
6628         }
6629       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6630         ;
6631       else if (unformat (i, "via-label %d", &next_hop_via_label))
6632         ;
6633       else if (unformat (i, "out-label %d", &next_hop_out_label))
6634         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6635       else
6636         {
6637           clib_warning ("parse error '%U'", format_unformat_error, i);
6638           return -99;
6639         }
6640     }
6641
6642   if (!next_hop_set && !is_classify)
6643     {
6644       errmsg ("next hop / classify not set");
6645       return -99;
6646     }
6647
6648   if (MPLS_LABEL_INVALID == local_label)
6649     {
6650       errmsg ("missing label");
6651       return -99;
6652     }
6653
6654   if (count > 1)
6655     {
6656       /* Turn on async mode */
6657       vam->async_mode = 1;
6658       vam->async_errors = 0;
6659       before = vat_time_now (vam);
6660     }
6661
6662   for (j = 0; j < count; j++)
6663     {
6664       /* Construct the API message */
6665       M2 (MPLS_ROUTE_ADD_DEL, mp,
6666           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6667
6668       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6669       mp->mr_table_id = ntohl (table_id);
6670       mp->mr_create_table_if_needed = create_table_if_needed;
6671
6672       mp->mr_is_add = is_add;
6673       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6674       mp->mr_is_classify = is_classify;
6675       mp->mr_is_multipath = is_multipath;
6676       mp->mr_is_resolve_host = resolve_host;
6677       mp->mr_is_resolve_attached = resolve_attached;
6678       mp->mr_next_hop_weight = next_hop_weight;
6679       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6680       mp->mr_classify_table_index = ntohl (classify_table_index);
6681       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6682       mp->mr_label = ntohl (local_label);
6683       mp->mr_eos = is_eos;
6684
6685       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6686       if (0 != mp->mr_next_hop_n_out_labels)
6687         {
6688           memcpy (mp->mr_next_hop_out_label_stack,
6689                   next_hop_out_label_stack,
6690                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6691           vec_free (next_hop_out_label_stack);
6692         }
6693
6694       if (next_hop_set)
6695         {
6696           if (next_hop_proto_is_ip4)
6697             {
6698               clib_memcpy (mp->mr_next_hop,
6699                            &v4_next_hop_address,
6700                            sizeof (v4_next_hop_address));
6701             }
6702           else
6703             {
6704               clib_memcpy (mp->mr_next_hop,
6705                            &v6_next_hop_address,
6706                            sizeof (v6_next_hop_address));
6707             }
6708         }
6709       local_label++;
6710
6711       /* send it... */
6712       S (mp);
6713       /* If we receive SIGTERM, stop now... */
6714       if (vam->do_exit)
6715         break;
6716     }
6717
6718   /* When testing multiple add/del ops, use a control-ping to sync */
6719   if (count > 1)
6720     {
6721       vl_api_control_ping_t *mp_ping;
6722       f64 after;
6723       f64 timeout;
6724
6725       /* Shut off async mode */
6726       vam->async_mode = 0;
6727
6728       M (CONTROL_PING, mp_ping);
6729       S (mp_ping);
6730
6731       timeout = vat_time_now (vam) + 1.0;
6732       while (vat_time_now (vam) < timeout)
6733         if (vam->result_ready == 1)
6734           goto out;
6735       vam->retval = -99;
6736
6737     out:
6738       if (vam->retval == -99)
6739         errmsg ("timeout");
6740
6741       if (vam->async_errors > 0)
6742         {
6743           errmsg ("%d asynchronous errors", vam->async_errors);
6744           vam->retval = -98;
6745         }
6746       vam->async_errors = 0;
6747       after = vat_time_now (vam);
6748
6749       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6750       if (j > 0)
6751         count = j;
6752
6753       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6754              count, after - before, count / (after - before));
6755     }
6756   else
6757     {
6758       int ret;
6759
6760       /* Wait for a reply... */
6761       W (ret);
6762       return ret;
6763     }
6764
6765   /* Return the good/bad news */
6766   return (vam->retval);
6767 }
6768
6769 static int
6770 api_mpls_ip_bind_unbind (vat_main_t * vam)
6771 {
6772   unformat_input_t *i = vam->input;
6773   vl_api_mpls_ip_bind_unbind_t *mp;
6774   u32 ip_table_id = 0;
6775   u8 create_table_if_needed = 0;
6776   u8 is_bind = 1;
6777   u8 is_ip4 = 1;
6778   ip4_address_t v4_address;
6779   ip6_address_t v6_address;
6780   u32 address_length;
6781   u8 address_set = 0;
6782   mpls_label_t local_label = MPLS_LABEL_INVALID;
6783   int ret;
6784
6785   /* Parse args required to build the message */
6786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6787     {
6788       if (unformat (i, "%U/%d", unformat_ip4_address,
6789                     &v4_address, &address_length))
6790         {
6791           is_ip4 = 1;
6792           address_set = 1;
6793         }
6794       else if (unformat (i, "%U/%d", unformat_ip6_address,
6795                          &v6_address, &address_length))
6796         {
6797           is_ip4 = 0;
6798           address_set = 1;
6799         }
6800       else if (unformat (i, "%d", &local_label))
6801         ;
6802       else if (unformat (i, "create-table"))
6803         create_table_if_needed = 1;
6804       else if (unformat (i, "table-id %d", &ip_table_id))
6805         ;
6806       else if (unformat (i, "unbind"))
6807         is_bind = 0;
6808       else if (unformat (i, "bind"))
6809         is_bind = 1;
6810       else
6811         {
6812           clib_warning ("parse error '%U'", format_unformat_error, i);
6813           return -99;
6814         }
6815     }
6816
6817   if (!address_set)
6818     {
6819       errmsg ("IP addres not set");
6820       return -99;
6821     }
6822
6823   if (MPLS_LABEL_INVALID == local_label)
6824     {
6825       errmsg ("missing label");
6826       return -99;
6827     }
6828
6829   /* Construct the API message */
6830   M (MPLS_IP_BIND_UNBIND, mp);
6831
6832   mp->mb_create_table_if_needed = create_table_if_needed;
6833   mp->mb_is_bind = is_bind;
6834   mp->mb_is_ip4 = is_ip4;
6835   mp->mb_ip_table_id = ntohl (ip_table_id);
6836   mp->mb_mpls_table_id = 0;
6837   mp->mb_label = ntohl (local_label);
6838   mp->mb_address_length = address_length;
6839
6840   if (is_ip4)
6841     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6842   else
6843     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6844
6845   /* send it... */
6846   S (mp);
6847
6848   /* Wait for a reply... */
6849   W (ret);
6850   return ret;
6851 }
6852
6853 static int
6854 api_proxy_arp_add_del (vat_main_t * vam)
6855 {
6856   unformat_input_t *i = vam->input;
6857   vl_api_proxy_arp_add_del_t *mp;
6858   u32 vrf_id = 0;
6859   u8 is_add = 1;
6860   ip4_address_t lo, hi;
6861   u8 range_set = 0;
6862   int ret;
6863
6864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6865     {
6866       if (unformat (i, "vrf %d", &vrf_id))
6867         ;
6868       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6869                          unformat_ip4_address, &hi))
6870         range_set = 1;
6871       else if (unformat (i, "del"))
6872         is_add = 0;
6873       else
6874         {
6875           clib_warning ("parse error '%U'", format_unformat_error, i);
6876           return -99;
6877         }
6878     }
6879
6880   if (range_set == 0)
6881     {
6882       errmsg ("address range not set");
6883       return -99;
6884     }
6885
6886   M (PROXY_ARP_ADD_DEL, mp);
6887
6888   mp->vrf_id = ntohl (vrf_id);
6889   mp->is_add = is_add;
6890   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6891   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6892
6893   S (mp);
6894   W (ret);
6895   return ret;
6896 }
6897
6898 static int
6899 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6900 {
6901   unformat_input_t *i = vam->input;
6902   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6903   u32 sw_if_index;
6904   u8 enable = 1;
6905   u8 sw_if_index_set = 0;
6906   int ret;
6907
6908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909     {
6910       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6911         sw_if_index_set = 1;
6912       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6913         sw_if_index_set = 1;
6914       else if (unformat (i, "enable"))
6915         enable = 1;
6916       else if (unformat (i, "disable"))
6917         enable = 0;
6918       else
6919         {
6920           clib_warning ("parse error '%U'", format_unformat_error, i);
6921           return -99;
6922         }
6923     }
6924
6925   if (sw_if_index_set == 0)
6926     {
6927       errmsg ("missing interface name or sw_if_index");
6928       return -99;
6929     }
6930
6931   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
6932
6933   mp->sw_if_index = ntohl (sw_if_index);
6934   mp->enable_disable = enable;
6935
6936   S (mp);
6937   W (ret);
6938   return ret;
6939 }
6940
6941 static int
6942 api_mpls_tunnel_add_del (vat_main_t * vam)
6943 {
6944   unformat_input_t *i = vam->input;
6945   vl_api_mpls_tunnel_add_del_t *mp;
6946
6947   u8 is_add = 1;
6948   u8 l2_only = 0;
6949   u32 sw_if_index = ~0;
6950   u32 next_hop_sw_if_index = ~0;
6951   u32 next_hop_proto_is_ip4 = 1;
6952
6953   u32 next_hop_table_id = 0;
6954   ip4_address_t v4_next_hop_address = {
6955     .as_u32 = 0,
6956   };
6957   ip6_address_t v6_next_hop_address = { {0} };
6958   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6959   int ret;
6960
6961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962     {
6963       if (unformat (i, "add"))
6964         is_add = 1;
6965       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6966         is_add = 0;
6967       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6968         ;
6969       else if (unformat (i, "via %U",
6970                          unformat_ip4_address, &v4_next_hop_address))
6971         {
6972           next_hop_proto_is_ip4 = 1;
6973         }
6974       else if (unformat (i, "via %U",
6975                          unformat_ip6_address, &v6_next_hop_address))
6976         {
6977           next_hop_proto_is_ip4 = 0;
6978         }
6979       else if (unformat (i, "l2-only"))
6980         l2_only = 1;
6981       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6982         ;
6983       else if (unformat (i, "out-label %d", &next_hop_out_label))
6984         vec_add1 (labels, ntohl (next_hop_out_label));
6985       else
6986         {
6987           clib_warning ("parse error '%U'", format_unformat_error, i);
6988           return -99;
6989         }
6990     }
6991
6992   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
6993
6994   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6995   mp->mt_sw_if_index = ntohl (sw_if_index);
6996   mp->mt_is_add = is_add;
6997   mp->mt_l2_only = l2_only;
6998   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6999   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7000
7001   mp->mt_next_hop_n_out_labels = vec_len (labels);
7002
7003   if (0 != mp->mt_next_hop_n_out_labels)
7004     {
7005       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7006                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7007       vec_free (labels);
7008     }
7009
7010   if (next_hop_proto_is_ip4)
7011     {
7012       clib_memcpy (mp->mt_next_hop,
7013                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7014     }
7015   else
7016     {
7017       clib_memcpy (mp->mt_next_hop,
7018                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7019     }
7020
7021   S (mp);
7022   W (ret);
7023   return ret;
7024 }
7025
7026 static int
7027 api_sw_interface_set_unnumbered (vat_main_t * vam)
7028 {
7029   unformat_input_t *i = vam->input;
7030   vl_api_sw_interface_set_unnumbered_t *mp;
7031   u32 sw_if_index;
7032   u32 unnum_sw_index = ~0;
7033   u8 is_add = 1;
7034   u8 sw_if_index_set = 0;
7035   int ret;
7036
7037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7038     {
7039       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7040         sw_if_index_set = 1;
7041       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7042         sw_if_index_set = 1;
7043       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7044         ;
7045       else if (unformat (i, "del"))
7046         is_add = 0;
7047       else
7048         {
7049           clib_warning ("parse error '%U'", format_unformat_error, i);
7050           return -99;
7051         }
7052     }
7053
7054   if (sw_if_index_set == 0)
7055     {
7056       errmsg ("missing interface name or sw_if_index");
7057       return -99;
7058     }
7059
7060   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7061
7062   mp->sw_if_index = ntohl (sw_if_index);
7063   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7064   mp->is_add = is_add;
7065
7066   S (mp);
7067   W (ret);
7068   return ret;
7069 }
7070
7071 static int
7072 api_ip_neighbor_add_del (vat_main_t * vam)
7073 {
7074   unformat_input_t *i = vam->input;
7075   vl_api_ip_neighbor_add_del_t *mp;
7076   u32 sw_if_index;
7077   u8 sw_if_index_set = 0;
7078   u8 is_add = 1;
7079   u8 is_static = 0;
7080   u8 mac_address[6];
7081   u8 mac_set = 0;
7082   u8 v4_address_set = 0;
7083   u8 v6_address_set = 0;
7084   ip4_address_t v4address;
7085   ip6_address_t v6address;
7086   int ret;
7087
7088   memset (mac_address, 0, sizeof (mac_address));
7089
7090   /* Parse args required to build the message */
7091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7092     {
7093       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7094         {
7095           mac_set = 1;
7096         }
7097       else if (unformat (i, "del"))
7098         is_add = 0;
7099       else
7100         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7101         sw_if_index_set = 1;
7102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7103         sw_if_index_set = 1;
7104       else if (unformat (i, "is_static"))
7105         is_static = 1;
7106       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7107         v4_address_set = 1;
7108       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7109         v6_address_set = 1;
7110       else
7111         {
7112           clib_warning ("parse error '%U'", format_unformat_error, i);
7113           return -99;
7114         }
7115     }
7116
7117   if (sw_if_index_set == 0)
7118     {
7119       errmsg ("missing interface name or sw_if_index");
7120       return -99;
7121     }
7122   if (v4_address_set && v6_address_set)
7123     {
7124       errmsg ("both v4 and v6 addresses set");
7125       return -99;
7126     }
7127   if (!v4_address_set && !v6_address_set)
7128     {
7129       errmsg ("no address set");
7130       return -99;
7131     }
7132
7133   /* Construct the API message */
7134   M (IP_NEIGHBOR_ADD_DEL, mp);
7135
7136   mp->sw_if_index = ntohl (sw_if_index);
7137   mp->is_add = is_add;
7138   mp->is_static = is_static;
7139   if (mac_set)
7140     clib_memcpy (mp->mac_address, mac_address, 6);
7141   if (v6_address_set)
7142     {
7143       mp->is_ipv6 = 1;
7144       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7145     }
7146   else
7147     {
7148       /* mp->is_ipv6 = 0; via memset in M macro above */
7149       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7150     }
7151
7152   /* send it... */
7153   S (mp);
7154
7155   /* Wait for a reply, return good/bad news  */
7156   W (ret);
7157   return ret;
7158 }
7159
7160 static int
7161 api_reset_vrf (vat_main_t * vam)
7162 {
7163   unformat_input_t *i = vam->input;
7164   vl_api_reset_vrf_t *mp;
7165   u32 vrf_id = 0;
7166   u8 is_ipv6 = 0;
7167   u8 vrf_id_set = 0;
7168   int ret;
7169
7170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171     {
7172       if (unformat (i, "vrf %d", &vrf_id))
7173         vrf_id_set = 1;
7174       else if (unformat (i, "ipv6"))
7175         is_ipv6 = 1;
7176       else
7177         {
7178           clib_warning ("parse error '%U'", format_unformat_error, i);
7179           return -99;
7180         }
7181     }
7182
7183   if (vrf_id_set == 0)
7184     {
7185       errmsg ("missing vrf id");
7186       return -99;
7187     }
7188
7189   M (RESET_VRF, mp);
7190
7191   mp->vrf_id = ntohl (vrf_id);
7192   mp->is_ipv6 = is_ipv6;
7193
7194   S (mp);
7195   W (ret);
7196   return ret;
7197 }
7198
7199 static int
7200 api_create_vlan_subif (vat_main_t * vam)
7201 {
7202   unformat_input_t *i = vam->input;
7203   vl_api_create_vlan_subif_t *mp;
7204   u32 sw_if_index;
7205   u8 sw_if_index_set = 0;
7206   u32 vlan_id;
7207   u8 vlan_id_set = 0;
7208   int ret;
7209
7210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7211     {
7212       if (unformat (i, "sw_if_index %d", &sw_if_index))
7213         sw_if_index_set = 1;
7214       else
7215         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7216         sw_if_index_set = 1;
7217       else if (unformat (i, "vlan %d", &vlan_id))
7218         vlan_id_set = 1;
7219       else
7220         {
7221           clib_warning ("parse error '%U'", format_unformat_error, i);
7222           return -99;
7223         }
7224     }
7225
7226   if (sw_if_index_set == 0)
7227     {
7228       errmsg ("missing interface name or sw_if_index");
7229       return -99;
7230     }
7231
7232   if (vlan_id_set == 0)
7233     {
7234       errmsg ("missing vlan_id");
7235       return -99;
7236     }
7237   M (CREATE_VLAN_SUBIF, mp);
7238
7239   mp->sw_if_index = ntohl (sw_if_index);
7240   mp->vlan_id = ntohl (vlan_id);
7241
7242   S (mp);
7243   W (ret);
7244   return ret;
7245 }
7246
7247 #define foreach_create_subif_bit                \
7248 _(no_tags)                                      \
7249 _(one_tag)                                      \
7250 _(two_tags)                                     \
7251 _(dot1ad)                                       \
7252 _(exact_match)                                  \
7253 _(default_sub)                                  \
7254 _(outer_vlan_id_any)                            \
7255 _(inner_vlan_id_any)
7256
7257 static int
7258 api_create_subif (vat_main_t * vam)
7259 {
7260   unformat_input_t *i = vam->input;
7261   vl_api_create_subif_t *mp;
7262   u32 sw_if_index;
7263   u8 sw_if_index_set = 0;
7264   u32 sub_id;
7265   u8 sub_id_set = 0;
7266   u32 no_tags = 0;
7267   u32 one_tag = 0;
7268   u32 two_tags = 0;
7269   u32 dot1ad = 0;
7270   u32 exact_match = 0;
7271   u32 default_sub = 0;
7272   u32 outer_vlan_id_any = 0;
7273   u32 inner_vlan_id_any = 0;
7274   u32 tmp;
7275   u16 outer_vlan_id = 0;
7276   u16 inner_vlan_id = 0;
7277   int ret;
7278
7279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7280     {
7281       if (unformat (i, "sw_if_index %d", &sw_if_index))
7282         sw_if_index_set = 1;
7283       else
7284         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7285         sw_if_index_set = 1;
7286       else if (unformat (i, "sub_id %d", &sub_id))
7287         sub_id_set = 1;
7288       else if (unformat (i, "outer_vlan_id %d", &tmp))
7289         outer_vlan_id = tmp;
7290       else if (unformat (i, "inner_vlan_id %d", &tmp))
7291         inner_vlan_id = tmp;
7292
7293 #define _(a) else if (unformat (i, #a)) a = 1 ;
7294       foreach_create_subif_bit
7295 #undef _
7296         else
7297         {
7298           clib_warning ("parse error '%U'", format_unformat_error, i);
7299           return -99;
7300         }
7301     }
7302
7303   if (sw_if_index_set == 0)
7304     {
7305       errmsg ("missing interface name or sw_if_index");
7306       return -99;
7307     }
7308
7309   if (sub_id_set == 0)
7310     {
7311       errmsg ("missing sub_id");
7312       return -99;
7313     }
7314   M (CREATE_SUBIF, mp);
7315
7316   mp->sw_if_index = ntohl (sw_if_index);
7317   mp->sub_id = ntohl (sub_id);
7318
7319 #define _(a) mp->a = a;
7320   foreach_create_subif_bit;
7321 #undef _
7322
7323   mp->outer_vlan_id = ntohs (outer_vlan_id);
7324   mp->inner_vlan_id = ntohs (inner_vlan_id);
7325
7326   S (mp);
7327   W (ret);
7328   return ret;
7329 }
7330
7331 static int
7332 api_oam_add_del (vat_main_t * vam)
7333 {
7334   unformat_input_t *i = vam->input;
7335   vl_api_oam_add_del_t *mp;
7336   u32 vrf_id = 0;
7337   u8 is_add = 1;
7338   ip4_address_t src, dst;
7339   u8 src_set = 0;
7340   u8 dst_set = 0;
7341   int ret;
7342
7343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7344     {
7345       if (unformat (i, "vrf %d", &vrf_id))
7346         ;
7347       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7348         src_set = 1;
7349       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7350         dst_set = 1;
7351       else if (unformat (i, "del"))
7352         is_add = 0;
7353       else
7354         {
7355           clib_warning ("parse error '%U'", format_unformat_error, i);
7356           return -99;
7357         }
7358     }
7359
7360   if (src_set == 0)
7361     {
7362       errmsg ("missing src addr");
7363       return -99;
7364     }
7365
7366   if (dst_set == 0)
7367     {
7368       errmsg ("missing dst addr");
7369       return -99;
7370     }
7371
7372   M (OAM_ADD_DEL, mp);
7373
7374   mp->vrf_id = ntohl (vrf_id);
7375   mp->is_add = is_add;
7376   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7377   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7378
7379   S (mp);
7380   W (ret);
7381   return ret;
7382 }
7383
7384 static int
7385 api_reset_fib (vat_main_t * vam)
7386 {
7387   unformat_input_t *i = vam->input;
7388   vl_api_reset_fib_t *mp;
7389   u32 vrf_id = 0;
7390   u8 is_ipv6 = 0;
7391   u8 vrf_id_set = 0;
7392
7393   int ret;
7394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7395     {
7396       if (unformat (i, "vrf %d", &vrf_id))
7397         vrf_id_set = 1;
7398       else if (unformat (i, "ipv6"))
7399         is_ipv6 = 1;
7400       else
7401         {
7402           clib_warning ("parse error '%U'", format_unformat_error, i);
7403           return -99;
7404         }
7405     }
7406
7407   if (vrf_id_set == 0)
7408     {
7409       errmsg ("missing vrf id");
7410       return -99;
7411     }
7412
7413   M (RESET_FIB, mp);
7414
7415   mp->vrf_id = ntohl (vrf_id);
7416   mp->is_ipv6 = is_ipv6;
7417
7418   S (mp);
7419   W (ret);
7420   return ret;
7421 }
7422
7423 static int
7424 api_dhcp_proxy_config (vat_main_t * vam)
7425 {
7426   unformat_input_t *i = vam->input;
7427   vl_api_dhcp_proxy_config_t *mp;
7428   u32 rx_vrf_id = 0;
7429   u32 server_vrf_id = 0;
7430   u8 is_add = 1;
7431   u8 v4_address_set = 0;
7432   u8 v6_address_set = 0;
7433   ip4_address_t v4address;
7434   ip6_address_t v6address;
7435   u8 v4_src_address_set = 0;
7436   u8 v6_src_address_set = 0;
7437   ip4_address_t v4srcaddress;
7438   ip6_address_t v6srcaddress;
7439   int ret;
7440
7441   /* Parse args required to build the message */
7442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7443     {
7444       if (unformat (i, "del"))
7445         is_add = 0;
7446       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7447         ;
7448       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7449         ;
7450       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7451         v4_address_set = 1;
7452       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7453         v6_address_set = 1;
7454       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7455         v4_src_address_set = 1;
7456       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7457         v6_src_address_set = 1;
7458       else
7459         break;
7460     }
7461
7462   if (v4_address_set && v6_address_set)
7463     {
7464       errmsg ("both v4 and v6 server addresses set");
7465       return -99;
7466     }
7467   if (!v4_address_set && !v6_address_set)
7468     {
7469       errmsg ("no server addresses set");
7470       return -99;
7471     }
7472
7473   if (v4_src_address_set && v6_src_address_set)
7474     {
7475       errmsg ("both v4 and v6  src addresses set");
7476       return -99;
7477     }
7478   if (!v4_src_address_set && !v6_src_address_set)
7479     {
7480       errmsg ("no src addresses set");
7481       return -99;
7482     }
7483
7484   if (!(v4_src_address_set && v4_address_set) &&
7485       !(v6_src_address_set && v6_address_set))
7486     {
7487       errmsg ("no matching server and src addresses set");
7488       return -99;
7489     }
7490
7491   /* Construct the API message */
7492   M (DHCP_PROXY_CONFIG, mp);
7493
7494   mp->is_add = is_add;
7495   mp->rx_vrf_id = ntohl (rx_vrf_id);
7496   mp->server_vrf_id = ntohl (server_vrf_id);
7497   if (v6_address_set)
7498     {
7499       mp->is_ipv6 = 1;
7500       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7501       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7502     }
7503   else
7504     {
7505       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7506       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7507     }
7508
7509   /* send it... */
7510   S (mp);
7511
7512   /* Wait for a reply, return good/bad news  */
7513   W (ret);
7514   return ret;
7515 }
7516
7517 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7518 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7519
7520 static void
7521 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7522 {
7523   vat_main_t *vam = &vat_main;
7524
7525   if (mp->is_ipv6)
7526     print (vam->ofp,
7527            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7528            ntohl (mp->rx_vrf_id),
7529            ntohl (mp->server_vrf_id),
7530            format_ip6_address, mp->dhcp_server,
7531            format_ip6_address, mp->dhcp_src_address,
7532            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7533   else
7534     print (vam->ofp,
7535            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7536            ntohl (mp->rx_vrf_id),
7537            ntohl (mp->server_vrf_id),
7538            format_ip4_address, mp->dhcp_server,
7539            format_ip4_address, mp->dhcp_src_address,
7540            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7541 }
7542
7543 static void vl_api_dhcp_proxy_details_t_handler_json
7544   (vl_api_dhcp_proxy_details_t * mp)
7545 {
7546   vat_main_t *vam = &vat_main;
7547   vat_json_node_t *node = NULL;
7548   struct in_addr ip4;
7549   struct in6_addr ip6;
7550
7551   if (VAT_JSON_ARRAY != vam->json_tree.type)
7552     {
7553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7554       vat_json_init_array (&vam->json_tree);
7555     }
7556   node = vat_json_array_add (&vam->json_tree);
7557
7558   vat_json_init_object (node);
7559   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7560   vat_json_object_add_uint (node, "server-table-id",
7561                             ntohl (mp->server_vrf_id));
7562   if (mp->is_ipv6)
7563     {
7564       clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7565       vat_json_object_add_ip6 (node, "server_address", ip6);
7566       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7567       vat_json_object_add_ip6 (node, "src_address", ip6);
7568     }
7569   else
7570     {
7571       clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7572       vat_json_object_add_ip4 (node, "server_address", ip4);
7573       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7574       vat_json_object_add_ip4 (node, "src_address", ip4);
7575     }
7576   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7577   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7578 }
7579
7580 static int
7581 api_dhcp_proxy_dump (vat_main_t * vam)
7582 {
7583   unformat_input_t *i = vam->input;
7584   vl_api_control_ping_t *mp_ping;
7585   vl_api_dhcp_proxy_dump_t *mp;
7586   u8 is_ipv6 = 0;
7587   int ret;
7588
7589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7590     {
7591       if (unformat (i, "ipv6"))
7592         is_ipv6 = 1;
7593       else
7594         {
7595           clib_warning ("parse error '%U'", format_unformat_error, i);
7596           return -99;
7597         }
7598     }
7599
7600   M (DHCP_PROXY_DUMP, mp);
7601
7602   mp->is_ip6 = is_ipv6;
7603   S (mp);
7604
7605   /* Use a control ping for synchronization */
7606   M (CONTROL_PING, mp_ping);
7607   S (mp_ping);
7608
7609   W (ret);
7610   return ret;
7611 }
7612
7613 static int
7614 api_dhcp_proxy_set_vss (vat_main_t * vam)
7615 {
7616   unformat_input_t *i = vam->input;
7617   vl_api_dhcp_proxy_set_vss_t *mp;
7618   u8 is_ipv6 = 0;
7619   u8 is_add = 1;
7620   u32 tbl_id;
7621   u8 tbl_id_set = 0;
7622   u32 oui;
7623   u8 oui_set = 0;
7624   u32 fib_id;
7625   u8 fib_id_set = 0;
7626   int ret;
7627
7628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7629     {
7630       if (unformat (i, "tbl_id %d", &tbl_id))
7631         tbl_id_set = 1;
7632       if (unformat (i, "fib_id %d", &fib_id))
7633         fib_id_set = 1;
7634       if (unformat (i, "oui %d", &oui))
7635         oui_set = 1;
7636       else if (unformat (i, "ipv6"))
7637         is_ipv6 = 1;
7638       else if (unformat (i, "del"))
7639         is_add = 0;
7640       else
7641         {
7642           clib_warning ("parse error '%U'", format_unformat_error, i);
7643           return -99;
7644         }
7645     }
7646
7647   if (tbl_id_set == 0)
7648     {
7649       errmsg ("missing tbl id");
7650       return -99;
7651     }
7652
7653   if (fib_id_set == 0)
7654     {
7655       errmsg ("missing fib id");
7656       return -99;
7657     }
7658   if (oui_set == 0)
7659     {
7660       errmsg ("missing oui");
7661       return -99;
7662     }
7663
7664   M (DHCP_PROXY_SET_VSS, mp);
7665   mp->tbl_id = ntohl (tbl_id);
7666   mp->fib_id = ntohl (fib_id);
7667   mp->oui = ntohl (oui);
7668   mp->is_ipv6 = is_ipv6;
7669   mp->is_add = is_add;
7670
7671   S (mp);
7672   W (ret);
7673   return ret;
7674 }
7675
7676 static int
7677 api_dhcp_client_config (vat_main_t * vam)
7678 {
7679   unformat_input_t *i = vam->input;
7680   vl_api_dhcp_client_config_t *mp;
7681   u32 sw_if_index;
7682   u8 sw_if_index_set = 0;
7683   u8 is_add = 1;
7684   u8 *hostname = 0;
7685   u8 disable_event = 0;
7686   int ret;
7687
7688   /* Parse args required to build the message */
7689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7690     {
7691       if (unformat (i, "del"))
7692         is_add = 0;
7693       else
7694         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7695         sw_if_index_set = 1;
7696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7697         sw_if_index_set = 1;
7698       else if (unformat (i, "hostname %s", &hostname))
7699         ;
7700       else if (unformat (i, "disable_event"))
7701         disable_event = 1;
7702       else
7703         break;
7704     }
7705
7706   if (sw_if_index_set == 0)
7707     {
7708       errmsg ("missing interface name or sw_if_index");
7709       return -99;
7710     }
7711
7712   if (vec_len (hostname) > 63)
7713     {
7714       errmsg ("hostname too long");
7715     }
7716   vec_add1 (hostname, 0);
7717
7718   /* Construct the API message */
7719   M (DHCP_CLIENT_CONFIG, mp);
7720
7721   mp->sw_if_index = ntohl (sw_if_index);
7722   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7723   vec_free (hostname);
7724   mp->is_add = is_add;
7725   mp->want_dhcp_event = disable_event ? 0 : 1;
7726   mp->pid = getpid ();
7727
7728   /* send it... */
7729   S (mp);
7730
7731   /* Wait for a reply, return good/bad news  */
7732   W (ret);
7733   return ret;
7734 }
7735
7736 static int
7737 api_set_ip_flow_hash (vat_main_t * vam)
7738 {
7739   unformat_input_t *i = vam->input;
7740   vl_api_set_ip_flow_hash_t *mp;
7741   u32 vrf_id = 0;
7742   u8 is_ipv6 = 0;
7743   u8 vrf_id_set = 0;
7744   u8 src = 0;
7745   u8 dst = 0;
7746   u8 sport = 0;
7747   u8 dport = 0;
7748   u8 proto = 0;
7749   u8 reverse = 0;
7750   int ret;
7751
7752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7753     {
7754       if (unformat (i, "vrf %d", &vrf_id))
7755         vrf_id_set = 1;
7756       else if (unformat (i, "ipv6"))
7757         is_ipv6 = 1;
7758       else if (unformat (i, "src"))
7759         src = 1;
7760       else if (unformat (i, "dst"))
7761         dst = 1;
7762       else if (unformat (i, "sport"))
7763         sport = 1;
7764       else if (unformat (i, "dport"))
7765         dport = 1;
7766       else if (unformat (i, "proto"))
7767         proto = 1;
7768       else if (unformat (i, "reverse"))
7769         reverse = 1;
7770
7771       else
7772         {
7773           clib_warning ("parse error '%U'", format_unformat_error, i);
7774           return -99;
7775         }
7776     }
7777
7778   if (vrf_id_set == 0)
7779     {
7780       errmsg ("missing vrf id");
7781       return -99;
7782     }
7783
7784   M (SET_IP_FLOW_HASH, mp);
7785   mp->src = src;
7786   mp->dst = dst;
7787   mp->sport = sport;
7788   mp->dport = dport;
7789   mp->proto = proto;
7790   mp->reverse = reverse;
7791   mp->vrf_id = ntohl (vrf_id);
7792   mp->is_ipv6 = is_ipv6;
7793
7794   S (mp);
7795   W (ret);
7796   return ret;
7797 }
7798
7799 static int
7800 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7801 {
7802   unformat_input_t *i = vam->input;
7803   vl_api_sw_interface_ip6_enable_disable_t *mp;
7804   u32 sw_if_index;
7805   u8 sw_if_index_set = 0;
7806   u8 enable = 0;
7807   int ret;
7808
7809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7810     {
7811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7812         sw_if_index_set = 1;
7813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7814         sw_if_index_set = 1;
7815       else if (unformat (i, "enable"))
7816         enable = 1;
7817       else if (unformat (i, "disable"))
7818         enable = 0;
7819       else
7820         {
7821           clib_warning ("parse error '%U'", format_unformat_error, i);
7822           return -99;
7823         }
7824     }
7825
7826   if (sw_if_index_set == 0)
7827     {
7828       errmsg ("missing interface name or sw_if_index");
7829       return -99;
7830     }
7831
7832   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7833
7834   mp->sw_if_index = ntohl (sw_if_index);
7835   mp->enable = enable;
7836
7837   S (mp);
7838   W (ret);
7839   return ret;
7840 }
7841
7842 static int
7843 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7844 {
7845   unformat_input_t *i = vam->input;
7846   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7847   u32 sw_if_index;
7848   u8 sw_if_index_set = 0;
7849   u8 v6_address_set = 0;
7850   ip6_address_t v6address;
7851   int ret;
7852
7853   /* Parse args required to build the message */
7854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7855     {
7856       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7857         sw_if_index_set = 1;
7858       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7859         sw_if_index_set = 1;
7860       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7861         v6_address_set = 1;
7862       else
7863         break;
7864     }
7865
7866   if (sw_if_index_set == 0)
7867     {
7868       errmsg ("missing interface name or sw_if_index");
7869       return -99;
7870     }
7871   if (!v6_address_set)
7872     {
7873       errmsg ("no address set");
7874       return -99;
7875     }
7876
7877   /* Construct the API message */
7878   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
7879
7880   mp->sw_if_index = ntohl (sw_if_index);
7881   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7882
7883   /* send it... */
7884   S (mp);
7885
7886   /* Wait for a reply, return good/bad news  */
7887   W (ret);
7888   return ret;
7889 }
7890
7891
7892 static int
7893 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7894 {
7895   unformat_input_t *i = vam->input;
7896   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7897   u32 sw_if_index;
7898   u8 sw_if_index_set = 0;
7899   u32 address_length = 0;
7900   u8 v6_address_set = 0;
7901   ip6_address_t v6address;
7902   u8 use_default = 0;
7903   u8 no_advertise = 0;
7904   u8 off_link = 0;
7905   u8 no_autoconfig = 0;
7906   u8 no_onlink = 0;
7907   u8 is_no = 0;
7908   u32 val_lifetime = 0;
7909   u32 pref_lifetime = 0;
7910   int ret;
7911
7912   /* Parse args required to build the message */
7913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7914     {
7915       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7916         sw_if_index_set = 1;
7917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7918         sw_if_index_set = 1;
7919       else if (unformat (i, "%U/%d",
7920                          unformat_ip6_address, &v6address, &address_length))
7921         v6_address_set = 1;
7922       else if (unformat (i, "val_life %d", &val_lifetime))
7923         ;
7924       else if (unformat (i, "pref_life %d", &pref_lifetime))
7925         ;
7926       else if (unformat (i, "def"))
7927         use_default = 1;
7928       else if (unformat (i, "noadv"))
7929         no_advertise = 1;
7930       else if (unformat (i, "offl"))
7931         off_link = 1;
7932       else if (unformat (i, "noauto"))
7933         no_autoconfig = 1;
7934       else if (unformat (i, "nolink"))
7935         no_onlink = 1;
7936       else if (unformat (i, "isno"))
7937         is_no = 1;
7938       else
7939         {
7940           clib_warning ("parse error '%U'", format_unformat_error, i);
7941           return -99;
7942         }
7943     }
7944
7945   if (sw_if_index_set == 0)
7946     {
7947       errmsg ("missing interface name or sw_if_index");
7948       return -99;
7949     }
7950   if (!v6_address_set)
7951     {
7952       errmsg ("no address set");
7953       return -99;
7954     }
7955
7956   /* Construct the API message */
7957   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
7958
7959   mp->sw_if_index = ntohl (sw_if_index);
7960   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7961   mp->address_length = address_length;
7962   mp->use_default = use_default;
7963   mp->no_advertise = no_advertise;
7964   mp->off_link = off_link;
7965   mp->no_autoconfig = no_autoconfig;
7966   mp->no_onlink = no_onlink;
7967   mp->is_no = is_no;
7968   mp->val_lifetime = ntohl (val_lifetime);
7969   mp->pref_lifetime = ntohl (pref_lifetime);
7970
7971   /* send it... */
7972   S (mp);
7973
7974   /* Wait for a reply, return good/bad news  */
7975   W (ret);
7976   return ret;
7977 }
7978
7979 static int
7980 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7981 {
7982   unformat_input_t *i = vam->input;
7983   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7984   u32 sw_if_index;
7985   u8 sw_if_index_set = 0;
7986   u8 suppress = 0;
7987   u8 managed = 0;
7988   u8 other = 0;
7989   u8 ll_option = 0;
7990   u8 send_unicast = 0;
7991   u8 cease = 0;
7992   u8 is_no = 0;
7993   u8 default_router = 0;
7994   u32 max_interval = 0;
7995   u32 min_interval = 0;
7996   u32 lifetime = 0;
7997   u32 initial_count = 0;
7998   u32 initial_interval = 0;
7999   int ret;
8000
8001
8002   /* Parse args required to build the message */
8003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8004     {
8005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8006         sw_if_index_set = 1;
8007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8008         sw_if_index_set = 1;
8009       else if (unformat (i, "maxint %d", &max_interval))
8010         ;
8011       else if (unformat (i, "minint %d", &min_interval))
8012         ;
8013       else if (unformat (i, "life %d", &lifetime))
8014         ;
8015       else if (unformat (i, "count %d", &initial_count))
8016         ;
8017       else if (unformat (i, "interval %d", &initial_interval))
8018         ;
8019       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8020         suppress = 1;
8021       else if (unformat (i, "managed"))
8022         managed = 1;
8023       else if (unformat (i, "other"))
8024         other = 1;
8025       else if (unformat (i, "ll"))
8026         ll_option = 1;
8027       else if (unformat (i, "send"))
8028         send_unicast = 1;
8029       else if (unformat (i, "cease"))
8030         cease = 1;
8031       else if (unformat (i, "isno"))
8032         is_no = 1;
8033       else if (unformat (i, "def"))
8034         default_router = 1;
8035       else
8036         {
8037           clib_warning ("parse error '%U'", format_unformat_error, i);
8038           return -99;
8039         }
8040     }
8041
8042   if (sw_if_index_set == 0)
8043     {
8044       errmsg ("missing interface name or sw_if_index");
8045       return -99;
8046     }
8047
8048   /* Construct the API message */
8049   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8050
8051   mp->sw_if_index = ntohl (sw_if_index);
8052   mp->max_interval = ntohl (max_interval);
8053   mp->min_interval = ntohl (min_interval);
8054   mp->lifetime = ntohl (lifetime);
8055   mp->initial_count = ntohl (initial_count);
8056   mp->initial_interval = ntohl (initial_interval);
8057   mp->suppress = suppress;
8058   mp->managed = managed;
8059   mp->other = other;
8060   mp->ll_option = ll_option;
8061   mp->send_unicast = send_unicast;
8062   mp->cease = cease;
8063   mp->is_no = is_no;
8064   mp->default_router = default_router;
8065
8066   /* send it... */
8067   S (mp);
8068
8069   /* Wait for a reply, return good/bad news  */
8070   W (ret);
8071   return ret;
8072 }
8073
8074 static int
8075 api_set_arp_neighbor_limit (vat_main_t * vam)
8076 {
8077   unformat_input_t *i = vam->input;
8078   vl_api_set_arp_neighbor_limit_t *mp;
8079   u32 arp_nbr_limit;
8080   u8 limit_set = 0;
8081   u8 is_ipv6 = 0;
8082   int ret;
8083
8084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8085     {
8086       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8087         limit_set = 1;
8088       else if (unformat (i, "ipv6"))
8089         is_ipv6 = 1;
8090       else
8091         {
8092           clib_warning ("parse error '%U'", format_unformat_error, i);
8093           return -99;
8094         }
8095     }
8096
8097   if (limit_set == 0)
8098     {
8099       errmsg ("missing limit value");
8100       return -99;
8101     }
8102
8103   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8104
8105   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8106   mp->is_ipv6 = is_ipv6;
8107
8108   S (mp);
8109   W (ret);
8110   return ret;
8111 }
8112
8113 static int
8114 api_l2_patch_add_del (vat_main_t * vam)
8115 {
8116   unformat_input_t *i = vam->input;
8117   vl_api_l2_patch_add_del_t *mp;
8118   u32 rx_sw_if_index;
8119   u8 rx_sw_if_index_set = 0;
8120   u32 tx_sw_if_index;
8121   u8 tx_sw_if_index_set = 0;
8122   u8 is_add = 1;
8123   int ret;
8124
8125   /* Parse args required to build the message */
8126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8127     {
8128       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8129         rx_sw_if_index_set = 1;
8130       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8131         tx_sw_if_index_set = 1;
8132       else if (unformat (i, "rx"))
8133         {
8134           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8135             {
8136               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8137                             &rx_sw_if_index))
8138                 rx_sw_if_index_set = 1;
8139             }
8140           else
8141             break;
8142         }
8143       else if (unformat (i, "tx"))
8144         {
8145           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8146             {
8147               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8148                             &tx_sw_if_index))
8149                 tx_sw_if_index_set = 1;
8150             }
8151           else
8152             break;
8153         }
8154       else if (unformat (i, "del"))
8155         is_add = 0;
8156       else
8157         break;
8158     }
8159
8160   if (rx_sw_if_index_set == 0)
8161     {
8162       errmsg ("missing rx interface name or rx_sw_if_index");
8163       return -99;
8164     }
8165
8166   if (tx_sw_if_index_set == 0)
8167     {
8168       errmsg ("missing tx interface name or tx_sw_if_index");
8169       return -99;
8170     }
8171
8172   M (L2_PATCH_ADD_DEL, mp);
8173
8174   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8175   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8176   mp->is_add = is_add;
8177
8178   S (mp);
8179   W (ret);
8180   return ret;
8181 }
8182
8183 static int
8184 api_ioam_enable (vat_main_t * vam)
8185 {
8186   unformat_input_t *input = vam->input;
8187   vl_api_ioam_enable_t *mp;
8188   u32 id = 0;
8189   int has_trace_option = 0;
8190   int has_pot_option = 0;
8191   int has_seqno_option = 0;
8192   int has_analyse_option = 0;
8193   int ret;
8194
8195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8196     {
8197       if (unformat (input, "trace"))
8198         has_trace_option = 1;
8199       else if (unformat (input, "pot"))
8200         has_pot_option = 1;
8201       else if (unformat (input, "seqno"))
8202         has_seqno_option = 1;
8203       else if (unformat (input, "analyse"))
8204         has_analyse_option = 1;
8205       else
8206         break;
8207     }
8208   M (IOAM_ENABLE, mp);
8209   mp->id = htons (id);
8210   mp->seqno = has_seqno_option;
8211   mp->analyse = has_analyse_option;
8212   mp->pot_enable = has_pot_option;
8213   mp->trace_enable = has_trace_option;
8214
8215   S (mp);
8216   W (ret);
8217   return ret;
8218 }
8219
8220
8221 static int
8222 api_ioam_disable (vat_main_t * vam)
8223 {
8224   vl_api_ioam_disable_t *mp;
8225   int ret;
8226
8227   M (IOAM_DISABLE, mp);
8228   S (mp);
8229   W (ret);
8230   return ret;
8231 }
8232
8233 static int
8234 api_sr_tunnel_add_del (vat_main_t * vam)
8235 {
8236   unformat_input_t *i = vam->input;
8237   vl_api_sr_tunnel_add_del_t *mp;
8238   int is_del = 0;
8239   int pl_index;
8240   ip6_address_t src_address;
8241   int src_address_set = 0;
8242   ip6_address_t dst_address;
8243   u32 dst_mask_width;
8244   int dst_address_set = 0;
8245   u16 flags = 0;
8246   u32 rx_table_id = 0;
8247   u32 tx_table_id = 0;
8248   ip6_address_t *segments = 0;
8249   ip6_address_t *this_seg;
8250   ip6_address_t *tags = 0;
8251   ip6_address_t *this_tag;
8252   ip6_address_t next_address, tag;
8253   u8 *name = 0;
8254   u8 *policy_name = 0;
8255   int ret;
8256
8257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8258     {
8259       if (unformat (i, "del"))
8260         is_del = 1;
8261       else if (unformat (i, "name %s", &name))
8262         ;
8263       else if (unformat (i, "policy %s", &policy_name))
8264         ;
8265       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8266         ;
8267       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8268         ;
8269       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8270         src_address_set = 1;
8271       else if (unformat (i, "dst %U/%d",
8272                          unformat_ip6_address, &dst_address, &dst_mask_width))
8273         dst_address_set = 1;
8274       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8275         {
8276           vec_add2 (segments, this_seg, 1);
8277           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8278                        sizeof (*this_seg));
8279         }
8280       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8281         {
8282           vec_add2 (tags, this_tag, 1);
8283           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8284         }
8285       else if (unformat (i, "clean"))
8286         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8287       else if (unformat (i, "protected"))
8288         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8289       else if (unformat (i, "InPE %d", &pl_index))
8290         {
8291           if (pl_index <= 0 || pl_index > 4)
8292             {
8293             pl_index_range_error:
8294               errmsg ("pl index %d out of range", pl_index);
8295               return -99;
8296             }
8297           flags |=
8298             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8299         }
8300       else if (unformat (i, "EgPE %d", &pl_index))
8301         {
8302           if (pl_index <= 0 || pl_index > 4)
8303             goto pl_index_range_error;
8304           flags |=
8305             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8306         }
8307       else if (unformat (i, "OrgSrc %d", &pl_index))
8308         {
8309           if (pl_index <= 0 || pl_index > 4)
8310             goto pl_index_range_error;
8311           flags |=
8312             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8313         }
8314       else
8315         break;
8316     }
8317
8318   if (!src_address_set)
8319     {
8320       errmsg ("src address required");
8321       return -99;
8322     }
8323
8324   if (!dst_address_set)
8325     {
8326       errmsg ("dst address required");
8327       return -99;
8328     }
8329
8330   if (!segments)
8331     {
8332       errmsg ("at least one sr segment required");
8333       return -99;
8334     }
8335
8336   M2 (SR_TUNNEL_ADD_DEL, mp,
8337       vec_len (segments) * sizeof (ip6_address_t)
8338       + vec_len (tags) * sizeof (ip6_address_t));
8339
8340   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8341   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8342   mp->dst_mask_width = dst_mask_width;
8343   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8344   mp->n_segments = vec_len (segments);
8345   mp->n_tags = vec_len (tags);
8346   mp->is_add = is_del == 0;
8347   clib_memcpy (mp->segs_and_tags, segments,
8348                vec_len (segments) * sizeof (ip6_address_t));
8349   clib_memcpy (mp->segs_and_tags +
8350                vec_len (segments) * sizeof (ip6_address_t), tags,
8351                vec_len (tags) * sizeof (ip6_address_t));
8352
8353   mp->outer_vrf_id = ntohl (rx_table_id);
8354   mp->inner_vrf_id = ntohl (tx_table_id);
8355   memcpy (mp->name, name, vec_len (name));
8356   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8357
8358   vec_free (segments);
8359   vec_free (tags);
8360
8361   S (mp);
8362   W (ret);
8363   return ret;
8364 }
8365
8366 static int
8367 api_sr_policy_add_del (vat_main_t * vam)
8368 {
8369   unformat_input_t *input = vam->input;
8370   vl_api_sr_policy_add_del_t *mp;
8371   int is_del = 0;
8372   u8 *name = 0;
8373   u8 *tunnel_name = 0;
8374   u8 **tunnel_names = 0;
8375
8376   int name_set = 0;
8377   int tunnel_set = 0;
8378   int j = 0;
8379   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8380   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8381   int ret;
8382
8383   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8384     {
8385       if (unformat (input, "del"))
8386         is_del = 1;
8387       else if (unformat (input, "name %s", &name))
8388         name_set = 1;
8389       else if (unformat (input, "tunnel %s", &tunnel_name))
8390         {
8391           if (tunnel_name)
8392             {
8393               vec_add1 (tunnel_names, tunnel_name);
8394               /* For serializer:
8395                  - length = #bytes to store in serial vector
8396                  - +1 = byte to store that length
8397                */
8398               tunnel_names_length += (vec_len (tunnel_name) + 1);
8399               tunnel_set = 1;
8400               tunnel_name = 0;
8401             }
8402         }
8403       else
8404         break;
8405     }
8406
8407   if (!name_set)
8408     {
8409       errmsg ("policy name required");
8410       return -99;
8411     }
8412
8413   if ((!tunnel_set) && (!is_del))
8414     {
8415       errmsg ("tunnel name required");
8416       return -99;
8417     }
8418
8419   M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
8420
8421
8422
8423   mp->is_add = !is_del;
8424
8425   memcpy (mp->name, name, vec_len (name));
8426   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8427   u8 *serial_orig = 0;
8428   vec_validate (serial_orig, tunnel_names_length);
8429   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8430   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8431
8432   for (j = 0; j < vec_len (tunnel_names); j++)
8433     {
8434       tun_name_len = vec_len (tunnel_names[j]);
8435       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8436       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8437       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8438       serial_orig += tun_name_len;      // Advance past the copy
8439     }
8440   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8441
8442   vec_free (tunnel_names);
8443   vec_free (tunnel_name);
8444
8445   S (mp);
8446   W (ret);
8447   return ret;
8448 }
8449
8450 static int
8451 api_sr_multicast_map_add_del (vat_main_t * vam)
8452 {
8453   unformat_input_t *input = vam->input;
8454   vl_api_sr_multicast_map_add_del_t *mp;
8455   int is_del = 0;
8456   ip6_address_t multicast_address;
8457   u8 *policy_name = 0;
8458   int multicast_address_set = 0;
8459   int ret;
8460
8461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8462     {
8463       if (unformat (input, "del"))
8464         is_del = 1;
8465       else
8466         if (unformat
8467             (input, "address %U", unformat_ip6_address, &multicast_address))
8468         multicast_address_set = 1;
8469       else if (unformat (input, "sr-policy %s", &policy_name))
8470         ;
8471       else
8472         break;
8473     }
8474
8475   if (!is_del && !policy_name)
8476     {
8477       errmsg ("sr-policy name required");
8478       return -99;
8479     }
8480
8481
8482   if (!multicast_address_set)
8483     {
8484       errmsg ("address required");
8485       return -99;
8486     }
8487
8488   M (SR_MULTICAST_MAP_ADD_DEL, mp);
8489
8490   mp->is_add = !is_del;
8491   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8492   clib_memcpy (mp->multicast_address, &multicast_address,
8493                sizeof (mp->multicast_address));
8494
8495
8496   vec_free (policy_name);
8497
8498   S (mp);
8499   W (ret);
8500   return ret;
8501 }
8502
8503
8504 #define foreach_tcp_proto_field                 \
8505 _(src_port)                                     \
8506 _(dst_port)
8507
8508 #define foreach_udp_proto_field                 \
8509 _(src_port)                                     \
8510 _(dst_port)
8511
8512 #define foreach_ip4_proto_field                 \
8513 _(src_address)                                  \
8514 _(dst_address)                                  \
8515 _(tos)                                          \
8516 _(length)                                       \
8517 _(fragment_id)                                  \
8518 _(ttl)                                          \
8519 _(protocol)                                     \
8520 _(checksum)
8521
8522 typedef struct
8523 {
8524   u16 src_port, dst_port;
8525 } tcpudp_header_t;
8526
8527 #if VPP_API_TEST_BUILTIN == 0
8528 uword
8529 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8530 {
8531   u8 **maskp = va_arg (*args, u8 **);
8532   u8 *mask = 0;
8533   u8 found_something = 0;
8534   tcp_header_t *tcp;
8535
8536 #define _(a) u8 a=0;
8537   foreach_tcp_proto_field;
8538 #undef _
8539
8540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8541     {
8542       if (0);
8543 #define _(a) else if (unformat (input, #a)) a=1;
8544       foreach_tcp_proto_field
8545 #undef _
8546         else
8547         break;
8548     }
8549
8550 #define _(a) found_something += a;
8551   foreach_tcp_proto_field;
8552 #undef _
8553
8554   if (found_something == 0)
8555     return 0;
8556
8557   vec_validate (mask, sizeof (*tcp) - 1);
8558
8559   tcp = (tcp_header_t *) mask;
8560
8561 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8562   foreach_tcp_proto_field;
8563 #undef _
8564
8565   *maskp = mask;
8566   return 1;
8567 }
8568
8569 uword
8570 unformat_udp_mask (unformat_input_t * input, va_list * args)
8571 {
8572   u8 **maskp = va_arg (*args, u8 **);
8573   u8 *mask = 0;
8574   u8 found_something = 0;
8575   udp_header_t *udp;
8576
8577 #define _(a) u8 a=0;
8578   foreach_udp_proto_field;
8579 #undef _
8580
8581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8582     {
8583       if (0);
8584 #define _(a) else if (unformat (input, #a)) a=1;
8585       foreach_udp_proto_field
8586 #undef _
8587         else
8588         break;
8589     }
8590
8591 #define _(a) found_something += a;
8592   foreach_udp_proto_field;
8593 #undef _
8594
8595   if (found_something == 0)
8596     return 0;
8597
8598   vec_validate (mask, sizeof (*udp) - 1);
8599
8600   udp = (udp_header_t *) mask;
8601
8602 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8603   foreach_udp_proto_field;
8604 #undef _
8605
8606   *maskp = mask;
8607   return 1;
8608 }
8609
8610 uword
8611 unformat_l4_mask (unformat_input_t * input, va_list * args)
8612 {
8613   u8 **maskp = va_arg (*args, u8 **);
8614   u16 src_port = 0, dst_port = 0;
8615   tcpudp_header_t *tcpudp;
8616
8617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8618     {
8619       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8620         return 1;
8621       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8622         return 1;
8623       else if (unformat (input, "src_port"))
8624         src_port = 0xFFFF;
8625       else if (unformat (input, "dst_port"))
8626         dst_port = 0xFFFF;
8627       else
8628         return 0;
8629     }
8630
8631   if (!src_port && !dst_port)
8632     return 0;
8633
8634   u8 *mask = 0;
8635   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8636
8637   tcpudp = (tcpudp_header_t *) mask;
8638   tcpudp->src_port = src_port;
8639   tcpudp->dst_port = dst_port;
8640
8641   *maskp = mask;
8642
8643   return 1;
8644 }
8645
8646 uword
8647 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8648 {
8649   u8 **maskp = va_arg (*args, u8 **);
8650   u8 *mask = 0;
8651   u8 found_something = 0;
8652   ip4_header_t *ip;
8653
8654 #define _(a) u8 a=0;
8655   foreach_ip4_proto_field;
8656 #undef _
8657   u8 version = 0;
8658   u8 hdr_length = 0;
8659
8660
8661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8662     {
8663       if (unformat (input, "version"))
8664         version = 1;
8665       else if (unformat (input, "hdr_length"))
8666         hdr_length = 1;
8667       else if (unformat (input, "src"))
8668         src_address = 1;
8669       else if (unformat (input, "dst"))
8670         dst_address = 1;
8671       else if (unformat (input, "proto"))
8672         protocol = 1;
8673
8674 #define _(a) else if (unformat (input, #a)) a=1;
8675       foreach_ip4_proto_field
8676 #undef _
8677         else
8678         break;
8679     }
8680
8681 #define _(a) found_something += a;
8682   foreach_ip4_proto_field;
8683 #undef _
8684
8685   if (found_something == 0)
8686     return 0;
8687
8688   vec_validate (mask, sizeof (*ip) - 1);
8689
8690   ip = (ip4_header_t *) mask;
8691
8692 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8693   foreach_ip4_proto_field;
8694 #undef _
8695
8696   ip->ip_version_and_header_length = 0;
8697
8698   if (version)
8699     ip->ip_version_and_header_length |= 0xF0;
8700
8701   if (hdr_length)
8702     ip->ip_version_and_header_length |= 0x0F;
8703
8704   *maskp = mask;
8705   return 1;
8706 }
8707
8708 #define foreach_ip6_proto_field                 \
8709 _(src_address)                                  \
8710 _(dst_address)                                  \
8711 _(payload_length)                               \
8712 _(hop_limit)                                    \
8713 _(protocol)
8714
8715 uword
8716 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8717 {
8718   u8 **maskp = va_arg (*args, u8 **);
8719   u8 *mask = 0;
8720   u8 found_something = 0;
8721   ip6_header_t *ip;
8722   u32 ip_version_traffic_class_and_flow_label;
8723
8724 #define _(a) u8 a=0;
8725   foreach_ip6_proto_field;
8726 #undef _
8727   u8 version = 0;
8728   u8 traffic_class = 0;
8729   u8 flow_label = 0;
8730
8731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8732     {
8733       if (unformat (input, "version"))
8734         version = 1;
8735       else if (unformat (input, "traffic-class"))
8736         traffic_class = 1;
8737       else if (unformat (input, "flow-label"))
8738         flow_label = 1;
8739       else if (unformat (input, "src"))
8740         src_address = 1;
8741       else if (unformat (input, "dst"))
8742         dst_address = 1;
8743       else if (unformat (input, "proto"))
8744         protocol = 1;
8745
8746 #define _(a) else if (unformat (input, #a)) a=1;
8747       foreach_ip6_proto_field
8748 #undef _
8749         else
8750         break;
8751     }
8752
8753 #define _(a) found_something += a;
8754   foreach_ip6_proto_field;
8755 #undef _
8756
8757   if (found_something == 0)
8758     return 0;
8759
8760   vec_validate (mask, sizeof (*ip) - 1);
8761
8762   ip = (ip6_header_t *) mask;
8763
8764 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8765   foreach_ip6_proto_field;
8766 #undef _
8767
8768   ip_version_traffic_class_and_flow_label = 0;
8769
8770   if (version)
8771     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8772
8773   if (traffic_class)
8774     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8775
8776   if (flow_label)
8777     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8778
8779   ip->ip_version_traffic_class_and_flow_label =
8780     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8781
8782   *maskp = mask;
8783   return 1;
8784 }
8785
8786 uword
8787 unformat_l3_mask (unformat_input_t * input, va_list * args)
8788 {
8789   u8 **maskp = va_arg (*args, u8 **);
8790
8791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8792     {
8793       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8794         return 1;
8795       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8796         return 1;
8797       else
8798         break;
8799     }
8800   return 0;
8801 }
8802
8803 uword
8804 unformat_l2_mask (unformat_input_t * input, va_list * args)
8805 {
8806   u8 **maskp = va_arg (*args, u8 **);
8807   u8 *mask = 0;
8808   u8 src = 0;
8809   u8 dst = 0;
8810   u8 proto = 0;
8811   u8 tag1 = 0;
8812   u8 tag2 = 0;
8813   u8 ignore_tag1 = 0;
8814   u8 ignore_tag2 = 0;
8815   u8 cos1 = 0;
8816   u8 cos2 = 0;
8817   u8 dot1q = 0;
8818   u8 dot1ad = 0;
8819   int len = 14;
8820
8821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8822     {
8823       if (unformat (input, "src"))
8824         src = 1;
8825       else if (unformat (input, "dst"))
8826         dst = 1;
8827       else if (unformat (input, "proto"))
8828         proto = 1;
8829       else if (unformat (input, "tag1"))
8830         tag1 = 1;
8831       else if (unformat (input, "tag2"))
8832         tag2 = 1;
8833       else if (unformat (input, "ignore-tag1"))
8834         ignore_tag1 = 1;
8835       else if (unformat (input, "ignore-tag2"))
8836         ignore_tag2 = 1;
8837       else if (unformat (input, "cos1"))
8838         cos1 = 1;
8839       else if (unformat (input, "cos2"))
8840         cos2 = 1;
8841       else if (unformat (input, "dot1q"))
8842         dot1q = 1;
8843       else if (unformat (input, "dot1ad"))
8844         dot1ad = 1;
8845       else
8846         break;
8847     }
8848   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8849        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8850     return 0;
8851
8852   if (tag1 || ignore_tag1 || cos1 || dot1q)
8853     len = 18;
8854   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8855     len = 22;
8856
8857   vec_validate (mask, len - 1);
8858
8859   if (dst)
8860     memset (mask, 0xff, 6);
8861
8862   if (src)
8863     memset (mask + 6, 0xff, 6);
8864
8865   if (tag2 || dot1ad)
8866     {
8867       /* inner vlan tag */
8868       if (tag2)
8869         {
8870           mask[19] = 0xff;
8871           mask[18] = 0x0f;
8872         }
8873       if (cos2)
8874         mask[18] |= 0xe0;
8875       if (proto)
8876         mask[21] = mask[20] = 0xff;
8877       if (tag1)
8878         {
8879           mask[15] = 0xff;
8880           mask[14] = 0x0f;
8881         }
8882       if (cos1)
8883         mask[14] |= 0xe0;
8884       *maskp = mask;
8885       return 1;
8886     }
8887   if (tag1 | dot1q)
8888     {
8889       if (tag1)
8890         {
8891           mask[15] = 0xff;
8892           mask[14] = 0x0f;
8893         }
8894       if (cos1)
8895         mask[14] |= 0xe0;
8896       if (proto)
8897         mask[16] = mask[17] = 0xff;
8898
8899       *maskp = mask;
8900       return 1;
8901     }
8902   if (cos2)
8903     mask[18] |= 0xe0;
8904   if (cos1)
8905     mask[14] |= 0xe0;
8906   if (proto)
8907     mask[12] = mask[13] = 0xff;
8908
8909   *maskp = mask;
8910   return 1;
8911 }
8912
8913 uword
8914 unformat_classify_mask (unformat_input_t * input, va_list * args)
8915 {
8916   u8 **maskp = va_arg (*args, u8 **);
8917   u32 *skipp = va_arg (*args, u32 *);
8918   u32 *matchp = va_arg (*args, u32 *);
8919   u32 match;
8920   u8 *mask = 0;
8921   u8 *l2 = 0;
8922   u8 *l3 = 0;
8923   u8 *l4 = 0;
8924   int i;
8925
8926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8927     {
8928       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8929         ;
8930       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8931         ;
8932       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8933         ;
8934       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8935         ;
8936       else
8937         break;
8938     }
8939
8940   if (l4 && !l3)
8941     {
8942       vec_free (mask);
8943       vec_free (l2);
8944       vec_free (l4);
8945       return 0;
8946     }
8947
8948   if (mask || l2 || l3 || l4)
8949     {
8950       if (l2 || l3 || l4)
8951         {
8952           /* "With a free Ethernet header in every package" */
8953           if (l2 == 0)
8954             vec_validate (l2, 13);
8955           mask = l2;
8956           if (vec_len (l3))
8957             {
8958               vec_append (mask, l3);
8959               vec_free (l3);
8960             }
8961           if (vec_len (l4))
8962             {
8963               vec_append (mask, l4);
8964               vec_free (l4);
8965             }
8966         }
8967
8968       /* Scan forward looking for the first significant mask octet */
8969       for (i = 0; i < vec_len (mask); i++)
8970         if (mask[i])
8971           break;
8972
8973       /* compute (skip, match) params */
8974       *skipp = i / sizeof (u32x4);
8975       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8976
8977       /* Pad mask to an even multiple of the vector size */
8978       while (vec_len (mask) % sizeof (u32x4))
8979         vec_add1 (mask, 0);
8980
8981       match = vec_len (mask) / sizeof (u32x4);
8982
8983       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8984         {
8985           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8986           if (*tmp || *(tmp + 1))
8987             break;
8988           match--;
8989         }
8990       if (match == 0)
8991         clib_warning ("BUG: match 0");
8992
8993       _vec_len (mask) = match * sizeof (u32x4);
8994
8995       *matchp = match;
8996       *maskp = mask;
8997
8998       return 1;
8999     }
9000
9001   return 0;
9002 }
9003 #endif /* VPP_API_TEST_BUILTIN */
9004
9005 #define foreach_l2_next                         \
9006 _(drop, DROP)                                   \
9007 _(ethernet, ETHERNET_INPUT)                     \
9008 _(ip4, IP4_INPUT)                               \
9009 _(ip6, IP6_INPUT)
9010
9011 uword
9012 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9013 {
9014   u32 *miss_next_indexp = va_arg (*args, u32 *);
9015   u32 next_index = 0;
9016   u32 tmp;
9017
9018 #define _(n,N) \
9019   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9020   foreach_l2_next;
9021 #undef _
9022
9023   if (unformat (input, "%d", &tmp))
9024     {
9025       next_index = tmp;
9026       goto out;
9027     }
9028
9029   return 0;
9030
9031 out:
9032   *miss_next_indexp = next_index;
9033   return 1;
9034 }
9035
9036 #define foreach_ip_next                         \
9037 _(drop, DROP)                                   \
9038 _(local, LOCAL)                                 \
9039 _(rewrite, REWRITE)
9040
9041 uword
9042 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9043 {
9044   u32 *miss_next_indexp = va_arg (*args, u32 *);
9045   u32 next_index = 0;
9046   u32 tmp;
9047
9048 #define _(n,N) \
9049   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9050   foreach_ip_next;
9051 #undef _
9052
9053   if (unformat (input, "%d", &tmp))
9054     {
9055       next_index = tmp;
9056       goto out;
9057     }
9058
9059   return 0;
9060
9061 out:
9062   *miss_next_indexp = next_index;
9063   return 1;
9064 }
9065
9066 #define foreach_acl_next                        \
9067 _(deny, DENY)
9068
9069 uword
9070 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9071 {
9072   u32 *miss_next_indexp = va_arg (*args, u32 *);
9073   u32 next_index = 0;
9074   u32 tmp;
9075
9076 #define _(n,N) \
9077   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9078   foreach_acl_next;
9079 #undef _
9080
9081   if (unformat (input, "permit"))
9082     {
9083       next_index = ~0;
9084       goto out;
9085     }
9086   else if (unformat (input, "%d", &tmp))
9087     {
9088       next_index = tmp;
9089       goto out;
9090     }
9091
9092   return 0;
9093
9094 out:
9095   *miss_next_indexp = next_index;
9096   return 1;
9097 }
9098
9099 uword
9100 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9101 {
9102   u32 *r = va_arg (*args, u32 *);
9103
9104   if (unformat (input, "conform-color"))
9105     *r = POLICE_CONFORM;
9106   else if (unformat (input, "exceed-color"))
9107     *r = POLICE_EXCEED;
9108   else
9109     return 0;
9110
9111   return 1;
9112 }
9113
9114 static int
9115 api_classify_add_del_table (vat_main_t * vam)
9116 {
9117   unformat_input_t *i = vam->input;
9118   vl_api_classify_add_del_table_t *mp;
9119
9120   u32 nbuckets = 2;
9121   u32 skip = ~0;
9122   u32 match = ~0;
9123   int is_add = 1;
9124   int del_chain = 0;
9125   u32 table_index = ~0;
9126   u32 next_table_index = ~0;
9127   u32 miss_next_index = ~0;
9128   u32 memory_size = 32 << 20;
9129   u8 *mask = 0;
9130   u32 current_data_flag = 0;
9131   int current_data_offset = 0;
9132   int ret;
9133
9134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9135     {
9136       if (unformat (i, "del"))
9137         is_add = 0;
9138       else if (unformat (i, "del-chain"))
9139         {
9140           is_add = 0;
9141           del_chain = 1;
9142         }
9143       else if (unformat (i, "buckets %d", &nbuckets))
9144         ;
9145       else if (unformat (i, "memory_size %d", &memory_size))
9146         ;
9147       else if (unformat (i, "skip %d", &skip))
9148         ;
9149       else if (unformat (i, "match %d", &match))
9150         ;
9151       else if (unformat (i, "table %d", &table_index))
9152         ;
9153       else if (unformat (i, "mask %U", unformat_classify_mask,
9154                          &mask, &skip, &match))
9155         ;
9156       else if (unformat (i, "next-table %d", &next_table_index))
9157         ;
9158       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9159                          &miss_next_index))
9160         ;
9161       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9162                          &miss_next_index))
9163         ;
9164       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9165                          &miss_next_index))
9166         ;
9167       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9168         ;
9169       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9170         ;
9171       else
9172         break;
9173     }
9174
9175   if (is_add && mask == 0)
9176     {
9177       errmsg ("Mask required");
9178       return -99;
9179     }
9180
9181   if (is_add && skip == ~0)
9182     {
9183       errmsg ("skip count required");
9184       return -99;
9185     }
9186
9187   if (is_add && match == ~0)
9188     {
9189       errmsg ("match count required");
9190       return -99;
9191     }
9192
9193   if (!is_add && table_index == ~0)
9194     {
9195       errmsg ("table index required for delete");
9196       return -99;
9197     }
9198
9199   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9200
9201   mp->is_add = is_add;
9202   mp->del_chain = del_chain;
9203   mp->table_index = ntohl (table_index);
9204   mp->nbuckets = ntohl (nbuckets);
9205   mp->memory_size = ntohl (memory_size);
9206   mp->skip_n_vectors = ntohl (skip);
9207   mp->match_n_vectors = ntohl (match);
9208   mp->next_table_index = ntohl (next_table_index);
9209   mp->miss_next_index = ntohl (miss_next_index);
9210   mp->current_data_flag = ntohl (current_data_flag);
9211   mp->current_data_offset = ntohl (current_data_offset);
9212   clib_memcpy (mp->mask, mask, vec_len (mask));
9213
9214   vec_free (mask);
9215
9216   S (mp);
9217   W (ret);
9218   return ret;
9219 }
9220
9221 #if VPP_API_TEST_BUILTIN == 0
9222 uword
9223 unformat_l4_match (unformat_input_t * input, va_list * args)
9224 {
9225   u8 **matchp = va_arg (*args, u8 **);
9226
9227   u8 *proto_header = 0;
9228   int src_port = 0;
9229   int dst_port = 0;
9230
9231   tcpudp_header_t h;
9232
9233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9234     {
9235       if (unformat (input, "src_port %d", &src_port))
9236         ;
9237       else if (unformat (input, "dst_port %d", &dst_port))
9238         ;
9239       else
9240         return 0;
9241     }
9242
9243   h.src_port = clib_host_to_net_u16 (src_port);
9244   h.dst_port = clib_host_to_net_u16 (dst_port);
9245   vec_validate (proto_header, sizeof (h) - 1);
9246   memcpy (proto_header, &h, sizeof (h));
9247
9248   *matchp = proto_header;
9249
9250   return 1;
9251 }
9252
9253 uword
9254 unformat_ip4_match (unformat_input_t * input, va_list * args)
9255 {
9256   u8 **matchp = va_arg (*args, u8 **);
9257   u8 *match = 0;
9258   ip4_header_t *ip;
9259   int version = 0;
9260   u32 version_val;
9261   int hdr_length = 0;
9262   u32 hdr_length_val;
9263   int src = 0, dst = 0;
9264   ip4_address_t src_val, dst_val;
9265   int proto = 0;
9266   u32 proto_val;
9267   int tos = 0;
9268   u32 tos_val;
9269   int length = 0;
9270   u32 length_val;
9271   int fragment_id = 0;
9272   u32 fragment_id_val;
9273   int ttl = 0;
9274   int ttl_val;
9275   int checksum = 0;
9276   u32 checksum_val;
9277
9278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9279     {
9280       if (unformat (input, "version %d", &version_val))
9281         version = 1;
9282       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9283         hdr_length = 1;
9284       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9285         src = 1;
9286       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9287         dst = 1;
9288       else if (unformat (input, "proto %d", &proto_val))
9289         proto = 1;
9290       else if (unformat (input, "tos %d", &tos_val))
9291         tos = 1;
9292       else if (unformat (input, "length %d", &length_val))
9293         length = 1;
9294       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9295         fragment_id = 1;
9296       else if (unformat (input, "ttl %d", &ttl_val))
9297         ttl = 1;
9298       else if (unformat (input, "checksum %d", &checksum_val))
9299         checksum = 1;
9300       else
9301         break;
9302     }
9303
9304   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9305       + ttl + checksum == 0)
9306     return 0;
9307
9308   /*
9309    * Aligned because we use the real comparison functions
9310    */
9311   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9312
9313   ip = (ip4_header_t *) match;
9314
9315   /* These are realistically matched in practice */
9316   if (src)
9317     ip->src_address.as_u32 = src_val.as_u32;
9318
9319   if (dst)
9320     ip->dst_address.as_u32 = dst_val.as_u32;
9321
9322   if (proto)
9323     ip->protocol = proto_val;
9324
9325
9326   /* These are not, but they're included for completeness */
9327   if (version)
9328     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9329
9330   if (hdr_length)
9331     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9332
9333   if (tos)
9334     ip->tos = tos_val;
9335
9336   if (length)
9337     ip->length = clib_host_to_net_u16 (length_val);
9338
9339   if (ttl)
9340     ip->ttl = ttl_val;
9341
9342   if (checksum)
9343     ip->checksum = clib_host_to_net_u16 (checksum_val);
9344
9345   *matchp = match;
9346   return 1;
9347 }
9348
9349 uword
9350 unformat_ip6_match (unformat_input_t * input, va_list * args)
9351 {
9352   u8 **matchp = va_arg (*args, u8 **);
9353   u8 *match = 0;
9354   ip6_header_t *ip;
9355   int version = 0;
9356   u32 version_val;
9357   u8 traffic_class = 0;
9358   u32 traffic_class_val = 0;
9359   u8 flow_label = 0;
9360   u8 flow_label_val;
9361   int src = 0, dst = 0;
9362   ip6_address_t src_val, dst_val;
9363   int proto = 0;
9364   u32 proto_val;
9365   int payload_length = 0;
9366   u32 payload_length_val;
9367   int hop_limit = 0;
9368   int hop_limit_val;
9369   u32 ip_version_traffic_class_and_flow_label;
9370
9371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9372     {
9373       if (unformat (input, "version %d", &version_val))
9374         version = 1;
9375       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9376         traffic_class = 1;
9377       else if (unformat (input, "flow_label %d", &flow_label_val))
9378         flow_label = 1;
9379       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9380         src = 1;
9381       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9382         dst = 1;
9383       else if (unformat (input, "proto %d", &proto_val))
9384         proto = 1;
9385       else if (unformat (input, "payload_length %d", &payload_length_val))
9386         payload_length = 1;
9387       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9388         hop_limit = 1;
9389       else
9390         break;
9391     }
9392
9393   if (version + traffic_class + flow_label + src + dst + proto +
9394       payload_length + hop_limit == 0)
9395     return 0;
9396
9397   /*
9398    * Aligned because we use the real comparison functions
9399    */
9400   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9401
9402   ip = (ip6_header_t *) match;
9403
9404   if (src)
9405     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9406
9407   if (dst)
9408     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9409
9410   if (proto)
9411     ip->protocol = proto_val;
9412
9413   ip_version_traffic_class_and_flow_label = 0;
9414
9415   if (version)
9416     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9417
9418   if (traffic_class)
9419     ip_version_traffic_class_and_flow_label |=
9420       (traffic_class_val & 0xFF) << 20;
9421
9422   if (flow_label)
9423     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9424
9425   ip->ip_version_traffic_class_and_flow_label =
9426     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9427
9428   if (payload_length)
9429     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9430
9431   if (hop_limit)
9432     ip->hop_limit = hop_limit_val;
9433
9434   *matchp = match;
9435   return 1;
9436 }
9437
9438 uword
9439 unformat_l3_match (unformat_input_t * input, va_list * args)
9440 {
9441   u8 **matchp = va_arg (*args, u8 **);
9442
9443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9444     {
9445       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9446         return 1;
9447       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9448         return 1;
9449       else
9450         break;
9451     }
9452   return 0;
9453 }
9454
9455 uword
9456 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9457 {
9458   u8 *tagp = va_arg (*args, u8 *);
9459   u32 tag;
9460
9461   if (unformat (input, "%d", &tag))
9462     {
9463       tagp[0] = (tag >> 8) & 0x0F;
9464       tagp[1] = tag & 0xFF;
9465       return 1;
9466     }
9467
9468   return 0;
9469 }
9470
9471 uword
9472 unformat_l2_match (unformat_input_t * input, va_list * args)
9473 {
9474   u8 **matchp = va_arg (*args, u8 **);
9475   u8 *match = 0;
9476   u8 src = 0;
9477   u8 src_val[6];
9478   u8 dst = 0;
9479   u8 dst_val[6];
9480   u8 proto = 0;
9481   u16 proto_val;
9482   u8 tag1 = 0;
9483   u8 tag1_val[2];
9484   u8 tag2 = 0;
9485   u8 tag2_val[2];
9486   int len = 14;
9487   u8 ignore_tag1 = 0;
9488   u8 ignore_tag2 = 0;
9489   u8 cos1 = 0;
9490   u8 cos2 = 0;
9491   u32 cos1_val = 0;
9492   u32 cos2_val = 0;
9493
9494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9495     {
9496       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9497         src = 1;
9498       else
9499         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9500         dst = 1;
9501       else if (unformat (input, "proto %U",
9502                          unformat_ethernet_type_host_byte_order, &proto_val))
9503         proto = 1;
9504       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9505         tag1 = 1;
9506       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9507         tag2 = 1;
9508       else if (unformat (input, "ignore-tag1"))
9509         ignore_tag1 = 1;
9510       else if (unformat (input, "ignore-tag2"))
9511         ignore_tag2 = 1;
9512       else if (unformat (input, "cos1 %d", &cos1_val))
9513         cos1 = 1;
9514       else if (unformat (input, "cos2 %d", &cos2_val))
9515         cos2 = 1;
9516       else
9517         break;
9518     }
9519   if ((src + dst + proto + tag1 + tag2 +
9520        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9521     return 0;
9522
9523   if (tag1 || ignore_tag1 || cos1)
9524     len = 18;
9525   if (tag2 || ignore_tag2 || cos2)
9526     len = 22;
9527
9528   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9529
9530   if (dst)
9531     clib_memcpy (match, dst_val, 6);
9532
9533   if (src)
9534     clib_memcpy (match + 6, src_val, 6);
9535
9536   if (tag2)
9537     {
9538       /* inner vlan tag */
9539       match[19] = tag2_val[1];
9540       match[18] = tag2_val[0];
9541       if (cos2)
9542         match[18] |= (cos2_val & 0x7) << 5;
9543       if (proto)
9544         {
9545           match[21] = proto_val & 0xff;
9546           match[20] = proto_val >> 8;
9547         }
9548       if (tag1)
9549         {
9550           match[15] = tag1_val[1];
9551           match[14] = tag1_val[0];
9552         }
9553       if (cos1)
9554         match[14] |= (cos1_val & 0x7) << 5;
9555       *matchp = match;
9556       return 1;
9557     }
9558   if (tag1)
9559     {
9560       match[15] = tag1_val[1];
9561       match[14] = tag1_val[0];
9562       if (proto)
9563         {
9564           match[17] = proto_val & 0xff;
9565           match[16] = proto_val >> 8;
9566         }
9567       if (cos1)
9568         match[14] |= (cos1_val & 0x7) << 5;
9569
9570       *matchp = match;
9571       return 1;
9572     }
9573   if (cos2)
9574     match[18] |= (cos2_val & 0x7) << 5;
9575   if (cos1)
9576     match[14] |= (cos1_val & 0x7) << 5;
9577   if (proto)
9578     {
9579       match[13] = proto_val & 0xff;
9580       match[12] = proto_val >> 8;
9581     }
9582
9583   *matchp = match;
9584   return 1;
9585 }
9586 #endif
9587
9588 uword
9589 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9590 {
9591   u8 **matchp = va_arg (*args, u8 **);
9592   u32 skip_n_vectors = va_arg (*args, u32);
9593   u32 match_n_vectors = va_arg (*args, u32);
9594
9595   u8 *match = 0;
9596   u8 *l2 = 0;
9597   u8 *l3 = 0;
9598   u8 *l4 = 0;
9599
9600   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9601     {
9602       if (unformat (input, "hex %U", unformat_hex_string, &match))
9603         ;
9604       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9605         ;
9606       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9607         ;
9608       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9609         ;
9610       else
9611         break;
9612     }
9613
9614   if (l4 && !l3)
9615     {
9616       vec_free (match);
9617       vec_free (l2);
9618       vec_free (l4);
9619       return 0;
9620     }
9621
9622   if (match || l2 || l3 || l4)
9623     {
9624       if (l2 || l3 || l4)
9625         {
9626           /* "Win a free Ethernet header in every packet" */
9627           if (l2 == 0)
9628             vec_validate_aligned (l2, 13, sizeof (u32x4));
9629           match = l2;
9630           if (vec_len (l3))
9631             {
9632               vec_append_aligned (match, l3, sizeof (u32x4));
9633               vec_free (l3);
9634             }
9635           if (vec_len (l4))
9636             {
9637               vec_append_aligned (match, l4, sizeof (u32x4));
9638               vec_free (l4);
9639             }
9640         }
9641
9642       /* Make sure the vector is big enough even if key is all 0's */
9643       vec_validate_aligned
9644         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9645          sizeof (u32x4));
9646
9647       /* Set size, include skipped vectors */
9648       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9649
9650       *matchp = match;
9651
9652       return 1;
9653     }
9654
9655   return 0;
9656 }
9657
9658 static int
9659 api_classify_add_del_session (vat_main_t * vam)
9660 {
9661   unformat_input_t *i = vam->input;
9662   vl_api_classify_add_del_session_t *mp;
9663   int is_add = 1;
9664   u32 table_index = ~0;
9665   u32 hit_next_index = ~0;
9666   u32 opaque_index = ~0;
9667   u8 *match = 0;
9668   i32 advance = 0;
9669   u32 skip_n_vectors = 0;
9670   u32 match_n_vectors = 0;
9671   u32 action = 0;
9672   u32 metadata = 0;
9673   int ret;
9674
9675   /*
9676    * Warning: you have to supply skip_n and match_n
9677    * because the API client cant simply look at the classify
9678    * table object.
9679    */
9680
9681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9682     {
9683       if (unformat (i, "del"))
9684         is_add = 0;
9685       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9686                          &hit_next_index))
9687         ;
9688       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9689                          &hit_next_index))
9690         ;
9691       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9692                          &hit_next_index))
9693         ;
9694       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9695         ;
9696       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9697         ;
9698       else if (unformat (i, "opaque-index %d", &opaque_index))
9699         ;
9700       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9701         ;
9702       else if (unformat (i, "match_n %d", &match_n_vectors))
9703         ;
9704       else if (unformat (i, "match %U", api_unformat_classify_match,
9705                          &match, skip_n_vectors, match_n_vectors))
9706         ;
9707       else if (unformat (i, "advance %d", &advance))
9708         ;
9709       else if (unformat (i, "table-index %d", &table_index))
9710         ;
9711       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9712         action = 1;
9713       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9714         action = 2;
9715       else if (unformat (i, "action %d", &action))
9716         ;
9717       else if (unformat (i, "metadata %d", &metadata))
9718         ;
9719       else
9720         break;
9721     }
9722
9723   if (table_index == ~0)
9724     {
9725       errmsg ("Table index required");
9726       return -99;
9727     }
9728
9729   if (is_add && match == 0)
9730     {
9731       errmsg ("Match value required");
9732       return -99;
9733     }
9734
9735   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9736
9737   mp->is_add = is_add;
9738   mp->table_index = ntohl (table_index);
9739   mp->hit_next_index = ntohl (hit_next_index);
9740   mp->opaque_index = ntohl (opaque_index);
9741   mp->advance = ntohl (advance);
9742   mp->action = action;
9743   mp->metadata = ntohl (metadata);
9744   clib_memcpy (mp->match, match, vec_len (match));
9745   vec_free (match);
9746
9747   S (mp);
9748   W (ret);
9749   return ret;
9750 }
9751
9752 static int
9753 api_classify_set_interface_ip_table (vat_main_t * vam)
9754 {
9755   unformat_input_t *i = vam->input;
9756   vl_api_classify_set_interface_ip_table_t *mp;
9757   u32 sw_if_index;
9758   int sw_if_index_set;
9759   u32 table_index = ~0;
9760   u8 is_ipv6 = 0;
9761   int ret;
9762
9763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9764     {
9765       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9766         sw_if_index_set = 1;
9767       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9768         sw_if_index_set = 1;
9769       else if (unformat (i, "table %d", &table_index))
9770         ;
9771       else
9772         {
9773           clib_warning ("parse error '%U'", format_unformat_error, i);
9774           return -99;
9775         }
9776     }
9777
9778   if (sw_if_index_set == 0)
9779     {
9780       errmsg ("missing interface name or sw_if_index");
9781       return -99;
9782     }
9783
9784
9785   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9786
9787   mp->sw_if_index = ntohl (sw_if_index);
9788   mp->table_index = ntohl (table_index);
9789   mp->is_ipv6 = is_ipv6;
9790
9791   S (mp);
9792   W (ret);
9793   return ret;
9794 }
9795
9796 static int
9797 api_classify_set_interface_l2_tables (vat_main_t * vam)
9798 {
9799   unformat_input_t *i = vam->input;
9800   vl_api_classify_set_interface_l2_tables_t *mp;
9801   u32 sw_if_index;
9802   int sw_if_index_set;
9803   u32 ip4_table_index = ~0;
9804   u32 ip6_table_index = ~0;
9805   u32 other_table_index = ~0;
9806   u32 is_input = 1;
9807   int ret;
9808
9809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9810     {
9811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9812         sw_if_index_set = 1;
9813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9814         sw_if_index_set = 1;
9815       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9816         ;
9817       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9818         ;
9819       else if (unformat (i, "other-table %d", &other_table_index))
9820         ;
9821       else if (unformat (i, "is-input %d", &is_input))
9822         ;
9823       else
9824         {
9825           clib_warning ("parse error '%U'", format_unformat_error, i);
9826           return -99;
9827         }
9828     }
9829
9830   if (sw_if_index_set == 0)
9831     {
9832       errmsg ("missing interface name or sw_if_index");
9833       return -99;
9834     }
9835
9836
9837   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
9838
9839   mp->sw_if_index = ntohl (sw_if_index);
9840   mp->ip4_table_index = ntohl (ip4_table_index);
9841   mp->ip6_table_index = ntohl (ip6_table_index);
9842   mp->other_table_index = ntohl (other_table_index);
9843   mp->is_input = (u8) is_input;
9844
9845   S (mp);
9846   W (ret);
9847   return ret;
9848 }
9849
9850 static int
9851 api_set_ipfix_exporter (vat_main_t * vam)
9852 {
9853   unformat_input_t *i = vam->input;
9854   vl_api_set_ipfix_exporter_t *mp;
9855   ip4_address_t collector_address;
9856   u8 collector_address_set = 0;
9857   u32 collector_port = ~0;
9858   ip4_address_t src_address;
9859   u8 src_address_set = 0;
9860   u32 vrf_id = ~0;
9861   u32 path_mtu = ~0;
9862   u32 template_interval = ~0;
9863   u8 udp_checksum = 0;
9864   int ret;
9865
9866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9867     {
9868       if (unformat (i, "collector_address %U", unformat_ip4_address,
9869                     &collector_address))
9870         collector_address_set = 1;
9871       else if (unformat (i, "collector_port %d", &collector_port))
9872         ;
9873       else if (unformat (i, "src_address %U", unformat_ip4_address,
9874                          &src_address))
9875         src_address_set = 1;
9876       else if (unformat (i, "vrf_id %d", &vrf_id))
9877         ;
9878       else if (unformat (i, "path_mtu %d", &path_mtu))
9879         ;
9880       else if (unformat (i, "template_interval %d", &template_interval))
9881         ;
9882       else if (unformat (i, "udp_checksum"))
9883         udp_checksum = 1;
9884       else
9885         break;
9886     }
9887
9888   if (collector_address_set == 0)
9889     {
9890       errmsg ("collector_address required");
9891       return -99;
9892     }
9893
9894   if (src_address_set == 0)
9895     {
9896       errmsg ("src_address required");
9897       return -99;
9898     }
9899
9900   M (SET_IPFIX_EXPORTER, mp);
9901
9902   memcpy (mp->collector_address, collector_address.data,
9903           sizeof (collector_address.data));
9904   mp->collector_port = htons ((u16) collector_port);
9905   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9906   mp->vrf_id = htonl (vrf_id);
9907   mp->path_mtu = htonl (path_mtu);
9908   mp->template_interval = htonl (template_interval);
9909   mp->udp_checksum = udp_checksum;
9910
9911   S (mp);
9912   W (ret);
9913   return ret;
9914 }
9915
9916 static int
9917 api_set_ipfix_classify_stream (vat_main_t * vam)
9918 {
9919   unformat_input_t *i = vam->input;
9920   vl_api_set_ipfix_classify_stream_t *mp;
9921   u32 domain_id = 0;
9922   u32 src_port = UDP_DST_PORT_ipfix;
9923   int ret;
9924
9925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9926     {
9927       if (unformat (i, "domain %d", &domain_id))
9928         ;
9929       else if (unformat (i, "src_port %d", &src_port))
9930         ;
9931       else
9932         {
9933           errmsg ("unknown input `%U'", format_unformat_error, i);
9934           return -99;
9935         }
9936     }
9937
9938   M (SET_IPFIX_CLASSIFY_STREAM, mp);
9939
9940   mp->domain_id = htonl (domain_id);
9941   mp->src_port = htons ((u16) src_port);
9942
9943   S (mp);
9944   W (ret);
9945   return ret;
9946 }
9947
9948 static int
9949 api_ipfix_classify_table_add_del (vat_main_t * vam)
9950 {
9951   unformat_input_t *i = vam->input;
9952   vl_api_ipfix_classify_table_add_del_t *mp;
9953   int is_add = -1;
9954   u32 classify_table_index = ~0;
9955   u8 ip_version = 0;
9956   u8 transport_protocol = 255;
9957   int ret;
9958
9959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9960     {
9961       if (unformat (i, "add"))
9962         is_add = 1;
9963       else if (unformat (i, "del"))
9964         is_add = 0;
9965       else if (unformat (i, "table %d", &classify_table_index))
9966         ;
9967       else if (unformat (i, "ip4"))
9968         ip_version = 4;
9969       else if (unformat (i, "ip6"))
9970         ip_version = 6;
9971       else if (unformat (i, "tcp"))
9972         transport_protocol = 6;
9973       else if (unformat (i, "udp"))
9974         transport_protocol = 17;
9975       else
9976         {
9977           errmsg ("unknown input `%U'", format_unformat_error, i);
9978           return -99;
9979         }
9980     }
9981
9982   if (is_add == -1)
9983     {
9984       errmsg ("expecting: add|del");
9985       return -99;
9986     }
9987   if (classify_table_index == ~0)
9988     {
9989       errmsg ("classifier table not specified");
9990       return -99;
9991     }
9992   if (ip_version == 0)
9993     {
9994       errmsg ("IP version not specified");
9995       return -99;
9996     }
9997
9998   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9999
10000   mp->is_add = is_add;
10001   mp->table_id = htonl (classify_table_index);
10002   mp->ip_version = ip_version;
10003   mp->transport_protocol = transport_protocol;
10004
10005   S (mp);
10006   W (ret);
10007   return ret;
10008 }
10009
10010 static int
10011 api_get_node_index (vat_main_t * vam)
10012 {
10013   unformat_input_t *i = vam->input;
10014   vl_api_get_node_index_t *mp;
10015   u8 *name = 0;
10016   int ret;
10017
10018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10019     {
10020       if (unformat (i, "node %s", &name))
10021         ;
10022       else
10023         break;
10024     }
10025   if (name == 0)
10026     {
10027       errmsg ("node name required");
10028       return -99;
10029     }
10030   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10031     {
10032       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10033       return -99;
10034     }
10035
10036   M (GET_NODE_INDEX, mp);
10037   clib_memcpy (mp->node_name, name, vec_len (name));
10038   vec_free (name);
10039
10040   S (mp);
10041   W (ret);
10042   return ret;
10043 }
10044
10045 static int
10046 api_get_next_index (vat_main_t * vam)
10047 {
10048   unformat_input_t *i = vam->input;
10049   vl_api_get_next_index_t *mp;
10050   u8 *node_name = 0, *next_node_name = 0;
10051   int ret;
10052
10053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10054     {
10055       if (unformat (i, "node-name %s", &node_name))
10056         ;
10057       else if (unformat (i, "next-node-name %s", &next_node_name))
10058         break;
10059     }
10060
10061   if (node_name == 0)
10062     {
10063       errmsg ("node name required");
10064       return -99;
10065     }
10066   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10067     {
10068       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10069       return -99;
10070     }
10071
10072   if (next_node_name == 0)
10073     {
10074       errmsg ("next node name required");
10075       return -99;
10076     }
10077   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10078     {
10079       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10080       return -99;
10081     }
10082
10083   M (GET_NEXT_INDEX, mp);
10084   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10085   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10086   vec_free (node_name);
10087   vec_free (next_node_name);
10088
10089   S (mp);
10090   W (ret);
10091   return ret;
10092 }
10093
10094 static int
10095 api_add_node_next (vat_main_t * vam)
10096 {
10097   unformat_input_t *i = vam->input;
10098   vl_api_add_node_next_t *mp;
10099   u8 *name = 0;
10100   u8 *next = 0;
10101   int ret;
10102
10103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104     {
10105       if (unformat (i, "node %s", &name))
10106         ;
10107       else if (unformat (i, "next %s", &next))
10108         ;
10109       else
10110         break;
10111     }
10112   if (name == 0)
10113     {
10114       errmsg ("node name required");
10115       return -99;
10116     }
10117   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10118     {
10119       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10120       return -99;
10121     }
10122   if (next == 0)
10123     {
10124       errmsg ("next node required");
10125       return -99;
10126     }
10127   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10128     {
10129       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10130       return -99;
10131     }
10132
10133   M (ADD_NODE_NEXT, mp);
10134   clib_memcpy (mp->node_name, name, vec_len (name));
10135   clib_memcpy (mp->next_name, next, vec_len (next));
10136   vec_free (name);
10137   vec_free (next);
10138
10139   S (mp);
10140   W (ret);
10141   return ret;
10142 }
10143
10144 static int
10145 api_l2tpv3_create_tunnel (vat_main_t * vam)
10146 {
10147   unformat_input_t *i = vam->input;
10148   ip6_address_t client_address, our_address;
10149   int client_address_set = 0;
10150   int our_address_set = 0;
10151   u32 local_session_id = 0;
10152   u32 remote_session_id = 0;
10153   u64 local_cookie = 0;
10154   u64 remote_cookie = 0;
10155   u8 l2_sublayer_present = 0;
10156   vl_api_l2tpv3_create_tunnel_t *mp;
10157   int ret;
10158
10159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10160     {
10161       if (unformat (i, "client_address %U", unformat_ip6_address,
10162                     &client_address))
10163         client_address_set = 1;
10164       else if (unformat (i, "our_address %U", unformat_ip6_address,
10165                          &our_address))
10166         our_address_set = 1;
10167       else if (unformat (i, "local_session_id %d", &local_session_id))
10168         ;
10169       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10170         ;
10171       else if (unformat (i, "local_cookie %lld", &local_cookie))
10172         ;
10173       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10174         ;
10175       else if (unformat (i, "l2-sublayer-present"))
10176         l2_sublayer_present = 1;
10177       else
10178         break;
10179     }
10180
10181   if (client_address_set == 0)
10182     {
10183       errmsg ("client_address required");
10184       return -99;
10185     }
10186
10187   if (our_address_set == 0)
10188     {
10189       errmsg ("our_address required");
10190       return -99;
10191     }
10192
10193   M (L2TPV3_CREATE_TUNNEL, mp);
10194
10195   clib_memcpy (mp->client_address, client_address.as_u8,
10196                sizeof (mp->client_address));
10197
10198   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10199
10200   mp->local_session_id = ntohl (local_session_id);
10201   mp->remote_session_id = ntohl (remote_session_id);
10202   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10203   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10204   mp->l2_sublayer_present = l2_sublayer_present;
10205   mp->is_ipv6 = 1;
10206
10207   S (mp);
10208   W (ret);
10209   return ret;
10210 }
10211
10212 static int
10213 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10214 {
10215   unformat_input_t *i = vam->input;
10216   u32 sw_if_index;
10217   u8 sw_if_index_set = 0;
10218   u64 new_local_cookie = 0;
10219   u64 new_remote_cookie = 0;
10220   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10221   int ret;
10222
10223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10224     {
10225       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10226         sw_if_index_set = 1;
10227       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10228         sw_if_index_set = 1;
10229       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10230         ;
10231       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10232         ;
10233       else
10234         break;
10235     }
10236
10237   if (sw_if_index_set == 0)
10238     {
10239       errmsg ("missing interface name or sw_if_index");
10240       return -99;
10241     }
10242
10243   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10244
10245   mp->sw_if_index = ntohl (sw_if_index);
10246   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10247   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10248
10249   S (mp);
10250   W (ret);
10251   return ret;
10252 }
10253
10254 static int
10255 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10256 {
10257   unformat_input_t *i = vam->input;
10258   vl_api_l2tpv3_interface_enable_disable_t *mp;
10259   u32 sw_if_index;
10260   u8 sw_if_index_set = 0;
10261   u8 enable_disable = 1;
10262   int ret;
10263
10264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10265     {
10266       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10267         sw_if_index_set = 1;
10268       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10269         sw_if_index_set = 1;
10270       else if (unformat (i, "enable"))
10271         enable_disable = 1;
10272       else if (unformat (i, "disable"))
10273         enable_disable = 0;
10274       else
10275         break;
10276     }
10277
10278   if (sw_if_index_set == 0)
10279     {
10280       errmsg ("missing interface name or sw_if_index");
10281       return -99;
10282     }
10283
10284   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10285
10286   mp->sw_if_index = ntohl (sw_if_index);
10287   mp->enable_disable = enable_disable;
10288
10289   S (mp);
10290   W (ret);
10291   return ret;
10292 }
10293
10294 static int
10295 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10296 {
10297   unformat_input_t *i = vam->input;
10298   vl_api_l2tpv3_set_lookup_key_t *mp;
10299   u8 key = ~0;
10300   int ret;
10301
10302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10303     {
10304       if (unformat (i, "lookup_v6_src"))
10305         key = L2T_LOOKUP_SRC_ADDRESS;
10306       else if (unformat (i, "lookup_v6_dst"))
10307         key = L2T_LOOKUP_DST_ADDRESS;
10308       else if (unformat (i, "lookup_session_id"))
10309         key = L2T_LOOKUP_SESSION_ID;
10310       else
10311         break;
10312     }
10313
10314   if (key == (u8) ~ 0)
10315     {
10316       errmsg ("l2tp session lookup key unset");
10317       return -99;
10318     }
10319
10320   M (L2TPV3_SET_LOOKUP_KEY, mp);
10321
10322   mp->key = key;
10323
10324   S (mp);
10325   W (ret);
10326   return ret;
10327 }
10328
10329 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10330   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10331 {
10332   vat_main_t *vam = &vat_main;
10333
10334   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10335          format_ip6_address, mp->our_address,
10336          format_ip6_address, mp->client_address,
10337          clib_net_to_host_u32 (mp->sw_if_index));
10338
10339   print (vam->ofp,
10340          "   local cookies %016llx %016llx remote cookie %016llx",
10341          clib_net_to_host_u64 (mp->local_cookie[0]),
10342          clib_net_to_host_u64 (mp->local_cookie[1]),
10343          clib_net_to_host_u64 (mp->remote_cookie));
10344
10345   print (vam->ofp, "   local session-id %d remote session-id %d",
10346          clib_net_to_host_u32 (mp->local_session_id),
10347          clib_net_to_host_u32 (mp->remote_session_id));
10348
10349   print (vam->ofp, "   l2 specific sublayer %s\n",
10350          mp->l2_sublayer_present ? "preset" : "absent");
10351
10352 }
10353
10354 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10355   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10356 {
10357   vat_main_t *vam = &vat_main;
10358   vat_json_node_t *node = NULL;
10359   struct in6_addr addr;
10360
10361   if (VAT_JSON_ARRAY != vam->json_tree.type)
10362     {
10363       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10364       vat_json_init_array (&vam->json_tree);
10365     }
10366   node = vat_json_array_add (&vam->json_tree);
10367
10368   vat_json_init_object (node);
10369
10370   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10371   vat_json_object_add_ip6 (node, "our_address", addr);
10372   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10373   vat_json_object_add_ip6 (node, "client_address", addr);
10374
10375   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10376   vat_json_init_array (lc);
10377   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10378   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10379   vat_json_object_add_uint (node, "remote_cookie",
10380                             clib_net_to_host_u64 (mp->remote_cookie));
10381
10382   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10383   vat_json_object_add_uint (node, "local_session_id",
10384                             clib_net_to_host_u32 (mp->local_session_id));
10385   vat_json_object_add_uint (node, "remote_session_id",
10386                             clib_net_to_host_u32 (mp->remote_session_id));
10387   vat_json_object_add_string_copy (node, "l2_sublayer",
10388                                    mp->l2_sublayer_present ? (u8 *) "present"
10389                                    : (u8 *) "absent");
10390 }
10391
10392 static int
10393 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10394 {
10395   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10396   vl_api_control_ping_t *mp_ping;
10397   int ret;
10398
10399   /* Get list of l2tpv3-tunnel interfaces */
10400   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10401   S (mp);
10402
10403   /* Use a control ping for synchronization */
10404   M (CONTROL_PING, mp_ping);
10405   S (mp_ping);
10406
10407   W (ret);
10408   return ret;
10409 }
10410
10411
10412 static void vl_api_sw_interface_tap_details_t_handler
10413   (vl_api_sw_interface_tap_details_t * mp)
10414 {
10415   vat_main_t *vam = &vat_main;
10416
10417   print (vam->ofp, "%-16s %d",
10418          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10419 }
10420
10421 static void vl_api_sw_interface_tap_details_t_handler_json
10422   (vl_api_sw_interface_tap_details_t * mp)
10423 {
10424   vat_main_t *vam = &vat_main;
10425   vat_json_node_t *node = NULL;
10426
10427   if (VAT_JSON_ARRAY != vam->json_tree.type)
10428     {
10429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10430       vat_json_init_array (&vam->json_tree);
10431     }
10432   node = vat_json_array_add (&vam->json_tree);
10433
10434   vat_json_init_object (node);
10435   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10436   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10437 }
10438
10439 static int
10440 api_sw_interface_tap_dump (vat_main_t * vam)
10441 {
10442   vl_api_sw_interface_tap_dump_t *mp;
10443   vl_api_control_ping_t *mp_ping;
10444   int ret;
10445
10446   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10447   /* Get list of tap interfaces */
10448   M (SW_INTERFACE_TAP_DUMP, mp);
10449   S (mp);
10450
10451   /* Use a control ping for synchronization */
10452   M (CONTROL_PING, mp_ping);
10453   S (mp_ping);
10454
10455   W (ret);
10456   return ret;
10457 }
10458
10459 static uword unformat_vxlan_decap_next
10460   (unformat_input_t * input, va_list * args)
10461 {
10462   u32 *result = va_arg (*args, u32 *);
10463   u32 tmp;
10464
10465   if (unformat (input, "l2"))
10466     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10467   else if (unformat (input, "%d", &tmp))
10468     *result = tmp;
10469   else
10470     return 0;
10471   return 1;
10472 }
10473
10474 static int
10475 api_vxlan_add_del_tunnel (vat_main_t * vam)
10476 {
10477   unformat_input_t *line_input = vam->input;
10478   vl_api_vxlan_add_del_tunnel_t *mp;
10479   ip46_address_t src, dst;
10480   u8 is_add = 1;
10481   u8 ipv4_set = 0, ipv6_set = 0;
10482   u8 src_set = 0;
10483   u8 dst_set = 0;
10484   u8 grp_set = 0;
10485   u32 mcast_sw_if_index = ~0;
10486   u32 encap_vrf_id = 0;
10487   u32 decap_next_index = ~0;
10488   u32 vni = 0;
10489   int ret;
10490
10491   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10492   memset (&src, 0, sizeof src);
10493   memset (&dst, 0, sizeof dst);
10494
10495   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10496     {
10497       if (unformat (line_input, "del"))
10498         is_add = 0;
10499       else
10500         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10501         {
10502           ipv4_set = 1;
10503           src_set = 1;
10504         }
10505       else
10506         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10507         {
10508           ipv4_set = 1;
10509           dst_set = 1;
10510         }
10511       else
10512         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10513         {
10514           ipv6_set = 1;
10515           src_set = 1;
10516         }
10517       else
10518         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10519         {
10520           ipv6_set = 1;
10521           dst_set = 1;
10522         }
10523       else if (unformat (line_input, "group %U %U",
10524                          unformat_ip4_address, &dst.ip4,
10525                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10526         {
10527           grp_set = dst_set = 1;
10528           ipv4_set = 1;
10529         }
10530       else if (unformat (line_input, "group %U",
10531                          unformat_ip4_address, &dst.ip4))
10532         {
10533           grp_set = dst_set = 1;
10534           ipv4_set = 1;
10535         }
10536       else if (unformat (line_input, "group %U %U",
10537                          unformat_ip6_address, &dst.ip6,
10538                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10539         {
10540           grp_set = dst_set = 1;
10541           ipv6_set = 1;
10542         }
10543       else if (unformat (line_input, "group %U",
10544                          unformat_ip6_address, &dst.ip6))
10545         {
10546           grp_set = dst_set = 1;
10547           ipv6_set = 1;
10548         }
10549       else
10550         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10551         ;
10552       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10553         ;
10554       else if (unformat (line_input, "decap-next %U",
10555                          unformat_vxlan_decap_next, &decap_next_index))
10556         ;
10557       else if (unformat (line_input, "vni %d", &vni))
10558         ;
10559       else
10560         {
10561           errmsg ("parse error '%U'", format_unformat_error, line_input);
10562           return -99;
10563         }
10564     }
10565
10566   if (src_set == 0)
10567     {
10568       errmsg ("tunnel src address not specified");
10569       return -99;
10570     }
10571   if (dst_set == 0)
10572     {
10573       errmsg ("tunnel dst address not specified");
10574       return -99;
10575     }
10576
10577   if (grp_set && !ip46_address_is_multicast (&dst))
10578     {
10579       errmsg ("tunnel group address not multicast");
10580       return -99;
10581     }
10582   if (grp_set && mcast_sw_if_index == ~0)
10583     {
10584       errmsg ("tunnel nonexistent multicast device");
10585       return -99;
10586     }
10587   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10588     {
10589       errmsg ("tunnel dst address must be unicast");
10590       return -99;
10591     }
10592
10593
10594   if (ipv4_set && ipv6_set)
10595     {
10596       errmsg ("both IPv4 and IPv6 addresses specified");
10597       return -99;
10598     }
10599
10600   if ((vni == 0) || (vni >> 24))
10601     {
10602       errmsg ("vni not specified or out of range");
10603       return -99;
10604     }
10605
10606   M (VXLAN_ADD_DEL_TUNNEL, mp);
10607
10608   if (ipv6_set)
10609     {
10610       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10611       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10612     }
10613   else
10614     {
10615       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10616       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10617     }
10618   mp->encap_vrf_id = ntohl (encap_vrf_id);
10619   mp->decap_next_index = ntohl (decap_next_index);
10620   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10621   mp->vni = ntohl (vni);
10622   mp->is_add = is_add;
10623   mp->is_ipv6 = ipv6_set;
10624
10625   S (mp);
10626   W (ret);
10627   return ret;
10628 }
10629
10630 static void vl_api_vxlan_tunnel_details_t_handler
10631   (vl_api_vxlan_tunnel_details_t * mp)
10632 {
10633   vat_main_t *vam = &vat_main;
10634   ip46_address_t src, dst;
10635
10636   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10637   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10638
10639   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10640          ntohl (mp->sw_if_index),
10641          format_ip46_address, &src, IP46_TYPE_ANY,
10642          format_ip46_address, &dst, IP46_TYPE_ANY,
10643          ntohl (mp->encap_vrf_id),
10644          ntohl (mp->decap_next_index), ntohl (mp->vni),
10645          ntohl (mp->mcast_sw_if_index));
10646 }
10647
10648 static void vl_api_vxlan_tunnel_details_t_handler_json
10649   (vl_api_vxlan_tunnel_details_t * mp)
10650 {
10651   vat_main_t *vam = &vat_main;
10652   vat_json_node_t *node = NULL;
10653
10654   if (VAT_JSON_ARRAY != vam->json_tree.type)
10655     {
10656       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10657       vat_json_init_array (&vam->json_tree);
10658     }
10659   node = vat_json_array_add (&vam->json_tree);
10660
10661   vat_json_init_object (node);
10662   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10663   if (mp->is_ipv6)
10664     {
10665       struct in6_addr ip6;
10666
10667       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10668       vat_json_object_add_ip6 (node, "src_address", ip6);
10669       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10670       vat_json_object_add_ip6 (node, "dst_address", ip6);
10671     }
10672   else
10673     {
10674       struct in_addr ip4;
10675
10676       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10677       vat_json_object_add_ip4 (node, "src_address", ip4);
10678       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10679       vat_json_object_add_ip4 (node, "dst_address", ip4);
10680     }
10681   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10682   vat_json_object_add_uint (node, "decap_next_index",
10683                             ntohl (mp->decap_next_index));
10684   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10685   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10686   vat_json_object_add_uint (node, "mcast_sw_if_index",
10687                             ntohl (mp->mcast_sw_if_index));
10688 }
10689
10690 static int
10691 api_vxlan_tunnel_dump (vat_main_t * vam)
10692 {
10693   unformat_input_t *i = vam->input;
10694   vl_api_vxlan_tunnel_dump_t *mp;
10695   vl_api_control_ping_t *mp_ping;
10696   u32 sw_if_index;
10697   u8 sw_if_index_set = 0;
10698   int ret;
10699
10700   /* Parse args required to build the message */
10701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10702     {
10703       if (unformat (i, "sw_if_index %d", &sw_if_index))
10704         sw_if_index_set = 1;
10705       else
10706         break;
10707     }
10708
10709   if (sw_if_index_set == 0)
10710     {
10711       sw_if_index = ~0;
10712     }
10713
10714   if (!vam->json_output)
10715     {
10716       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10717              "sw_if_index", "src_address", "dst_address",
10718              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10719     }
10720
10721   /* Get list of vxlan-tunnel interfaces */
10722   M (VXLAN_TUNNEL_DUMP, mp);
10723
10724   mp->sw_if_index = htonl (sw_if_index);
10725
10726   S (mp);
10727
10728   /* Use a control ping for synchronization */
10729   M (CONTROL_PING, mp_ping);
10730   S (mp_ping);
10731
10732   W (ret);
10733   return ret;
10734 }
10735
10736 static int
10737 api_gre_add_del_tunnel (vat_main_t * vam)
10738 {
10739   unformat_input_t *line_input = vam->input;
10740   vl_api_gre_add_del_tunnel_t *mp;
10741   ip4_address_t src4, dst4;
10742   u8 is_add = 1;
10743   u8 teb = 0;
10744   u8 src_set = 0;
10745   u8 dst_set = 0;
10746   u32 outer_fib_id = 0;
10747   int ret;
10748
10749   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10750     {
10751       if (unformat (line_input, "del"))
10752         is_add = 0;
10753       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10754         src_set = 1;
10755       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10756         dst_set = 1;
10757       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10758         ;
10759       else if (unformat (line_input, "teb"))
10760         teb = 1;
10761       else
10762         {
10763           errmsg ("parse error '%U'", format_unformat_error, line_input);
10764           return -99;
10765         }
10766     }
10767
10768   if (src_set == 0)
10769     {
10770       errmsg ("tunnel src address not specified");
10771       return -99;
10772     }
10773   if (dst_set == 0)
10774     {
10775       errmsg ("tunnel dst address not specified");
10776       return -99;
10777     }
10778
10779
10780   M (GRE_ADD_DEL_TUNNEL, mp);
10781
10782   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10783   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10784   mp->outer_fib_id = ntohl (outer_fib_id);
10785   mp->is_add = is_add;
10786   mp->teb = teb;
10787
10788   S (mp);
10789   W (ret);
10790   return ret;
10791 }
10792
10793 static void vl_api_gre_tunnel_details_t_handler
10794   (vl_api_gre_tunnel_details_t * mp)
10795 {
10796   vat_main_t *vam = &vat_main;
10797
10798   print (vam->ofp, "%11d%15U%15U%6d%14d",
10799          ntohl (mp->sw_if_index),
10800          format_ip4_address, &mp->src_address,
10801          format_ip4_address, &mp->dst_address,
10802          mp->teb, ntohl (mp->outer_fib_id));
10803 }
10804
10805 static void vl_api_gre_tunnel_details_t_handler_json
10806   (vl_api_gre_tunnel_details_t * mp)
10807 {
10808   vat_main_t *vam = &vat_main;
10809   vat_json_node_t *node = NULL;
10810   struct in_addr ip4;
10811
10812   if (VAT_JSON_ARRAY != vam->json_tree.type)
10813     {
10814       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10815       vat_json_init_array (&vam->json_tree);
10816     }
10817   node = vat_json_array_add (&vam->json_tree);
10818
10819   vat_json_init_object (node);
10820   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10821   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10822   vat_json_object_add_ip4 (node, "src_address", ip4);
10823   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10824   vat_json_object_add_ip4 (node, "dst_address", ip4);
10825   vat_json_object_add_uint (node, "teb", mp->teb);
10826   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10827 }
10828
10829 static int
10830 api_gre_tunnel_dump (vat_main_t * vam)
10831 {
10832   unformat_input_t *i = vam->input;
10833   vl_api_gre_tunnel_dump_t *mp;
10834   vl_api_control_ping_t *mp_ping;
10835   u32 sw_if_index;
10836   u8 sw_if_index_set = 0;
10837   int ret;
10838
10839   /* Parse args required to build the message */
10840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10841     {
10842       if (unformat (i, "sw_if_index %d", &sw_if_index))
10843         sw_if_index_set = 1;
10844       else
10845         break;
10846     }
10847
10848   if (sw_if_index_set == 0)
10849     {
10850       sw_if_index = ~0;
10851     }
10852
10853   if (!vam->json_output)
10854     {
10855       print (vam->ofp, "%11s%15s%15s%6s%14s",
10856              "sw_if_index", "src_address", "dst_address", "teb",
10857              "outer_fib_id");
10858     }
10859
10860   /* Get list of gre-tunnel interfaces */
10861   M (GRE_TUNNEL_DUMP, mp);
10862
10863   mp->sw_if_index = htonl (sw_if_index);
10864
10865   S (mp);
10866
10867   /* Use a control ping for synchronization */
10868   M (CONTROL_PING, mp_ping);
10869   S (mp_ping);
10870
10871   W (ret);
10872   return ret;
10873 }
10874
10875 static int
10876 api_l2_fib_clear_table (vat_main_t * vam)
10877 {
10878 //  unformat_input_t * i = vam->input;
10879   vl_api_l2_fib_clear_table_t *mp;
10880   int ret;
10881
10882   M (L2_FIB_CLEAR_TABLE, mp);
10883
10884   S (mp);
10885   W (ret);
10886   return ret;
10887 }
10888
10889 static int
10890 api_l2_interface_efp_filter (vat_main_t * vam)
10891 {
10892   unformat_input_t *i = vam->input;
10893   vl_api_l2_interface_efp_filter_t *mp;
10894   u32 sw_if_index;
10895   u8 enable = 1;
10896   u8 sw_if_index_set = 0;
10897   int ret;
10898
10899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10900     {
10901       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10902         sw_if_index_set = 1;
10903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10904         sw_if_index_set = 1;
10905       else if (unformat (i, "enable"))
10906         enable = 1;
10907       else if (unformat (i, "disable"))
10908         enable = 0;
10909       else
10910         {
10911           clib_warning ("parse error '%U'", format_unformat_error, i);
10912           return -99;
10913         }
10914     }
10915
10916   if (sw_if_index_set == 0)
10917     {
10918       errmsg ("missing sw_if_index");
10919       return -99;
10920     }
10921
10922   M (L2_INTERFACE_EFP_FILTER, mp);
10923
10924   mp->sw_if_index = ntohl (sw_if_index);
10925   mp->enable_disable = enable;
10926
10927   S (mp);
10928   W (ret);
10929   return ret;
10930 }
10931
10932 #define foreach_vtr_op                          \
10933 _("disable",  L2_VTR_DISABLED)                  \
10934 _("push-1",  L2_VTR_PUSH_1)                     \
10935 _("push-2",  L2_VTR_PUSH_2)                     \
10936 _("pop-1",  L2_VTR_POP_1)                       \
10937 _("pop-2",  L2_VTR_POP_2)                       \
10938 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10939 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10940 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10941 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10942
10943 static int
10944 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10945 {
10946   unformat_input_t *i = vam->input;
10947   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10948   u32 sw_if_index;
10949   u8 sw_if_index_set = 0;
10950   u8 vtr_op_set = 0;
10951   u32 vtr_op = 0;
10952   u32 push_dot1q = 1;
10953   u32 tag1 = ~0;
10954   u32 tag2 = ~0;
10955   int ret;
10956
10957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10958     {
10959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10960         sw_if_index_set = 1;
10961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10962         sw_if_index_set = 1;
10963       else if (unformat (i, "vtr_op %d", &vtr_op))
10964         vtr_op_set = 1;
10965 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10966       foreach_vtr_op
10967 #undef _
10968         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10969         ;
10970       else if (unformat (i, "tag1 %d", &tag1))
10971         ;
10972       else if (unformat (i, "tag2 %d", &tag2))
10973         ;
10974       else
10975         {
10976           clib_warning ("parse error '%U'", format_unformat_error, i);
10977           return -99;
10978         }
10979     }
10980
10981   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10982     {
10983       errmsg ("missing vtr operation or sw_if_index");
10984       return -99;
10985     }
10986
10987   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
10988   mp->sw_if_index = ntohl (sw_if_index);
10989   mp->vtr_op = ntohl (vtr_op);
10990   mp->push_dot1q = ntohl (push_dot1q);
10991   mp->tag1 = ntohl (tag1);
10992   mp->tag2 = ntohl (tag2);
10993
10994   S (mp);
10995   W (ret);
10996   return ret;
10997 }
10998
10999 static int
11000 api_create_vhost_user_if (vat_main_t * vam)
11001 {
11002   unformat_input_t *i = vam->input;
11003   vl_api_create_vhost_user_if_t *mp;
11004   u8 *file_name;
11005   u8 is_server = 0;
11006   u8 file_name_set = 0;
11007   u32 custom_dev_instance = ~0;
11008   u8 hwaddr[6];
11009   u8 use_custom_mac = 0;
11010   u8 *tag = 0;
11011   int ret;
11012
11013   /* Shut up coverity */
11014   memset (hwaddr, 0, sizeof (hwaddr));
11015
11016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11017     {
11018       if (unformat (i, "socket %s", &file_name))
11019         {
11020           file_name_set = 1;
11021         }
11022       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11023         ;
11024       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11025         use_custom_mac = 1;
11026       else if (unformat (i, "server"))
11027         is_server = 1;
11028       else if (unformat (i, "tag %s", &tag))
11029         ;
11030       else
11031         break;
11032     }
11033
11034   if (file_name_set == 0)
11035     {
11036       errmsg ("missing socket file name");
11037       return -99;
11038     }
11039
11040   if (vec_len (file_name) > 255)
11041     {
11042       errmsg ("socket file name too long");
11043       return -99;
11044     }
11045   vec_add1 (file_name, 0);
11046
11047   M (CREATE_VHOST_USER_IF, mp);
11048
11049   mp->is_server = is_server;
11050   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11051   vec_free (file_name);
11052   if (custom_dev_instance != ~0)
11053     {
11054       mp->renumber = 1;
11055       mp->custom_dev_instance = ntohl (custom_dev_instance);
11056     }
11057   mp->use_custom_mac = use_custom_mac;
11058   clib_memcpy (mp->mac_address, hwaddr, 6);
11059   if (tag)
11060     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11061   vec_free (tag);
11062
11063   S (mp);
11064   W (ret);
11065   return ret;
11066 }
11067
11068 static int
11069 api_modify_vhost_user_if (vat_main_t * vam)
11070 {
11071   unformat_input_t *i = vam->input;
11072   vl_api_modify_vhost_user_if_t *mp;
11073   u8 *file_name;
11074   u8 is_server = 0;
11075   u8 file_name_set = 0;
11076   u32 custom_dev_instance = ~0;
11077   u8 sw_if_index_set = 0;
11078   u32 sw_if_index = (u32) ~ 0;
11079   int ret;
11080
11081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11082     {
11083       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11084         sw_if_index_set = 1;
11085       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11086         sw_if_index_set = 1;
11087       else if (unformat (i, "socket %s", &file_name))
11088         {
11089           file_name_set = 1;
11090         }
11091       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11092         ;
11093       else if (unformat (i, "server"))
11094         is_server = 1;
11095       else
11096         break;
11097     }
11098
11099   if (sw_if_index_set == 0)
11100     {
11101       errmsg ("missing sw_if_index or interface name");
11102       return -99;
11103     }
11104
11105   if (file_name_set == 0)
11106     {
11107       errmsg ("missing socket file name");
11108       return -99;
11109     }
11110
11111   if (vec_len (file_name) > 255)
11112     {
11113       errmsg ("socket file name too long");
11114       return -99;
11115     }
11116   vec_add1 (file_name, 0);
11117
11118   M (MODIFY_VHOST_USER_IF, mp);
11119
11120   mp->sw_if_index = ntohl (sw_if_index);
11121   mp->is_server = is_server;
11122   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11123   vec_free (file_name);
11124   if (custom_dev_instance != ~0)
11125     {
11126       mp->renumber = 1;
11127       mp->custom_dev_instance = ntohl (custom_dev_instance);
11128     }
11129
11130   S (mp);
11131   W (ret);
11132   return ret;
11133 }
11134
11135 static int
11136 api_delete_vhost_user_if (vat_main_t * vam)
11137 {
11138   unformat_input_t *i = vam->input;
11139   vl_api_delete_vhost_user_if_t *mp;
11140   u32 sw_if_index = ~0;
11141   u8 sw_if_index_set = 0;
11142   int ret;
11143
11144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11145     {
11146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11147         sw_if_index_set = 1;
11148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11149         sw_if_index_set = 1;
11150       else
11151         break;
11152     }
11153
11154   if (sw_if_index_set == 0)
11155     {
11156       errmsg ("missing sw_if_index or interface name");
11157       return -99;
11158     }
11159
11160
11161   M (DELETE_VHOST_USER_IF, mp);
11162
11163   mp->sw_if_index = ntohl (sw_if_index);
11164
11165   S (mp);
11166   W (ret);
11167   return ret;
11168 }
11169
11170 static void vl_api_sw_interface_vhost_user_details_t_handler
11171   (vl_api_sw_interface_vhost_user_details_t * mp)
11172 {
11173   vat_main_t *vam = &vat_main;
11174
11175   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11176          (char *) mp->interface_name,
11177          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11178          clib_net_to_host_u64 (mp->features), mp->is_server,
11179          ntohl (mp->num_regions), (char *) mp->sock_filename);
11180   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11181 }
11182
11183 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11184   (vl_api_sw_interface_vhost_user_details_t * mp)
11185 {
11186   vat_main_t *vam = &vat_main;
11187   vat_json_node_t *node = NULL;
11188
11189   if (VAT_JSON_ARRAY != vam->json_tree.type)
11190     {
11191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11192       vat_json_init_array (&vam->json_tree);
11193     }
11194   node = vat_json_array_add (&vam->json_tree);
11195
11196   vat_json_init_object (node);
11197   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11198   vat_json_object_add_string_copy (node, "interface_name",
11199                                    mp->interface_name);
11200   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11201                             ntohl (mp->virtio_net_hdr_sz));
11202   vat_json_object_add_uint (node, "features",
11203                             clib_net_to_host_u64 (mp->features));
11204   vat_json_object_add_uint (node, "is_server", mp->is_server);
11205   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11206   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11207   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11208 }
11209
11210 static int
11211 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11212 {
11213   vl_api_sw_interface_vhost_user_dump_t *mp;
11214   vl_api_control_ping_t *mp_ping;
11215   int ret;
11216   print (vam->ofp,
11217          "Interface name           idx hdr_sz features server regions filename");
11218
11219   /* Get list of vhost-user interfaces */
11220   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11221   S (mp);
11222
11223   /* Use a control ping for synchronization */
11224   M (CONTROL_PING, mp_ping);
11225   S (mp_ping);
11226
11227   W (ret);
11228   return ret;
11229 }
11230
11231 static int
11232 api_show_version (vat_main_t * vam)
11233 {
11234   vl_api_show_version_t *mp;
11235   int ret;
11236
11237   M (SHOW_VERSION, mp);
11238
11239   S (mp);
11240   W (ret);
11241   return ret;
11242 }
11243
11244
11245 static int
11246 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11247 {
11248   unformat_input_t *line_input = vam->input;
11249   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11250   ip4_address_t local4, remote4;
11251   ip6_address_t local6, remote6;
11252   u8 is_add = 1;
11253   u8 ipv4_set = 0, ipv6_set = 0;
11254   u8 local_set = 0;
11255   u8 remote_set = 0;
11256   u32 encap_vrf_id = 0;
11257   u32 decap_vrf_id = 0;
11258   u8 protocol = ~0;
11259   u32 vni;
11260   u8 vni_set = 0;
11261   int ret;
11262
11263   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11264     {
11265       if (unformat (line_input, "del"))
11266         is_add = 0;
11267       else if (unformat (line_input, "local %U",
11268                          unformat_ip4_address, &local4))
11269         {
11270           local_set = 1;
11271           ipv4_set = 1;
11272         }
11273       else if (unformat (line_input, "remote %U",
11274                          unformat_ip4_address, &remote4))
11275         {
11276           remote_set = 1;
11277           ipv4_set = 1;
11278         }
11279       else if (unformat (line_input, "local %U",
11280                          unformat_ip6_address, &local6))
11281         {
11282           local_set = 1;
11283           ipv6_set = 1;
11284         }
11285       else if (unformat (line_input, "remote %U",
11286                          unformat_ip6_address, &remote6))
11287         {
11288           remote_set = 1;
11289           ipv6_set = 1;
11290         }
11291       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11292         ;
11293       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11294         ;
11295       else if (unformat (line_input, "vni %d", &vni))
11296         vni_set = 1;
11297       else if (unformat (line_input, "next-ip4"))
11298         protocol = 1;
11299       else if (unformat (line_input, "next-ip6"))
11300         protocol = 2;
11301       else if (unformat (line_input, "next-ethernet"))
11302         protocol = 3;
11303       else if (unformat (line_input, "next-nsh"))
11304         protocol = 4;
11305       else
11306         {
11307           errmsg ("parse error '%U'", format_unformat_error, line_input);
11308           return -99;
11309         }
11310     }
11311
11312   if (local_set == 0)
11313     {
11314       errmsg ("tunnel local address not specified");
11315       return -99;
11316     }
11317   if (remote_set == 0)
11318     {
11319       errmsg ("tunnel remote address not specified");
11320       return -99;
11321     }
11322   if (ipv4_set && ipv6_set)
11323     {
11324       errmsg ("both IPv4 and IPv6 addresses specified");
11325       return -99;
11326     }
11327
11328   if (vni_set == 0)
11329     {
11330       errmsg ("vni not specified");
11331       return -99;
11332     }
11333
11334   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11335
11336
11337   if (ipv6_set)
11338     {
11339       clib_memcpy (&mp->local, &local6, sizeof (local6));
11340       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11341     }
11342   else
11343     {
11344       clib_memcpy (&mp->local, &local4, sizeof (local4));
11345       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11346     }
11347
11348   mp->encap_vrf_id = ntohl (encap_vrf_id);
11349   mp->decap_vrf_id = ntohl (decap_vrf_id);
11350   mp->protocol = protocol;
11351   mp->vni = ntohl (vni);
11352   mp->is_add = is_add;
11353   mp->is_ipv6 = ipv6_set;
11354
11355   S (mp);
11356   W (ret);
11357   return ret;
11358 }
11359
11360 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11361   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11362 {
11363   vat_main_t *vam = &vat_main;
11364
11365   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11366          ntohl (mp->sw_if_index),
11367          format_ip46_address, &(mp->local[0]),
11368          format_ip46_address, &(mp->remote[0]),
11369          ntohl (mp->vni),
11370          ntohl (mp->protocol),
11371          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11372 }
11373
11374 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11375   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11376 {
11377   vat_main_t *vam = &vat_main;
11378   vat_json_node_t *node = NULL;
11379   struct in_addr ip4;
11380   struct in6_addr ip6;
11381
11382   if (VAT_JSON_ARRAY != vam->json_tree.type)
11383     {
11384       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11385       vat_json_init_array (&vam->json_tree);
11386     }
11387   node = vat_json_array_add (&vam->json_tree);
11388
11389   vat_json_init_object (node);
11390   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11391   if (mp->is_ipv6)
11392     {
11393       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11394       vat_json_object_add_ip6 (node, "local", ip6);
11395       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11396       vat_json_object_add_ip6 (node, "remote", ip6);
11397     }
11398   else
11399     {
11400       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11401       vat_json_object_add_ip4 (node, "local", ip4);
11402       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11403       vat_json_object_add_ip4 (node, "remote", ip4);
11404     }
11405   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11406   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11407   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11408   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11409   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11410 }
11411
11412 static int
11413 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11414 {
11415   unformat_input_t *i = vam->input;
11416   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11417   vl_api_control_ping_t *mp_ping;
11418   u32 sw_if_index;
11419   u8 sw_if_index_set = 0;
11420   int ret;
11421
11422   /* Parse args required to build the message */
11423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11424     {
11425       if (unformat (i, "sw_if_index %d", &sw_if_index))
11426         sw_if_index_set = 1;
11427       else
11428         break;
11429     }
11430
11431   if (sw_if_index_set == 0)
11432     {
11433       sw_if_index = ~0;
11434     }
11435
11436   if (!vam->json_output)
11437     {
11438       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11439              "sw_if_index", "local", "remote", "vni",
11440              "protocol", "encap_vrf_id", "decap_vrf_id");
11441     }
11442
11443   /* Get list of vxlan-tunnel interfaces */
11444   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11445
11446   mp->sw_if_index = htonl (sw_if_index);
11447
11448   S (mp);
11449
11450   /* Use a control ping for synchronization */
11451   M (CONTROL_PING, mp_ping);
11452   S (mp_ping);
11453
11454   W (ret);
11455   return ret;
11456 }
11457
11458 u8 *
11459 format_l2_fib_mac_address (u8 * s, va_list * args)
11460 {
11461   u8 *a = va_arg (*args, u8 *);
11462
11463   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11464                  a[2], a[3], a[4], a[5], a[6], a[7]);
11465 }
11466
11467 static void vl_api_l2_fib_table_entry_t_handler
11468   (vl_api_l2_fib_table_entry_t * mp)
11469 {
11470   vat_main_t *vam = &vat_main;
11471
11472   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11473          "       %d       %d     %d",
11474          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11475          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11476          mp->bvi_mac);
11477 }
11478
11479 static void vl_api_l2_fib_table_entry_t_handler_json
11480   (vl_api_l2_fib_table_entry_t * mp)
11481 {
11482   vat_main_t *vam = &vat_main;
11483   vat_json_node_t *node = NULL;
11484
11485   if (VAT_JSON_ARRAY != vam->json_tree.type)
11486     {
11487       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11488       vat_json_init_array (&vam->json_tree);
11489     }
11490   node = vat_json_array_add (&vam->json_tree);
11491
11492   vat_json_init_object (node);
11493   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11494   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11495   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11496   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11497   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11498   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11499 }
11500
11501 static int
11502 api_l2_fib_table_dump (vat_main_t * vam)
11503 {
11504   unformat_input_t *i = vam->input;
11505   vl_api_l2_fib_table_dump_t *mp;
11506   vl_api_control_ping_t *mp_ping;
11507   u32 bd_id;
11508   u8 bd_id_set = 0;
11509   int ret;
11510
11511   /* Parse args required to build the message */
11512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11513     {
11514       if (unformat (i, "bd_id %d", &bd_id))
11515         bd_id_set = 1;
11516       else
11517         break;
11518     }
11519
11520   if (bd_id_set == 0)
11521     {
11522       errmsg ("missing bridge domain");
11523       return -99;
11524     }
11525
11526   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11527
11528   /* Get list of l2 fib entries */
11529   M (L2_FIB_TABLE_DUMP, mp);
11530
11531   mp->bd_id = ntohl (bd_id);
11532   S (mp);
11533
11534   /* Use a control ping for synchronization */
11535   M (CONTROL_PING, mp_ping);
11536   S (mp_ping);
11537
11538   W (ret);
11539   return ret;
11540 }
11541
11542
11543 static int
11544 api_interface_name_renumber (vat_main_t * vam)
11545 {
11546   unformat_input_t *line_input = vam->input;
11547   vl_api_interface_name_renumber_t *mp;
11548   u32 sw_if_index = ~0;
11549   u32 new_show_dev_instance = ~0;
11550   int ret;
11551
11552   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11553     {
11554       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11555                     &sw_if_index))
11556         ;
11557       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11558         ;
11559       else if (unformat (line_input, "new_show_dev_instance %d",
11560                          &new_show_dev_instance))
11561         ;
11562       else
11563         break;
11564     }
11565
11566   if (sw_if_index == ~0)
11567     {
11568       errmsg ("missing interface name or sw_if_index");
11569       return -99;
11570     }
11571
11572   if (new_show_dev_instance == ~0)
11573     {
11574       errmsg ("missing new_show_dev_instance");
11575       return -99;
11576     }
11577
11578   M (INTERFACE_NAME_RENUMBER, mp);
11579
11580   mp->sw_if_index = ntohl (sw_if_index);
11581   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11582
11583   S (mp);
11584   W (ret);
11585   return ret;
11586 }
11587
11588 static int
11589 api_want_ip4_arp_events (vat_main_t * vam)
11590 {
11591   unformat_input_t *line_input = vam->input;
11592   vl_api_want_ip4_arp_events_t *mp;
11593   ip4_address_t address;
11594   int address_set = 0;
11595   u32 enable_disable = 1;
11596   int ret;
11597
11598   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11599     {
11600       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11601         address_set = 1;
11602       else if (unformat (line_input, "del"))
11603         enable_disable = 0;
11604       else
11605         break;
11606     }
11607
11608   if (address_set == 0)
11609     {
11610       errmsg ("missing addresses");
11611       return -99;
11612     }
11613
11614   M (WANT_IP4_ARP_EVENTS, mp);
11615   mp->enable_disable = enable_disable;
11616   mp->pid = getpid ();
11617   mp->address = address.as_u32;
11618
11619   S (mp);
11620   W (ret);
11621   return ret;
11622 }
11623
11624 static int
11625 api_want_ip6_nd_events (vat_main_t * vam)
11626 {
11627   unformat_input_t *line_input = vam->input;
11628   vl_api_want_ip6_nd_events_t *mp;
11629   ip6_address_t address;
11630   int address_set = 0;
11631   u32 enable_disable = 1;
11632   int ret;
11633
11634   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11635     {
11636       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11637         address_set = 1;
11638       else if (unformat (line_input, "del"))
11639         enable_disable = 0;
11640       else
11641         break;
11642     }
11643
11644   if (address_set == 0)
11645     {
11646       errmsg ("missing addresses");
11647       return -99;
11648     }
11649
11650   M (WANT_IP6_ND_EVENTS, mp);
11651   mp->enable_disable = enable_disable;
11652   mp->pid = getpid ();
11653   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11654
11655   S (mp);
11656   W (ret);
11657   return ret;
11658 }
11659
11660 static int
11661 api_input_acl_set_interface (vat_main_t * vam)
11662 {
11663   unformat_input_t *i = vam->input;
11664   vl_api_input_acl_set_interface_t *mp;
11665   u32 sw_if_index;
11666   int sw_if_index_set;
11667   u32 ip4_table_index = ~0;
11668   u32 ip6_table_index = ~0;
11669   u32 l2_table_index = ~0;
11670   u8 is_add = 1;
11671   int ret;
11672
11673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11674     {
11675       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11676         sw_if_index_set = 1;
11677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11678         sw_if_index_set = 1;
11679       else if (unformat (i, "del"))
11680         is_add = 0;
11681       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11682         ;
11683       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11684         ;
11685       else if (unformat (i, "l2-table %d", &l2_table_index))
11686         ;
11687       else
11688         {
11689           clib_warning ("parse error '%U'", format_unformat_error, i);
11690           return -99;
11691         }
11692     }
11693
11694   if (sw_if_index_set == 0)
11695     {
11696       errmsg ("missing interface name or sw_if_index");
11697       return -99;
11698     }
11699
11700   M (INPUT_ACL_SET_INTERFACE, mp);
11701
11702   mp->sw_if_index = ntohl (sw_if_index);
11703   mp->ip4_table_index = ntohl (ip4_table_index);
11704   mp->ip6_table_index = ntohl (ip6_table_index);
11705   mp->l2_table_index = ntohl (l2_table_index);
11706   mp->is_add = is_add;
11707
11708   S (mp);
11709   W (ret);
11710   return ret;
11711 }
11712
11713 static int
11714 api_ip_address_dump (vat_main_t * vam)
11715 {
11716   unformat_input_t *i = vam->input;
11717   vl_api_ip_address_dump_t *mp;
11718   vl_api_control_ping_t *mp_ping;
11719   u32 sw_if_index = ~0;
11720   u8 sw_if_index_set = 0;
11721   u8 ipv4_set = 0;
11722   u8 ipv6_set = 0;
11723   int ret;
11724
11725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11726     {
11727       if (unformat (i, "sw_if_index %d", &sw_if_index))
11728         sw_if_index_set = 1;
11729       else
11730         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11731         sw_if_index_set = 1;
11732       else if (unformat (i, "ipv4"))
11733         ipv4_set = 1;
11734       else if (unformat (i, "ipv6"))
11735         ipv6_set = 1;
11736       else
11737         break;
11738     }
11739
11740   if (ipv4_set && ipv6_set)
11741     {
11742       errmsg ("ipv4 and ipv6 flags cannot be both set");
11743       return -99;
11744     }
11745
11746   if ((!ipv4_set) && (!ipv6_set))
11747     {
11748       errmsg ("no ipv4 nor ipv6 flag set");
11749       return -99;
11750     }
11751
11752   if (sw_if_index_set == 0)
11753     {
11754       errmsg ("missing interface name or sw_if_index");
11755       return -99;
11756     }
11757
11758   vam->current_sw_if_index = sw_if_index;
11759   vam->is_ipv6 = ipv6_set;
11760
11761   M (IP_ADDRESS_DUMP, mp);
11762   mp->sw_if_index = ntohl (sw_if_index);
11763   mp->is_ipv6 = ipv6_set;
11764   S (mp);
11765
11766   /* Use a control ping for synchronization */
11767   M (CONTROL_PING, mp_ping);
11768   S (mp_ping);
11769
11770   W (ret);
11771   return ret;
11772 }
11773
11774 static int
11775 api_ip_dump (vat_main_t * vam)
11776 {
11777   vl_api_ip_dump_t *mp;
11778   vl_api_control_ping_t *mp_ping;
11779   unformat_input_t *in = vam->input;
11780   int ipv4_set = 0;
11781   int ipv6_set = 0;
11782   int is_ipv6;
11783   int i;
11784   int ret;
11785
11786   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11787     {
11788       if (unformat (in, "ipv4"))
11789         ipv4_set = 1;
11790       else if (unformat (in, "ipv6"))
11791         ipv6_set = 1;
11792       else
11793         break;
11794     }
11795
11796   if (ipv4_set && ipv6_set)
11797     {
11798       errmsg ("ipv4 and ipv6 flags cannot be both set");
11799       return -99;
11800     }
11801
11802   if ((!ipv4_set) && (!ipv6_set))
11803     {
11804       errmsg ("no ipv4 nor ipv6 flag set");
11805       return -99;
11806     }
11807
11808   is_ipv6 = ipv6_set;
11809   vam->is_ipv6 = is_ipv6;
11810
11811   /* free old data */
11812   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11813     {
11814       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11815     }
11816   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11817
11818   M (IP_DUMP, mp);
11819   mp->is_ipv6 = ipv6_set;
11820   S (mp);
11821
11822   /* Use a control ping for synchronization */
11823   M (CONTROL_PING, mp_ping);
11824   S (mp_ping);
11825
11826   W (ret);
11827   return ret;
11828 }
11829
11830 static int
11831 api_ipsec_spd_add_del (vat_main_t * vam)
11832 {
11833   unformat_input_t *i = vam->input;
11834   vl_api_ipsec_spd_add_del_t *mp;
11835   u32 spd_id = ~0;
11836   u8 is_add = 1;
11837   int ret;
11838
11839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11840     {
11841       if (unformat (i, "spd_id %d", &spd_id))
11842         ;
11843       else if (unformat (i, "del"))
11844         is_add = 0;
11845       else
11846         {
11847           clib_warning ("parse error '%U'", format_unformat_error, i);
11848           return -99;
11849         }
11850     }
11851   if (spd_id == ~0)
11852     {
11853       errmsg ("spd_id must be set");
11854       return -99;
11855     }
11856
11857   M (IPSEC_SPD_ADD_DEL, mp);
11858
11859   mp->spd_id = ntohl (spd_id);
11860   mp->is_add = is_add;
11861
11862   S (mp);
11863   W (ret);
11864   return ret;
11865 }
11866
11867 static int
11868 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11869 {
11870   unformat_input_t *i = vam->input;
11871   vl_api_ipsec_interface_add_del_spd_t *mp;
11872   u32 sw_if_index;
11873   u8 sw_if_index_set = 0;
11874   u32 spd_id = (u32) ~ 0;
11875   u8 is_add = 1;
11876   int ret;
11877
11878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11879     {
11880       if (unformat (i, "del"))
11881         is_add = 0;
11882       else if (unformat (i, "spd_id %d", &spd_id))
11883         ;
11884       else
11885         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11886         sw_if_index_set = 1;
11887       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11888         sw_if_index_set = 1;
11889       else
11890         {
11891           clib_warning ("parse error '%U'", format_unformat_error, i);
11892           return -99;
11893         }
11894
11895     }
11896
11897   if (spd_id == (u32) ~ 0)
11898     {
11899       errmsg ("spd_id must be set");
11900       return -99;
11901     }
11902
11903   if (sw_if_index_set == 0)
11904     {
11905       errmsg ("missing interface name or sw_if_index");
11906       return -99;
11907     }
11908
11909   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
11910
11911   mp->spd_id = ntohl (spd_id);
11912   mp->sw_if_index = ntohl (sw_if_index);
11913   mp->is_add = is_add;
11914
11915   S (mp);
11916   W (ret);
11917   return ret;
11918 }
11919
11920 static int
11921 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11922 {
11923   unformat_input_t *i = vam->input;
11924   vl_api_ipsec_spd_add_del_entry_t *mp;
11925   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11926   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11927   i32 priority = 0;
11928   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11929   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11930   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11931   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11932   int ret;
11933
11934   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11935   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11936   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11937   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11938   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11939   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11940
11941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11942     {
11943       if (unformat (i, "del"))
11944         is_add = 0;
11945       if (unformat (i, "outbound"))
11946         is_outbound = 1;
11947       if (unformat (i, "inbound"))
11948         is_outbound = 0;
11949       else if (unformat (i, "spd_id %d", &spd_id))
11950         ;
11951       else if (unformat (i, "sa_id %d", &sa_id))
11952         ;
11953       else if (unformat (i, "priority %d", &priority))
11954         ;
11955       else if (unformat (i, "protocol %d", &protocol))
11956         ;
11957       else if (unformat (i, "lport_start %d", &lport_start))
11958         ;
11959       else if (unformat (i, "lport_stop %d", &lport_stop))
11960         ;
11961       else if (unformat (i, "rport_start %d", &rport_start))
11962         ;
11963       else if (unformat (i, "rport_stop %d", &rport_stop))
11964         ;
11965       else
11966         if (unformat
11967             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11968         {
11969           is_ipv6 = 0;
11970           is_ip_any = 0;
11971         }
11972       else
11973         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11974         {
11975           is_ipv6 = 0;
11976           is_ip_any = 0;
11977         }
11978       else
11979         if (unformat
11980             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11981         {
11982           is_ipv6 = 0;
11983           is_ip_any = 0;
11984         }
11985       else
11986         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11987         {
11988           is_ipv6 = 0;
11989           is_ip_any = 0;
11990         }
11991       else
11992         if (unformat
11993             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11994         {
11995           is_ipv6 = 1;
11996           is_ip_any = 0;
11997         }
11998       else
11999         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12000         {
12001           is_ipv6 = 1;
12002           is_ip_any = 0;
12003         }
12004       else
12005         if (unformat
12006             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12007         {
12008           is_ipv6 = 1;
12009           is_ip_any = 0;
12010         }
12011       else
12012         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12013         {
12014           is_ipv6 = 1;
12015           is_ip_any = 0;
12016         }
12017       else
12018         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12019         {
12020           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12021             {
12022               clib_warning ("unsupported action: 'resolve'");
12023               return -99;
12024             }
12025         }
12026       else
12027         {
12028           clib_warning ("parse error '%U'", format_unformat_error, i);
12029           return -99;
12030         }
12031
12032     }
12033
12034   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12035
12036   mp->spd_id = ntohl (spd_id);
12037   mp->priority = ntohl (priority);
12038   mp->is_outbound = is_outbound;
12039
12040   mp->is_ipv6 = is_ipv6;
12041   if (is_ipv6 || is_ip_any)
12042     {
12043       clib_memcpy (mp->remote_address_start, &raddr6_start,
12044                    sizeof (ip6_address_t));
12045       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12046                    sizeof (ip6_address_t));
12047       clib_memcpy (mp->local_address_start, &laddr6_start,
12048                    sizeof (ip6_address_t));
12049       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12050                    sizeof (ip6_address_t));
12051     }
12052   else
12053     {
12054       clib_memcpy (mp->remote_address_start, &raddr4_start,
12055                    sizeof (ip4_address_t));
12056       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12057                    sizeof (ip4_address_t));
12058       clib_memcpy (mp->local_address_start, &laddr4_start,
12059                    sizeof (ip4_address_t));
12060       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12061                    sizeof (ip4_address_t));
12062     }
12063   mp->protocol = (u8) protocol;
12064   mp->local_port_start = ntohs ((u16) lport_start);
12065   mp->local_port_stop = ntohs ((u16) lport_stop);
12066   mp->remote_port_start = ntohs ((u16) rport_start);
12067   mp->remote_port_stop = ntohs ((u16) rport_stop);
12068   mp->policy = (u8) policy;
12069   mp->sa_id = ntohl (sa_id);
12070   mp->is_add = is_add;
12071   mp->is_ip_any = is_ip_any;
12072   S (mp);
12073   W (ret);
12074   return ret;
12075 }
12076
12077 static int
12078 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12079 {
12080   unformat_input_t *i = vam->input;
12081   vl_api_ipsec_sad_add_del_entry_t *mp;
12082   u32 sad_id = 0, spi = 0;
12083   u8 *ck = 0, *ik = 0;
12084   u8 is_add = 1;
12085
12086   u8 protocol = IPSEC_PROTOCOL_AH;
12087   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12088   u32 crypto_alg = 0, integ_alg = 0;
12089   ip4_address_t tun_src4;
12090   ip4_address_t tun_dst4;
12091   ip6_address_t tun_src6;
12092   ip6_address_t tun_dst6;
12093   int ret;
12094
12095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12096     {
12097       if (unformat (i, "del"))
12098         is_add = 0;
12099       else if (unformat (i, "sad_id %d", &sad_id))
12100         ;
12101       else if (unformat (i, "spi %d", &spi))
12102         ;
12103       else if (unformat (i, "esp"))
12104         protocol = IPSEC_PROTOCOL_ESP;
12105       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12106         {
12107           is_tunnel = 1;
12108           is_tunnel_ipv6 = 0;
12109         }
12110       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12111         {
12112           is_tunnel = 1;
12113           is_tunnel_ipv6 = 0;
12114         }
12115       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12116         {
12117           is_tunnel = 1;
12118           is_tunnel_ipv6 = 1;
12119         }
12120       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12121         {
12122           is_tunnel = 1;
12123           is_tunnel_ipv6 = 1;
12124         }
12125       else
12126         if (unformat
12127             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12128         {
12129           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12130               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12131             {
12132               clib_warning ("unsupported crypto-alg: '%U'",
12133                             format_ipsec_crypto_alg, crypto_alg);
12134               return -99;
12135             }
12136         }
12137       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12138         ;
12139       else
12140         if (unformat
12141             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12142         {
12143           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12144               integ_alg >= IPSEC_INTEG_N_ALG)
12145             {
12146               clib_warning ("unsupported integ-alg: '%U'",
12147                             format_ipsec_integ_alg, integ_alg);
12148               return -99;
12149             }
12150         }
12151       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12152         ;
12153       else
12154         {
12155           clib_warning ("parse error '%U'", format_unformat_error, i);
12156           return -99;
12157         }
12158
12159     }
12160
12161   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12162
12163   mp->sad_id = ntohl (sad_id);
12164   mp->is_add = is_add;
12165   mp->protocol = protocol;
12166   mp->spi = ntohl (spi);
12167   mp->is_tunnel = is_tunnel;
12168   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12169   mp->crypto_algorithm = crypto_alg;
12170   mp->integrity_algorithm = integ_alg;
12171   mp->crypto_key_length = vec_len (ck);
12172   mp->integrity_key_length = vec_len (ik);
12173
12174   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12175     mp->crypto_key_length = sizeof (mp->crypto_key);
12176
12177   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12178     mp->integrity_key_length = sizeof (mp->integrity_key);
12179
12180   if (ck)
12181     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12182   if (ik)
12183     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12184
12185   if (is_tunnel)
12186     {
12187       if (is_tunnel_ipv6)
12188         {
12189           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12190                        sizeof (ip6_address_t));
12191           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12192                        sizeof (ip6_address_t));
12193         }
12194       else
12195         {
12196           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12197                        sizeof (ip4_address_t));
12198           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12199                        sizeof (ip4_address_t));
12200         }
12201     }
12202
12203   S (mp);
12204   W (ret);
12205   return ret;
12206 }
12207
12208 static int
12209 api_ipsec_sa_set_key (vat_main_t * vam)
12210 {
12211   unformat_input_t *i = vam->input;
12212   vl_api_ipsec_sa_set_key_t *mp;
12213   u32 sa_id;
12214   u8 *ck = 0, *ik = 0;
12215   int ret;
12216
12217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12218     {
12219       if (unformat (i, "sa_id %d", &sa_id))
12220         ;
12221       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12222         ;
12223       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12224         ;
12225       else
12226         {
12227           clib_warning ("parse error '%U'", format_unformat_error, i);
12228           return -99;
12229         }
12230     }
12231
12232   M (IPSEC_SA_SET_KEY, mp);
12233
12234   mp->sa_id = ntohl (sa_id);
12235   mp->crypto_key_length = vec_len (ck);
12236   mp->integrity_key_length = vec_len (ik);
12237
12238   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12239     mp->crypto_key_length = sizeof (mp->crypto_key);
12240
12241   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12242     mp->integrity_key_length = sizeof (mp->integrity_key);
12243
12244   if (ck)
12245     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12246   if (ik)
12247     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12248
12249   S (mp);
12250   W (ret);
12251   return ret;
12252 }
12253
12254 static int
12255 api_ikev2_profile_add_del (vat_main_t * vam)
12256 {
12257   unformat_input_t *i = vam->input;
12258   vl_api_ikev2_profile_add_del_t *mp;
12259   u8 is_add = 1;
12260   u8 *name = 0;
12261   int ret;
12262
12263   const char *valid_chars = "a-zA-Z0-9_";
12264
12265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12266     {
12267       if (unformat (i, "del"))
12268         is_add = 0;
12269       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12270         vec_add1 (name, 0);
12271       else
12272         {
12273           errmsg ("parse error '%U'", format_unformat_error, i);
12274           return -99;
12275         }
12276     }
12277
12278   if (!vec_len (name))
12279     {
12280       errmsg ("profile name must be specified");
12281       return -99;
12282     }
12283
12284   if (vec_len (name) > 64)
12285     {
12286       errmsg ("profile name too long");
12287       return -99;
12288     }
12289
12290   M (IKEV2_PROFILE_ADD_DEL, mp);
12291
12292   clib_memcpy (mp->name, name, vec_len (name));
12293   mp->is_add = is_add;
12294   vec_free (name);
12295
12296   S (mp);
12297   W (ret);
12298   return ret;
12299 }
12300
12301 static int
12302 api_ikev2_profile_set_auth (vat_main_t * vam)
12303 {
12304   unformat_input_t *i = vam->input;
12305   vl_api_ikev2_profile_set_auth_t *mp;
12306   u8 *name = 0;
12307   u8 *data = 0;
12308   u32 auth_method = 0;
12309   u8 is_hex = 0;
12310   int ret;
12311
12312   const char *valid_chars = "a-zA-Z0-9_";
12313
12314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12315     {
12316       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12317         vec_add1 (name, 0);
12318       else if (unformat (i, "auth_method %U",
12319                          unformat_ikev2_auth_method, &auth_method))
12320         ;
12321       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12322         is_hex = 1;
12323       else if (unformat (i, "auth_data %v", &data))
12324         ;
12325       else
12326         {
12327           errmsg ("parse error '%U'", format_unformat_error, i);
12328           return -99;
12329         }
12330     }
12331
12332   if (!vec_len (name))
12333     {
12334       errmsg ("profile name must be specified");
12335       return -99;
12336     }
12337
12338   if (vec_len (name) > 64)
12339     {
12340       errmsg ("profile name too long");
12341       return -99;
12342     }
12343
12344   if (!vec_len (data))
12345     {
12346       errmsg ("auth_data must be specified");
12347       return -99;
12348     }
12349
12350   if (!auth_method)
12351     {
12352       errmsg ("auth_method must be specified");
12353       return -99;
12354     }
12355
12356   M (IKEV2_PROFILE_SET_AUTH, mp);
12357
12358   mp->is_hex = is_hex;
12359   mp->auth_method = (u8) auth_method;
12360   mp->data_len = vec_len (data);
12361   clib_memcpy (mp->name, name, vec_len (name));
12362   clib_memcpy (mp->data, data, vec_len (data));
12363   vec_free (name);
12364   vec_free (data);
12365
12366   S (mp);
12367   W (ret);
12368   return ret;
12369 }
12370
12371 static int
12372 api_ikev2_profile_set_id (vat_main_t * vam)
12373 {
12374   unformat_input_t *i = vam->input;
12375   vl_api_ikev2_profile_set_id_t *mp;
12376   u8 *name = 0;
12377   u8 *data = 0;
12378   u8 is_local = 0;
12379   u32 id_type = 0;
12380   ip4_address_t ip4;
12381   int ret;
12382
12383   const char *valid_chars = "a-zA-Z0-9_";
12384
12385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12386     {
12387       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12388         vec_add1 (name, 0);
12389       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12390         ;
12391       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12392         {
12393           data = vec_new (u8, 4);
12394           clib_memcpy (data, ip4.as_u8, 4);
12395         }
12396       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12397         ;
12398       else if (unformat (i, "id_data %v", &data))
12399         ;
12400       else if (unformat (i, "local"))
12401         is_local = 1;
12402       else if (unformat (i, "remote"))
12403         is_local = 0;
12404       else
12405         {
12406           errmsg ("parse error '%U'", format_unformat_error, i);
12407           return -99;
12408         }
12409     }
12410
12411   if (!vec_len (name))
12412     {
12413       errmsg ("profile name must be specified");
12414       return -99;
12415     }
12416
12417   if (vec_len (name) > 64)
12418     {
12419       errmsg ("profile name too long");
12420       return -99;
12421     }
12422
12423   if (!vec_len (data))
12424     {
12425       errmsg ("id_data must be specified");
12426       return -99;
12427     }
12428
12429   if (!id_type)
12430     {
12431       errmsg ("id_type must be specified");
12432       return -99;
12433     }
12434
12435   M (IKEV2_PROFILE_SET_ID, mp);
12436
12437   mp->is_local = is_local;
12438   mp->id_type = (u8) id_type;
12439   mp->data_len = vec_len (data);
12440   clib_memcpy (mp->name, name, vec_len (name));
12441   clib_memcpy (mp->data, data, vec_len (data));
12442   vec_free (name);
12443   vec_free (data);
12444
12445   S (mp);
12446   W (ret);
12447   return ret;
12448 }
12449
12450 static int
12451 api_ikev2_profile_set_ts (vat_main_t * vam)
12452 {
12453   unformat_input_t *i = vam->input;
12454   vl_api_ikev2_profile_set_ts_t *mp;
12455   u8 *name = 0;
12456   u8 is_local = 0;
12457   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12458   ip4_address_t start_addr, end_addr;
12459
12460   const char *valid_chars = "a-zA-Z0-9_";
12461   int ret;
12462
12463   start_addr.as_u32 = 0;
12464   end_addr.as_u32 = (u32) ~ 0;
12465
12466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12467     {
12468       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12469         vec_add1 (name, 0);
12470       else if (unformat (i, "protocol %d", &proto))
12471         ;
12472       else if (unformat (i, "start_port %d", &start_port))
12473         ;
12474       else if (unformat (i, "end_port %d", &end_port))
12475         ;
12476       else
12477         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12478         ;
12479       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12480         ;
12481       else if (unformat (i, "local"))
12482         is_local = 1;
12483       else if (unformat (i, "remote"))
12484         is_local = 0;
12485       else
12486         {
12487           errmsg ("parse error '%U'", format_unformat_error, i);
12488           return -99;
12489         }
12490     }
12491
12492   if (!vec_len (name))
12493     {
12494       errmsg ("profile name must be specified");
12495       return -99;
12496     }
12497
12498   if (vec_len (name) > 64)
12499     {
12500       errmsg ("profile name too long");
12501       return -99;
12502     }
12503
12504   M (IKEV2_PROFILE_SET_TS, mp);
12505
12506   mp->is_local = is_local;
12507   mp->proto = (u8) proto;
12508   mp->start_port = (u16) start_port;
12509   mp->end_port = (u16) end_port;
12510   mp->start_addr = start_addr.as_u32;
12511   mp->end_addr = end_addr.as_u32;
12512   clib_memcpy (mp->name, name, vec_len (name));
12513   vec_free (name);
12514
12515   S (mp);
12516   W (ret);
12517   return ret;
12518 }
12519
12520 static int
12521 api_ikev2_set_local_key (vat_main_t * vam)
12522 {
12523   unformat_input_t *i = vam->input;
12524   vl_api_ikev2_set_local_key_t *mp;
12525   u8 *file = 0;
12526   int ret;
12527
12528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12529     {
12530       if (unformat (i, "file %v", &file))
12531         vec_add1 (file, 0);
12532       else
12533         {
12534           errmsg ("parse error '%U'", format_unformat_error, i);
12535           return -99;
12536         }
12537     }
12538
12539   if (!vec_len (file))
12540     {
12541       errmsg ("RSA key file must be specified");
12542       return -99;
12543     }
12544
12545   if (vec_len (file) > 256)
12546     {
12547       errmsg ("file name too long");
12548       return -99;
12549     }
12550
12551   M (IKEV2_SET_LOCAL_KEY, mp);
12552
12553   clib_memcpy (mp->key_file, file, vec_len (file));
12554   vec_free (file);
12555
12556   S (mp);
12557   W (ret);
12558   return ret;
12559 }
12560
12561 static int
12562 api_ikev2_set_responder (vat_main_t * vam)
12563 {
12564   unformat_input_t *i = vam->input;
12565   vl_api_ikev2_set_responder_t *mp;
12566   int ret;
12567   u8 *name = 0;
12568   u32 sw_if_index = ~0;
12569   ip4_address_t address;
12570
12571   const char *valid_chars = "a-zA-Z0-9_";
12572
12573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12574     {
12575       if (unformat
12576           (i, "%U interface %d address %U", unformat_token, valid_chars,
12577            &name, &sw_if_index, unformat_ip4_address, &address))
12578         vec_add1 (name, 0);
12579       else
12580         {
12581           errmsg ("parse error '%U'", format_unformat_error, i);
12582           return -99;
12583         }
12584     }
12585
12586   if (!vec_len (name))
12587     {
12588       errmsg ("profile name must be specified");
12589       return -99;
12590     }
12591
12592   if (vec_len (name) > 64)
12593     {
12594       errmsg ("profile name too long");
12595       return -99;
12596     }
12597
12598   M (IKEV2_SET_RESPONDER, mp);
12599
12600   clib_memcpy (mp->name, name, vec_len (name));
12601   vec_free (name);
12602
12603   mp->sw_if_index = sw_if_index;
12604   clib_memcpy (mp->address, &address, sizeof (address));
12605
12606   S (mp);
12607   W (ret);
12608   return ret;
12609 }
12610
12611 static int
12612 api_ikev2_set_ike_transforms (vat_main_t * vam)
12613 {
12614   unformat_input_t *i = vam->input;
12615   vl_api_ikev2_set_ike_transforms_t *mp;
12616   int ret;
12617   u8 *name = 0;
12618   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12619
12620   const char *valid_chars = "a-zA-Z0-9_";
12621
12622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12623     {
12624       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12625                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12626         vec_add1 (name, 0);
12627       else
12628         {
12629           errmsg ("parse error '%U'", format_unformat_error, i);
12630           return -99;
12631         }
12632     }
12633
12634   if (!vec_len (name))
12635     {
12636       errmsg ("profile name must be specified");
12637       return -99;
12638     }
12639
12640   if (vec_len (name) > 64)
12641     {
12642       errmsg ("profile name too long");
12643       return -99;
12644     }
12645
12646   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12647
12648   clib_memcpy (mp->name, name, vec_len (name));
12649   vec_free (name);
12650   mp->crypto_alg = crypto_alg;
12651   mp->crypto_key_size = crypto_key_size;
12652   mp->integ_alg = integ_alg;
12653   mp->dh_group = dh_group;
12654
12655   S (mp);
12656   W (ret);
12657   return ret;
12658 }
12659
12660
12661 static int
12662 api_ikev2_set_esp_transforms (vat_main_t * vam)
12663 {
12664   unformat_input_t *i = vam->input;
12665   vl_api_ikev2_set_esp_transforms_t *mp;
12666   int ret;
12667   u8 *name = 0;
12668   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12669
12670   const char *valid_chars = "a-zA-Z0-9_";
12671
12672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12673     {
12674       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12675                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12676         vec_add1 (name, 0);
12677       else
12678         {
12679           errmsg ("parse error '%U'", format_unformat_error, i);
12680           return -99;
12681         }
12682     }
12683
12684   if (!vec_len (name))
12685     {
12686       errmsg ("profile name must be specified");
12687       return -99;
12688     }
12689
12690   if (vec_len (name) > 64)
12691     {
12692       errmsg ("profile name too long");
12693       return -99;
12694     }
12695
12696   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12697
12698   clib_memcpy (mp->name, name, vec_len (name));
12699   vec_free (name);
12700   mp->crypto_alg = crypto_alg;
12701   mp->crypto_key_size = crypto_key_size;
12702   mp->integ_alg = integ_alg;
12703   mp->dh_group = dh_group;
12704
12705   S (mp);
12706   W (ret);
12707   return ret;
12708 }
12709
12710 static int
12711 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12712 {
12713   unformat_input_t *i = vam->input;
12714   vl_api_ikev2_set_sa_lifetime_t *mp;
12715   int ret;
12716   u8 *name = 0;
12717   u64 lifetime, lifetime_maxdata;
12718   u32 lifetime_jitter, handover;
12719
12720   const char *valid_chars = "a-zA-Z0-9_";
12721
12722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12723     {
12724       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12725                     &lifetime, &lifetime_jitter, &handover,
12726                     &lifetime_maxdata))
12727         vec_add1 (name, 0);
12728       else
12729         {
12730           errmsg ("parse error '%U'", format_unformat_error, i);
12731           return -99;
12732         }
12733     }
12734
12735   if (!vec_len (name))
12736     {
12737       errmsg ("profile name must be specified");
12738       return -99;
12739     }
12740
12741   if (vec_len (name) > 64)
12742     {
12743       errmsg ("profile name too long");
12744       return -99;
12745     }
12746
12747   M (IKEV2_SET_SA_LIFETIME, mp);
12748
12749   clib_memcpy (mp->name, name, vec_len (name));
12750   vec_free (name);
12751   mp->lifetime = lifetime;
12752   mp->lifetime_jitter = lifetime_jitter;
12753   mp->handover = handover;
12754   mp->lifetime_maxdata = lifetime_maxdata;
12755
12756   S (mp);
12757   W (ret);
12758   return ret;
12759 }
12760
12761 static int
12762 api_ikev2_initiate_sa_init (vat_main_t * vam)
12763 {
12764   unformat_input_t *i = vam->input;
12765   vl_api_ikev2_initiate_sa_init_t *mp;
12766   int ret;
12767   u8 *name = 0;
12768
12769   const char *valid_chars = "a-zA-Z0-9_";
12770
12771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12772     {
12773       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12774         vec_add1 (name, 0);
12775       else
12776         {
12777           errmsg ("parse error '%U'", format_unformat_error, i);
12778           return -99;
12779         }
12780     }
12781
12782   if (!vec_len (name))
12783     {
12784       errmsg ("profile name must be specified");
12785       return -99;
12786     }
12787
12788   if (vec_len (name) > 64)
12789     {
12790       errmsg ("profile name too long");
12791       return -99;
12792     }
12793
12794   M (IKEV2_INITIATE_SA_INIT, mp);
12795
12796   clib_memcpy (mp->name, name, vec_len (name));
12797   vec_free (name);
12798
12799   S (mp);
12800   W (ret);
12801   return ret;
12802 }
12803
12804 static int
12805 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12806 {
12807   unformat_input_t *i = vam->input;
12808   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12809   int ret;
12810   u64 ispi;
12811
12812
12813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12814     {
12815       if (unformat (i, "%lx", &ispi))
12816         ;
12817       else
12818         {
12819           errmsg ("parse error '%U'", format_unformat_error, i);
12820           return -99;
12821         }
12822     }
12823
12824   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12825
12826   mp->ispi = ispi;
12827
12828   S (mp);
12829   W (ret);
12830   return ret;
12831 }
12832
12833 static int
12834 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
12835 {
12836   unformat_input_t *i = vam->input;
12837   vl_api_ikev2_initiate_del_child_sa_t *mp;
12838   int ret;
12839   u32 ispi;
12840
12841
12842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12843     {
12844       if (unformat (i, "%x", &ispi))
12845         ;
12846       else
12847         {
12848           errmsg ("parse error '%U'", format_unformat_error, i);
12849           return -99;
12850         }
12851     }
12852
12853   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
12854
12855   mp->ispi = ispi;
12856
12857   S (mp);
12858   W (ret);
12859   return ret;
12860 }
12861
12862 static int
12863 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
12864 {
12865   unformat_input_t *i = vam->input;
12866   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
12867   int ret;
12868   u32 ispi;
12869
12870
12871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12872     {
12873       if (unformat (i, "%x", &ispi))
12874         ;
12875       else
12876         {
12877           errmsg ("parse error '%U'", format_unformat_error, i);
12878           return -99;
12879         }
12880     }
12881
12882   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
12883
12884   mp->ispi = ispi;
12885
12886   S (mp);
12887   W (ret);
12888   return ret;
12889 }
12890
12891 /*
12892  * MAP
12893  */
12894 static int
12895 api_map_add_domain (vat_main_t * vam)
12896 {
12897   unformat_input_t *i = vam->input;
12898   vl_api_map_add_domain_t *mp;
12899
12900   ip4_address_t ip4_prefix;
12901   ip6_address_t ip6_prefix;
12902   ip6_address_t ip6_src;
12903   u32 num_m_args = 0;
12904   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12905     0, psid_length = 0;
12906   u8 is_translation = 0;
12907   u32 mtu = 0;
12908   u32 ip6_src_len = 128;
12909   int ret;
12910
12911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12912     {
12913       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12914                     &ip4_prefix, &ip4_prefix_len))
12915         num_m_args++;
12916       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12917                          &ip6_prefix, &ip6_prefix_len))
12918         num_m_args++;
12919       else
12920         if (unformat
12921             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12922              &ip6_src_len))
12923         num_m_args++;
12924       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12925         num_m_args++;
12926       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12927         num_m_args++;
12928       else if (unformat (i, "psid-offset %d", &psid_offset))
12929         num_m_args++;
12930       else if (unformat (i, "psid-len %d", &psid_length))
12931         num_m_args++;
12932       else if (unformat (i, "mtu %d", &mtu))
12933         num_m_args++;
12934       else if (unformat (i, "map-t"))
12935         is_translation = 1;
12936       else
12937         {
12938           clib_warning ("parse error '%U'", format_unformat_error, i);
12939           return -99;
12940         }
12941     }
12942
12943   if (num_m_args < 3)
12944     {
12945       errmsg ("mandatory argument(s) missing");
12946       return -99;
12947     }
12948
12949   /* Construct the API message */
12950   M (MAP_ADD_DOMAIN, mp);
12951
12952   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12953   mp->ip4_prefix_len = ip4_prefix_len;
12954
12955   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12956   mp->ip6_prefix_len = ip6_prefix_len;
12957
12958   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12959   mp->ip6_src_prefix_len = ip6_src_len;
12960
12961   mp->ea_bits_len = ea_bits_len;
12962   mp->psid_offset = psid_offset;
12963   mp->psid_length = psid_length;
12964   mp->is_translation = is_translation;
12965   mp->mtu = htons (mtu);
12966
12967   /* send it... */
12968   S (mp);
12969
12970   /* Wait for a reply, return good/bad news  */
12971   W (ret);
12972   return ret;
12973 }
12974
12975 static int
12976 api_map_del_domain (vat_main_t * vam)
12977 {
12978   unformat_input_t *i = vam->input;
12979   vl_api_map_del_domain_t *mp;
12980
12981   u32 num_m_args = 0;
12982   u32 index;
12983   int ret;
12984
12985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12986     {
12987       if (unformat (i, "index %d", &index))
12988         num_m_args++;
12989       else
12990         {
12991           clib_warning ("parse error '%U'", format_unformat_error, i);
12992           return -99;
12993         }
12994     }
12995
12996   if (num_m_args != 1)
12997     {
12998       errmsg ("mandatory argument(s) missing");
12999       return -99;
13000     }
13001
13002   /* Construct the API message */
13003   M (MAP_DEL_DOMAIN, mp);
13004
13005   mp->index = ntohl (index);
13006
13007   /* send it... */
13008   S (mp);
13009
13010   /* Wait for a reply, return good/bad news  */
13011   W (ret);
13012   return ret;
13013 }
13014
13015 static int
13016 api_map_add_del_rule (vat_main_t * vam)
13017 {
13018   unformat_input_t *i = vam->input;
13019   vl_api_map_add_del_rule_t *mp;
13020   u8 is_add = 1;
13021   ip6_address_t ip6_dst;
13022   u32 num_m_args = 0, index, psid = 0;
13023   int ret;
13024
13025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (i, "index %d", &index))
13028         num_m_args++;
13029       else if (unformat (i, "psid %d", &psid))
13030         num_m_args++;
13031       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13032         num_m_args++;
13033       else if (unformat (i, "del"))
13034         {
13035           is_add = 0;
13036         }
13037       else
13038         {
13039           clib_warning ("parse error '%U'", format_unformat_error, i);
13040           return -99;
13041         }
13042     }
13043
13044   /* Construct the API message */
13045   M (MAP_ADD_DEL_RULE, mp);
13046
13047   mp->index = ntohl (index);
13048   mp->is_add = is_add;
13049   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13050   mp->psid = ntohs (psid);
13051
13052   /* send it... */
13053   S (mp);
13054
13055   /* Wait for a reply, return good/bad news  */
13056   W (ret);
13057   return ret;
13058 }
13059
13060 static int
13061 api_map_domain_dump (vat_main_t * vam)
13062 {
13063   vl_api_map_domain_dump_t *mp;
13064   vl_api_control_ping_t *mp_ping;
13065   int ret;
13066
13067   /* Construct the API message */
13068   M (MAP_DOMAIN_DUMP, mp);
13069
13070   /* send it... */
13071   S (mp);
13072
13073   /* Use a control ping for synchronization */
13074   M (CONTROL_PING, mp_ping);
13075   S (mp_ping);
13076
13077   W (ret);
13078   return ret;
13079 }
13080
13081 static int
13082 api_map_rule_dump (vat_main_t * vam)
13083 {
13084   unformat_input_t *i = vam->input;
13085   vl_api_map_rule_dump_t *mp;
13086   vl_api_control_ping_t *mp_ping;
13087   u32 domain_index = ~0;
13088   int ret;
13089
13090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13091     {
13092       if (unformat (i, "index %u", &domain_index))
13093         ;
13094       else
13095         break;
13096     }
13097
13098   if (domain_index == ~0)
13099     {
13100       clib_warning ("parse error: domain index expected");
13101       return -99;
13102     }
13103
13104   /* Construct the API message */
13105   M (MAP_RULE_DUMP, mp);
13106
13107   mp->domain_index = htonl (domain_index);
13108
13109   /* send it... */
13110   S (mp);
13111
13112   /* Use a control ping for synchronization */
13113   M (CONTROL_PING, mp_ping);
13114   S (mp_ping);
13115
13116   W (ret);
13117   return ret;
13118 }
13119
13120 static void vl_api_map_add_domain_reply_t_handler
13121   (vl_api_map_add_domain_reply_t * mp)
13122 {
13123   vat_main_t *vam = &vat_main;
13124   i32 retval = ntohl (mp->retval);
13125
13126   if (vam->async_mode)
13127     {
13128       vam->async_errors += (retval < 0);
13129     }
13130   else
13131     {
13132       vam->retval = retval;
13133       vam->result_ready = 1;
13134     }
13135 }
13136
13137 static void vl_api_map_add_domain_reply_t_handler_json
13138   (vl_api_map_add_domain_reply_t * mp)
13139 {
13140   vat_main_t *vam = &vat_main;
13141   vat_json_node_t node;
13142
13143   vat_json_init_object (&node);
13144   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13145   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13146
13147   vat_json_print (vam->ofp, &node);
13148   vat_json_free (&node);
13149
13150   vam->retval = ntohl (mp->retval);
13151   vam->result_ready = 1;
13152 }
13153
13154 static int
13155 api_get_first_msg_id (vat_main_t * vam)
13156 {
13157   vl_api_get_first_msg_id_t *mp;
13158   unformat_input_t *i = vam->input;
13159   u8 *name;
13160   u8 name_set = 0;
13161   int ret;
13162
13163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13164     {
13165       if (unformat (i, "client %s", &name))
13166         name_set = 1;
13167       else
13168         break;
13169     }
13170
13171   if (name_set == 0)
13172     {
13173       errmsg ("missing client name");
13174       return -99;
13175     }
13176   vec_add1 (name, 0);
13177
13178   if (vec_len (name) > 63)
13179     {
13180       errmsg ("client name too long");
13181       return -99;
13182     }
13183
13184   M (GET_FIRST_MSG_ID, mp);
13185   clib_memcpy (mp->name, name, vec_len (name));
13186   S (mp);
13187   W (ret);
13188   return ret;
13189 }
13190
13191 static int
13192 api_cop_interface_enable_disable (vat_main_t * vam)
13193 {
13194   unformat_input_t *line_input = vam->input;
13195   vl_api_cop_interface_enable_disable_t *mp;
13196   u32 sw_if_index = ~0;
13197   u8 enable_disable = 1;
13198   int ret;
13199
13200   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13201     {
13202       if (unformat (line_input, "disable"))
13203         enable_disable = 0;
13204       if (unformat (line_input, "enable"))
13205         enable_disable = 1;
13206       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13207                          vam, &sw_if_index))
13208         ;
13209       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13210         ;
13211       else
13212         break;
13213     }
13214
13215   if (sw_if_index == ~0)
13216     {
13217       errmsg ("missing interface name or sw_if_index");
13218       return -99;
13219     }
13220
13221   /* Construct the API message */
13222   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13223   mp->sw_if_index = ntohl (sw_if_index);
13224   mp->enable_disable = enable_disable;
13225
13226   /* send it... */
13227   S (mp);
13228   /* Wait for the reply */
13229   W (ret);
13230   return ret;
13231 }
13232
13233 static int
13234 api_cop_whitelist_enable_disable (vat_main_t * vam)
13235 {
13236   unformat_input_t *line_input = vam->input;
13237   vl_api_cop_whitelist_enable_disable_t *mp;
13238   u32 sw_if_index = ~0;
13239   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13240   u32 fib_id = 0;
13241   int ret;
13242
13243   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13244     {
13245       if (unformat (line_input, "ip4"))
13246         ip4 = 1;
13247       else if (unformat (line_input, "ip6"))
13248         ip6 = 1;
13249       else if (unformat (line_input, "default"))
13250         default_cop = 1;
13251       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13252                          vam, &sw_if_index))
13253         ;
13254       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13255         ;
13256       else if (unformat (line_input, "fib-id %d", &fib_id))
13257         ;
13258       else
13259         break;
13260     }
13261
13262   if (sw_if_index == ~0)
13263     {
13264       errmsg ("missing interface name or sw_if_index");
13265       return -99;
13266     }
13267
13268   /* Construct the API message */
13269   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13270   mp->sw_if_index = ntohl (sw_if_index);
13271   mp->fib_id = ntohl (fib_id);
13272   mp->ip4 = ip4;
13273   mp->ip6 = ip6;
13274   mp->default_cop = default_cop;
13275
13276   /* send it... */
13277   S (mp);
13278   /* Wait for the reply */
13279   W (ret);
13280   return ret;
13281 }
13282
13283 static int
13284 api_get_node_graph (vat_main_t * vam)
13285 {
13286   vl_api_get_node_graph_t *mp;
13287   int ret;
13288
13289   M (GET_NODE_GRAPH, mp);
13290
13291   /* send it... */
13292   S (mp);
13293   /* Wait for the reply */
13294   W (ret);
13295   return ret;
13296 }
13297
13298 /* *INDENT-OFF* */
13299 /** Used for parsing LISP eids */
13300 typedef CLIB_PACKED(struct{
13301   u8 addr[16];   /**< eid address */
13302   u32 len;       /**< prefix length if IP */
13303   u8 type;      /**< type of eid */
13304 }) lisp_eid_vat_t;
13305 /* *INDENT-ON* */
13306
13307 static uword
13308 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13309 {
13310   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13311
13312   memset (a, 0, sizeof (a[0]));
13313
13314   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13315     {
13316       a->type = 0;              /* ipv4 type */
13317     }
13318   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13319     {
13320       a->type = 1;              /* ipv6 type */
13321     }
13322   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13323     {
13324       a->type = 2;              /* mac type */
13325     }
13326   else
13327     {
13328       return 0;
13329     }
13330
13331   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13332     {
13333       return 0;
13334     }
13335
13336   return 1;
13337 }
13338
13339 static int
13340 lisp_eid_size_vat (u8 type)
13341 {
13342   switch (type)
13343     {
13344     case 0:
13345       return 4;
13346     case 1:
13347       return 16;
13348     case 2:
13349       return 6;
13350     }
13351   return 0;
13352 }
13353
13354 static void
13355 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13356 {
13357   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13358 }
13359
13360 static int
13361 api_one_add_del_locator_set (vat_main_t * vam)
13362 {
13363   unformat_input_t *input = vam->input;
13364   vl_api_one_add_del_locator_set_t *mp;
13365   u8 is_add = 1;
13366   u8 *locator_set_name = NULL;
13367   u8 locator_set_name_set = 0;
13368   vl_api_local_locator_t locator, *locators = 0;
13369   u32 sw_if_index, priority, weight;
13370   u32 data_len = 0;
13371
13372   int ret;
13373   /* Parse args required to build the message */
13374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13375     {
13376       if (unformat (input, "del"))
13377         {
13378           is_add = 0;
13379         }
13380       else if (unformat (input, "locator-set %s", &locator_set_name))
13381         {
13382           locator_set_name_set = 1;
13383         }
13384       else if (unformat (input, "sw_if_index %u p %u w %u",
13385                          &sw_if_index, &priority, &weight))
13386         {
13387           locator.sw_if_index = htonl (sw_if_index);
13388           locator.priority = priority;
13389           locator.weight = weight;
13390           vec_add1 (locators, locator);
13391         }
13392       else
13393         if (unformat
13394             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13395              &sw_if_index, &priority, &weight))
13396         {
13397           locator.sw_if_index = htonl (sw_if_index);
13398           locator.priority = priority;
13399           locator.weight = weight;
13400           vec_add1 (locators, locator);
13401         }
13402       else
13403         break;
13404     }
13405
13406   if (locator_set_name_set == 0)
13407     {
13408       errmsg ("missing locator-set name");
13409       vec_free (locators);
13410       return -99;
13411     }
13412
13413   if (vec_len (locator_set_name) > 64)
13414     {
13415       errmsg ("locator-set name too long");
13416       vec_free (locator_set_name);
13417       vec_free (locators);
13418       return -99;
13419     }
13420   vec_add1 (locator_set_name, 0);
13421
13422   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13423
13424   /* Construct the API message */
13425   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13426
13427   mp->is_add = is_add;
13428   clib_memcpy (mp->locator_set_name, locator_set_name,
13429                vec_len (locator_set_name));
13430   vec_free (locator_set_name);
13431
13432   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13433   if (locators)
13434     clib_memcpy (mp->locators, locators, data_len);
13435   vec_free (locators);
13436
13437   /* send it... */
13438   S (mp);
13439
13440   /* Wait for a reply... */
13441   W (ret);
13442   return ret;
13443 }
13444
13445 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13446
13447 static int
13448 api_one_add_del_locator (vat_main_t * vam)
13449 {
13450   unformat_input_t *input = vam->input;
13451   vl_api_one_add_del_locator_t *mp;
13452   u32 tmp_if_index = ~0;
13453   u32 sw_if_index = ~0;
13454   u8 sw_if_index_set = 0;
13455   u8 sw_if_index_if_name_set = 0;
13456   u32 priority = ~0;
13457   u8 priority_set = 0;
13458   u32 weight = ~0;
13459   u8 weight_set = 0;
13460   u8 is_add = 1;
13461   u8 *locator_set_name = NULL;
13462   u8 locator_set_name_set = 0;
13463   int ret;
13464
13465   /* Parse args required to build the message */
13466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13467     {
13468       if (unformat (input, "del"))
13469         {
13470           is_add = 0;
13471         }
13472       else if (unformat (input, "locator-set %s", &locator_set_name))
13473         {
13474           locator_set_name_set = 1;
13475         }
13476       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13477                          &tmp_if_index))
13478         {
13479           sw_if_index_if_name_set = 1;
13480           sw_if_index = tmp_if_index;
13481         }
13482       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13483         {
13484           sw_if_index_set = 1;
13485           sw_if_index = tmp_if_index;
13486         }
13487       else if (unformat (input, "p %d", &priority))
13488         {
13489           priority_set = 1;
13490         }
13491       else if (unformat (input, "w %d", &weight))
13492         {
13493           weight_set = 1;
13494         }
13495       else
13496         break;
13497     }
13498
13499   if (locator_set_name_set == 0)
13500     {
13501       errmsg ("missing locator-set name");
13502       return -99;
13503     }
13504
13505   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13506     {
13507       errmsg ("missing sw_if_index");
13508       vec_free (locator_set_name);
13509       return -99;
13510     }
13511
13512   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13513     {
13514       errmsg ("cannot use both params interface name and sw_if_index");
13515       vec_free (locator_set_name);
13516       return -99;
13517     }
13518
13519   if (priority_set == 0)
13520     {
13521       errmsg ("missing locator-set priority");
13522       vec_free (locator_set_name);
13523       return -99;
13524     }
13525
13526   if (weight_set == 0)
13527     {
13528       errmsg ("missing locator-set weight");
13529       vec_free (locator_set_name);
13530       return -99;
13531     }
13532
13533   if (vec_len (locator_set_name) > 64)
13534     {
13535       errmsg ("locator-set name too long");
13536       vec_free (locator_set_name);
13537       return -99;
13538     }
13539   vec_add1 (locator_set_name, 0);
13540
13541   /* Construct the API message */
13542   M (ONE_ADD_DEL_LOCATOR, mp);
13543
13544   mp->is_add = is_add;
13545   mp->sw_if_index = ntohl (sw_if_index);
13546   mp->priority = priority;
13547   mp->weight = weight;
13548   clib_memcpy (mp->locator_set_name, locator_set_name,
13549                vec_len (locator_set_name));
13550   vec_free (locator_set_name);
13551
13552   /* send it... */
13553   S (mp);
13554
13555   /* Wait for a reply... */
13556   W (ret);
13557   return ret;
13558 }
13559
13560 #define api_lisp_add_del_locator api_one_add_del_locator
13561
13562 uword
13563 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13564 {
13565   u32 *key_id = va_arg (*args, u32 *);
13566   u8 *s = 0;
13567
13568   if (unformat (input, "%s", &s))
13569     {
13570       if (!strcmp ((char *) s, "sha1"))
13571         key_id[0] = HMAC_SHA_1_96;
13572       else if (!strcmp ((char *) s, "sha256"))
13573         key_id[0] = HMAC_SHA_256_128;
13574       else
13575         {
13576           clib_warning ("invalid key_id: '%s'", s);
13577           key_id[0] = HMAC_NO_KEY;
13578         }
13579     }
13580   else
13581     return 0;
13582
13583   vec_free (s);
13584   return 1;
13585 }
13586
13587 static int
13588 api_one_add_del_local_eid (vat_main_t * vam)
13589 {
13590   unformat_input_t *input = vam->input;
13591   vl_api_one_add_del_local_eid_t *mp;
13592   u8 is_add = 1;
13593   u8 eid_set = 0;
13594   lisp_eid_vat_t _eid, *eid = &_eid;
13595   u8 *locator_set_name = 0;
13596   u8 locator_set_name_set = 0;
13597   u32 vni = 0;
13598   u16 key_id = 0;
13599   u8 *key = 0;
13600   int ret;
13601
13602   /* Parse args required to build the message */
13603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13604     {
13605       if (unformat (input, "del"))
13606         {
13607           is_add = 0;
13608         }
13609       else if (unformat (input, "vni %d", &vni))
13610         {
13611           ;
13612         }
13613       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13614         {
13615           eid_set = 1;
13616         }
13617       else if (unformat (input, "locator-set %s", &locator_set_name))
13618         {
13619           locator_set_name_set = 1;
13620         }
13621       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13622         ;
13623       else if (unformat (input, "secret-key %_%v%_", &key))
13624         ;
13625       else
13626         break;
13627     }
13628
13629   if (locator_set_name_set == 0)
13630     {
13631       errmsg ("missing locator-set name");
13632       return -99;
13633     }
13634
13635   if (0 == eid_set)
13636     {
13637       errmsg ("EID address not set!");
13638       vec_free (locator_set_name);
13639       return -99;
13640     }
13641
13642   if (key && (0 == key_id))
13643     {
13644       errmsg ("invalid key_id!");
13645       return -99;
13646     }
13647
13648   if (vec_len (key) > 64)
13649     {
13650       errmsg ("key too long");
13651       vec_free (key);
13652       return -99;
13653     }
13654
13655   if (vec_len (locator_set_name) > 64)
13656     {
13657       errmsg ("locator-set name too long");
13658       vec_free (locator_set_name);
13659       return -99;
13660     }
13661   vec_add1 (locator_set_name, 0);
13662
13663   /* Construct the API message */
13664   M (ONE_ADD_DEL_LOCAL_EID, mp);
13665
13666   mp->is_add = is_add;
13667   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13668   mp->eid_type = eid->type;
13669   mp->prefix_len = eid->len;
13670   mp->vni = clib_host_to_net_u32 (vni);
13671   mp->key_id = clib_host_to_net_u16 (key_id);
13672   clib_memcpy (mp->locator_set_name, locator_set_name,
13673                vec_len (locator_set_name));
13674   clib_memcpy (mp->key, key, vec_len (key));
13675
13676   vec_free (locator_set_name);
13677   vec_free (key);
13678
13679   /* send it... */
13680   S (mp);
13681
13682   /* Wait for a reply... */
13683   W (ret);
13684   return ret;
13685 }
13686
13687 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13688
13689 static int
13690 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13691 {
13692   u32 dp_table = 0, vni = 0;;
13693   unformat_input_t *input = vam->input;
13694   vl_api_gpe_add_del_fwd_entry_t *mp;
13695   u8 is_add = 1;
13696   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13697   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13698   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13699   u32 action = ~0, w;
13700   ip4_address_t rmt_rloc4, lcl_rloc4;
13701   ip6_address_t rmt_rloc6, lcl_rloc6;
13702   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13703   int ret;
13704
13705   memset (&rloc, 0, sizeof (rloc));
13706
13707   /* Parse args required to build the message */
13708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13709     {
13710       if (unformat (input, "del"))
13711         is_add = 0;
13712       else if (unformat (input, "add"))
13713         is_add = 1;
13714       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13715         {
13716           rmt_eid_set = 1;
13717         }
13718       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13719         {
13720           lcl_eid_set = 1;
13721         }
13722       else if (unformat (input, "vrf %d", &dp_table))
13723         ;
13724       else if (unformat (input, "bd %d", &dp_table))
13725         ;
13726       else if (unformat (input, "vni %d", &vni))
13727         ;
13728       else if (unformat (input, "w %d", &w))
13729         {
13730           if (!curr_rloc)
13731             {
13732               errmsg ("No RLOC configured for setting priority/weight!");
13733               return -99;
13734             }
13735           curr_rloc->weight = w;
13736         }
13737       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13738                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13739         {
13740           rloc.is_ip4 = 1;
13741
13742           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13743           rloc.weight = 0;
13744           vec_add1 (lcl_locs, rloc);
13745
13746           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13747           vec_add1 (rmt_locs, rloc);
13748           /* weight saved in rmt loc */
13749           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13750         }
13751       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13752                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13753         {
13754           rloc.is_ip4 = 0;
13755           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13756           rloc.weight = 0;
13757           vec_add1 (lcl_locs, rloc);
13758
13759           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13760           vec_add1 (rmt_locs, rloc);
13761           /* weight saved in rmt loc */
13762           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13763         }
13764       else if (unformat (input, "action %d", &action))
13765         {
13766           ;
13767         }
13768       else
13769         {
13770           clib_warning ("parse error '%U'", format_unformat_error, input);
13771           return -99;
13772         }
13773     }
13774
13775   if (!rmt_eid_set)
13776     {
13777       errmsg ("remote eid addresses not set");
13778       return -99;
13779     }
13780
13781   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13782     {
13783       errmsg ("eid types don't match");
13784       return -99;
13785     }
13786
13787   if (0 == rmt_locs && (u32) ~ 0 == action)
13788     {
13789       errmsg ("action not set for negative mapping");
13790       return -99;
13791     }
13792
13793   /* Construct the API message */
13794   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13795       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13796
13797   mp->is_add = is_add;
13798   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13799   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13800   mp->eid_type = rmt_eid->type;
13801   mp->dp_table = clib_host_to_net_u32 (dp_table);
13802   mp->vni = clib_host_to_net_u32 (vni);
13803   mp->rmt_len = rmt_eid->len;
13804   mp->lcl_len = lcl_eid->len;
13805   mp->action = action;
13806
13807   if (0 != rmt_locs && 0 != lcl_locs)
13808     {
13809       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13810       clib_memcpy (mp->locs, lcl_locs,
13811                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13812
13813       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13814       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13815                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13816     }
13817   vec_free (lcl_locs);
13818   vec_free (rmt_locs);
13819
13820   /* send it... */
13821   S (mp);
13822
13823   /* Wait for a reply... */
13824   W (ret);
13825   return ret;
13826 }
13827
13828 static int
13829 api_one_add_del_map_server (vat_main_t * vam)
13830 {
13831   unformat_input_t *input = vam->input;
13832   vl_api_one_add_del_map_server_t *mp;
13833   u8 is_add = 1;
13834   u8 ipv4_set = 0;
13835   u8 ipv6_set = 0;
13836   ip4_address_t ipv4;
13837   ip6_address_t ipv6;
13838   int ret;
13839
13840   /* Parse args required to build the message */
13841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13842     {
13843       if (unformat (input, "del"))
13844         {
13845           is_add = 0;
13846         }
13847       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13848         {
13849           ipv4_set = 1;
13850         }
13851       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13852         {
13853           ipv6_set = 1;
13854         }
13855       else
13856         break;
13857     }
13858
13859   if (ipv4_set && ipv6_set)
13860     {
13861       errmsg ("both eid v4 and v6 addresses set");
13862       return -99;
13863     }
13864
13865   if (!ipv4_set && !ipv6_set)
13866     {
13867       errmsg ("eid addresses not set");
13868       return -99;
13869     }
13870
13871   /* Construct the API message */
13872   M (ONE_ADD_DEL_MAP_SERVER, mp);
13873
13874   mp->is_add = is_add;
13875   if (ipv6_set)
13876     {
13877       mp->is_ipv6 = 1;
13878       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13879     }
13880   else
13881     {
13882       mp->is_ipv6 = 0;
13883       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13884     }
13885
13886   /* send it... */
13887   S (mp);
13888
13889   /* Wait for a reply... */
13890   W (ret);
13891   return ret;
13892 }
13893
13894 #define api_lisp_add_del_map_server api_one_add_del_map_server
13895
13896 static int
13897 api_one_add_del_map_resolver (vat_main_t * vam)
13898 {
13899   unformat_input_t *input = vam->input;
13900   vl_api_one_add_del_map_resolver_t *mp;
13901   u8 is_add = 1;
13902   u8 ipv4_set = 0;
13903   u8 ipv6_set = 0;
13904   ip4_address_t ipv4;
13905   ip6_address_t ipv6;
13906   int ret;
13907
13908   /* Parse args required to build the message */
13909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13910     {
13911       if (unformat (input, "del"))
13912         {
13913           is_add = 0;
13914         }
13915       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13916         {
13917           ipv4_set = 1;
13918         }
13919       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13920         {
13921           ipv6_set = 1;
13922         }
13923       else
13924         break;
13925     }
13926
13927   if (ipv4_set && ipv6_set)
13928     {
13929       errmsg ("both eid v4 and v6 addresses set");
13930       return -99;
13931     }
13932
13933   if (!ipv4_set && !ipv6_set)
13934     {
13935       errmsg ("eid addresses not set");
13936       return -99;
13937     }
13938
13939   /* Construct the API message */
13940   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
13941
13942   mp->is_add = is_add;
13943   if (ipv6_set)
13944     {
13945       mp->is_ipv6 = 1;
13946       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13947     }
13948   else
13949     {
13950       mp->is_ipv6 = 0;
13951       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13952     }
13953
13954   /* send it... */
13955   S (mp);
13956
13957   /* Wait for a reply... */
13958   W (ret);
13959   return ret;
13960 }
13961
13962 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
13963
13964 static int
13965 api_lisp_gpe_enable_disable (vat_main_t * vam)
13966 {
13967   unformat_input_t *input = vam->input;
13968   vl_api_gpe_enable_disable_t *mp;
13969   u8 is_set = 0;
13970   u8 is_en = 1;
13971   int ret;
13972
13973   /* Parse args required to build the message */
13974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13975     {
13976       if (unformat (input, "enable"))
13977         {
13978           is_set = 1;
13979           is_en = 1;
13980         }
13981       else if (unformat (input, "disable"))
13982         {
13983           is_set = 1;
13984           is_en = 0;
13985         }
13986       else
13987         break;
13988     }
13989
13990   if (is_set == 0)
13991     {
13992       errmsg ("Value not set");
13993       return -99;
13994     }
13995
13996   /* Construct the API message */
13997   M (GPE_ENABLE_DISABLE, mp);
13998
13999   mp->is_en = is_en;
14000
14001   /* send it... */
14002   S (mp);
14003
14004   /* Wait for a reply... */
14005   W (ret);
14006   return ret;
14007 }
14008
14009 static int
14010 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14011 {
14012   unformat_input_t *input = vam->input;
14013   vl_api_one_rloc_probe_enable_disable_t *mp;
14014   u8 is_set = 0;
14015   u8 is_en = 0;
14016   int ret;
14017
14018   /* Parse args required to build the message */
14019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14020     {
14021       if (unformat (input, "enable"))
14022         {
14023           is_set = 1;
14024           is_en = 1;
14025         }
14026       else if (unformat (input, "disable"))
14027         is_set = 1;
14028       else
14029         break;
14030     }
14031
14032   if (!is_set)
14033     {
14034       errmsg ("Value not set");
14035       return -99;
14036     }
14037
14038   /* Construct the API message */
14039   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14040
14041   mp->is_enabled = is_en;
14042
14043   /* send it... */
14044   S (mp);
14045
14046   /* Wait for a reply... */
14047   W (ret);
14048   return ret;
14049 }
14050
14051 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14052
14053 static int
14054 api_one_map_register_enable_disable (vat_main_t * vam)
14055 {
14056   unformat_input_t *input = vam->input;
14057   vl_api_one_map_register_enable_disable_t *mp;
14058   u8 is_set = 0;
14059   u8 is_en = 0;
14060   int ret;
14061
14062   /* Parse args required to build the message */
14063   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14064     {
14065       if (unformat (input, "enable"))
14066         {
14067           is_set = 1;
14068           is_en = 1;
14069         }
14070       else if (unformat (input, "disable"))
14071         is_set = 1;
14072       else
14073         break;
14074     }
14075
14076   if (!is_set)
14077     {
14078       errmsg ("Value not set");
14079       return -99;
14080     }
14081
14082   /* Construct the API message */
14083   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14084
14085   mp->is_enabled = is_en;
14086
14087   /* send it... */
14088   S (mp);
14089
14090   /* Wait for a reply... */
14091   W (ret);
14092   return ret;
14093 }
14094
14095 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14096
14097 static int
14098 api_one_enable_disable (vat_main_t * vam)
14099 {
14100   unformat_input_t *input = vam->input;
14101   vl_api_one_enable_disable_t *mp;
14102   u8 is_set = 0;
14103   u8 is_en = 0;
14104   int ret;
14105
14106   /* Parse args required to build the message */
14107   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14108     {
14109       if (unformat (input, "enable"))
14110         {
14111           is_set = 1;
14112           is_en = 1;
14113         }
14114       else if (unformat (input, "disable"))
14115         {
14116           is_set = 1;
14117         }
14118       else
14119         break;
14120     }
14121
14122   if (!is_set)
14123     {
14124       errmsg ("Value not set");
14125       return -99;
14126     }
14127
14128   /* Construct the API message */
14129   M (ONE_ENABLE_DISABLE, mp);
14130
14131   mp->is_en = is_en;
14132
14133   /* send it... */
14134   S (mp);
14135
14136   /* Wait for a reply... */
14137   W (ret);
14138   return ret;
14139 }
14140
14141 #define api_lisp_enable_disable api_one_enable_disable
14142
14143 static int
14144 api_show_one_map_register_state (vat_main_t * vam)
14145 {
14146   vl_api_show_one_map_register_state_t *mp;
14147   int ret;
14148
14149   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14150
14151   /* send */
14152   S (mp);
14153
14154   /* wait for reply */
14155   W (ret);
14156   return ret;
14157 }
14158
14159 #define api_show_lisp_map_register_state api_show_one_map_register_state
14160
14161 static int
14162 api_show_one_rloc_probe_state (vat_main_t * vam)
14163 {
14164   vl_api_show_one_rloc_probe_state_t *mp;
14165   int ret;
14166
14167   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14168
14169   /* send */
14170   S (mp);
14171
14172   /* wait for reply */
14173   W (ret);
14174   return ret;
14175 }
14176
14177 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14178
14179 static int
14180 api_show_one_map_request_mode (vat_main_t * vam)
14181 {
14182   vl_api_show_one_map_request_mode_t *mp;
14183   int ret;
14184
14185   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14186
14187   /* send */
14188   S (mp);
14189
14190   /* wait for reply */
14191   W (ret);
14192   return ret;
14193 }
14194
14195 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14196
14197 static int
14198 api_one_map_request_mode (vat_main_t * vam)
14199 {
14200   unformat_input_t *input = vam->input;
14201   vl_api_one_map_request_mode_t *mp;
14202   u8 mode = 0;
14203   int ret;
14204
14205   /* Parse args required to build the message */
14206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14207     {
14208       if (unformat (input, "dst-only"))
14209         mode = 0;
14210       else if (unformat (input, "src-dst"))
14211         mode = 1;
14212       else
14213         {
14214           errmsg ("parse error '%U'", format_unformat_error, input);
14215           return -99;
14216         }
14217     }
14218
14219   M (ONE_MAP_REQUEST_MODE, mp);
14220
14221   mp->mode = mode;
14222
14223   /* send */
14224   S (mp);
14225
14226   /* wait for reply */
14227   W (ret);
14228   return ret;
14229 }
14230
14231 #define api_lisp_map_request_mode api_one_map_request_mode
14232
14233 /**
14234  * Enable/disable ONE proxy ITR.
14235  *
14236  * @param vam vpp API test context
14237  * @return return code
14238  */
14239 static int
14240 api_one_pitr_set_locator_set (vat_main_t * vam)
14241 {
14242   u8 ls_name_set = 0;
14243   unformat_input_t *input = vam->input;
14244   vl_api_one_pitr_set_locator_set_t *mp;
14245   u8 is_add = 1;
14246   u8 *ls_name = 0;
14247   int ret;
14248
14249   /* Parse args required to build the message */
14250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14251     {
14252       if (unformat (input, "del"))
14253         is_add = 0;
14254       else if (unformat (input, "locator-set %s", &ls_name))
14255         ls_name_set = 1;
14256       else
14257         {
14258           errmsg ("parse error '%U'", format_unformat_error, input);
14259           return -99;
14260         }
14261     }
14262
14263   if (!ls_name_set)
14264     {
14265       errmsg ("locator-set name not set!");
14266       return -99;
14267     }
14268
14269   M (ONE_PITR_SET_LOCATOR_SET, mp);
14270
14271   mp->is_add = is_add;
14272   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14273   vec_free (ls_name);
14274
14275   /* send */
14276   S (mp);
14277
14278   /* wait for reply */
14279   W (ret);
14280   return ret;
14281 }
14282
14283 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14284
14285 static int
14286 api_show_one_pitr (vat_main_t * vam)
14287 {
14288   vl_api_show_one_pitr_t *mp;
14289   int ret;
14290
14291   if (!vam->json_output)
14292     {
14293       print (vam->ofp, "%=20s", "lisp status:");
14294     }
14295
14296   M (SHOW_ONE_PITR, mp);
14297   /* send it... */
14298   S (mp);
14299
14300   /* Wait for a reply... */
14301   W (ret);
14302   return ret;
14303 }
14304
14305 #define api_show_lisp_pitr api_show_one_pitr
14306
14307 /**
14308  * Add/delete mapping between vni and vrf
14309  */
14310 static int
14311 api_one_eid_table_add_del_map (vat_main_t * vam)
14312 {
14313   unformat_input_t *input = vam->input;
14314   vl_api_one_eid_table_add_del_map_t *mp;
14315   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14316   u32 vni, vrf, bd_index;
14317   int ret;
14318
14319   /* Parse args required to build the message */
14320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14321     {
14322       if (unformat (input, "del"))
14323         is_add = 0;
14324       else if (unformat (input, "vrf %d", &vrf))
14325         vrf_set = 1;
14326       else if (unformat (input, "bd_index %d", &bd_index))
14327         bd_index_set = 1;
14328       else if (unformat (input, "vni %d", &vni))
14329         vni_set = 1;
14330       else
14331         break;
14332     }
14333
14334   if (!vni_set || (!vrf_set && !bd_index_set))
14335     {
14336       errmsg ("missing arguments!");
14337       return -99;
14338     }
14339
14340   if (vrf_set && bd_index_set)
14341     {
14342       errmsg ("error: both vrf and bd entered!");
14343       return -99;
14344     }
14345
14346   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14347
14348   mp->is_add = is_add;
14349   mp->vni = htonl (vni);
14350   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14351   mp->is_l2 = bd_index_set;
14352
14353   /* send */
14354   S (mp);
14355
14356   /* wait for reply */
14357   W (ret);
14358   return ret;
14359 }
14360
14361 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14362
14363 uword
14364 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14365 {
14366   u32 *action = va_arg (*args, u32 *);
14367   u8 *s = 0;
14368
14369   if (unformat (input, "%s", &s))
14370     {
14371       if (!strcmp ((char *) s, "no-action"))
14372         action[0] = 0;
14373       else if (!strcmp ((char *) s, "natively-forward"))
14374         action[0] = 1;
14375       else if (!strcmp ((char *) s, "send-map-request"))
14376         action[0] = 2;
14377       else if (!strcmp ((char *) s, "drop"))
14378         action[0] = 3;
14379       else
14380         {
14381           clib_warning ("invalid action: '%s'", s);
14382           action[0] = 3;
14383         }
14384     }
14385   else
14386     return 0;
14387
14388   vec_free (s);
14389   return 1;
14390 }
14391
14392 /**
14393  * Add/del remote mapping to/from ONE control plane
14394  *
14395  * @param vam vpp API test context
14396  * @return return code
14397  */
14398 static int
14399 api_one_add_del_remote_mapping (vat_main_t * vam)
14400 {
14401   unformat_input_t *input = vam->input;
14402   vl_api_one_add_del_remote_mapping_t *mp;
14403   u32 vni = 0;
14404   lisp_eid_vat_t _eid, *eid = &_eid;
14405   lisp_eid_vat_t _seid, *seid = &_seid;
14406   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14407   u32 action = ~0, p, w, data_len;
14408   ip4_address_t rloc4;
14409   ip6_address_t rloc6;
14410   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14411   int ret;
14412
14413   memset (&rloc, 0, sizeof (rloc));
14414
14415   /* Parse args required to build the message */
14416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14417     {
14418       if (unformat (input, "del-all"))
14419         {
14420           del_all = 1;
14421         }
14422       else if (unformat (input, "del"))
14423         {
14424           is_add = 0;
14425         }
14426       else if (unformat (input, "add"))
14427         {
14428           is_add = 1;
14429         }
14430       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14431         {
14432           eid_set = 1;
14433         }
14434       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14435         {
14436           seid_set = 1;
14437         }
14438       else if (unformat (input, "vni %d", &vni))
14439         {
14440           ;
14441         }
14442       else if (unformat (input, "p %d w %d", &p, &w))
14443         {
14444           if (!curr_rloc)
14445             {
14446               errmsg ("No RLOC configured for setting priority/weight!");
14447               return -99;
14448             }
14449           curr_rloc->priority = p;
14450           curr_rloc->weight = w;
14451         }
14452       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14453         {
14454           rloc.is_ip4 = 1;
14455           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14456           vec_add1 (rlocs, rloc);
14457           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14458         }
14459       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14460         {
14461           rloc.is_ip4 = 0;
14462           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14463           vec_add1 (rlocs, rloc);
14464           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14465         }
14466       else if (unformat (input, "action %U",
14467                          unformat_negative_mapping_action, &action))
14468         {
14469           ;
14470         }
14471       else
14472         {
14473           clib_warning ("parse error '%U'", format_unformat_error, input);
14474           return -99;
14475         }
14476     }
14477
14478   if (0 == eid_set)
14479     {
14480       errmsg ("missing params!");
14481       return -99;
14482     }
14483
14484   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14485     {
14486       errmsg ("no action set for negative map-reply!");
14487       return -99;
14488     }
14489
14490   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14491
14492   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14493   mp->is_add = is_add;
14494   mp->vni = htonl (vni);
14495   mp->action = (u8) action;
14496   mp->is_src_dst = seid_set;
14497   mp->eid_len = eid->len;
14498   mp->seid_len = seid->len;
14499   mp->del_all = del_all;
14500   mp->eid_type = eid->type;
14501   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14502   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14503
14504   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14505   clib_memcpy (mp->rlocs, rlocs, data_len);
14506   vec_free (rlocs);
14507
14508   /* send it... */
14509   S (mp);
14510
14511   /* Wait for a reply... */
14512   W (ret);
14513   return ret;
14514 }
14515
14516 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14517
14518 /**
14519  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14520  * forwarding entries in data-plane accordingly.
14521  *
14522  * @param vam vpp API test context
14523  * @return return code
14524  */
14525 static int
14526 api_one_add_del_adjacency (vat_main_t * vam)
14527 {
14528   unformat_input_t *input = vam->input;
14529   vl_api_one_add_del_adjacency_t *mp;
14530   u32 vni = 0;
14531   ip4_address_t leid4, reid4;
14532   ip6_address_t leid6, reid6;
14533   u8 reid_mac[6] = { 0 };
14534   u8 leid_mac[6] = { 0 };
14535   u8 reid_type, leid_type;
14536   u32 leid_len = 0, reid_len = 0, len;
14537   u8 is_add = 1;
14538   int ret;
14539
14540   leid_type = reid_type = (u8) ~ 0;
14541
14542   /* Parse args required to build the message */
14543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14544     {
14545       if (unformat (input, "del"))
14546         {
14547           is_add = 0;
14548         }
14549       else if (unformat (input, "add"))
14550         {
14551           is_add = 1;
14552         }
14553       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14554                          &reid4, &len))
14555         {
14556           reid_type = 0;        /* ipv4 */
14557           reid_len = len;
14558         }
14559       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14560                          &reid6, &len))
14561         {
14562           reid_type = 1;        /* ipv6 */
14563           reid_len = len;
14564         }
14565       else if (unformat (input, "reid %U", unformat_ethernet_address,
14566                          reid_mac))
14567         {
14568           reid_type = 2;        /* mac */
14569         }
14570       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14571                          &leid4, &len))
14572         {
14573           leid_type = 0;        /* ipv4 */
14574           leid_len = len;
14575         }
14576       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14577                          &leid6, &len))
14578         {
14579           leid_type = 1;        /* ipv6 */
14580           leid_len = len;
14581         }
14582       else if (unformat (input, "leid %U", unformat_ethernet_address,
14583                          leid_mac))
14584         {
14585           leid_type = 2;        /* mac */
14586         }
14587       else if (unformat (input, "vni %d", &vni))
14588         {
14589           ;
14590         }
14591       else
14592         {
14593           errmsg ("parse error '%U'", format_unformat_error, input);
14594           return -99;
14595         }
14596     }
14597
14598   if ((u8) ~ 0 == reid_type)
14599     {
14600       errmsg ("missing params!");
14601       return -99;
14602     }
14603
14604   if (leid_type != reid_type)
14605     {
14606       errmsg ("remote and local EIDs are of different types!");
14607       return -99;
14608     }
14609
14610   M (ONE_ADD_DEL_ADJACENCY, mp);
14611   mp->is_add = is_add;
14612   mp->vni = htonl (vni);
14613   mp->leid_len = leid_len;
14614   mp->reid_len = reid_len;
14615   mp->eid_type = reid_type;
14616
14617   switch (mp->eid_type)
14618     {
14619     case 0:
14620       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14621       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14622       break;
14623     case 1:
14624       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14625       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14626       break;
14627     case 2:
14628       clib_memcpy (mp->leid, leid_mac, 6);
14629       clib_memcpy (mp->reid, reid_mac, 6);
14630       break;
14631     default:
14632       errmsg ("unknown EID type %d!", mp->eid_type);
14633       return 0;
14634     }
14635
14636   /* send it... */
14637   S (mp);
14638
14639   /* Wait for a reply... */
14640   W (ret);
14641   return ret;
14642 }
14643
14644 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14645
14646 uword
14647 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14648 {
14649   u32 *mode = va_arg (*args, u32 *);
14650
14651   if (unformat (input, "lisp"))
14652     *mode = 0;
14653   else if (unformat (input, "vxlan"))
14654     *mode = 1;
14655   else
14656     return 0;
14657
14658   return 1;
14659 }
14660
14661 static int
14662 api_gpe_get_encap_mode (vat_main_t * vam)
14663 {
14664   vl_api_gpe_get_encap_mode_t *mp;
14665   int ret;
14666
14667   /* Construct the API message */
14668   M (GPE_GET_ENCAP_MODE, mp);
14669
14670   /* send it... */
14671   S (mp);
14672
14673   /* Wait for a reply... */
14674   W (ret);
14675   return ret;
14676 }
14677
14678 static int
14679 api_gpe_set_encap_mode (vat_main_t * vam)
14680 {
14681   unformat_input_t *input = vam->input;
14682   vl_api_gpe_set_encap_mode_t *mp;
14683   int ret;
14684   u32 mode = 0;
14685
14686   /* Parse args required to build the message */
14687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14688     {
14689       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14690         ;
14691       else
14692         break;
14693     }
14694
14695   /* Construct the API message */
14696   M (GPE_SET_ENCAP_MODE, mp);
14697
14698   mp->mode = mode;
14699
14700   /* send it... */
14701   S (mp);
14702
14703   /* Wait for a reply... */
14704   W (ret);
14705   return ret;
14706 }
14707
14708 static int
14709 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14710 {
14711   unformat_input_t *input = vam->input;
14712   vl_api_gpe_add_del_iface_t *mp;
14713   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14714   u32 dp_table = 0, vni = 0;
14715   int ret;
14716
14717   /* Parse args required to build the message */
14718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14719     {
14720       if (unformat (input, "up"))
14721         {
14722           action_set = 1;
14723           is_add = 1;
14724         }
14725       else if (unformat (input, "down"))
14726         {
14727           action_set = 1;
14728           is_add = 0;
14729         }
14730       else if (unformat (input, "table_id %d", &dp_table))
14731         {
14732           dp_table_set = 1;
14733         }
14734       else if (unformat (input, "bd_id %d", &dp_table))
14735         {
14736           dp_table_set = 1;
14737           is_l2 = 1;
14738         }
14739       else if (unformat (input, "vni %d", &vni))
14740         {
14741           vni_set = 1;
14742         }
14743       else
14744         break;
14745     }
14746
14747   if (action_set == 0)
14748     {
14749       errmsg ("Action not set");
14750       return -99;
14751     }
14752   if (dp_table_set == 0 || vni_set == 0)
14753     {
14754       errmsg ("vni and dp_table must be set");
14755       return -99;
14756     }
14757
14758   /* Construct the API message */
14759   M (GPE_ADD_DEL_IFACE, mp);
14760
14761   mp->is_add = is_add;
14762   mp->dp_table = dp_table;
14763   mp->is_l2 = is_l2;
14764   mp->vni = vni;
14765
14766   /* send it... */
14767   S (mp);
14768
14769   /* Wait for a reply... */
14770   W (ret);
14771   return ret;
14772 }
14773
14774 /**
14775  * Add/del map request itr rlocs from ONE control plane and updates
14776  *
14777  * @param vam vpp API test context
14778  * @return return code
14779  */
14780 static int
14781 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14782 {
14783   unformat_input_t *input = vam->input;
14784   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14785   u8 *locator_set_name = 0;
14786   u8 locator_set_name_set = 0;
14787   u8 is_add = 1;
14788   int ret;
14789
14790   /* Parse args required to build the message */
14791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14792     {
14793       if (unformat (input, "del"))
14794         {
14795           is_add = 0;
14796         }
14797       else if (unformat (input, "%_%v%_", &locator_set_name))
14798         {
14799           locator_set_name_set = 1;
14800         }
14801       else
14802         {
14803           clib_warning ("parse error '%U'", format_unformat_error, input);
14804           return -99;
14805         }
14806     }
14807
14808   if (is_add && !locator_set_name_set)
14809     {
14810       errmsg ("itr-rloc is not set!");
14811       return -99;
14812     }
14813
14814   if (is_add && vec_len (locator_set_name) > 64)
14815     {
14816       errmsg ("itr-rloc locator-set name too long");
14817       vec_free (locator_set_name);
14818       return -99;
14819     }
14820
14821   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14822   mp->is_add = is_add;
14823   if (is_add)
14824     {
14825       clib_memcpy (mp->locator_set_name, locator_set_name,
14826                    vec_len (locator_set_name));
14827     }
14828   else
14829     {
14830       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14831     }
14832   vec_free (locator_set_name);
14833
14834   /* send it... */
14835   S (mp);
14836
14837   /* Wait for a reply... */
14838   W (ret);
14839   return ret;
14840 }
14841
14842 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14843
14844 static int
14845 api_one_locator_dump (vat_main_t * vam)
14846 {
14847   unformat_input_t *input = vam->input;
14848   vl_api_one_locator_dump_t *mp;
14849   vl_api_control_ping_t *mp_ping;
14850   u8 is_index_set = 0, is_name_set = 0;
14851   u8 *ls_name = 0;
14852   u32 ls_index = ~0;
14853   int ret;
14854
14855   /* Parse args required to build the message */
14856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14857     {
14858       if (unformat (input, "ls_name %_%v%_", &ls_name))
14859         {
14860           is_name_set = 1;
14861         }
14862       else if (unformat (input, "ls_index %d", &ls_index))
14863         {
14864           is_index_set = 1;
14865         }
14866       else
14867         {
14868           errmsg ("parse error '%U'", format_unformat_error, input);
14869           return -99;
14870         }
14871     }
14872
14873   if (!is_index_set && !is_name_set)
14874     {
14875       errmsg ("error: expected one of index or name!");
14876       return -99;
14877     }
14878
14879   if (is_index_set && is_name_set)
14880     {
14881       errmsg ("error: only one param expected!");
14882       return -99;
14883     }
14884
14885   if (vec_len (ls_name) > 62)
14886     {
14887       errmsg ("error: locator set name too long!");
14888       return -99;
14889     }
14890
14891   if (!vam->json_output)
14892     {
14893       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14894     }
14895
14896   M (ONE_LOCATOR_DUMP, mp);
14897   mp->is_index_set = is_index_set;
14898
14899   if (is_index_set)
14900     mp->ls_index = clib_host_to_net_u32 (ls_index);
14901   else
14902     {
14903       vec_add1 (ls_name, 0);
14904       strncpy ((char *) mp->ls_name, (char *) ls_name,
14905                sizeof (mp->ls_name) - 1);
14906     }
14907
14908   /* send it... */
14909   S (mp);
14910
14911   /* Use a control ping for synchronization */
14912   M (CONTROL_PING, mp_ping);
14913   S (mp_ping);
14914
14915   /* Wait for a reply... */
14916   W (ret);
14917   return ret;
14918 }
14919
14920 #define api_lisp_locator_dump api_one_locator_dump
14921
14922 static int
14923 api_one_locator_set_dump (vat_main_t * vam)
14924 {
14925   vl_api_one_locator_set_dump_t *mp;
14926   vl_api_control_ping_t *mp_ping;
14927   unformat_input_t *input = vam->input;
14928   u8 filter = 0;
14929   int ret;
14930
14931   /* Parse args required to build the message */
14932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14933     {
14934       if (unformat (input, "local"))
14935         {
14936           filter = 1;
14937         }
14938       else if (unformat (input, "remote"))
14939         {
14940           filter = 2;
14941         }
14942       else
14943         {
14944           errmsg ("parse error '%U'", format_unformat_error, input);
14945           return -99;
14946         }
14947     }
14948
14949   if (!vam->json_output)
14950     {
14951       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14952     }
14953
14954   M (ONE_LOCATOR_SET_DUMP, mp);
14955
14956   mp->filter = filter;
14957
14958   /* send it... */
14959   S (mp);
14960
14961   /* Use a control ping for synchronization */
14962   M (CONTROL_PING, mp_ping);
14963   S (mp_ping);
14964
14965   /* Wait for a reply... */
14966   W (ret);
14967   return ret;
14968 }
14969
14970 #define api_lisp_locator_set_dump api_one_locator_set_dump
14971
14972 static int
14973 api_one_eid_table_map_dump (vat_main_t * vam)
14974 {
14975   u8 is_l2 = 0;
14976   u8 mode_set = 0;
14977   unformat_input_t *input = vam->input;
14978   vl_api_one_eid_table_map_dump_t *mp;
14979   vl_api_control_ping_t *mp_ping;
14980   int ret;
14981
14982   /* Parse args required to build the message */
14983   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14984     {
14985       if (unformat (input, "l2"))
14986         {
14987           is_l2 = 1;
14988           mode_set = 1;
14989         }
14990       else if (unformat (input, "l3"))
14991         {
14992           is_l2 = 0;
14993           mode_set = 1;
14994         }
14995       else
14996         {
14997           errmsg ("parse error '%U'", format_unformat_error, input);
14998           return -99;
14999         }
15000     }
15001
15002   if (!mode_set)
15003     {
15004       errmsg ("expected one of 'l2' or 'l3' parameter!");
15005       return -99;
15006     }
15007
15008   if (!vam->json_output)
15009     {
15010       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15011     }
15012
15013   M (ONE_EID_TABLE_MAP_DUMP, mp);
15014   mp->is_l2 = is_l2;
15015
15016   /* send it... */
15017   S (mp);
15018
15019   /* Use a control ping for synchronization */
15020   M (CONTROL_PING, mp_ping);
15021   S (mp_ping);
15022
15023   /* Wait for a reply... */
15024   W (ret);
15025   return ret;
15026 }
15027
15028 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15029
15030 static int
15031 api_one_eid_table_vni_dump (vat_main_t * vam)
15032 {
15033   vl_api_one_eid_table_vni_dump_t *mp;
15034   vl_api_control_ping_t *mp_ping;
15035   int ret;
15036
15037   if (!vam->json_output)
15038     {
15039       print (vam->ofp, "VNI");
15040     }
15041
15042   M (ONE_EID_TABLE_VNI_DUMP, mp);
15043
15044   /* send it... */
15045   S (mp);
15046
15047   /* Use a control ping for synchronization */
15048   M (CONTROL_PING, mp_ping);
15049   S (mp_ping);
15050
15051   /* Wait for a reply... */
15052   W (ret);
15053   return ret;
15054 }
15055
15056 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15057
15058 static int
15059 api_one_eid_table_dump (vat_main_t * vam)
15060 {
15061   unformat_input_t *i = vam->input;
15062   vl_api_one_eid_table_dump_t *mp;
15063   vl_api_control_ping_t *mp_ping;
15064   struct in_addr ip4;
15065   struct in6_addr ip6;
15066   u8 mac[6];
15067   u8 eid_type = ~0, eid_set = 0;
15068   u32 prefix_length = ~0, t, vni = 0;
15069   u8 filter = 0;
15070   int ret;
15071
15072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15073     {
15074       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15075         {
15076           eid_set = 1;
15077           eid_type = 0;
15078           prefix_length = t;
15079         }
15080       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15081         {
15082           eid_set = 1;
15083           eid_type = 1;
15084           prefix_length = t;
15085         }
15086       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15087         {
15088           eid_set = 1;
15089           eid_type = 2;
15090         }
15091       else if (unformat (i, "vni %d", &t))
15092         {
15093           vni = t;
15094         }
15095       else if (unformat (i, "local"))
15096         {
15097           filter = 1;
15098         }
15099       else if (unformat (i, "remote"))
15100         {
15101           filter = 2;
15102         }
15103       else
15104         {
15105           errmsg ("parse error '%U'", format_unformat_error, i);
15106           return -99;
15107         }
15108     }
15109
15110   if (!vam->json_output)
15111     {
15112       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15113              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15114     }
15115
15116   M (ONE_EID_TABLE_DUMP, mp);
15117
15118   mp->filter = filter;
15119   if (eid_set)
15120     {
15121       mp->eid_set = 1;
15122       mp->vni = htonl (vni);
15123       mp->eid_type = eid_type;
15124       switch (eid_type)
15125         {
15126         case 0:
15127           mp->prefix_length = prefix_length;
15128           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15129           break;
15130         case 1:
15131           mp->prefix_length = prefix_length;
15132           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15133           break;
15134         case 2:
15135           clib_memcpy (mp->eid, mac, sizeof (mac));
15136           break;
15137         default:
15138           errmsg ("unknown EID type %d!", eid_type);
15139           return -99;
15140         }
15141     }
15142
15143   /* send it... */
15144   S (mp);
15145
15146   /* Use a control ping for synchronization */
15147   M (CONTROL_PING, mp_ping);
15148   S (mp_ping);
15149
15150   /* Wait for a reply... */
15151   W (ret);
15152   return ret;
15153 }
15154
15155 #define api_lisp_eid_table_dump api_one_eid_table_dump
15156
15157 static int
15158 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15159 {
15160   unformat_input_t *i = vam->input;
15161   vl_api_gpe_fwd_entries_get_t *mp;
15162   u8 vni_set = 0;
15163   u32 vni = ~0;
15164   int ret;
15165
15166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15167     {
15168       if (unformat (i, "vni %d", &vni))
15169         {
15170           vni_set = 1;
15171         }
15172       else
15173         {
15174           errmsg ("parse error '%U'", format_unformat_error, i);
15175           return -99;
15176         }
15177     }
15178
15179   if (!vni_set)
15180     {
15181       errmsg ("vni not set!");
15182       return -99;
15183     }
15184
15185   if (!vam->json_output)
15186     {
15187       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15188              "leid", "reid");
15189     }
15190
15191   M (GPE_FWD_ENTRIES_GET, mp);
15192   mp->vni = clib_host_to_net_u32 (vni);
15193
15194   /* send it... */
15195   S (mp);
15196
15197   /* Wait for a reply... */
15198   W (ret);
15199   return ret;
15200 }
15201
15202 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15203 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15204 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15205 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15206
15207 static int
15208 api_one_adjacencies_get (vat_main_t * vam)
15209 {
15210   unformat_input_t *i = vam->input;
15211   vl_api_one_adjacencies_get_t *mp;
15212   u8 vni_set = 0;
15213   u32 vni = ~0;
15214   int ret;
15215
15216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15217     {
15218       if (unformat (i, "vni %d", &vni))
15219         {
15220           vni_set = 1;
15221         }
15222       else
15223         {
15224           errmsg ("parse error '%U'", format_unformat_error, i);
15225           return -99;
15226         }
15227     }
15228
15229   if (!vni_set)
15230     {
15231       errmsg ("vni not set!");
15232       return -99;
15233     }
15234
15235   if (!vam->json_output)
15236     {
15237       print (vam->ofp, "%s %40s", "leid", "reid");
15238     }
15239
15240   M (ONE_ADJACENCIES_GET, mp);
15241   mp->vni = clib_host_to_net_u32 (vni);
15242
15243   /* send it... */
15244   S (mp);
15245
15246   /* Wait for a reply... */
15247   W (ret);
15248   return ret;
15249 }
15250
15251 #define api_lisp_adjacencies_get api_one_adjacencies_get
15252
15253 static int
15254 api_one_map_server_dump (vat_main_t * vam)
15255 {
15256   vl_api_one_map_server_dump_t *mp;
15257   vl_api_control_ping_t *mp_ping;
15258   int ret;
15259
15260   if (!vam->json_output)
15261     {
15262       print (vam->ofp, "%=20s", "Map server");
15263     }
15264
15265   M (ONE_MAP_SERVER_DUMP, mp);
15266   /* send it... */
15267   S (mp);
15268
15269   /* Use a control ping for synchronization */
15270   M (CONTROL_PING, mp_ping);
15271   S (mp_ping);
15272
15273   /* Wait for a reply... */
15274   W (ret);
15275   return ret;
15276 }
15277
15278 #define api_lisp_map_server_dump api_one_map_server_dump
15279
15280 static int
15281 api_one_map_resolver_dump (vat_main_t * vam)
15282 {
15283   vl_api_one_map_resolver_dump_t *mp;
15284   vl_api_control_ping_t *mp_ping;
15285   int ret;
15286
15287   if (!vam->json_output)
15288     {
15289       print (vam->ofp, "%=20s", "Map resolver");
15290     }
15291
15292   M (ONE_MAP_RESOLVER_DUMP, mp);
15293   /* send it... */
15294   S (mp);
15295
15296   /* Use a control ping for synchronization */
15297   M (CONTROL_PING, mp_ping);
15298   S (mp_ping);
15299
15300   /* Wait for a reply... */
15301   W (ret);
15302   return ret;
15303 }
15304
15305 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15306
15307 static int
15308 api_show_one_status (vat_main_t * vam)
15309 {
15310   vl_api_show_one_status_t *mp;
15311   int ret;
15312
15313   if (!vam->json_output)
15314     {
15315       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15316     }
15317
15318   M (SHOW_ONE_STATUS, mp);
15319   /* send it... */
15320   S (mp);
15321   /* Wait for a reply... */
15322   W (ret);
15323   return ret;
15324 }
15325
15326 #define api_show_lisp_status api_show_one_status
15327
15328 static int
15329 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15330 {
15331   vl_api_gpe_fwd_entry_path_dump_t *mp;
15332   vl_api_control_ping_t *mp_ping;
15333   unformat_input_t *i = vam->input;
15334   u32 fwd_entry_index = ~0;
15335   int ret;
15336
15337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15338     {
15339       if (unformat (i, "index %d", &fwd_entry_index))
15340         ;
15341       else
15342         break;
15343     }
15344
15345   if (~0 == fwd_entry_index)
15346     {
15347       errmsg ("no index specified!");
15348       return -99;
15349     }
15350
15351   if (!vam->json_output)
15352     {
15353       print (vam->ofp, "first line");
15354     }
15355
15356   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15357
15358   /* send it... */
15359   S (mp);
15360   /* Use a control ping for synchronization */
15361   M (CONTROL_PING, mp_ping);
15362   S (mp_ping);
15363
15364   /* Wait for a reply... */
15365   W (ret);
15366   return ret;
15367 }
15368
15369 static int
15370 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15371 {
15372   vl_api_one_get_map_request_itr_rlocs_t *mp;
15373   int ret;
15374
15375   if (!vam->json_output)
15376     {
15377       print (vam->ofp, "%=20s", "itr-rlocs:");
15378     }
15379
15380   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15381   /* send it... */
15382   S (mp);
15383   /* Wait for a reply... */
15384   W (ret);
15385   return ret;
15386 }
15387
15388 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15389
15390 static int
15391 api_af_packet_create (vat_main_t * vam)
15392 {
15393   unformat_input_t *i = vam->input;
15394   vl_api_af_packet_create_t *mp;
15395   u8 *host_if_name = 0;
15396   u8 hw_addr[6];
15397   u8 random_hw_addr = 1;
15398   int ret;
15399
15400   memset (hw_addr, 0, sizeof (hw_addr));
15401
15402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15403     {
15404       if (unformat (i, "name %s", &host_if_name))
15405         vec_add1 (host_if_name, 0);
15406       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15407         random_hw_addr = 0;
15408       else
15409         break;
15410     }
15411
15412   if (!vec_len (host_if_name))
15413     {
15414       errmsg ("host-interface name must be specified");
15415       return -99;
15416     }
15417
15418   if (vec_len (host_if_name) > 64)
15419     {
15420       errmsg ("host-interface name too long");
15421       return -99;
15422     }
15423
15424   M (AF_PACKET_CREATE, mp);
15425
15426   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15427   clib_memcpy (mp->hw_addr, hw_addr, 6);
15428   mp->use_random_hw_addr = random_hw_addr;
15429   vec_free (host_if_name);
15430
15431   S (mp);
15432
15433   /* *INDENT-OFF* */
15434   W2 (ret,
15435       ({
15436         if (ret == 0)
15437           fprintf (vam->ofp ? vam->ofp : stderr,
15438                    " new sw_if_index = %d\n", vam->sw_if_index);
15439       }));
15440   /* *INDENT-ON* */
15441   return ret;
15442 }
15443
15444 static int
15445 api_af_packet_delete (vat_main_t * vam)
15446 {
15447   unformat_input_t *i = vam->input;
15448   vl_api_af_packet_delete_t *mp;
15449   u8 *host_if_name = 0;
15450   int ret;
15451
15452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15453     {
15454       if (unformat (i, "name %s", &host_if_name))
15455         vec_add1 (host_if_name, 0);
15456       else
15457         break;
15458     }
15459
15460   if (!vec_len (host_if_name))
15461     {
15462       errmsg ("host-interface name must be specified");
15463       return -99;
15464     }
15465
15466   if (vec_len (host_if_name) > 64)
15467     {
15468       errmsg ("host-interface name too long");
15469       return -99;
15470     }
15471
15472   M (AF_PACKET_DELETE, mp);
15473
15474   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15475   vec_free (host_if_name);
15476
15477   S (mp);
15478   W (ret);
15479   return ret;
15480 }
15481
15482 static int
15483 api_policer_add_del (vat_main_t * vam)
15484 {
15485   unformat_input_t *i = vam->input;
15486   vl_api_policer_add_del_t *mp;
15487   u8 is_add = 1;
15488   u8 *name = 0;
15489   u32 cir = 0;
15490   u32 eir = 0;
15491   u64 cb = 0;
15492   u64 eb = 0;
15493   u8 rate_type = 0;
15494   u8 round_type = 0;
15495   u8 type = 0;
15496   u8 color_aware = 0;
15497   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15498   int ret;
15499
15500   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15501   conform_action.dscp = 0;
15502   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15503   exceed_action.dscp = 0;
15504   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15505   violate_action.dscp = 0;
15506
15507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15508     {
15509       if (unformat (i, "del"))
15510         is_add = 0;
15511       else if (unformat (i, "name %s", &name))
15512         vec_add1 (name, 0);
15513       else if (unformat (i, "cir %u", &cir))
15514         ;
15515       else if (unformat (i, "eir %u", &eir))
15516         ;
15517       else if (unformat (i, "cb %u", &cb))
15518         ;
15519       else if (unformat (i, "eb %u", &eb))
15520         ;
15521       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15522                          &rate_type))
15523         ;
15524       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15525                          &round_type))
15526         ;
15527       else if (unformat (i, "type %U", unformat_policer_type, &type))
15528         ;
15529       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15530                          &conform_action))
15531         ;
15532       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15533                          &exceed_action))
15534         ;
15535       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15536                          &violate_action))
15537         ;
15538       else if (unformat (i, "color-aware"))
15539         color_aware = 1;
15540       else
15541         break;
15542     }
15543
15544   if (!vec_len (name))
15545     {
15546       errmsg ("policer name must be specified");
15547       return -99;
15548     }
15549
15550   if (vec_len (name) > 64)
15551     {
15552       errmsg ("policer name too long");
15553       return -99;
15554     }
15555
15556   M (POLICER_ADD_DEL, mp);
15557
15558   clib_memcpy (mp->name, name, vec_len (name));
15559   vec_free (name);
15560   mp->is_add = is_add;
15561   mp->cir = cir;
15562   mp->eir = eir;
15563   mp->cb = cb;
15564   mp->eb = eb;
15565   mp->rate_type = rate_type;
15566   mp->round_type = round_type;
15567   mp->type = type;
15568   mp->conform_action_type = conform_action.action_type;
15569   mp->conform_dscp = conform_action.dscp;
15570   mp->exceed_action_type = exceed_action.action_type;
15571   mp->exceed_dscp = exceed_action.dscp;
15572   mp->violate_action_type = violate_action.action_type;
15573   mp->violate_dscp = violate_action.dscp;
15574   mp->color_aware = color_aware;
15575
15576   S (mp);
15577   W (ret);
15578   return ret;
15579 }
15580
15581 static int
15582 api_policer_dump (vat_main_t * vam)
15583 {
15584   unformat_input_t *i = vam->input;
15585   vl_api_policer_dump_t *mp;
15586   vl_api_control_ping_t *mp_ping;
15587   u8 *match_name = 0;
15588   u8 match_name_valid = 0;
15589   int ret;
15590
15591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15592     {
15593       if (unformat (i, "name %s", &match_name))
15594         {
15595           vec_add1 (match_name, 0);
15596           match_name_valid = 1;
15597         }
15598       else
15599         break;
15600     }
15601
15602   M (POLICER_DUMP, mp);
15603   mp->match_name_valid = match_name_valid;
15604   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15605   vec_free (match_name);
15606   /* send it... */
15607   S (mp);
15608
15609   /* Use a control ping for synchronization */
15610   M (CONTROL_PING, mp_ping);
15611   S (mp_ping);
15612
15613   /* Wait for a reply... */
15614   W (ret);
15615   return ret;
15616 }
15617
15618 static int
15619 api_policer_classify_set_interface (vat_main_t * vam)
15620 {
15621   unformat_input_t *i = vam->input;
15622   vl_api_policer_classify_set_interface_t *mp;
15623   u32 sw_if_index;
15624   int sw_if_index_set;
15625   u32 ip4_table_index = ~0;
15626   u32 ip6_table_index = ~0;
15627   u32 l2_table_index = ~0;
15628   u8 is_add = 1;
15629   int ret;
15630
15631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15632     {
15633       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15634         sw_if_index_set = 1;
15635       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15636         sw_if_index_set = 1;
15637       else if (unformat (i, "del"))
15638         is_add = 0;
15639       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15640         ;
15641       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15642         ;
15643       else if (unformat (i, "l2-table %d", &l2_table_index))
15644         ;
15645       else
15646         {
15647           clib_warning ("parse error '%U'", format_unformat_error, i);
15648           return -99;
15649         }
15650     }
15651
15652   if (sw_if_index_set == 0)
15653     {
15654       errmsg ("missing interface name or sw_if_index");
15655       return -99;
15656     }
15657
15658   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15659
15660   mp->sw_if_index = ntohl (sw_if_index);
15661   mp->ip4_table_index = ntohl (ip4_table_index);
15662   mp->ip6_table_index = ntohl (ip6_table_index);
15663   mp->l2_table_index = ntohl (l2_table_index);
15664   mp->is_add = is_add;
15665
15666   S (mp);
15667   W (ret);
15668   return ret;
15669 }
15670
15671 static int
15672 api_policer_classify_dump (vat_main_t * vam)
15673 {
15674   unformat_input_t *i = vam->input;
15675   vl_api_policer_classify_dump_t *mp;
15676   vl_api_control_ping_t *mp_ping;
15677   u8 type = POLICER_CLASSIFY_N_TABLES;
15678   int ret;
15679
15680   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15681     ;
15682   else
15683     {
15684       errmsg ("classify table type must be specified");
15685       return -99;
15686     }
15687
15688   if (!vam->json_output)
15689     {
15690       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15691     }
15692
15693   M (POLICER_CLASSIFY_DUMP, mp);
15694   mp->type = type;
15695   /* send it... */
15696   S (mp);
15697
15698   /* Use a control ping for synchronization */
15699   M (CONTROL_PING, mp_ping);
15700   S (mp_ping);
15701
15702   /* Wait for a reply... */
15703   W (ret);
15704   return ret;
15705 }
15706
15707 static int
15708 api_netmap_create (vat_main_t * vam)
15709 {
15710   unformat_input_t *i = vam->input;
15711   vl_api_netmap_create_t *mp;
15712   u8 *if_name = 0;
15713   u8 hw_addr[6];
15714   u8 random_hw_addr = 1;
15715   u8 is_pipe = 0;
15716   u8 is_master = 0;
15717   int ret;
15718
15719   memset (hw_addr, 0, sizeof (hw_addr));
15720
15721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15722     {
15723       if (unformat (i, "name %s", &if_name))
15724         vec_add1 (if_name, 0);
15725       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15726         random_hw_addr = 0;
15727       else if (unformat (i, "pipe"))
15728         is_pipe = 1;
15729       else if (unformat (i, "master"))
15730         is_master = 1;
15731       else if (unformat (i, "slave"))
15732         is_master = 0;
15733       else
15734         break;
15735     }
15736
15737   if (!vec_len (if_name))
15738     {
15739       errmsg ("interface name must be specified");
15740       return -99;
15741     }
15742
15743   if (vec_len (if_name) > 64)
15744     {
15745       errmsg ("interface name too long");
15746       return -99;
15747     }
15748
15749   M (NETMAP_CREATE, mp);
15750
15751   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15752   clib_memcpy (mp->hw_addr, hw_addr, 6);
15753   mp->use_random_hw_addr = random_hw_addr;
15754   mp->is_pipe = is_pipe;
15755   mp->is_master = is_master;
15756   vec_free (if_name);
15757
15758   S (mp);
15759   W (ret);
15760   return ret;
15761 }
15762
15763 static int
15764 api_netmap_delete (vat_main_t * vam)
15765 {
15766   unformat_input_t *i = vam->input;
15767   vl_api_netmap_delete_t *mp;
15768   u8 *if_name = 0;
15769   int ret;
15770
15771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15772     {
15773       if (unformat (i, "name %s", &if_name))
15774         vec_add1 (if_name, 0);
15775       else
15776         break;
15777     }
15778
15779   if (!vec_len (if_name))
15780     {
15781       errmsg ("interface name must be specified");
15782       return -99;
15783     }
15784
15785   if (vec_len (if_name) > 64)
15786     {
15787       errmsg ("interface name too long");
15788       return -99;
15789     }
15790
15791   M (NETMAP_DELETE, mp);
15792
15793   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15794   vec_free (if_name);
15795
15796   S (mp);
15797   W (ret);
15798   return ret;
15799 }
15800
15801 static void vl_api_mpls_tunnel_details_t_handler
15802   (vl_api_mpls_tunnel_details_t * mp)
15803 {
15804   vat_main_t *vam = &vat_main;
15805   i32 len = mp->mt_next_hop_n_labels;
15806   i32 i;
15807
15808   print (vam->ofp, "[%d]: via %U %d labels ",
15809          mp->tunnel_index,
15810          format_ip4_address, mp->mt_next_hop,
15811          ntohl (mp->mt_next_hop_sw_if_index));
15812   for (i = 0; i < len; i++)
15813     {
15814       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15815     }
15816   print (vam->ofp, "");
15817 }
15818
15819 static void vl_api_mpls_tunnel_details_t_handler_json
15820   (vl_api_mpls_tunnel_details_t * mp)
15821 {
15822   vat_main_t *vam = &vat_main;
15823   vat_json_node_t *node = NULL;
15824   struct in_addr ip4;
15825   i32 i;
15826   i32 len = mp->mt_next_hop_n_labels;
15827
15828   if (VAT_JSON_ARRAY != vam->json_tree.type)
15829     {
15830       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15831       vat_json_init_array (&vam->json_tree);
15832     }
15833   node = vat_json_array_add (&vam->json_tree);
15834
15835   vat_json_init_object (node);
15836   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15837   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15838   vat_json_object_add_ip4 (node, "next_hop", ip4);
15839   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15840                             ntohl (mp->mt_next_hop_sw_if_index));
15841   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15842   vat_json_object_add_uint (node, "label_count", len);
15843   for (i = 0; i < len; i++)
15844     {
15845       vat_json_object_add_uint (node, "label",
15846                                 ntohl (mp->mt_next_hop_out_labels[i]));
15847     }
15848 }
15849
15850 static int
15851 api_mpls_tunnel_dump (vat_main_t * vam)
15852 {
15853   vl_api_mpls_tunnel_dump_t *mp;
15854   vl_api_control_ping_t *mp_ping;
15855   i32 index = -1;
15856   int ret;
15857
15858   /* Parse args required to build the message */
15859   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15860     {
15861       if (!unformat (vam->input, "tunnel_index %d", &index))
15862         {
15863           index = -1;
15864           break;
15865         }
15866     }
15867
15868   print (vam->ofp, "  tunnel_index %d", index);
15869
15870   M (MPLS_TUNNEL_DUMP, mp);
15871   mp->tunnel_index = htonl (index);
15872   S (mp);
15873
15874   /* Use a control ping for synchronization */
15875   M (CONTROL_PING, mp_ping);
15876   S (mp_ping);
15877
15878   W (ret);
15879   return ret;
15880 }
15881
15882 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15883 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15884
15885 static void
15886 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15887 {
15888   vat_main_t *vam = &vat_main;
15889   int count = ntohl (mp->count);
15890   vl_api_fib_path2_t *fp;
15891   int i;
15892
15893   print (vam->ofp,
15894          "table-id %d, label %u, ess_bit %u",
15895          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15896   fp = mp->path;
15897   for (i = 0; i < count; i++)
15898     {
15899       if (fp->afi == IP46_TYPE_IP6)
15900         print (vam->ofp,
15901                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15902                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15903                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15904                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15905                format_ip6_address, fp->next_hop);
15906       else if (fp->afi == IP46_TYPE_IP4)
15907         print (vam->ofp,
15908                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15909                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15910                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15911                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15912                format_ip4_address, fp->next_hop);
15913       fp++;
15914     }
15915 }
15916
15917 static void vl_api_mpls_fib_details_t_handler_json
15918   (vl_api_mpls_fib_details_t * mp)
15919 {
15920   vat_main_t *vam = &vat_main;
15921   int count = ntohl (mp->count);
15922   vat_json_node_t *node = NULL;
15923   struct in_addr ip4;
15924   struct in6_addr ip6;
15925   vl_api_fib_path2_t *fp;
15926   int i;
15927
15928   if (VAT_JSON_ARRAY != vam->json_tree.type)
15929     {
15930       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15931       vat_json_init_array (&vam->json_tree);
15932     }
15933   node = vat_json_array_add (&vam->json_tree);
15934
15935   vat_json_init_object (node);
15936   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15937   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15938   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15939   vat_json_object_add_uint (node, "path_count", count);
15940   fp = mp->path;
15941   for (i = 0; i < count; i++)
15942     {
15943       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15944       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15945       vat_json_object_add_uint (node, "is_local", fp->is_local);
15946       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15947       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15948       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15949       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15950       if (fp->afi == IP46_TYPE_IP4)
15951         {
15952           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15953           vat_json_object_add_ip4 (node, "next_hop", ip4);
15954         }
15955       else if (fp->afi == IP46_TYPE_IP6)
15956         {
15957           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15958           vat_json_object_add_ip6 (node, "next_hop", ip6);
15959         }
15960     }
15961 }
15962
15963 static int
15964 api_mpls_fib_dump (vat_main_t * vam)
15965 {
15966   vl_api_mpls_fib_dump_t *mp;
15967   vl_api_control_ping_t *mp_ping;
15968   int ret;
15969
15970   M (MPLS_FIB_DUMP, mp);
15971   S (mp);
15972
15973   /* Use a control ping for synchronization */
15974   M (CONTROL_PING, mp_ping);
15975   S (mp_ping);
15976
15977   W (ret);
15978   return ret;
15979 }
15980
15981 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15982 #define vl_api_ip_fib_details_t_print vl_noop_handler
15983
15984 static void
15985 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15986 {
15987   vat_main_t *vam = &vat_main;
15988   int count = ntohl (mp->count);
15989   vl_api_fib_path_t *fp;
15990   int i;
15991
15992   print (vam->ofp,
15993          "table-id %d, prefix %U/%d",
15994          ntohl (mp->table_id), format_ip4_address, mp->address,
15995          mp->address_length);
15996   fp = mp->path;
15997   for (i = 0; i < count; i++)
15998     {
15999       if (fp->afi == IP46_TYPE_IP6)
16000         print (vam->ofp,
16001                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16002                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16003                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16004                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16005                format_ip6_address, fp->next_hop);
16006       else if (fp->afi == IP46_TYPE_IP4)
16007         print (vam->ofp,
16008                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16009                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16010                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16011                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16012                format_ip4_address, fp->next_hop);
16013       fp++;
16014     }
16015 }
16016
16017 static void vl_api_ip_fib_details_t_handler_json
16018   (vl_api_ip_fib_details_t * mp)
16019 {
16020   vat_main_t *vam = &vat_main;
16021   int count = ntohl (mp->count);
16022   vat_json_node_t *node = NULL;
16023   struct in_addr ip4;
16024   struct in6_addr ip6;
16025   vl_api_fib_path_t *fp;
16026   int i;
16027
16028   if (VAT_JSON_ARRAY != vam->json_tree.type)
16029     {
16030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16031       vat_json_init_array (&vam->json_tree);
16032     }
16033   node = vat_json_array_add (&vam->json_tree);
16034
16035   vat_json_init_object (node);
16036   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16037   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16038   vat_json_object_add_ip4 (node, "prefix", ip4);
16039   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16040   vat_json_object_add_uint (node, "path_count", count);
16041   fp = mp->path;
16042   for (i = 0; i < count; i++)
16043     {
16044       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16045       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16046       vat_json_object_add_uint (node, "is_local", fp->is_local);
16047       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16048       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16049       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16050       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16051       if (fp->afi == IP46_TYPE_IP4)
16052         {
16053           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16054           vat_json_object_add_ip4 (node, "next_hop", ip4);
16055         }
16056       else if (fp->afi == IP46_TYPE_IP6)
16057         {
16058           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16059           vat_json_object_add_ip6 (node, "next_hop", ip6);
16060         }
16061     }
16062 }
16063
16064 static int
16065 api_ip_fib_dump (vat_main_t * vam)
16066 {
16067   vl_api_ip_fib_dump_t *mp;
16068   vl_api_control_ping_t *mp_ping;
16069   int ret;
16070
16071   M (IP_FIB_DUMP, mp);
16072   S (mp);
16073
16074   /* Use a control ping for synchronization */
16075   M (CONTROL_PING, mp_ping);
16076   S (mp_ping);
16077
16078   W (ret);
16079   return ret;
16080 }
16081
16082 static int
16083 api_ip_mfib_dump (vat_main_t * vam)
16084 {
16085   vl_api_ip_mfib_dump_t *mp;
16086   vl_api_control_ping_t *mp_ping;
16087   int ret;
16088
16089   M (IP_MFIB_DUMP, mp);
16090   S (mp);
16091
16092   /* Use a control ping for synchronization */
16093   M (CONTROL_PING, mp_ping);
16094   S (mp_ping);
16095
16096   W (ret);
16097   return ret;
16098 }
16099
16100 static void vl_api_ip_neighbor_details_t_handler
16101   (vl_api_ip_neighbor_details_t * mp)
16102 {
16103   vat_main_t *vam = &vat_main;
16104
16105   print (vam->ofp, "%c %U %U",
16106          (mp->is_static) ? 'S' : 'D',
16107          format_ethernet_address, &mp->mac_address,
16108          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16109          &mp->ip_address);
16110 }
16111
16112 static void vl_api_ip_neighbor_details_t_handler_json
16113   (vl_api_ip_neighbor_details_t * mp)
16114 {
16115
16116   vat_main_t *vam = &vat_main;
16117   vat_json_node_t *node;
16118   struct in_addr ip4;
16119   struct in6_addr ip6;
16120
16121   if (VAT_JSON_ARRAY != vam->json_tree.type)
16122     {
16123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16124       vat_json_init_array (&vam->json_tree);
16125     }
16126   node = vat_json_array_add (&vam->json_tree);
16127
16128   vat_json_init_object (node);
16129   vat_json_object_add_string_copy (node, "flag",
16130                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16131                                    "dynamic");
16132
16133   vat_json_object_add_string_copy (node, "link_layer",
16134                                    format (0, "%U", format_ethernet_address,
16135                                            &mp->mac_address));
16136
16137   if (mp->is_ipv6)
16138     {
16139       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16140       vat_json_object_add_ip6 (node, "ip_address", ip6);
16141     }
16142   else
16143     {
16144       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16145       vat_json_object_add_ip4 (node, "ip_address", ip4);
16146     }
16147 }
16148
16149 static int
16150 api_ip_neighbor_dump (vat_main_t * vam)
16151 {
16152   unformat_input_t *i = vam->input;
16153   vl_api_ip_neighbor_dump_t *mp;
16154   vl_api_control_ping_t *mp_ping;
16155   u8 is_ipv6 = 0;
16156   u32 sw_if_index = ~0;
16157   int ret;
16158
16159   /* Parse args required to build the message */
16160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16161     {
16162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16163         ;
16164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16165         ;
16166       else if (unformat (i, "ip6"))
16167         is_ipv6 = 1;
16168       else
16169         break;
16170     }
16171
16172   if (sw_if_index == ~0)
16173     {
16174       errmsg ("missing interface name or sw_if_index");
16175       return -99;
16176     }
16177
16178   M (IP_NEIGHBOR_DUMP, mp);
16179   mp->is_ipv6 = (u8) is_ipv6;
16180   mp->sw_if_index = ntohl (sw_if_index);
16181   S (mp);
16182
16183   /* Use a control ping for synchronization */
16184   M (CONTROL_PING, mp_ping);
16185   S (mp_ping);
16186
16187   W (ret);
16188   return ret;
16189 }
16190
16191 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16192 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16193
16194 static void
16195 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16196 {
16197   vat_main_t *vam = &vat_main;
16198   int count = ntohl (mp->count);
16199   vl_api_fib_path_t *fp;
16200   int i;
16201
16202   print (vam->ofp,
16203          "table-id %d, prefix %U/%d",
16204          ntohl (mp->table_id), format_ip6_address, mp->address,
16205          mp->address_length);
16206   fp = mp->path;
16207   for (i = 0; i < count; i++)
16208     {
16209       if (fp->afi == IP46_TYPE_IP6)
16210         print (vam->ofp,
16211                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16212                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16213                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16214                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16215                format_ip6_address, fp->next_hop);
16216       else if (fp->afi == IP46_TYPE_IP4)
16217         print (vam->ofp,
16218                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16219                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16220                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16221                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16222                format_ip4_address, fp->next_hop);
16223       fp++;
16224     }
16225 }
16226
16227 static void vl_api_ip6_fib_details_t_handler_json
16228   (vl_api_ip6_fib_details_t * mp)
16229 {
16230   vat_main_t *vam = &vat_main;
16231   int count = ntohl (mp->count);
16232   vat_json_node_t *node = NULL;
16233   struct in_addr ip4;
16234   struct in6_addr ip6;
16235   vl_api_fib_path_t *fp;
16236   int i;
16237
16238   if (VAT_JSON_ARRAY != vam->json_tree.type)
16239     {
16240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16241       vat_json_init_array (&vam->json_tree);
16242     }
16243   node = vat_json_array_add (&vam->json_tree);
16244
16245   vat_json_init_object (node);
16246   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16247   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16248   vat_json_object_add_ip6 (node, "prefix", ip6);
16249   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16250   vat_json_object_add_uint (node, "path_count", count);
16251   fp = mp->path;
16252   for (i = 0; i < count; i++)
16253     {
16254       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16255       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16256       vat_json_object_add_uint (node, "is_local", fp->is_local);
16257       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16258       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16259       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16260       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16261       if (fp->afi == IP46_TYPE_IP4)
16262         {
16263           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16264           vat_json_object_add_ip4 (node, "next_hop", ip4);
16265         }
16266       else if (fp->afi == IP46_TYPE_IP6)
16267         {
16268           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16269           vat_json_object_add_ip6 (node, "next_hop", ip6);
16270         }
16271     }
16272 }
16273
16274 static int
16275 api_ip6_fib_dump (vat_main_t * vam)
16276 {
16277   vl_api_ip6_fib_dump_t *mp;
16278   vl_api_control_ping_t *mp_ping;
16279   int ret;
16280
16281   M (IP6_FIB_DUMP, mp);
16282   S (mp);
16283
16284   /* Use a control ping for synchronization */
16285   M (CONTROL_PING, mp_ping);
16286   S (mp_ping);
16287
16288   W (ret);
16289   return ret;
16290 }
16291
16292 static int
16293 api_ip6_mfib_dump (vat_main_t * vam)
16294 {
16295   vl_api_ip6_mfib_dump_t *mp;
16296   vl_api_control_ping_t *mp_ping;
16297   int ret;
16298
16299   M (IP6_MFIB_DUMP, mp);
16300   S (mp);
16301
16302   /* Use a control ping for synchronization */
16303   M (CONTROL_PING, mp_ping);
16304   S (mp_ping);
16305
16306   W (ret);
16307   return ret;
16308 }
16309
16310 int
16311 api_classify_table_ids (vat_main_t * vam)
16312 {
16313   vl_api_classify_table_ids_t *mp;
16314   int ret;
16315
16316   /* Construct the API message */
16317   M (CLASSIFY_TABLE_IDS, mp);
16318   mp->context = 0;
16319
16320   S (mp);
16321   W (ret);
16322   return ret;
16323 }
16324
16325 int
16326 api_classify_table_by_interface (vat_main_t * vam)
16327 {
16328   unformat_input_t *input = vam->input;
16329   vl_api_classify_table_by_interface_t *mp;
16330
16331   u32 sw_if_index = ~0;
16332   int ret;
16333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16334     {
16335       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16336         ;
16337       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16338         ;
16339       else
16340         break;
16341     }
16342   if (sw_if_index == ~0)
16343     {
16344       errmsg ("missing interface name or sw_if_index");
16345       return -99;
16346     }
16347
16348   /* Construct the API message */
16349   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16350   mp->context = 0;
16351   mp->sw_if_index = ntohl (sw_if_index);
16352
16353   S (mp);
16354   W (ret);
16355   return ret;
16356 }
16357
16358 int
16359 api_classify_table_info (vat_main_t * vam)
16360 {
16361   unformat_input_t *input = vam->input;
16362   vl_api_classify_table_info_t *mp;
16363
16364   u32 table_id = ~0;
16365   int ret;
16366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16367     {
16368       if (unformat (input, "table_id %d", &table_id))
16369         ;
16370       else
16371         break;
16372     }
16373   if (table_id == ~0)
16374     {
16375       errmsg ("missing table id");
16376       return -99;
16377     }
16378
16379   /* Construct the API message */
16380   M (CLASSIFY_TABLE_INFO, mp);
16381   mp->context = 0;
16382   mp->table_id = ntohl (table_id);
16383
16384   S (mp);
16385   W (ret);
16386   return ret;
16387 }
16388
16389 int
16390 api_classify_session_dump (vat_main_t * vam)
16391 {
16392   unformat_input_t *input = vam->input;
16393   vl_api_classify_session_dump_t *mp;
16394   vl_api_control_ping_t *mp_ping;
16395
16396   u32 table_id = ~0;
16397   int ret;
16398   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16399     {
16400       if (unformat (input, "table_id %d", &table_id))
16401         ;
16402       else
16403         break;
16404     }
16405   if (table_id == ~0)
16406     {
16407       errmsg ("missing table id");
16408       return -99;
16409     }
16410
16411   /* Construct the API message */
16412   M (CLASSIFY_SESSION_DUMP, mp);
16413   mp->context = 0;
16414   mp->table_id = ntohl (table_id);
16415   S (mp);
16416
16417   /* Use a control ping for synchronization */
16418   M (CONTROL_PING, mp_ping);
16419   S (mp_ping);
16420
16421   W (ret);
16422   return ret;
16423 }
16424
16425 static void
16426 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16427 {
16428   vat_main_t *vam = &vat_main;
16429
16430   print (vam->ofp, "collector_address %U, collector_port %d, "
16431          "src_address %U, vrf_id %d, path_mtu %u, "
16432          "template_interval %u, udp_checksum %d",
16433          format_ip4_address, mp->collector_address,
16434          ntohs (mp->collector_port),
16435          format_ip4_address, mp->src_address,
16436          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16437          ntohl (mp->template_interval), mp->udp_checksum);
16438
16439   vam->retval = 0;
16440   vam->result_ready = 1;
16441 }
16442
16443 static void
16444   vl_api_ipfix_exporter_details_t_handler_json
16445   (vl_api_ipfix_exporter_details_t * mp)
16446 {
16447   vat_main_t *vam = &vat_main;
16448   vat_json_node_t node;
16449   struct in_addr collector_address;
16450   struct in_addr src_address;
16451
16452   vat_json_init_object (&node);
16453   clib_memcpy (&collector_address, &mp->collector_address,
16454                sizeof (collector_address));
16455   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16456   vat_json_object_add_uint (&node, "collector_port",
16457                             ntohs (mp->collector_port));
16458   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16459   vat_json_object_add_ip4 (&node, "src_address", src_address);
16460   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16461   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16462   vat_json_object_add_uint (&node, "template_interval",
16463                             ntohl (mp->template_interval));
16464   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16465
16466   vat_json_print (vam->ofp, &node);
16467   vat_json_free (&node);
16468   vam->retval = 0;
16469   vam->result_ready = 1;
16470 }
16471
16472 int
16473 api_ipfix_exporter_dump (vat_main_t * vam)
16474 {
16475   vl_api_ipfix_exporter_dump_t *mp;
16476   int ret;
16477
16478   /* Construct the API message */
16479   M (IPFIX_EXPORTER_DUMP, mp);
16480   mp->context = 0;
16481
16482   S (mp);
16483   W (ret);
16484   return ret;
16485 }
16486
16487 static int
16488 api_ipfix_classify_stream_dump (vat_main_t * vam)
16489 {
16490   vl_api_ipfix_classify_stream_dump_t *mp;
16491   int ret;
16492
16493   /* Construct the API message */
16494   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16495   mp->context = 0;
16496
16497   S (mp);
16498   W (ret);
16499   return ret;
16500   /* NOTREACHED */
16501   return 0;
16502 }
16503
16504 static void
16505   vl_api_ipfix_classify_stream_details_t_handler
16506   (vl_api_ipfix_classify_stream_details_t * mp)
16507 {
16508   vat_main_t *vam = &vat_main;
16509   print (vam->ofp, "domain_id %d, src_port %d",
16510          ntohl (mp->domain_id), ntohs (mp->src_port));
16511   vam->retval = 0;
16512   vam->result_ready = 1;
16513 }
16514
16515 static void
16516   vl_api_ipfix_classify_stream_details_t_handler_json
16517   (vl_api_ipfix_classify_stream_details_t * mp)
16518 {
16519   vat_main_t *vam = &vat_main;
16520   vat_json_node_t node;
16521
16522   vat_json_init_object (&node);
16523   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16524   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16525
16526   vat_json_print (vam->ofp, &node);
16527   vat_json_free (&node);
16528   vam->retval = 0;
16529   vam->result_ready = 1;
16530 }
16531
16532 static int
16533 api_ipfix_classify_table_dump (vat_main_t * vam)
16534 {
16535   vl_api_ipfix_classify_table_dump_t *mp;
16536   vl_api_control_ping_t *mp_ping;
16537   int ret;
16538
16539   if (!vam->json_output)
16540     {
16541       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16542              "transport_protocol");
16543     }
16544
16545   /* Construct the API message */
16546   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16547
16548   /* send it... */
16549   S (mp);
16550
16551   /* Use a control ping for synchronization */
16552   M (CONTROL_PING, mp_ping);
16553   S (mp_ping);
16554
16555   W (ret);
16556   return ret;
16557 }
16558
16559 static void
16560   vl_api_ipfix_classify_table_details_t_handler
16561   (vl_api_ipfix_classify_table_details_t * mp)
16562 {
16563   vat_main_t *vam = &vat_main;
16564   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16565          mp->transport_protocol);
16566 }
16567
16568 static void
16569   vl_api_ipfix_classify_table_details_t_handler_json
16570   (vl_api_ipfix_classify_table_details_t * mp)
16571 {
16572   vat_json_node_t *node = NULL;
16573   vat_main_t *vam = &vat_main;
16574
16575   if (VAT_JSON_ARRAY != vam->json_tree.type)
16576     {
16577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16578       vat_json_init_array (&vam->json_tree);
16579     }
16580
16581   node = vat_json_array_add (&vam->json_tree);
16582   vat_json_init_object (node);
16583
16584   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16585   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16586   vat_json_object_add_uint (node, "transport_protocol",
16587                             mp->transport_protocol);
16588 }
16589
16590 static int
16591 api_sw_interface_span_enable_disable (vat_main_t * vam)
16592 {
16593   unformat_input_t *i = vam->input;
16594   vl_api_sw_interface_span_enable_disable_t *mp;
16595   u32 src_sw_if_index = ~0;
16596   u32 dst_sw_if_index = ~0;
16597   u8 state = 3;
16598   int ret;
16599
16600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16601     {
16602       if (unformat
16603           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16604         ;
16605       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16606         ;
16607       else
16608         if (unformat
16609             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16610         ;
16611       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16612         ;
16613       else if (unformat (i, "disable"))
16614         state = 0;
16615       else if (unformat (i, "rx"))
16616         state = 1;
16617       else if (unformat (i, "tx"))
16618         state = 2;
16619       else if (unformat (i, "both"))
16620         state = 3;
16621       else
16622         break;
16623     }
16624
16625   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16626
16627   mp->sw_if_index_from = htonl (src_sw_if_index);
16628   mp->sw_if_index_to = htonl (dst_sw_if_index);
16629   mp->state = state;
16630
16631   S (mp);
16632   W (ret);
16633   return ret;
16634 }
16635
16636 static void
16637 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16638                                             * mp)
16639 {
16640   vat_main_t *vam = &vat_main;
16641   u8 *sw_if_from_name = 0;
16642   u8 *sw_if_to_name = 0;
16643   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16644   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16645   char *states[] = { "none", "rx", "tx", "both" };
16646   hash_pair_t *p;
16647
16648   /* *INDENT-OFF* */
16649   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16650   ({
16651     if ((u32) p->value[0] == sw_if_index_from)
16652       {
16653         sw_if_from_name = (u8 *)(p->key);
16654         if (sw_if_to_name)
16655           break;
16656       }
16657     if ((u32) p->value[0] == sw_if_index_to)
16658       {
16659         sw_if_to_name = (u8 *)(p->key);
16660         if (sw_if_from_name)
16661           break;
16662       }
16663   }));
16664   /* *INDENT-ON* */
16665   print (vam->ofp, "%20s => %20s (%s)",
16666          sw_if_from_name, sw_if_to_name, states[mp->state]);
16667 }
16668
16669 static void
16670   vl_api_sw_interface_span_details_t_handler_json
16671   (vl_api_sw_interface_span_details_t * mp)
16672 {
16673   vat_main_t *vam = &vat_main;
16674   vat_json_node_t *node = NULL;
16675   u8 *sw_if_from_name = 0;
16676   u8 *sw_if_to_name = 0;
16677   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16678   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16679   hash_pair_t *p;
16680
16681   /* *INDENT-OFF* */
16682   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16683   ({
16684     if ((u32) p->value[0] == sw_if_index_from)
16685       {
16686         sw_if_from_name = (u8 *)(p->key);
16687         if (sw_if_to_name)
16688           break;
16689       }
16690     if ((u32) p->value[0] == sw_if_index_to)
16691       {
16692         sw_if_to_name = (u8 *)(p->key);
16693         if (sw_if_from_name)
16694           break;
16695       }
16696   }));
16697   /* *INDENT-ON* */
16698
16699   if (VAT_JSON_ARRAY != vam->json_tree.type)
16700     {
16701       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16702       vat_json_init_array (&vam->json_tree);
16703     }
16704   node = vat_json_array_add (&vam->json_tree);
16705
16706   vat_json_init_object (node);
16707   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16708   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16709   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16710   if (0 != sw_if_to_name)
16711     {
16712       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16713     }
16714   vat_json_object_add_uint (node, "state", mp->state);
16715 }
16716
16717 static int
16718 api_sw_interface_span_dump (vat_main_t * vam)
16719 {
16720   vl_api_sw_interface_span_dump_t *mp;
16721   vl_api_control_ping_t *mp_ping;
16722   int ret;
16723
16724   M (SW_INTERFACE_SPAN_DUMP, mp);
16725   S (mp);
16726
16727   /* Use a control ping for synchronization */
16728   M (CONTROL_PING, mp_ping);
16729   S (mp_ping);
16730
16731   W (ret);
16732   return ret;
16733 }
16734
16735 int
16736 api_pg_create_interface (vat_main_t * vam)
16737 {
16738   unformat_input_t *input = vam->input;
16739   vl_api_pg_create_interface_t *mp;
16740
16741   u32 if_id = ~0;
16742   int ret;
16743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16744     {
16745       if (unformat (input, "if_id %d", &if_id))
16746         ;
16747       else
16748         break;
16749     }
16750   if (if_id == ~0)
16751     {
16752       errmsg ("missing pg interface index");
16753       return -99;
16754     }
16755
16756   /* Construct the API message */
16757   M (PG_CREATE_INTERFACE, mp);
16758   mp->context = 0;
16759   mp->interface_id = ntohl (if_id);
16760
16761   S (mp);
16762   W (ret);
16763   return ret;
16764 }
16765
16766 int
16767 api_pg_capture (vat_main_t * vam)
16768 {
16769   unformat_input_t *input = vam->input;
16770   vl_api_pg_capture_t *mp;
16771
16772   u32 if_id = ~0;
16773   u8 enable = 1;
16774   u32 count = 1;
16775   u8 pcap_file_set = 0;
16776   u8 *pcap_file = 0;
16777   int ret;
16778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16779     {
16780       if (unformat (input, "if_id %d", &if_id))
16781         ;
16782       else if (unformat (input, "pcap %s", &pcap_file))
16783         pcap_file_set = 1;
16784       else if (unformat (input, "count %d", &count))
16785         ;
16786       else if (unformat (input, "disable"))
16787         enable = 0;
16788       else
16789         break;
16790     }
16791   if (if_id == ~0)
16792     {
16793       errmsg ("missing pg interface index");
16794       return -99;
16795     }
16796   if (pcap_file_set > 0)
16797     {
16798       if (vec_len (pcap_file) > 255)
16799         {
16800           errmsg ("pcap file name is too long");
16801           return -99;
16802         }
16803     }
16804
16805   u32 name_len = vec_len (pcap_file);
16806   /* Construct the API message */
16807   M (PG_CAPTURE, mp);
16808   mp->context = 0;
16809   mp->interface_id = ntohl (if_id);
16810   mp->is_enabled = enable;
16811   mp->count = ntohl (count);
16812   mp->pcap_name_length = ntohl (name_len);
16813   if (pcap_file_set != 0)
16814     {
16815       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16816     }
16817   vec_free (pcap_file);
16818
16819   S (mp);
16820   W (ret);
16821   return ret;
16822 }
16823
16824 int
16825 api_pg_enable_disable (vat_main_t * vam)
16826 {
16827   unformat_input_t *input = vam->input;
16828   vl_api_pg_enable_disable_t *mp;
16829
16830   u8 enable = 1;
16831   u8 stream_name_set = 0;
16832   u8 *stream_name = 0;
16833   int ret;
16834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16835     {
16836       if (unformat (input, "stream %s", &stream_name))
16837         stream_name_set = 1;
16838       else if (unformat (input, "disable"))
16839         enable = 0;
16840       else
16841         break;
16842     }
16843
16844   if (stream_name_set > 0)
16845     {
16846       if (vec_len (stream_name) > 255)
16847         {
16848           errmsg ("stream name too long");
16849           return -99;
16850         }
16851     }
16852
16853   u32 name_len = vec_len (stream_name);
16854   /* Construct the API message */
16855   M (PG_ENABLE_DISABLE, mp);
16856   mp->context = 0;
16857   mp->is_enabled = enable;
16858   if (stream_name_set != 0)
16859     {
16860       mp->stream_name_length = ntohl (name_len);
16861       clib_memcpy (mp->stream_name, stream_name, name_len);
16862     }
16863   vec_free (stream_name);
16864
16865   S (mp);
16866   W (ret);
16867   return ret;
16868 }
16869
16870 int
16871 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16872 {
16873   unformat_input_t *input = vam->input;
16874   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16875
16876   u16 *low_ports = 0;
16877   u16 *high_ports = 0;
16878   u16 this_low;
16879   u16 this_hi;
16880   ip4_address_t ip4_addr;
16881   ip6_address_t ip6_addr;
16882   u32 length;
16883   u32 tmp, tmp2;
16884   u8 prefix_set = 0;
16885   u32 vrf_id = ~0;
16886   u8 is_add = 1;
16887   u8 is_ipv6 = 0;
16888   int ret;
16889
16890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16891     {
16892       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16893         {
16894           prefix_set = 1;
16895         }
16896       else
16897         if (unformat
16898             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16899         {
16900           prefix_set = 1;
16901           is_ipv6 = 1;
16902         }
16903       else if (unformat (input, "vrf %d", &vrf_id))
16904         ;
16905       else if (unformat (input, "del"))
16906         is_add = 0;
16907       else if (unformat (input, "port %d", &tmp))
16908         {
16909           if (tmp == 0 || tmp > 65535)
16910             {
16911               errmsg ("port %d out of range", tmp);
16912               return -99;
16913             }
16914           this_low = tmp;
16915           this_hi = this_low + 1;
16916           vec_add1 (low_ports, this_low);
16917           vec_add1 (high_ports, this_hi);
16918         }
16919       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16920         {
16921           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16922             {
16923               errmsg ("incorrect range parameters");
16924               return -99;
16925             }
16926           this_low = tmp;
16927           /* Note: in debug CLI +1 is added to high before
16928              passing to real fn that does "the work"
16929              (ip_source_and_port_range_check_add_del).
16930              This fn is a wrapper around the binary API fn a
16931              control plane will call, which expects this increment
16932              to have occurred. Hence letting the binary API control
16933              plane fn do the increment for consistency between VAT
16934              and other control planes.
16935            */
16936           this_hi = tmp2;
16937           vec_add1 (low_ports, this_low);
16938           vec_add1 (high_ports, this_hi);
16939         }
16940       else
16941         break;
16942     }
16943
16944   if (prefix_set == 0)
16945     {
16946       errmsg ("<address>/<mask> not specified");
16947       return -99;
16948     }
16949
16950   if (vrf_id == ~0)
16951     {
16952       errmsg ("VRF ID required, not specified");
16953       return -99;
16954     }
16955
16956   if (vrf_id == 0)
16957     {
16958       errmsg
16959         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16960       return -99;
16961     }
16962
16963   if (vec_len (low_ports) == 0)
16964     {
16965       errmsg ("At least one port or port range required");
16966       return -99;
16967     }
16968
16969   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
16970
16971   mp->is_add = is_add;
16972
16973   if (is_ipv6)
16974     {
16975       mp->is_ipv6 = 1;
16976       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16977     }
16978   else
16979     {
16980       mp->is_ipv6 = 0;
16981       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16982     }
16983
16984   mp->mask_length = length;
16985   mp->number_of_ranges = vec_len (low_ports);
16986
16987   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16988   vec_free (low_ports);
16989
16990   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16991   vec_free (high_ports);
16992
16993   mp->vrf_id = ntohl (vrf_id);
16994
16995   S (mp);
16996   W (ret);
16997   return ret;
16998 }
16999
17000 int
17001 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17002 {
17003   unformat_input_t *input = vam->input;
17004   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17005   u32 sw_if_index = ~0;
17006   int vrf_set = 0;
17007   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17008   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17009   u8 is_add = 1;
17010   int ret;
17011
17012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17013     {
17014       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17015         ;
17016       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17017         ;
17018       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17019         vrf_set = 1;
17020       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17021         vrf_set = 1;
17022       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17023         vrf_set = 1;
17024       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17025         vrf_set = 1;
17026       else if (unformat (input, "del"))
17027         is_add = 0;
17028       else
17029         break;
17030     }
17031
17032   if (sw_if_index == ~0)
17033     {
17034       errmsg ("Interface required but not specified");
17035       return -99;
17036     }
17037
17038   if (vrf_set == 0)
17039     {
17040       errmsg ("VRF ID required but not specified");
17041       return -99;
17042     }
17043
17044   if (tcp_out_vrf_id == 0
17045       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17046     {
17047       errmsg
17048         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17049       return -99;
17050     }
17051
17052   /* Construct the API message */
17053   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17054
17055   mp->sw_if_index = ntohl (sw_if_index);
17056   mp->is_add = is_add;
17057   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17058   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17059   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17060   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17061
17062   /* send it... */
17063   S (mp);
17064
17065   /* Wait for a reply... */
17066   W (ret);
17067   return ret;
17068 }
17069
17070 static int
17071 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17072 {
17073   unformat_input_t *i = vam->input;
17074   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17075   u32 local_sa_id = 0;
17076   u32 remote_sa_id = 0;
17077   ip4_address_t src_address;
17078   ip4_address_t dst_address;
17079   u8 is_add = 1;
17080   int ret;
17081
17082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17083     {
17084       if (unformat (i, "local_sa %d", &local_sa_id))
17085         ;
17086       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17087         ;
17088       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17089         ;
17090       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17091         ;
17092       else if (unformat (i, "del"))
17093         is_add = 0;
17094       else
17095         {
17096           clib_warning ("parse error '%U'", format_unformat_error, i);
17097           return -99;
17098         }
17099     }
17100
17101   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17102
17103   mp->local_sa_id = ntohl (local_sa_id);
17104   mp->remote_sa_id = ntohl (remote_sa_id);
17105   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17106   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17107   mp->is_add = is_add;
17108
17109   S (mp);
17110   W (ret);
17111   return ret;
17112 }
17113
17114 static int
17115 api_punt (vat_main_t * vam)
17116 {
17117   unformat_input_t *i = vam->input;
17118   vl_api_punt_t *mp;
17119   u32 ipv = ~0;
17120   u32 protocol = ~0;
17121   u32 port = ~0;
17122   int is_add = 1;
17123   int ret;
17124
17125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17126     {
17127       if (unformat (i, "ip %d", &ipv))
17128         ;
17129       else if (unformat (i, "protocol %d", &protocol))
17130         ;
17131       else if (unformat (i, "port %d", &port))
17132         ;
17133       else if (unformat (i, "del"))
17134         is_add = 0;
17135       else
17136         {
17137           clib_warning ("parse error '%U'", format_unformat_error, i);
17138           return -99;
17139         }
17140     }
17141
17142   M (PUNT, mp);
17143
17144   mp->is_add = (u8) is_add;
17145   mp->ipv = (u8) ipv;
17146   mp->l4_protocol = (u8) protocol;
17147   mp->l4_port = htons ((u16) port);
17148
17149   S (mp);
17150   W (ret);
17151   return ret;
17152 }
17153
17154 static void vl_api_ipsec_gre_tunnel_details_t_handler
17155   (vl_api_ipsec_gre_tunnel_details_t * mp)
17156 {
17157   vat_main_t *vam = &vat_main;
17158
17159   print (vam->ofp, "%11d%15U%15U%14d%14d",
17160          ntohl (mp->sw_if_index),
17161          format_ip4_address, &mp->src_address,
17162          format_ip4_address, &mp->dst_address,
17163          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17164 }
17165
17166 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17167   (vl_api_ipsec_gre_tunnel_details_t * mp)
17168 {
17169   vat_main_t *vam = &vat_main;
17170   vat_json_node_t *node = NULL;
17171   struct in_addr ip4;
17172
17173   if (VAT_JSON_ARRAY != vam->json_tree.type)
17174     {
17175       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17176       vat_json_init_array (&vam->json_tree);
17177     }
17178   node = vat_json_array_add (&vam->json_tree);
17179
17180   vat_json_init_object (node);
17181   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17182   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17183   vat_json_object_add_ip4 (node, "src_address", ip4);
17184   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17185   vat_json_object_add_ip4 (node, "dst_address", ip4);
17186   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17187   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17188 }
17189
17190 static int
17191 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17192 {
17193   unformat_input_t *i = vam->input;
17194   vl_api_ipsec_gre_tunnel_dump_t *mp;
17195   vl_api_control_ping_t *mp_ping;
17196   u32 sw_if_index;
17197   u8 sw_if_index_set = 0;
17198   int ret;
17199
17200   /* Parse args required to build the message */
17201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17202     {
17203       if (unformat (i, "sw_if_index %d", &sw_if_index))
17204         sw_if_index_set = 1;
17205       else
17206         break;
17207     }
17208
17209   if (sw_if_index_set == 0)
17210     {
17211       sw_if_index = ~0;
17212     }
17213
17214   if (!vam->json_output)
17215     {
17216       print (vam->ofp, "%11s%15s%15s%14s%14s",
17217              "sw_if_index", "src_address", "dst_address",
17218              "local_sa_id", "remote_sa_id");
17219     }
17220
17221   /* Get list of gre-tunnel interfaces */
17222   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17223
17224   mp->sw_if_index = htonl (sw_if_index);
17225
17226   S (mp);
17227
17228   /* Use a control ping for synchronization */
17229   M (CONTROL_PING, mp_ping);
17230   S (mp_ping);
17231
17232   W (ret);
17233   return ret;
17234 }
17235
17236 static int
17237 api_delete_subif (vat_main_t * vam)
17238 {
17239   unformat_input_t *i = vam->input;
17240   vl_api_delete_subif_t *mp;
17241   u32 sw_if_index = ~0;
17242   int ret;
17243
17244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17245     {
17246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17247         ;
17248       if (unformat (i, "sw_if_index %d", &sw_if_index))
17249         ;
17250       else
17251         break;
17252     }
17253
17254   if (sw_if_index == ~0)
17255     {
17256       errmsg ("missing sw_if_index");
17257       return -99;
17258     }
17259
17260   /* Construct the API message */
17261   M (DELETE_SUBIF, mp);
17262   mp->sw_if_index = ntohl (sw_if_index);
17263
17264   S (mp);
17265   W (ret);
17266   return ret;
17267 }
17268
17269 #define foreach_pbb_vtr_op      \
17270 _("disable",  L2_VTR_DISABLED)  \
17271 _("pop",  L2_VTR_POP_2)         \
17272 _("push",  L2_VTR_PUSH_2)
17273
17274 static int
17275 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17276 {
17277   unformat_input_t *i = vam->input;
17278   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17279   u32 sw_if_index = ~0, vtr_op = ~0;
17280   u16 outer_tag = ~0;
17281   u8 dmac[6], smac[6];
17282   u8 dmac_set = 0, smac_set = 0;
17283   u16 vlanid = 0;
17284   u32 sid = ~0;
17285   u32 tmp;
17286   int ret;
17287
17288   /* Shut up coverity */
17289   memset (dmac, 0, sizeof (dmac));
17290   memset (smac, 0, sizeof (smac));
17291
17292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17293     {
17294       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17295         ;
17296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17297         ;
17298       else if (unformat (i, "vtr_op %d", &vtr_op))
17299         ;
17300 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17301       foreach_pbb_vtr_op
17302 #undef _
17303         else if (unformat (i, "translate_pbb_stag"))
17304         {
17305           if (unformat (i, "%d", &tmp))
17306             {
17307               vtr_op = L2_VTR_TRANSLATE_2_1;
17308               outer_tag = tmp;
17309             }
17310           else
17311             {
17312               errmsg
17313                 ("translate_pbb_stag operation requires outer tag definition");
17314               return -99;
17315             }
17316         }
17317       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17318         dmac_set++;
17319       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17320         smac_set++;
17321       else if (unformat (i, "sid %d", &sid))
17322         ;
17323       else if (unformat (i, "vlanid %d", &tmp))
17324         vlanid = tmp;
17325       else
17326         {
17327           clib_warning ("parse error '%U'", format_unformat_error, i);
17328           return -99;
17329         }
17330     }
17331
17332   if ((sw_if_index == ~0) || (vtr_op == ~0))
17333     {
17334       errmsg ("missing sw_if_index or vtr operation");
17335       return -99;
17336     }
17337   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17338       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17339     {
17340       errmsg
17341         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17342       return -99;
17343     }
17344
17345   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17346   mp->sw_if_index = ntohl (sw_if_index);
17347   mp->vtr_op = ntohl (vtr_op);
17348   mp->outer_tag = ntohs (outer_tag);
17349   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17350   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17351   mp->b_vlanid = ntohs (vlanid);
17352   mp->i_sid = ntohl (sid);
17353
17354   S (mp);
17355   W (ret);
17356   return ret;
17357 }
17358
17359 static int
17360 api_flow_classify_set_interface (vat_main_t * vam)
17361 {
17362   unformat_input_t *i = vam->input;
17363   vl_api_flow_classify_set_interface_t *mp;
17364   u32 sw_if_index;
17365   int sw_if_index_set;
17366   u32 ip4_table_index = ~0;
17367   u32 ip6_table_index = ~0;
17368   u8 is_add = 1;
17369   int ret;
17370
17371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17372     {
17373       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17374         sw_if_index_set = 1;
17375       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17376         sw_if_index_set = 1;
17377       else if (unformat (i, "del"))
17378         is_add = 0;
17379       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17380         ;
17381       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17382         ;
17383       else
17384         {
17385           clib_warning ("parse error '%U'", format_unformat_error, i);
17386           return -99;
17387         }
17388     }
17389
17390   if (sw_if_index_set == 0)
17391     {
17392       errmsg ("missing interface name or sw_if_index");
17393       return -99;
17394     }
17395
17396   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17397
17398   mp->sw_if_index = ntohl (sw_if_index);
17399   mp->ip4_table_index = ntohl (ip4_table_index);
17400   mp->ip6_table_index = ntohl (ip6_table_index);
17401   mp->is_add = is_add;
17402
17403   S (mp);
17404   W (ret);
17405   return ret;
17406 }
17407
17408 static int
17409 api_flow_classify_dump (vat_main_t * vam)
17410 {
17411   unformat_input_t *i = vam->input;
17412   vl_api_flow_classify_dump_t *mp;
17413   vl_api_control_ping_t *mp_ping;
17414   u8 type = FLOW_CLASSIFY_N_TABLES;
17415   int ret;
17416
17417   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17418     ;
17419   else
17420     {
17421       errmsg ("classify table type must be specified");
17422       return -99;
17423     }
17424
17425   if (!vam->json_output)
17426     {
17427       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17428     }
17429
17430   M (FLOW_CLASSIFY_DUMP, mp);
17431   mp->type = type;
17432   /* send it... */
17433   S (mp);
17434
17435   /* Use a control ping for synchronization */
17436   M (CONTROL_PING, mp_ping);
17437   S (mp_ping);
17438
17439   /* Wait for a reply... */
17440   W (ret);
17441   return ret;
17442 }
17443
17444 static int
17445 api_feature_enable_disable (vat_main_t * vam)
17446 {
17447   unformat_input_t *i = vam->input;
17448   vl_api_feature_enable_disable_t *mp;
17449   u8 *arc_name = 0;
17450   u8 *feature_name = 0;
17451   u32 sw_if_index = ~0;
17452   u8 enable = 1;
17453   int ret;
17454
17455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17456     {
17457       if (unformat (i, "arc_name %s", &arc_name))
17458         ;
17459       else if (unformat (i, "feature_name %s", &feature_name))
17460         ;
17461       else
17462         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17463         ;
17464       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17465         ;
17466       else if (unformat (i, "disable"))
17467         enable = 0;
17468       else
17469         break;
17470     }
17471
17472   if (arc_name == 0)
17473     {
17474       errmsg ("missing arc name");
17475       return -99;
17476     }
17477   if (vec_len (arc_name) > 63)
17478     {
17479       errmsg ("arc name too long");
17480     }
17481
17482   if (feature_name == 0)
17483     {
17484       errmsg ("missing feature name");
17485       return -99;
17486     }
17487   if (vec_len (feature_name) > 63)
17488     {
17489       errmsg ("feature name too long");
17490     }
17491
17492   if (sw_if_index == ~0)
17493     {
17494       errmsg ("missing interface name or sw_if_index");
17495       return -99;
17496     }
17497
17498   /* Construct the API message */
17499   M (FEATURE_ENABLE_DISABLE, mp);
17500   mp->sw_if_index = ntohl (sw_if_index);
17501   mp->enable = enable;
17502   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17503   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17504   vec_free (arc_name);
17505   vec_free (feature_name);
17506
17507   S (mp);
17508   W (ret);
17509   return ret;
17510 }
17511
17512 static int
17513 api_sw_interface_tag_add_del (vat_main_t * vam)
17514 {
17515   unformat_input_t *i = vam->input;
17516   vl_api_sw_interface_tag_add_del_t *mp;
17517   u32 sw_if_index = ~0;
17518   u8 *tag = 0;
17519   u8 enable = 1;
17520   int ret;
17521
17522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17523     {
17524       if (unformat (i, "tag %s", &tag))
17525         ;
17526       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17527         ;
17528       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17529         ;
17530       else if (unformat (i, "del"))
17531         enable = 0;
17532       else
17533         break;
17534     }
17535
17536   if (sw_if_index == ~0)
17537     {
17538       errmsg ("missing interface name or sw_if_index");
17539       return -99;
17540     }
17541
17542   if (enable && (tag == 0))
17543     {
17544       errmsg ("no tag specified");
17545       return -99;
17546     }
17547
17548   /* Construct the API message */
17549   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17550   mp->sw_if_index = ntohl (sw_if_index);
17551   mp->is_add = enable;
17552   if (enable)
17553     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17554   vec_free (tag);
17555
17556   S (mp);
17557   W (ret);
17558   return ret;
17559 }
17560
17561 static void vl_api_l2_xconnect_details_t_handler
17562   (vl_api_l2_xconnect_details_t * mp)
17563 {
17564   vat_main_t *vam = &vat_main;
17565
17566   print (vam->ofp, "%15d%15d",
17567          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17568 }
17569
17570 static void vl_api_l2_xconnect_details_t_handler_json
17571   (vl_api_l2_xconnect_details_t * mp)
17572 {
17573   vat_main_t *vam = &vat_main;
17574   vat_json_node_t *node = NULL;
17575
17576   if (VAT_JSON_ARRAY != vam->json_tree.type)
17577     {
17578       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17579       vat_json_init_array (&vam->json_tree);
17580     }
17581   node = vat_json_array_add (&vam->json_tree);
17582
17583   vat_json_init_object (node);
17584   vat_json_object_add_uint (node, "rx_sw_if_index",
17585                             ntohl (mp->rx_sw_if_index));
17586   vat_json_object_add_uint (node, "tx_sw_if_index",
17587                             ntohl (mp->tx_sw_if_index));
17588 }
17589
17590 static int
17591 api_l2_xconnect_dump (vat_main_t * vam)
17592 {
17593   vl_api_l2_xconnect_dump_t *mp;
17594   vl_api_control_ping_t *mp_ping;
17595   int ret;
17596
17597   if (!vam->json_output)
17598     {
17599       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17600     }
17601
17602   M (L2_XCONNECT_DUMP, mp);
17603
17604   S (mp);
17605
17606   /* Use a control ping for synchronization */
17607   M (CONTROL_PING, mp_ping);
17608   S (mp_ping);
17609
17610   W (ret);
17611   return ret;
17612 }
17613
17614 static int
17615 api_sw_interface_set_mtu (vat_main_t * vam)
17616 {
17617   unformat_input_t *i = vam->input;
17618   vl_api_sw_interface_set_mtu_t *mp;
17619   u32 sw_if_index = ~0;
17620   u32 mtu = 0;
17621   int ret;
17622
17623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17624     {
17625       if (unformat (i, "mtu %d", &mtu))
17626         ;
17627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17628         ;
17629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17630         ;
17631       else
17632         break;
17633     }
17634
17635   if (sw_if_index == ~0)
17636     {
17637       errmsg ("missing interface name or sw_if_index");
17638       return -99;
17639     }
17640
17641   if (mtu == 0)
17642     {
17643       errmsg ("no mtu specified");
17644       return -99;
17645     }
17646
17647   /* Construct the API message */
17648   M (SW_INTERFACE_SET_MTU, mp);
17649   mp->sw_if_index = ntohl (sw_if_index);
17650   mp->mtu = ntohs ((u16) mtu);
17651
17652   S (mp);
17653   W (ret);
17654   return ret;
17655 }
17656
17657
17658 static int
17659 q_or_quit (vat_main_t * vam)
17660 {
17661 #if VPP_API_TEST_BUILTIN == 0
17662   longjmp (vam->jump_buf, 1);
17663 #endif
17664   return 0;                     /* not so much */
17665 }
17666
17667 static int
17668 q (vat_main_t * vam)
17669 {
17670   return q_or_quit (vam);
17671 }
17672
17673 static int
17674 quit (vat_main_t * vam)
17675 {
17676   return q_or_quit (vam);
17677 }
17678
17679 static int
17680 comment (vat_main_t * vam)
17681 {
17682   return 0;
17683 }
17684
17685 static int
17686 cmd_cmp (void *a1, void *a2)
17687 {
17688   u8 **c1 = a1;
17689   u8 **c2 = a2;
17690
17691   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17692 }
17693
17694 static int
17695 help (vat_main_t * vam)
17696 {
17697   u8 **cmds = 0;
17698   u8 *name = 0;
17699   hash_pair_t *p;
17700   unformat_input_t *i = vam->input;
17701   int j;
17702
17703   if (unformat (i, "%s", &name))
17704     {
17705       uword *hs;
17706
17707       vec_add1 (name, 0);
17708
17709       hs = hash_get_mem (vam->help_by_name, name);
17710       if (hs)
17711         print (vam->ofp, "usage: %s %s", name, hs[0]);
17712       else
17713         print (vam->ofp, "No such msg / command '%s'", name);
17714       vec_free (name);
17715       return 0;
17716     }
17717
17718   print (vam->ofp, "Help is available for the following:");
17719
17720     /* *INDENT-OFF* */
17721     hash_foreach_pair (p, vam->function_by_name,
17722     ({
17723       vec_add1 (cmds, (u8 *)(p->key));
17724     }));
17725     /* *INDENT-ON* */
17726
17727   vec_sort_with_function (cmds, cmd_cmp);
17728
17729   for (j = 0; j < vec_len (cmds); j++)
17730     print (vam->ofp, "%s", cmds[j]);
17731
17732   vec_free (cmds);
17733   return 0;
17734 }
17735
17736 static int
17737 set (vat_main_t * vam)
17738 {
17739   u8 *name = 0, *value = 0;
17740   unformat_input_t *i = vam->input;
17741
17742   if (unformat (i, "%s", &name))
17743     {
17744       /* The input buffer is a vector, not a string. */
17745       value = vec_dup (i->buffer);
17746       vec_delete (value, i->index, 0);
17747       /* Almost certainly has a trailing newline */
17748       if (value[vec_len (value) - 1] == '\n')
17749         value[vec_len (value) - 1] = 0;
17750       /* Make sure it's a proper string, one way or the other */
17751       vec_add1 (value, 0);
17752       (void) clib_macro_set_value (&vam->macro_main,
17753                                    (char *) name, (char *) value);
17754     }
17755   else
17756     errmsg ("usage: set <name> <value>");
17757
17758   vec_free (name);
17759   vec_free (value);
17760   return 0;
17761 }
17762
17763 static int
17764 unset (vat_main_t * vam)
17765 {
17766   u8 *name = 0;
17767
17768   if (unformat (vam->input, "%s", &name))
17769     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17770       errmsg ("unset: %s wasn't set", name);
17771   vec_free (name);
17772   return 0;
17773 }
17774
17775 typedef struct
17776 {
17777   u8 *name;
17778   u8 *value;
17779 } macro_sort_t;
17780
17781
17782 static int
17783 macro_sort_cmp (void *a1, void *a2)
17784 {
17785   macro_sort_t *s1 = a1;
17786   macro_sort_t *s2 = a2;
17787
17788   return strcmp ((char *) (s1->name), (char *) (s2->name));
17789 }
17790
17791 static int
17792 dump_macro_table (vat_main_t * vam)
17793 {
17794   macro_sort_t *sort_me = 0, *sm;
17795   int i;
17796   hash_pair_t *p;
17797
17798     /* *INDENT-OFF* */
17799     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17800     ({
17801       vec_add2 (sort_me, sm, 1);
17802       sm->name = (u8 *)(p->key);
17803       sm->value = (u8 *) (p->value[0]);
17804     }));
17805     /* *INDENT-ON* */
17806
17807   vec_sort_with_function (sort_me, macro_sort_cmp);
17808
17809   if (vec_len (sort_me))
17810     print (vam->ofp, "%-15s%s", "Name", "Value");
17811   else
17812     print (vam->ofp, "The macro table is empty...");
17813
17814   for (i = 0; i < vec_len (sort_me); i++)
17815     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17816   return 0;
17817 }
17818
17819 static int
17820 dump_node_table (vat_main_t * vam)
17821 {
17822   int i, j;
17823   vlib_node_t *node, *next_node;
17824
17825   if (vec_len (vam->graph_nodes) == 0)
17826     {
17827       print (vam->ofp, "Node table empty, issue get_node_graph...");
17828       return 0;
17829     }
17830
17831   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17832     {
17833       node = vam->graph_nodes[i];
17834       print (vam->ofp, "[%d] %s", i, node->name);
17835       for (j = 0; j < vec_len (node->next_nodes); j++)
17836         {
17837           if (node->next_nodes[j] != ~0)
17838             {
17839               next_node = vam->graph_nodes[node->next_nodes[j]];
17840               print (vam->ofp, "  [%d] %s", j, next_node->name);
17841             }
17842         }
17843     }
17844   return 0;
17845 }
17846
17847 static int
17848 value_sort_cmp (void *a1, void *a2)
17849 {
17850   name_sort_t *n1 = a1;
17851   name_sort_t *n2 = a2;
17852
17853   if (n1->value < n2->value)
17854     return -1;
17855   if (n1->value > n2->value)
17856     return 1;
17857   return 0;
17858 }
17859
17860
17861 static int
17862 dump_msg_api_table (vat_main_t * vam)
17863 {
17864   api_main_t *am = &api_main;
17865   name_sort_t *nses = 0, *ns;
17866   hash_pair_t *hp;
17867   int i;
17868
17869   /* *INDENT-OFF* */
17870   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17871   ({
17872     vec_add2 (nses, ns, 1);
17873     ns->name = (u8 *)(hp->key);
17874     ns->value = (u32) hp->value[0];
17875   }));
17876   /* *INDENT-ON* */
17877
17878   vec_sort_with_function (nses, value_sort_cmp);
17879
17880   for (i = 0; i < vec_len (nses); i++)
17881     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17882   vec_free (nses);
17883   return 0;
17884 }
17885
17886 static int
17887 get_msg_id (vat_main_t * vam)
17888 {
17889   u8 *name_and_crc;
17890   u32 message_index;
17891
17892   if (unformat (vam->input, "%s", &name_and_crc))
17893     {
17894       message_index = vl_api_get_msg_index (name_and_crc);
17895       if (message_index == ~0)
17896         {
17897           print (vam->ofp, " '%s' not found", name_and_crc);
17898           return 0;
17899         }
17900       print (vam->ofp, " '%s' has message index %d",
17901              name_and_crc, message_index);
17902       return 0;
17903     }
17904   errmsg ("name_and_crc required...");
17905   return 0;
17906 }
17907
17908 static int
17909 search_node_table (vat_main_t * vam)
17910 {
17911   unformat_input_t *line_input = vam->input;
17912   u8 *node_to_find;
17913   int j;
17914   vlib_node_t *node, *next_node;
17915   uword *p;
17916
17917   if (vam->graph_node_index_by_name == 0)
17918     {
17919       print (vam->ofp, "Node table empty, issue get_node_graph...");
17920       return 0;
17921     }
17922
17923   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17924     {
17925       if (unformat (line_input, "%s", &node_to_find))
17926         {
17927           vec_add1 (node_to_find, 0);
17928           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17929           if (p == 0)
17930             {
17931               print (vam->ofp, "%s not found...", node_to_find);
17932               goto out;
17933             }
17934           node = vam->graph_nodes[p[0]];
17935           print (vam->ofp, "[%d] %s", p[0], node->name);
17936           for (j = 0; j < vec_len (node->next_nodes); j++)
17937             {
17938               if (node->next_nodes[j] != ~0)
17939                 {
17940                   next_node = vam->graph_nodes[node->next_nodes[j]];
17941                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17942                 }
17943             }
17944         }
17945
17946       else
17947         {
17948           clib_warning ("parse error '%U'", format_unformat_error,
17949                         line_input);
17950           return -99;
17951         }
17952
17953     out:
17954       vec_free (node_to_find);
17955
17956     }
17957
17958   return 0;
17959 }
17960
17961
17962 static int
17963 script (vat_main_t * vam)
17964 {
17965 #if (VPP_API_TEST_BUILTIN==0)
17966   u8 *s = 0;
17967   char *save_current_file;
17968   unformat_input_t save_input;
17969   jmp_buf save_jump_buf;
17970   u32 save_line_number;
17971
17972   FILE *new_fp, *save_ifp;
17973
17974   if (unformat (vam->input, "%s", &s))
17975     {
17976       new_fp = fopen ((char *) s, "r");
17977       if (new_fp == 0)
17978         {
17979           errmsg ("Couldn't open script file %s", s);
17980           vec_free (s);
17981           return -99;
17982         }
17983     }
17984   else
17985     {
17986       errmsg ("Missing script name");
17987       return -99;
17988     }
17989
17990   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17991   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17992   save_ifp = vam->ifp;
17993   save_line_number = vam->input_line_number;
17994   save_current_file = (char *) vam->current_file;
17995
17996   vam->input_line_number = 0;
17997   vam->ifp = new_fp;
17998   vam->current_file = s;
17999   do_one_file (vam);
18000
18001   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18002   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18003   vam->ifp = save_ifp;
18004   vam->input_line_number = save_line_number;
18005   vam->current_file = (u8 *) save_current_file;
18006   vec_free (s);
18007
18008   return 0;
18009 #else
18010   clib_warning ("use the exec command...");
18011   return -99;
18012 #endif
18013 }
18014
18015 static int
18016 echo (vat_main_t * vam)
18017 {
18018   print (vam->ofp, "%v", vam->input->buffer);
18019   return 0;
18020 }
18021
18022 /* List of API message constructors, CLI names map to api_xxx */
18023 #define foreach_vpe_api_msg                                             \
18024 _(create_loopback,"[mac <mac-addr>]")                                   \
18025 _(sw_interface_dump,"")                                                 \
18026 _(sw_interface_set_flags,                                               \
18027   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18028 _(sw_interface_add_del_address,                                         \
18029   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18030 _(sw_interface_set_table,                                               \
18031   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18032 _(sw_interface_set_mpls_enable,                                         \
18033   "<intfc> | sw_if_index [disable | dis]")                              \
18034 _(sw_interface_set_vpath,                                               \
18035   "<intfc> | sw_if_index <id> enable | disable")                        \
18036 _(sw_interface_set_vxlan_bypass,                                        \
18037   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18038 _(sw_interface_set_l2_xconnect,                                         \
18039   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18040   "enable | disable")                                                   \
18041 _(sw_interface_set_l2_bridge,                                           \
18042   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18043   "[shg <split-horizon-group>] [bvi]\n"                                 \
18044   "enable | disable")                                                   \
18045 _(bridge_domain_add_del,                                                \
18046   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18047 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18048 _(l2fib_add_del,                                                        \
18049   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18050 _(l2_flags,                                                             \
18051   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18052 _(bridge_flags,                                                         \
18053   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18054 _(tap_connect,                                                          \
18055   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18056 _(tap_modify,                                                           \
18057   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18058 _(tap_delete,                                                           \
18059   "<vpp-if-name> | sw_if_index <id>")                                   \
18060 _(sw_interface_tap_dump, "")                                            \
18061 _(ip_add_del_route,                                                     \
18062   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18063   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18064   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18065   "[multipath] [count <n>]")                                            \
18066 _(ip_mroute_add_del,                                                    \
18067   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18068   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18069 _(mpls_route_add_del,                                                   \
18070   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18071   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18072   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18073   "[multipath] [count <n>]")                                            \
18074 _(mpls_ip_bind_unbind,                                                  \
18075   "<label> <addr/len>")                                                 \
18076 _(mpls_tunnel_add_del,                                                  \
18077   " via <addr> [table-id <n>]\n"                                        \
18078   "sw_if_index <id>] [l2]  [del]")                                      \
18079 _(proxy_arp_add_del,                                                    \
18080   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18081 _(proxy_arp_intfc_enable_disable,                                       \
18082   "<intfc> | sw_if_index <id> enable | disable")                        \
18083 _(sw_interface_set_unnumbered,                                          \
18084   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18085 _(ip_neighbor_add_del,                                                  \
18086   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18087   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18088 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18089 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18090 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18091   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18092   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18093   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18094 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18095 _(reset_fib, "vrf <n> [ipv6]")                                          \
18096 _(dhcp_proxy_config,                                                    \
18097   "svr <v46-address> src <v46-address>\n"                               \
18098    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18099 _(dhcp_proxy_set_vss,                                                   \
18100   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18101 _(dhcp_proxy_dump, "ip6")                                               \
18102 _(dhcp_client_config,                                                   \
18103   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18104 _(set_ip_flow_hash,                                                     \
18105   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18106 _(sw_interface_ip6_enable_disable,                                      \
18107   "<intfc> | sw_if_index <id> enable | disable")                        \
18108 _(sw_interface_ip6_set_link_local_address,                              \
18109   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18110 _(sw_interface_ip6nd_ra_prefix,                                         \
18111   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18112   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18113   "[nolink] [isno]")                                                    \
18114 _(sw_interface_ip6nd_ra_config,                                         \
18115   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18116   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18117   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18118 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18119 _(l2_patch_add_del,                                                     \
18120   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18121   "enable | disable")                                                   \
18122 _(sr_tunnel_add_del,                                                    \
18123   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
18124   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
18125   "[policy <policy_name>]")                                             \
18126 _(sr_policy_add_del,                                                    \
18127   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
18128 _(sr_multicast_map_add_del,                                             \
18129   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
18130 _(classify_add_del_table,                                               \
18131   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18132   " [del] [del-chain] mask <mask-value>\n"                              \
18133   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18134   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18135 _(classify_add_del_session,                                             \
18136   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18137   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18138   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18139   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18140 _(classify_set_interface_ip_table,                                      \
18141   "<intfc> | sw_if_index <nn> table <nn>")                              \
18142 _(classify_set_interface_l2_tables,                                     \
18143   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18144   "  [other-table <nn>]")                                               \
18145 _(get_node_index, "node <node-name")                                    \
18146 _(add_node_next, "node <node-name> next <next-node-name>")              \
18147 _(l2tpv3_create_tunnel,                                                 \
18148   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18149   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18150   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18151 _(l2tpv3_set_tunnel_cookies,                                            \
18152   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18153   "[new_remote_cookie <nn>]\n")                                         \
18154 _(l2tpv3_interface_enable_disable,                                      \
18155   "<intfc> | sw_if_index <nn> enable | disable")                        \
18156 _(l2tpv3_set_lookup_key,                                                \
18157   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18158 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18159 _(vxlan_add_del_tunnel,                                                 \
18160   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18161   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18162   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18163 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18164 _(gre_add_del_tunnel,                                                   \
18165   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18166 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18167 _(l2_fib_clear_table, "")                                               \
18168 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18169 _(l2_interface_vlan_tag_rewrite,                                        \
18170   "<intfc> | sw_if_index <nn> \n"                                       \
18171   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18172   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18173 _(create_vhost_user_if,                                                 \
18174         "socket <filename> [server] [renumber <dev_instance>] "         \
18175         "[mac <mac_address>]")                                          \
18176 _(modify_vhost_user_if,                                                 \
18177         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18178         "[server] [renumber <dev_instance>]")                           \
18179 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18180 _(sw_interface_vhost_user_dump, "")                                     \
18181 _(show_version, "")                                                     \
18182 _(vxlan_gpe_add_del_tunnel,                                             \
18183   "local <addr> remote <addr> vni <nn>\n"                               \
18184     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18185   "[next-ethernet] [next-nsh]\n")                                       \
18186 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18187 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18188 _(interface_name_renumber,                                              \
18189   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18190 _(input_acl_set_interface,                                              \
18191   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18192   "  [l2-table <nn>] [del]")                                            \
18193 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18194 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18195 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18196 _(ip_dump, "ipv4 | ipv6")                                               \
18197 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18198 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18199   "  spid_id <n> ")                                                     \
18200 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18201   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18202   "  integ_alg <alg> integ_key <hex>")                                  \
18203 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18204   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18205   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18206   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18207 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18208 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18209 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18210   "(auth_data 0x<data> | auth_data <data>)")                            \
18211 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18212   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18213 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18214   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18215   "(local|remote)")                                                     \
18216 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18217 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18218 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18219 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18220 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18221 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18222 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18223 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18224 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18225 _(delete_loopback,"sw_if_index <nn>")                                   \
18226 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18227 _(map_add_domain,                                                       \
18228   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18229   "ip6-src <ip6addr> "                                                  \
18230   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18231 _(map_del_domain, "index <n>")                                          \
18232 _(map_add_del_rule,                                                     \
18233   "index <n> psid <n> dst <ip6addr> [del]")                             \
18234 _(map_domain_dump, "")                                                  \
18235 _(map_rule_dump, "index <map-domain>")                                  \
18236 _(want_interface_events,  "enable|disable")                             \
18237 _(want_stats,"enable|disable")                                          \
18238 _(get_first_msg_id, "client <name>")                                    \
18239 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18240 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18241   "fib-id <nn> [ip4][ip6][default]")                                    \
18242 _(get_node_graph, " ")                                                  \
18243 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18244 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18245 _(ioam_disable, "")                                                     \
18246 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18247                             " sw_if_index <sw_if_index> p <priority> "  \
18248                             "w <weight>] [del]")                        \
18249 _(one_add_del_locator, "locator-set <locator_name> "                    \
18250                         "iface <intf> | sw_if_index <sw_if_index> "     \
18251                         "p <priority> w <weight> [del]")                \
18252 _(one_add_del_local_eid,"vni <vni> eid "                                \
18253                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18254                          "locator-set <locator_name> [del]"             \
18255                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18256 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18257 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18258 _(one_enable_disable, "enable|disable")                                 \
18259 _(one_map_register_enable_disable, "enable|disable")                    \
18260 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18261 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18262                                "[seid <seid>] "                         \
18263                                "rloc <locator> p <prio> "               \
18264                                "w <weight> [rloc <loc> ... ] "          \
18265                                "action <action> [del-all]")             \
18266 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18267                           "<local-eid>")                                \
18268 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18269 _(one_map_request_mode, "src-dst|dst-only")                             \
18270 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18271 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18272 _(one_locator_set_dump, "[local | remote]")                             \
18273 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18274 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18275                        "[local] | [remote]")                            \
18276 _(one_eid_table_vni_dump, "")                                           \
18277 _(one_eid_table_map_dump, "l2|l3")                                      \
18278 _(one_map_resolver_dump, "")                                            \
18279 _(one_map_server_dump, "")                                              \
18280 _(one_adjacencies_get, "vni <vni>")                                     \
18281 _(show_one_rloc_probe_state, "")                                        \
18282 _(show_one_map_register_state, "")                                      \
18283 _(show_one_status, "")                                                  \
18284 _(one_get_map_request_itr_rlocs, "")                                    \
18285 _(show_one_pitr, "")                                                    \
18286 _(show_one_map_request_mode, "")                                        \
18287 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18288                             " sw_if_index <sw_if_index> p <priority> "  \
18289                             "w <weight>] [del]")                        \
18290 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18291                         "iface <intf> | sw_if_index <sw_if_index> "     \
18292                         "p <priority> w <weight> [del]")                \
18293 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18294                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18295                          "locator-set <locator_name> [del]"             \
18296                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18297 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18298 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18299 _(lisp_enable_disable, "enable|disable")                                \
18300 _(lisp_map_register_enable_disable, "enable|disable")                   \
18301 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18302 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18303                                "[seid <seid>] "                         \
18304                                "rloc <locator> p <prio> "               \
18305                                "w <weight> [rloc <loc> ... ] "          \
18306                                "action <action> [del-all]")             \
18307 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18308                           "<local-eid>")                                \
18309 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18310 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18311 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18312 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18313 _(lisp_locator_set_dump, "[local | remote]")                            \
18314 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18315 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18316                        "[local] | [remote]")                            \
18317 _(lisp_eid_table_vni_dump, "")                                          \
18318 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18319 _(lisp_map_resolver_dump, "")                                           \
18320 _(lisp_map_server_dump, "")                                             \
18321 _(lisp_adjacencies_get, "vni <vni>")                                    \
18322 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18323 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18324 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18325 _(gpe_get_encap_mode, "")                                               \
18326 _(lisp_gpe_add_del_iface, "up|down")                                    \
18327 _(lisp_gpe_enable_disable, "enable|disable")                            \
18328 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18329   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18330 _(show_lisp_rloc_probe_state, "")                                       \
18331 _(show_lisp_map_register_state, "")                                     \
18332 _(show_lisp_status, "")                                                 \
18333 _(lisp_get_map_request_itr_rlocs, "")                                   \
18334 _(show_lisp_pitr, "")                                                   \
18335 _(show_lisp_map_request_mode, "")                                       \
18336 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18337 _(af_packet_delete, "name <host interface name>")                       \
18338 _(policer_add_del, "name <policer name> <params> [del]")                \
18339 _(policer_dump, "[name <policer name>]")                                \
18340 _(policer_classify_set_interface,                                       \
18341   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18342   "  [l2-table <nn>] [del]")                                            \
18343 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18344 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18345     "[master|slave]")                                                   \
18346 _(netmap_delete, "name <interface name>")                               \
18347 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18348 _(mpls_fib_dump, "")                                                    \
18349 _(classify_table_ids, "")                                               \
18350 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18351 _(classify_table_info, "table_id <nn>")                                 \
18352 _(classify_session_dump, "table_id <nn>")                               \
18353 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18354     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18355     "[template_interval <nn>] [udp_checksum]")                          \
18356 _(ipfix_exporter_dump, "")                                              \
18357 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18358 _(ipfix_classify_stream_dump, "")                                       \
18359 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18360 _(ipfix_classify_table_dump, "")                                        \
18361 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18362 _(sw_interface_span_dump, "")                                           \
18363 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18364 _(pg_create_interface, "if_id <nn>")                                    \
18365 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18366 _(pg_enable_disable, "[stream <id>] disable")                           \
18367 _(ip_source_and_port_range_check_add_del,                               \
18368   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18369 _(ip_source_and_port_range_check_interface_add_del,                     \
18370   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18371   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18372 _(ipsec_gre_add_del_tunnel,                                             \
18373   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18374 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18375 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18376 _(l2_interface_pbb_tag_rewrite,                                         \
18377   "<intfc> | sw_if_index <nn> \n"                                       \
18378   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18379   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18380 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18381 _(flow_classify_set_interface,                                          \
18382   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18383 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18384 _(ip_fib_dump, "")                                                      \
18385 _(ip_mfib_dump, "")                                                     \
18386 _(ip6_fib_dump, "")                                                     \
18387 _(ip6_mfib_dump, "")                                                    \
18388 _(feature_enable_disable, "arc_name <arc_name> "                        \
18389   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18390 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18391 "[disable]")                                                            \
18392 _(l2_xconnect_dump, "")                                                 \
18393 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18394 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18395 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18396
18397 /* List of command functions, CLI names map directly to functions */
18398 #define foreach_cli_function                                    \
18399 _(comment, "usage: comment <ignore-rest-of-line>")              \
18400 _(dump_interface_table, "usage: dump_interface_table")          \
18401 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18402 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18403 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18404 _(dump_stats_table, "usage: dump_stats_table")                  \
18405 _(dump_macro_table, "usage: dump_macro_table ")                 \
18406 _(dump_node_table, "usage: dump_node_table")                    \
18407 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18408 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18409 _(echo, "usage: echo <message>")                                \
18410 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18411 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18412 _(help, "usage: help")                                          \
18413 _(q, "usage: quit")                                             \
18414 _(quit, "usage: quit")                                          \
18415 _(search_node_table, "usage: search_node_table <name>...")      \
18416 _(set, "usage: set <variable-name> <value>")                    \
18417 _(script, "usage: script <file-name>")                          \
18418 _(unset, "usage: unset <variable-name>")
18419
18420 #define _(N,n)                                  \
18421     static void vl_api_##n##_t_handler_uni      \
18422     (vl_api_##n##_t * mp)                       \
18423     {                                           \
18424         vat_main_t * vam = &vat_main;           \
18425         if (vam->json_output) {                 \
18426             vl_api_##n##_t_handler_json(mp);    \
18427         } else {                                \
18428             vl_api_##n##_t_handler(mp);         \
18429         }                                       \
18430     }
18431 foreach_vpe_api_reply_msg;
18432 #if VPP_API_TEST_BUILTIN == 0
18433 foreach_standalone_reply_msg;
18434 #endif
18435 #undef _
18436
18437 void
18438 vat_api_hookup (vat_main_t * vam)
18439 {
18440 #define _(N,n)                                                  \
18441     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18442                            vl_api_##n##_t_handler_uni,          \
18443                            vl_noop_handler,                     \
18444                            vl_api_##n##_t_endian,               \
18445                            vl_api_##n##_t_print,                \
18446                            sizeof(vl_api_##n##_t), 1);
18447   foreach_vpe_api_reply_msg;
18448 #if VPP_API_TEST_BUILTIN == 0
18449   foreach_standalone_reply_msg;
18450 #endif
18451 #undef _
18452
18453 #if (VPP_API_TEST_BUILTIN==0)
18454   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18455 #endif
18456
18457   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18458
18459   vam->function_by_name = hash_create_string (0, sizeof (uword));
18460
18461   vam->help_by_name = hash_create_string (0, sizeof (uword));
18462
18463   /* API messages we can send */
18464 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18465   foreach_vpe_api_msg;
18466 #undef _
18467
18468   /* Help strings */
18469 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18470   foreach_vpe_api_msg;
18471 #undef _
18472
18473   /* CLI functions */
18474 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18475   foreach_cli_function;
18476 #undef _
18477
18478   /* Help strings */
18479 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18480   foreach_cli_function;
18481 #undef _
18482 }
18483
18484 #if VPP_API_TEST_BUILTIN
18485 static clib_error_t *
18486 vat_api_hookup_shim (vlib_main_t * vm)
18487 {
18488   vat_api_hookup (&vat_main);
18489   return 0;
18490 }
18491
18492 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18493 #endif
18494
18495 /*
18496  * fd.io coding-style-patch-verification: ON
18497  *
18498  * Local Variables:
18499  * eval: (c-set-style "gnu")
18500  * End:
18501  */