14e78817b61c0deb685ca155cadfba0018083354
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52
53 #include "vat/json_format.h"
54
55 #include <inttypes.h>
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp/api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp/api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp/api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 #define __plugin_msg_base 0
75 #include <vlibapi/vat_helper_macros.h>
76
77 f64
78 vat_time_now (vat_main_t * vam)
79 {
80 #if VPP_API_TEST_BUILTIN
81   return vlib_time_now (vam->vlib_main);
82 #else
83   return clib_time_now (&vam->clib_time);
84 #endif
85 }
86
87 void
88 errmsg (char *fmt, ...)
89 {
90   vat_main_t *vam = &vat_main;
91   va_list va;
92   u8 *s;
93
94   va_start (va, fmt);
95   s = va_format (0, fmt, &va);
96   va_end (va);
97
98   vec_add1 (s, 0);
99
100 #if VPP_API_TEST_BUILTIN
101   vlib_cli_output (vam->vlib_main, (char *) s);
102 #else
103   {
104     if (vam->ifp != stdin)
105       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
106                vam->input_line_number);
107     fformat (vam->ofp, (char *) s);
108     fflush (vam->ofp);
109   }
110 #endif
111
112   vec_free (s);
113 }
114
115 #if VPP_API_TEST_BUILTIN == 0
116 static uword
117 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
118 {
119   vat_main_t *vam = va_arg (*args, vat_main_t *);
120   u32 *result = va_arg (*args, u32 *);
121   u8 *if_name;
122   uword *p;
123
124   if (!unformat (input, "%s", &if_name))
125     return 0;
126
127   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
128   if (p == 0)
129     return 0;
130   *result = p[0];
131   return 1;
132 }
133
134 /* Parse an IP4 address %d.%d.%d.%d. */
135 uword
136 unformat_ip4_address (unformat_input_t * input, va_list * args)
137 {
138   u8 *result = va_arg (*args, u8 *);
139   unsigned a[4];
140
141   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
142     return 0;
143
144   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
145     return 0;
146
147   result[0] = a[0];
148   result[1] = a[1];
149   result[2] = a[2];
150   result[3] = a[3];
151
152   return 1;
153 }
154
155 uword
156 unformat_ethernet_address (unformat_input_t * input, va_list * args)
157 {
158   u8 *result = va_arg (*args, u8 *);
159   u32 i, a[6];
160
161   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
162                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
163     return 0;
164
165   /* Check range. */
166   for (i = 0; i < 6; i++)
167     if (a[i] >= (1 << 8))
168       return 0;
169
170   for (i = 0; i < 6; i++)
171     result[i] = a[i];
172
173   return 1;
174 }
175
176 /* Returns ethernet type as an int in host byte order. */
177 uword
178 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
179                                         va_list * args)
180 {
181   u16 *result = va_arg (*args, u16 *);
182   int type;
183
184   /* Numeric type. */
185   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
186     {
187       if (type >= (1 << 16))
188         return 0;
189       *result = type;
190       return 1;
191     }
192   return 0;
193 }
194
195 /* Parse an IP6 address. */
196 uword
197 unformat_ip6_address (unformat_input_t * input, va_list * args)
198 {
199   ip6_address_t *result = va_arg (*args, ip6_address_t *);
200   u16 hex_quads[8];
201   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
202   uword c, n_colon, double_colon_index;
203
204   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
205   double_colon_index = ARRAY_LEN (hex_quads);
206   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
207     {
208       hex_digit = 16;
209       if (c >= '0' && c <= '9')
210         hex_digit = c - '0';
211       else if (c >= 'a' && c <= 'f')
212         hex_digit = c + 10 - 'a';
213       else if (c >= 'A' && c <= 'F')
214         hex_digit = c + 10 - 'A';
215       else if (c == ':' && n_colon < 2)
216         n_colon++;
217       else
218         {
219           unformat_put_input (input);
220           break;
221         }
222
223       /* Too many hex quads. */
224       if (n_hex_quads >= ARRAY_LEN (hex_quads))
225         return 0;
226
227       if (hex_digit < 16)
228         {
229           hex_quad = (hex_quad << 4) | hex_digit;
230
231           /* Hex quad must fit in 16 bits. */
232           if (n_hex_digits >= 4)
233             return 0;
234
235           n_colon = 0;
236           n_hex_digits++;
237         }
238
239       /* Save position of :: */
240       if (n_colon == 2)
241         {
242           /* More than one :: ? */
243           if (double_colon_index < ARRAY_LEN (hex_quads))
244             return 0;
245           double_colon_index = n_hex_quads;
246         }
247
248       if (n_colon > 0 && n_hex_digits > 0)
249         {
250           hex_quads[n_hex_quads++] = hex_quad;
251           hex_quad = 0;
252           n_hex_digits = 0;
253         }
254     }
255
256   if (n_hex_digits > 0)
257     hex_quads[n_hex_quads++] = hex_quad;
258
259   {
260     word i;
261
262     /* Expand :: to appropriate number of zero hex quads. */
263     if (double_colon_index < ARRAY_LEN (hex_quads))
264       {
265         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
266
267         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
268           hex_quads[n_zero + i] = hex_quads[i];
269
270         for (i = 0; i < n_zero; i++)
271           hex_quads[double_colon_index + i] = 0;
272
273         n_hex_quads = ARRAY_LEN (hex_quads);
274       }
275
276     /* Too few hex quads given. */
277     if (n_hex_quads < ARRAY_LEN (hex_quads))
278       return 0;
279
280     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
281       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
282
283     return 1;
284   }
285 }
286
287 uword
288 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
289 {
290   u32 *r = va_arg (*args, u32 *);
291
292   if (0);
293 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
294   foreach_ipsec_policy_action
295 #undef _
296     else
297     return 0;
298   return 1;
299 }
300
301 uword
302 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
303 {
304   u32 *r = va_arg (*args, u32 *);
305
306   if (0);
307 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
308   foreach_ipsec_crypto_alg
309 #undef _
310     else
311     return 0;
312   return 1;
313 }
314
315 u8 *
316 format_ipsec_crypto_alg (u8 * s, va_list * args)
317 {
318   u32 i = va_arg (*args, u32);
319   u8 *t = 0;
320
321   switch (i)
322     {
323 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
324       foreach_ipsec_crypto_alg
325 #undef _
326     default:
327       return format (s, "unknown");
328     }
329   return format (s, "%s", t);
330 }
331
332 uword
333 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
339   foreach_ipsec_integ_alg
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 u8 *
347 format_ipsec_integ_alg (u8 * s, va_list * args)
348 {
349   u32 i = va_arg (*args, u32);
350   u8 *t = 0;
351
352   switch (i)
353     {
354 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
355       foreach_ipsec_integ_alg
356 #undef _
357     default:
358       return format (s, "unknown");
359     }
360   return format (s, "%s", t);
361 }
362
363 uword
364 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
370   foreach_ikev2_auth_method
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 uword
378 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
379 {
380   u32 *r = va_arg (*args, u32 *);
381
382   if (0);
383 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
384   foreach_ikev2_id_type
385 #undef _
386     else
387     return 0;
388   return 1;
389 }
390 #else /* VPP_API_TEST_BUILTIN == 1 */
391 static uword
392 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
393 {
394   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
395   vnet_main_t *vnm = vnet_get_main ();
396   u32 *result = va_arg (*args, u32 *);
397   u32 sw_if_index;
398
399   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
400     return 0;
401
402   *result = sw_if_index;
403   return 1;
404 }
405 #endif /* VPP_API_TEST_BUILTIN */
406
407 static uword
408 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "kbps"))
413     *r = SSE2_QOS_RATE_KBPS;
414   else if (unformat (input, "pps"))
415     *r = SSE2_QOS_RATE_PPS;
416   else
417     return 0;
418   return 1;
419 }
420
421 static uword
422 unformat_policer_round_type (unformat_input_t * input, va_list * args)
423 {
424   u8 *r = va_arg (*args, u8 *);
425
426   if (unformat (input, "closest"))
427     *r = SSE2_QOS_ROUND_TO_CLOSEST;
428   else if (unformat (input, "up"))
429     *r = SSE2_QOS_ROUND_TO_UP;
430   else if (unformat (input, "down"))
431     *r = SSE2_QOS_ROUND_TO_DOWN;
432   else
433     return 0;
434   return 1;
435 }
436
437 static uword
438 unformat_policer_type (unformat_input_t * input, va_list * args)
439 {
440   u8 *r = va_arg (*args, u8 *);
441
442   if (unformat (input, "1r2c"))
443     *r = SSE2_QOS_POLICER_TYPE_1R2C;
444   else if (unformat (input, "1r3c"))
445     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
446   else if (unformat (input, "2r3c-2698"))
447     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
448   else if (unformat (input, "2r3c-4115"))
449     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
450   else if (unformat (input, "2r3c-mef5cf1"))
451     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
452   else
453     return 0;
454   return 1;
455 }
456
457 static uword
458 unformat_dscp (unformat_input_t * input, va_list * va)
459 {
460   u8 *r = va_arg (*va, u8 *);
461
462   if (0);
463 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
464   foreach_vnet_dscp
465 #undef _
466     else
467     return 0;
468   return 1;
469 }
470
471 static uword
472 unformat_policer_action_type (unformat_input_t * input, va_list * va)
473 {
474   sse2_qos_pol_action_params_st *a
475     = va_arg (*va, sse2_qos_pol_action_params_st *);
476
477   if (unformat (input, "drop"))
478     a->action_type = SSE2_QOS_ACTION_DROP;
479   else if (unformat (input, "transmit"))
480     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
481   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
482     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
490 {
491   u32 *r = va_arg (*va, u32 *);
492   u32 tid;
493
494   if (unformat (input, "ip4"))
495     tid = POLICER_CLASSIFY_TABLE_IP4;
496   else if (unformat (input, "ip6"))
497     tid = POLICER_CLASSIFY_TABLE_IP6;
498   else if (unformat (input, "l2"))
499     tid = POLICER_CLASSIFY_TABLE_L2;
500   else
501     return 0;
502
503   *r = tid;
504   return 1;
505 }
506
507 static uword
508 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
509 {
510   u32 *r = va_arg (*va, u32 *);
511   u32 tid;
512
513   if (unformat (input, "ip4"))
514     tid = FLOW_CLASSIFY_TABLE_IP4;
515   else if (unformat (input, "ip6"))
516     tid = FLOW_CLASSIFY_TABLE_IP6;
517   else
518     return 0;
519
520   *r = tid;
521   return 1;
522 }
523
524 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
525 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
526 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
527 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
528
529 #if (VPP_API_TEST_BUILTIN==0)
530 uword
531 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
532 {
533   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
534   mfib_itf_attribute_t attr;
535
536   old = *iflags;
537   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
538   {
539     if (unformat (input, mfib_itf_flag_long_names[attr]))
540       *iflags |= (1 << attr);
541   }
542   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
543   {
544     if (unformat (input, mfib_itf_flag_names[attr]))
545       *iflags |= (1 << attr);
546   }
547
548   return (old == *iflags ? 0 : 1);
549 }
550
551 uword
552 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
553 {
554   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
555   mfib_entry_attribute_t attr;
556
557   old = *eflags;
558   FOR_EACH_MFIB_ATTRIBUTE (attr)
559   {
560     if (unformat (input, mfib_flag_long_names[attr]))
561       *eflags |= (1 << attr);
562   }
563   FOR_EACH_MFIB_ATTRIBUTE (attr)
564   {
565     if (unformat (input, mfib_flag_names[attr]))
566       *eflags |= (1 << attr);
567   }
568
569   return (old == *eflags ? 0 : 1);
570 }
571
572 u8 *
573 format_ip4_address (u8 * s, va_list * args)
574 {
575   u8 *a = va_arg (*args, u8 *);
576   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
577 }
578
579 u8 *
580 format_ip6_address (u8 * s, va_list * args)
581 {
582   ip6_address_t *a = va_arg (*args, ip6_address_t *);
583   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
584
585   i_max_n_zero = ARRAY_LEN (a->as_u16);
586   max_n_zeros = 0;
587   i_first_zero = i_max_n_zero;
588   n_zeros = 0;
589   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
590     {
591       u32 is_zero = a->as_u16[i] == 0;
592       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
593         {
594           i_first_zero = i;
595           n_zeros = 0;
596         }
597       n_zeros += is_zero;
598       if ((!is_zero && n_zeros > max_n_zeros)
599           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
600         {
601           i_max_n_zero = i_first_zero;
602           max_n_zeros = n_zeros;
603           i_first_zero = ARRAY_LEN (a->as_u16);
604           n_zeros = 0;
605         }
606     }
607
608   last_double_colon = 0;
609   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
610     {
611       if (i == i_max_n_zero && max_n_zeros > 1)
612         {
613           s = format (s, "::");
614           i += max_n_zeros - 1;
615           last_double_colon = 1;
616         }
617       else
618         {
619           s = format (s, "%s%x",
620                       (last_double_colon || i == 0) ? "" : ":",
621                       clib_net_to_host_u16 (a->as_u16[i]));
622           last_double_colon = 0;
623         }
624     }
625
626   return s;
627 }
628
629 /* Format an IP46 address. */
630 u8 *
631 format_ip46_address (u8 * s, va_list * args)
632 {
633   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
634   ip46_type_t type = va_arg (*args, ip46_type_t);
635   int is_ip4 = 1;
636
637   switch (type)
638     {
639     case IP46_TYPE_ANY:
640       is_ip4 = ip46_address_is_ip4 (ip46);
641       break;
642     case IP46_TYPE_IP4:
643       is_ip4 = 1;
644       break;
645     case IP46_TYPE_IP6:
646       is_ip4 = 0;
647       break;
648     }
649
650   return is_ip4 ?
651     format (s, "%U", format_ip4_address, &ip46->ip4) :
652     format (s, "%U", format_ip6_address, &ip46->ip6);
653 }
654
655 u8 *
656 format_ethernet_address (u8 * s, va_list * args)
657 {
658   u8 *a = va_arg (*args, u8 *);
659
660   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
661                  a[0], a[1], a[2], a[3], a[4], a[5]);
662 }
663 #endif
664
665 static void
666 increment_v4_address (ip4_address_t * a)
667 {
668   u32 v;
669
670   v = ntohl (a->as_u32) + 1;
671   a->as_u32 = ntohl (v);
672 }
673
674 static void
675 increment_v6_address (ip6_address_t * a)
676 {
677   u64 v0, v1;
678
679   v0 = clib_net_to_host_u64 (a->as_u64[0]);
680   v1 = clib_net_to_host_u64 (a->as_u64[1]);
681
682   v1 += 1;
683   if (v1 == 0)
684     v0 += 1;
685   a->as_u64[0] = clib_net_to_host_u64 (v0);
686   a->as_u64[1] = clib_net_to_host_u64 (v1);
687 }
688
689 static void
690 increment_mac_address (u64 * mac)
691 {
692   u64 tmp = *mac;
693
694   tmp = clib_net_to_host_u64 (tmp);
695   tmp += 1 << 16;               /* skip unused (least significant) octets */
696   tmp = clib_host_to_net_u64 (tmp);
697   *mac = tmp;
698 }
699
700 static void vl_api_create_loopback_reply_t_handler
701   (vl_api_create_loopback_reply_t * mp)
702 {
703   vat_main_t *vam = &vat_main;
704   i32 retval = ntohl (mp->retval);
705
706   vam->retval = retval;
707   vam->regenerate_interface_table = 1;
708   vam->sw_if_index = ntohl (mp->sw_if_index);
709   vam->result_ready = 1;
710 }
711
712 static void vl_api_create_loopback_reply_t_handler_json
713   (vl_api_create_loopback_reply_t * mp)
714 {
715   vat_main_t *vam = &vat_main;
716   vat_json_node_t node;
717
718   vat_json_init_object (&node);
719   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
720   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
721
722   vat_json_print (vam->ofp, &node);
723   vat_json_free (&node);
724   vam->retval = ntohl (mp->retval);
725   vam->result_ready = 1;
726 }
727
728 static void vl_api_af_packet_create_reply_t_handler
729   (vl_api_af_packet_create_reply_t * mp)
730 {
731   vat_main_t *vam = &vat_main;
732   i32 retval = ntohl (mp->retval);
733
734   vam->retval = retval;
735   vam->regenerate_interface_table = 1;
736   vam->sw_if_index = ntohl (mp->sw_if_index);
737   vam->result_ready = 1;
738 }
739
740 static void vl_api_af_packet_create_reply_t_handler_json
741   (vl_api_af_packet_create_reply_t * mp)
742 {
743   vat_main_t *vam = &vat_main;
744   vat_json_node_t node;
745
746   vat_json_init_object (&node);
747   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
748   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
749
750   vat_json_print (vam->ofp, &node);
751   vat_json_free (&node);
752
753   vam->retval = ntohl (mp->retval);
754   vam->result_ready = 1;
755 }
756
757 static void vl_api_create_vlan_subif_reply_t_handler
758   (vl_api_create_vlan_subif_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   i32 retval = ntohl (mp->retval);
762
763   vam->retval = retval;
764   vam->regenerate_interface_table = 1;
765   vam->sw_if_index = ntohl (mp->sw_if_index);
766   vam->result_ready = 1;
767 }
768
769 static void vl_api_create_vlan_subif_reply_t_handler_json
770   (vl_api_create_vlan_subif_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   vat_json_node_t node;
774
775   vat_json_init_object (&node);
776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
777   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
778
779   vat_json_print (vam->ofp, &node);
780   vat_json_free (&node);
781
782   vam->retval = ntohl (mp->retval);
783   vam->result_ready = 1;
784 }
785
786 static void vl_api_create_subif_reply_t_handler
787   (vl_api_create_subif_reply_t * mp)
788 {
789   vat_main_t *vam = &vat_main;
790   i32 retval = ntohl (mp->retval);
791
792   vam->retval = retval;
793   vam->regenerate_interface_table = 1;
794   vam->sw_if_index = ntohl (mp->sw_if_index);
795   vam->result_ready = 1;
796 }
797
798 static void vl_api_create_subif_reply_t_handler_json
799   (vl_api_create_subif_reply_t * mp)
800 {
801   vat_main_t *vam = &vat_main;
802   vat_json_node_t node;
803
804   vat_json_init_object (&node);
805   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
806   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
807
808   vat_json_print (vam->ofp, &node);
809   vat_json_free (&node);
810
811   vam->retval = ntohl (mp->retval);
812   vam->result_ready = 1;
813 }
814
815 static void vl_api_interface_name_renumber_reply_t_handler
816   (vl_api_interface_name_renumber_reply_t * mp)
817 {
818   vat_main_t *vam = &vat_main;
819   i32 retval = ntohl (mp->retval);
820
821   vam->retval = retval;
822   vam->regenerate_interface_table = 1;
823   vam->result_ready = 1;
824 }
825
826 static void vl_api_interface_name_renumber_reply_t_handler_json
827   (vl_api_interface_name_renumber_reply_t * mp)
828 {
829   vat_main_t *vam = &vat_main;
830   vat_json_node_t node;
831
832   vat_json_init_object (&node);
833   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 /*
843  * Special-case: build the interface table, maintain
844  * the next loopback sw_if_index vbl.
845  */
846 static void vl_api_sw_interface_details_t_handler
847   (vl_api_sw_interface_details_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   u8 *s = format (0, "%s%c", mp->interface_name, 0);
851
852   hash_set_mem (vam->sw_if_index_by_interface_name, s,
853                 ntohl (mp->sw_if_index));
854
855   /* In sub interface case, fill the sub interface table entry */
856   if (mp->sw_if_index != mp->sup_sw_if_index)
857     {
858       sw_interface_subif_t *sub = NULL;
859
860       vec_add2 (vam->sw_if_subif_table, sub, 1);
861
862       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
863       strncpy ((char *) sub->interface_name, (char *) s,
864                vec_len (sub->interface_name));
865       sub->sw_if_index = ntohl (mp->sw_if_index);
866       sub->sub_id = ntohl (mp->sub_id);
867
868       sub->sub_dot1ad = mp->sub_dot1ad;
869       sub->sub_number_of_tags = mp->sub_number_of_tags;
870       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
871       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
872       sub->sub_exact_match = mp->sub_exact_match;
873       sub->sub_default = mp->sub_default;
874       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
875       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
876
877       /* vlan tag rewrite */
878       sub->vtr_op = ntohl (mp->vtr_op);
879       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
880       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
881       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
882     }
883 }
884
885 static void vl_api_sw_interface_details_t_handler_json
886   (vl_api_sw_interface_details_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   vat_json_node_t *node = NULL;
890
891   if (VAT_JSON_ARRAY != vam->json_tree.type)
892     {
893       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
894       vat_json_init_array (&vam->json_tree);
895     }
896   node = vat_json_array_add (&vam->json_tree);
897
898   vat_json_init_object (node);
899   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
900   vat_json_object_add_uint (node, "sup_sw_if_index",
901                             ntohl (mp->sup_sw_if_index));
902   vat_json_object_add_uint (node, "l2_address_length",
903                             ntohl (mp->l2_address_length));
904   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
905                              sizeof (mp->l2_address));
906   vat_json_object_add_string_copy (node, "interface_name",
907                                    mp->interface_name);
908   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
909   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
910   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
911   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
912   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
913   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
914   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
915   vat_json_object_add_uint (node, "sub_number_of_tags",
916                             mp->sub_number_of_tags);
917   vat_json_object_add_uint (node, "sub_outer_vlan_id",
918                             ntohs (mp->sub_outer_vlan_id));
919   vat_json_object_add_uint (node, "sub_inner_vlan_id",
920                             ntohs (mp->sub_inner_vlan_id));
921   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
922   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
923   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
924                             mp->sub_outer_vlan_id_any);
925   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
926                             mp->sub_inner_vlan_id_any);
927   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
928   vat_json_object_add_uint (node, "vtr_push_dot1q",
929                             ntohl (mp->vtr_push_dot1q));
930   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
931   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
932   if (mp->sub_dot1ah)
933     {
934       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
935                                        format (0, "%U",
936                                                format_ethernet_address,
937                                                &mp->b_dmac));
938       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
939                                        format (0, "%U",
940                                                format_ethernet_address,
941                                                &mp->b_smac));
942       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
943       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
944     }
945 }
946
947 static void vl_api_sw_interface_set_flags_t_handler
948   (vl_api_sw_interface_set_flags_t * mp)
949 {
950   vat_main_t *vam = &vat_main;
951   if (vam->interface_event_display)
952     errmsg ("interface flags: sw_if_index %d %s %s",
953             ntohl (mp->sw_if_index),
954             mp->admin_up_down ? "admin-up" : "admin-down",
955             mp->link_up_down ? "link-up" : "link-down");
956 }
957
958 static void vl_api_sw_interface_set_flags_t_handler_json
959   (vl_api_sw_interface_set_flags_t * mp)
960 {
961   /* JSON output not supported */
962 }
963
964 static void
965 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
966 {
967   vat_main_t *vam = &vat_main;
968   i32 retval = ntohl (mp->retval);
969
970   vam->retval = retval;
971   vam->shmem_result = (u8 *) mp->reply_in_shmem;
972   vam->result_ready = 1;
973 }
974
975 static void
976 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   vat_json_node_t node;
980   api_main_t *am = &api_main;
981   void *oldheap;
982   u8 *reply;
983
984   vat_json_init_object (&node);
985   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
986   vat_json_object_add_uint (&node, "reply_in_shmem",
987                             ntohl (mp->reply_in_shmem));
988   /* Toss the shared-memory original... */
989   pthread_mutex_lock (&am->vlib_rp->mutex);
990   oldheap = svm_push_data_heap (am->vlib_rp);
991
992   reply = (u8 *) (mp->reply_in_shmem);
993   vec_free (reply);
994
995   svm_pop_heap (oldheap);
996   pthread_mutex_unlock (&am->vlib_rp->mutex);
997
998   vat_json_print (vam->ofp, &node);
999   vat_json_free (&node);
1000
1001   vam->retval = ntohl (mp->retval);
1002   vam->result_ready = 1;
1003 }
1004
1005 static void
1006 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   i32 retval = ntohl (mp->retval);
1010
1011   vam->retval = retval;
1012   vam->cmd_reply = mp->reply;
1013   vam->result_ready = 1;
1014 }
1015
1016 static void
1017 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1018 {
1019   vat_main_t *vam = &vat_main;
1020   vat_json_node_t node;
1021
1022   vat_json_init_object (&node);
1023   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1024   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1025
1026   vat_json_print (vam->ofp, &node);
1027   vat_json_free (&node);
1028
1029   vam->retval = ntohl (mp->retval);
1030   vam->result_ready = 1;
1031 }
1032
1033 static void vl_api_classify_add_del_table_reply_t_handler
1034   (vl_api_classify_add_del_table_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   i32 retval = ntohl (mp->retval);
1038   if (vam->async_mode)
1039     {
1040       vam->async_errors += (retval < 0);
1041     }
1042   else
1043     {
1044       vam->retval = retval;
1045       if (retval == 0 &&
1046           ((mp->new_table_index != 0xFFFFFFFF) ||
1047            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1048            (mp->match_n_vectors != 0xFFFFFFFF)))
1049         /*
1050          * Note: this is just barely thread-safe, depends on
1051          * the main thread spinning waiting for an answer...
1052          */
1053         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1054                 ntohl (mp->new_table_index),
1055                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1056       vam->result_ready = 1;
1057     }
1058 }
1059
1060 static void vl_api_classify_add_del_table_reply_t_handler_json
1061   (vl_api_classify_add_del_table_reply_t * mp)
1062 {
1063   vat_main_t *vam = &vat_main;
1064   vat_json_node_t node;
1065
1066   vat_json_init_object (&node);
1067   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1068   vat_json_object_add_uint (&node, "new_table_index",
1069                             ntohl (mp->new_table_index));
1070   vat_json_object_add_uint (&node, "skip_n_vectors",
1071                             ntohl (mp->skip_n_vectors));
1072   vat_json_object_add_uint (&node, "match_n_vectors",
1073                             ntohl (mp->match_n_vectors));
1074
1075   vat_json_print (vam->ofp, &node);
1076   vat_json_free (&node);
1077
1078   vam->retval = ntohl (mp->retval);
1079   vam->result_ready = 1;
1080 }
1081
1082 static void vl_api_get_node_index_reply_t_handler
1083   (vl_api_get_node_index_reply_t * mp)
1084 {
1085   vat_main_t *vam = &vat_main;
1086   i32 retval = ntohl (mp->retval);
1087   if (vam->async_mode)
1088     {
1089       vam->async_errors += (retval < 0);
1090     }
1091   else
1092     {
1093       vam->retval = retval;
1094       if (retval == 0)
1095         errmsg ("node index %d", ntohl (mp->node_index));
1096       vam->result_ready = 1;
1097     }
1098 }
1099
1100 static void vl_api_get_node_index_reply_t_handler_json
1101   (vl_api_get_node_index_reply_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   vat_json_node_t node;
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1109
1110   vat_json_print (vam->ofp, &node);
1111   vat_json_free (&node);
1112
1113   vam->retval = ntohl (mp->retval);
1114   vam->result_ready = 1;
1115 }
1116
1117 static void vl_api_get_next_index_reply_t_handler
1118   (vl_api_get_next_index_reply_t * mp)
1119 {
1120   vat_main_t *vam = &vat_main;
1121   i32 retval = ntohl (mp->retval);
1122   if (vam->async_mode)
1123     {
1124       vam->async_errors += (retval < 0);
1125     }
1126   else
1127     {
1128       vam->retval = retval;
1129       if (retval == 0)
1130         errmsg ("next node index %d", ntohl (mp->next_index));
1131       vam->result_ready = 1;
1132     }
1133 }
1134
1135 static void vl_api_get_next_index_reply_t_handler_json
1136   (vl_api_get_next_index_reply_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   vat_json_node_t node;
1140
1141   vat_json_init_object (&node);
1142   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1143   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1144
1145   vat_json_print (vam->ofp, &node);
1146   vat_json_free (&node);
1147
1148   vam->retval = ntohl (mp->retval);
1149   vam->result_ready = 1;
1150 }
1151
1152 static void vl_api_add_node_next_reply_t_handler
1153   (vl_api_add_node_next_reply_t * mp)
1154 {
1155   vat_main_t *vam = &vat_main;
1156   i32 retval = ntohl (mp->retval);
1157   if (vam->async_mode)
1158     {
1159       vam->async_errors += (retval < 0);
1160     }
1161   else
1162     {
1163       vam->retval = retval;
1164       if (retval == 0)
1165         errmsg ("next index %d", ntohl (mp->next_index));
1166       vam->result_ready = 1;
1167     }
1168 }
1169
1170 static void vl_api_add_node_next_reply_t_handler_json
1171   (vl_api_add_node_next_reply_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   vat_json_node_t node;
1175
1176   vat_json_init_object (&node);
1177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1178   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1179
1180   vat_json_print (vam->ofp, &node);
1181   vat_json_free (&node);
1182
1183   vam->retval = ntohl (mp->retval);
1184   vam->result_ready = 1;
1185 }
1186
1187 static void vl_api_show_version_reply_t_handler
1188   (vl_api_show_version_reply_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   i32 retval = ntohl (mp->retval);
1192
1193   if (retval >= 0)
1194     {
1195       errmsg ("        program: %s", mp->program);
1196       errmsg ("        version: %s", mp->version);
1197       errmsg ("     build date: %s", mp->build_date);
1198       errmsg ("build directory: %s", mp->build_directory);
1199     }
1200   vam->retval = retval;
1201   vam->result_ready = 1;
1202 }
1203
1204 static void vl_api_show_version_reply_t_handler_json
1205   (vl_api_show_version_reply_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t node;
1209
1210   vat_json_init_object (&node);
1211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1212   vat_json_object_add_string_copy (&node, "program", mp->program);
1213   vat_json_object_add_string_copy (&node, "version", mp->version);
1214   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1215   vat_json_object_add_string_copy (&node, "build_directory",
1216                                    mp->build_directory);
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void
1226 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1227 {
1228   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1229           mp->mac_ip ? "mac/ip binding" : "address resolution",
1230           format_ip4_address, &mp->address,
1231           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1232 }
1233
1234 static void
1235 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1236 {
1237   /* JSON output not supported */
1238 }
1239
1240 static void
1241 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1242 {
1243   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1244           mp->mac_ip ? "mac/ip binding" : "address resolution",
1245           format_ip6_address, mp->address,
1246           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1247 }
1248
1249 static void
1250 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1251 {
1252   /* JSON output not supported */
1253 }
1254
1255 /*
1256  * Special-case: build the bridge domain table, maintain
1257  * the next bd id vbl.
1258  */
1259 static void vl_api_bridge_domain_details_t_handler
1260   (vl_api_bridge_domain_details_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1264
1265   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1266          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1267
1268   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1269          ntohl (mp->bd_id), mp->learn, mp->forward,
1270          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1271
1272   if (n_sw_ifs)
1273     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1274 }
1275
1276 static void vl_api_bridge_domain_details_t_handler_json
1277   (vl_api_bridge_domain_details_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t *node, *array = NULL;
1281
1282   if (VAT_JSON_ARRAY != vam->json_tree.type)
1283     {
1284       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1285       vat_json_init_array (&vam->json_tree);
1286     }
1287   node = vat_json_array_add (&vam->json_tree);
1288
1289   vat_json_init_object (node);
1290   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1291   vat_json_object_add_uint (node, "flood", mp->flood);
1292   vat_json_object_add_uint (node, "forward", mp->forward);
1293   vat_json_object_add_uint (node, "learn", mp->learn);
1294   vat_json_object_add_uint (node, "bvi_sw_if_index",
1295                             ntohl (mp->bvi_sw_if_index));
1296   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1297   array = vat_json_object_add (node, "sw_if");
1298   vat_json_init_array (array);
1299 }
1300
1301 /*
1302  * Special-case: build the bridge domain sw if table.
1303  */
1304 static void vl_api_bridge_domain_sw_if_details_t_handler
1305   (vl_api_bridge_domain_sw_if_details_t * mp)
1306 {
1307   vat_main_t *vam = &vat_main;
1308   hash_pair_t *p;
1309   u8 *sw_if_name = 0;
1310   u32 sw_if_index;
1311
1312   sw_if_index = ntohl (mp->sw_if_index);
1313   /* *INDENT-OFF* */
1314   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1315   ({
1316     if ((u32) p->value[0] == sw_if_index)
1317       {
1318         sw_if_name = (u8 *)(p->key);
1319         break;
1320       }
1321   }));
1322   /* *INDENT-ON* */
1323
1324   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1325          mp->shg, sw_if_name ? (char *) sw_if_name :
1326          "sw_if_index not found!");
1327 }
1328
1329 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1330   (vl_api_bridge_domain_sw_if_details_t * mp)
1331 {
1332   vat_main_t *vam = &vat_main;
1333   vat_json_node_t *node = NULL;
1334   uword last_index = 0;
1335
1336   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1337   ASSERT (vec_len (vam->json_tree.array) >= 1);
1338   last_index = vec_len (vam->json_tree.array) - 1;
1339   node = &vam->json_tree.array[last_index];
1340   node = vat_json_object_get_element (node, "sw_if");
1341   ASSERT (NULL != node);
1342   node = vat_json_array_add (node);
1343
1344   vat_json_init_object (node);
1345   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1346   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1347   vat_json_object_add_uint (node, "shg", mp->shg);
1348 }
1349
1350 static void vl_api_control_ping_reply_t_handler
1351   (vl_api_control_ping_reply_t * mp)
1352 {
1353   vat_main_t *vam = &vat_main;
1354   i32 retval = ntohl (mp->retval);
1355   if (vam->async_mode)
1356     {
1357       vam->async_errors += (retval < 0);
1358     }
1359   else
1360     {
1361       vam->retval = retval;
1362       vam->result_ready = 1;
1363     }
1364 }
1365
1366 static void vl_api_control_ping_reply_t_handler_json
1367   (vl_api_control_ping_reply_t * mp)
1368 {
1369   vat_main_t *vam = &vat_main;
1370   i32 retval = ntohl (mp->retval);
1371
1372   if (VAT_JSON_NONE != vam->json_tree.type)
1373     {
1374       vat_json_print (vam->ofp, &vam->json_tree);
1375       vat_json_free (&vam->json_tree);
1376       vam->json_tree.type = VAT_JSON_NONE;
1377     }
1378   else
1379     {
1380       /* just print [] */
1381       vat_json_init_array (&vam->json_tree);
1382       vat_json_print (vam->ofp, &vam->json_tree);
1383       vam->json_tree.type = VAT_JSON_NONE;
1384     }
1385
1386   vam->retval = retval;
1387   vam->result_ready = 1;
1388 }
1389
1390 static void
1391 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1392 {
1393   vat_main_t *vam = &vat_main;
1394   i32 retval = ntohl (mp->retval);
1395   if (vam->async_mode)
1396     {
1397       vam->async_errors += (retval < 0);
1398     }
1399   else
1400     {
1401       vam->retval = retval;
1402       vam->result_ready = 1;
1403     }
1404 }
1405
1406 static void vl_api_l2_flags_reply_t_handler_json
1407   (vl_api_l2_flags_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1415                             ntohl (mp->resulting_feature_bitmap));
1416
1417   vat_json_print (vam->ofp, &node);
1418   vat_json_free (&node);
1419
1420   vam->retval = ntohl (mp->retval);
1421   vam->result_ready = 1;
1422 }
1423
1424 static void vl_api_bridge_flags_reply_t_handler
1425   (vl_api_bridge_flags_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   i32 retval = ntohl (mp->retval);
1429   if (vam->async_mode)
1430     {
1431       vam->async_errors += (retval < 0);
1432     }
1433   else
1434     {
1435       vam->retval = retval;
1436       vam->result_ready = 1;
1437     }
1438 }
1439
1440 static void vl_api_bridge_flags_reply_t_handler_json
1441   (vl_api_bridge_flags_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   vat_json_node_t node;
1445
1446   vat_json_init_object (&node);
1447   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1448   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1449                             ntohl (mp->resulting_feature_bitmap));
1450
1451   vat_json_print (vam->ofp, &node);
1452   vat_json_free (&node);
1453
1454   vam->retval = ntohl (mp->retval);
1455   vam->result_ready = 1;
1456 }
1457
1458 static void vl_api_tap_connect_reply_t_handler
1459   (vl_api_tap_connect_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   i32 retval = ntohl (mp->retval);
1463   if (vam->async_mode)
1464     {
1465       vam->async_errors += (retval < 0);
1466     }
1467   else
1468     {
1469       vam->retval = retval;
1470       vam->sw_if_index = ntohl (mp->sw_if_index);
1471       vam->result_ready = 1;
1472     }
1473
1474 }
1475
1476 static void vl_api_tap_connect_reply_t_handler_json
1477   (vl_api_tap_connect_reply_t * mp)
1478 {
1479   vat_main_t *vam = &vat_main;
1480   vat_json_node_t node;
1481
1482   vat_json_init_object (&node);
1483   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1484   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491
1492 }
1493
1494 static void
1495 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->sw_if_index = ntohl (mp->sw_if_index);
1507       vam->result_ready = 1;
1508     }
1509 }
1510
1511 static void vl_api_tap_modify_reply_t_handler_json
1512   (vl_api_tap_modify_reply_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t node;
1516
1517   vat_json_init_object (&node);
1518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1520
1521   vat_json_print (vam->ofp, &node);
1522   vat_json_free (&node);
1523
1524   vam->retval = ntohl (mp->retval);
1525   vam->result_ready = 1;
1526 }
1527
1528 static void
1529 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   i32 retval = ntohl (mp->retval);
1533   if (vam->async_mode)
1534     {
1535       vam->async_errors += (retval < 0);
1536     }
1537   else
1538     {
1539       vam->retval = retval;
1540       vam->result_ready = 1;
1541     }
1542 }
1543
1544 static void vl_api_tap_delete_reply_t_handler_json
1545   (vl_api_tap_delete_reply_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t node;
1549
1550   vat_json_init_object (&node);
1551   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1552
1553   vat_json_print (vam->ofp, &node);
1554   vat_json_free (&node);
1555
1556   vam->retval = ntohl (mp->retval);
1557   vam->result_ready = 1;
1558 }
1559
1560 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1561   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1562 {
1563   vat_main_t *vam = &vat_main;
1564   i32 retval = ntohl (mp->retval);
1565   if (vam->async_mode)
1566     {
1567       vam->async_errors += (retval < 0);
1568     }
1569   else
1570     {
1571       vam->retval = retval;
1572       vam->result_ready = 1;
1573     }
1574 }
1575
1576 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1577   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   vat_json_node_t node;
1581
1582   vat_json_init_object (&node);
1583   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1584   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1585                             ntohl (mp->sw_if_index));
1586
1587   vat_json_print (vam->ofp, &node);
1588   vat_json_free (&node);
1589
1590   vam->retval = ntohl (mp->retval);
1591   vam->result_ready = 1;
1592 }
1593
1594 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1595   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1596 {
1597   vat_main_t *vam = &vat_main;
1598   i32 retval = ntohl (mp->retval);
1599   if (vam->async_mode)
1600     {
1601       vam->async_errors += (retval < 0);
1602     }
1603   else
1604     {
1605       vam->retval = retval;
1606       vam->sw_if_index = ntohl (mp->sw_if_index);
1607       vam->result_ready = 1;
1608     }
1609 }
1610
1611 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1612   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1613 {
1614   vat_main_t *vam = &vat_main;
1615   vat_json_node_t node;
1616
1617   vat_json_init_object (&node);
1618   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1619   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1620
1621   vat_json_print (vam->ofp, &node);
1622   vat_json_free (&node);
1623
1624   vam->retval = ntohl (mp->retval);
1625   vam->result_ready = 1;
1626 }
1627
1628
1629 static void vl_api_one_add_del_locator_set_reply_t_handler
1630   (vl_api_one_add_del_locator_set_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1646   (vl_api_one_add_del_locator_set_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1654
1655   vat_json_print (vam->ofp, &node);
1656   vat_json_free (&node);
1657
1658   vam->retval = ntohl (mp->retval);
1659   vam->result_ready = 1;
1660 }
1661
1662 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1663   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1664 {
1665   vat_main_t *vam = &vat_main;
1666   i32 retval = ntohl (mp->retval);
1667   if (vam->async_mode)
1668     {
1669       vam->async_errors += (retval < 0);
1670     }
1671   else
1672     {
1673       vam->retval = retval;
1674       vam->sw_if_index = ntohl (mp->sw_if_index);
1675       vam->result_ready = 1;
1676     }
1677 }
1678
1679 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1680   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1681 {
1682   vat_main_t *vam = &vat_main;
1683   vat_json_node_t node;
1684
1685   vat_json_init_object (&node);
1686   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1687   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1688
1689   vat_json_print (vam->ofp, &node);
1690   vat_json_free (&node);
1691
1692   vam->retval = ntohl (mp->retval);
1693   vam->result_ready = 1;
1694 }
1695
1696 static void vl_api_gre_add_del_tunnel_reply_t_handler
1697   (vl_api_gre_add_del_tunnel_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   i32 retval = ntohl (mp->retval);
1701   if (vam->async_mode)
1702     {
1703       vam->async_errors += (retval < 0);
1704     }
1705   else
1706     {
1707       vam->retval = retval;
1708       vam->sw_if_index = ntohl (mp->sw_if_index);
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1714   (vl_api_gre_add_del_tunnel_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1722
1723   vat_json_print (vam->ofp, &node);
1724   vat_json_free (&node);
1725
1726   vam->retval = ntohl (mp->retval);
1727   vam->result_ready = 1;
1728 }
1729
1730 static void vl_api_create_vhost_user_if_reply_t_handler
1731   (vl_api_create_vhost_user_if_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   i32 retval = ntohl (mp->retval);
1735   if (vam->async_mode)
1736     {
1737       vam->async_errors += (retval < 0);
1738     }
1739   else
1740     {
1741       vam->retval = retval;
1742       vam->sw_if_index = ntohl (mp->sw_if_index);
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_create_vhost_user_if_reply_t_handler_json
1748   (vl_api_create_vhost_user_if_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_ip_address_details_t_handler
1765   (vl_api_ip_address_details_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   static ip_address_details_t empty_ip_address_details = { {0} };
1769   ip_address_details_t *address = NULL;
1770   ip_details_t *current_ip_details = NULL;
1771   ip_details_t *details = NULL;
1772
1773   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1774
1775   if (!details || vam->current_sw_if_index >= vec_len (details)
1776       || !details[vam->current_sw_if_index].present)
1777     {
1778       errmsg ("ip address details arrived but not stored");
1779       errmsg ("ip_dump should be called first");
1780       return;
1781     }
1782
1783   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1784
1785 #define addresses (current_ip_details->addr)
1786
1787   vec_validate_init_empty (addresses, vec_len (addresses),
1788                            empty_ip_address_details);
1789
1790   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1791
1792   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1793   address->prefix_length = mp->prefix_length;
1794 #undef addresses
1795 }
1796
1797 static void vl_api_ip_address_details_t_handler_json
1798   (vl_api_ip_address_details_t * mp)
1799 {
1800   vat_main_t *vam = &vat_main;
1801   vat_json_node_t *node = NULL;
1802   struct in6_addr ip6;
1803   struct in_addr ip4;
1804
1805   if (VAT_JSON_ARRAY != vam->json_tree.type)
1806     {
1807       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1808       vat_json_init_array (&vam->json_tree);
1809     }
1810   node = vat_json_array_add (&vam->json_tree);
1811
1812   vat_json_init_object (node);
1813   if (vam->is_ipv6)
1814     {
1815       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1816       vat_json_object_add_ip6 (node, "ip", ip6);
1817     }
1818   else
1819     {
1820       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1821       vat_json_object_add_ip4 (node, "ip", ip4);
1822     }
1823   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1824 }
1825
1826 static void
1827 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   static ip_details_t empty_ip_details = { 0 };
1831   ip_details_t *ip = NULL;
1832   u32 sw_if_index = ~0;
1833
1834   sw_if_index = ntohl (mp->sw_if_index);
1835
1836   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1837                            sw_if_index, empty_ip_details);
1838
1839   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1840                          sw_if_index);
1841
1842   ip->present = 1;
1843 }
1844
1845 static void
1846 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1847 {
1848   vat_main_t *vam = &vat_main;
1849
1850   if (VAT_JSON_ARRAY != vam->json_tree.type)
1851     {
1852       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1853       vat_json_init_array (&vam->json_tree);
1854     }
1855   vat_json_array_add_uint (&vam->json_tree,
1856                            clib_net_to_host_u32 (mp->sw_if_index));
1857 }
1858
1859 static void vl_api_map_domain_details_t_handler_json
1860   (vl_api_map_domain_details_t * mp)
1861 {
1862   vat_json_node_t *node = NULL;
1863   vat_main_t *vam = &vat_main;
1864   struct in6_addr ip6;
1865   struct in_addr ip4;
1866
1867   if (VAT_JSON_ARRAY != vam->json_tree.type)
1868     {
1869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1870       vat_json_init_array (&vam->json_tree);
1871     }
1872
1873   node = vat_json_array_add (&vam->json_tree);
1874   vat_json_init_object (node);
1875
1876   vat_json_object_add_uint (node, "domain_index",
1877                             clib_net_to_host_u32 (mp->domain_index));
1878   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1879   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1880   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1881   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1882   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1883   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1884   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1885   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1886   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1887   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1888   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1889   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1890   vat_json_object_add_uint (node, "flags", mp->flags);
1891   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1892   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1893 }
1894
1895 static void vl_api_map_domain_details_t_handler
1896   (vl_api_map_domain_details_t * mp)
1897 {
1898   vat_main_t *vam = &vat_main;
1899
1900   if (mp->is_translation)
1901     {
1902       print (vam->ofp,
1903              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1904              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1905              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1906              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1907              clib_net_to_host_u32 (mp->domain_index));
1908     }
1909   else
1910     {
1911       print (vam->ofp,
1912              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1913              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1914              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1915              format_ip6_address, mp->ip6_src,
1916              clib_net_to_host_u32 (mp->domain_index));
1917     }
1918   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1919          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1920          mp->is_translation ? "map-t" : "");
1921 }
1922
1923 static void vl_api_map_rule_details_t_handler_json
1924   (vl_api_map_rule_details_t * mp)
1925 {
1926   struct in6_addr ip6;
1927   vat_json_node_t *node = NULL;
1928   vat_main_t *vam = &vat_main;
1929
1930   if (VAT_JSON_ARRAY != vam->json_tree.type)
1931     {
1932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1933       vat_json_init_array (&vam->json_tree);
1934     }
1935
1936   node = vat_json_array_add (&vam->json_tree);
1937   vat_json_init_object (node);
1938
1939   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1940   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1941   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1942 }
1943
1944 static void
1945 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1946 {
1947   vat_main_t *vam = &vat_main;
1948   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1949          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1950 }
1951
1952 static void
1953 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1954 {
1955   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1956           "router_addr %U host_mac %U",
1957           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1958           format_ip4_address, &mp->host_address,
1959           format_ip4_address, &mp->router_address,
1960           format_ethernet_address, mp->host_mac);
1961 }
1962
1963 static void vl_api_dhcp_compl_event_t_handler_json
1964   (vl_api_dhcp_compl_event_t * mp)
1965 {
1966   /* JSON output not supported */
1967 }
1968
1969 static void
1970 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1971                               u32 counter)
1972 {
1973   vat_main_t *vam = &vat_main;
1974   static u64 default_counter = 0;
1975
1976   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1977                            NULL);
1978   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1979                            sw_if_index, default_counter);
1980   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1981 }
1982
1983 static void
1984 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1985                                 interface_counter_t counter)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   static interface_counter_t default_counter = { 0, };
1989
1990   vec_validate_init_empty (vam->combined_interface_counters,
1991                            vnet_counter_type, NULL);
1992   vec_validate_init_empty (vam->combined_interface_counters
1993                            [vnet_counter_type], sw_if_index, default_counter);
1994   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1995 }
1996
1997 static void vl_api_vnet_interface_counters_t_handler
1998   (vl_api_vnet_interface_counters_t * mp)
1999 {
2000   /* not supported */
2001 }
2002
2003 static void vl_api_vnet_interface_counters_t_handler_json
2004   (vl_api_vnet_interface_counters_t * mp)
2005 {
2006   interface_counter_t counter;
2007   vlib_counter_t *v;
2008   u64 *v_packets;
2009   u64 packets;
2010   u32 count;
2011   u32 first_sw_if_index;
2012   int i;
2013
2014   count = ntohl (mp->count);
2015   first_sw_if_index = ntohl (mp->first_sw_if_index);
2016
2017   if (!mp->is_combined)
2018     {
2019       v_packets = (u64 *) & mp->data;
2020       for (i = 0; i < count; i++)
2021         {
2022           packets =
2023             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2024           set_simple_interface_counter (mp->vnet_counter_type,
2025                                         first_sw_if_index + i, packets);
2026           v_packets++;
2027         }
2028     }
2029   else
2030     {
2031       v = (vlib_counter_t *) & mp->data;
2032       for (i = 0; i < count; i++)
2033         {
2034           counter.packets =
2035             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2036           counter.bytes =
2037             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2038           set_combined_interface_counter (mp->vnet_counter_type,
2039                                           first_sw_if_index + i, counter);
2040           v++;
2041         }
2042     }
2043 }
2044
2045 static u32
2046 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2047 {
2048   vat_main_t *vam = &vat_main;
2049   u32 i;
2050
2051   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2052     {
2053       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2054         {
2055           return i;
2056         }
2057     }
2058   return ~0;
2059 }
2060
2061 static u32
2062 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2063 {
2064   vat_main_t *vam = &vat_main;
2065   u32 i;
2066
2067   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2068     {
2069       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2070         {
2071           return i;
2072         }
2073     }
2074   return ~0;
2075 }
2076
2077 static void vl_api_vnet_ip4_fib_counters_t_handler
2078   (vl_api_vnet_ip4_fib_counters_t * mp)
2079 {
2080   /* not supported */
2081 }
2082
2083 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2084   (vl_api_vnet_ip4_fib_counters_t * mp)
2085 {
2086   vat_main_t *vam = &vat_main;
2087   vl_api_ip4_fib_counter_t *v;
2088   ip4_fib_counter_t *counter;
2089   struct in_addr ip4;
2090   u32 vrf_id;
2091   u32 vrf_index;
2092   u32 count;
2093   int i;
2094
2095   vrf_id = ntohl (mp->vrf_id);
2096   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2097   if (~0 == vrf_index)
2098     {
2099       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2100       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2101       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2102       vec_validate (vam->ip4_fib_counters, vrf_index);
2103       vam->ip4_fib_counters[vrf_index] = NULL;
2104     }
2105
2106   vec_free (vam->ip4_fib_counters[vrf_index]);
2107   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2108   count = ntohl (mp->count);
2109   for (i = 0; i < count; i++)
2110     {
2111       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2112       counter = &vam->ip4_fib_counters[vrf_index][i];
2113       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2114       counter->address = ip4;
2115       counter->address_length = v->address_length;
2116       counter->packets = clib_net_to_host_u64 (v->packets);
2117       counter->bytes = clib_net_to_host_u64 (v->bytes);
2118       v++;
2119     }
2120 }
2121
2122 static void vl_api_vnet_ip4_nbr_counters_t_handler
2123   (vl_api_vnet_ip4_nbr_counters_t * mp)
2124 {
2125   /* not supported */
2126 }
2127
2128 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2129   (vl_api_vnet_ip4_nbr_counters_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   vl_api_ip4_nbr_counter_t *v;
2133   ip4_nbr_counter_t *counter;
2134   u32 sw_if_index;
2135   u32 count;
2136   int i;
2137
2138   sw_if_index = ntohl (mp->sw_if_index);
2139   count = ntohl (mp->count);
2140   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2141
2142   if (mp->begin)
2143     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2144
2145   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2146   for (i = 0; i < count; i++)
2147     {
2148       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2149       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2150       counter->address.s_addr = v->address;
2151       counter->packets = clib_net_to_host_u64 (v->packets);
2152       counter->bytes = clib_net_to_host_u64 (v->bytes);
2153       counter->linkt = v->link_type;
2154       v++;
2155     }
2156 }
2157
2158 static void vl_api_vnet_ip6_fib_counters_t_handler
2159   (vl_api_vnet_ip6_fib_counters_t * mp)
2160 {
2161   /* not supported */
2162 }
2163
2164 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2165   (vl_api_vnet_ip6_fib_counters_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   vl_api_ip6_fib_counter_t *v;
2169   ip6_fib_counter_t *counter;
2170   struct in6_addr ip6;
2171   u32 vrf_id;
2172   u32 vrf_index;
2173   u32 count;
2174   int i;
2175
2176   vrf_id = ntohl (mp->vrf_id);
2177   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2178   if (~0 == vrf_index)
2179     {
2180       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2181       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2182       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2183       vec_validate (vam->ip6_fib_counters, vrf_index);
2184       vam->ip6_fib_counters[vrf_index] = NULL;
2185     }
2186
2187   vec_free (vam->ip6_fib_counters[vrf_index]);
2188   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2189   count = ntohl (mp->count);
2190   for (i = 0; i < count; i++)
2191     {
2192       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2193       counter = &vam->ip6_fib_counters[vrf_index][i];
2194       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2195       counter->address = ip6;
2196       counter->address_length = v->address_length;
2197       counter->packets = clib_net_to_host_u64 (v->packets);
2198       counter->bytes = clib_net_to_host_u64 (v->bytes);
2199       v++;
2200     }
2201 }
2202
2203 static void vl_api_vnet_ip6_nbr_counters_t_handler
2204   (vl_api_vnet_ip6_nbr_counters_t * mp)
2205 {
2206   /* not supported */
2207 }
2208
2209 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2210   (vl_api_vnet_ip6_nbr_counters_t * mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   vl_api_ip6_nbr_counter_t *v;
2214   ip6_nbr_counter_t *counter;
2215   struct in6_addr ip6;
2216   u32 sw_if_index;
2217   u32 count;
2218   int i;
2219
2220   sw_if_index = ntohl (mp->sw_if_index);
2221   count = ntohl (mp->count);
2222   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2223
2224   if (mp->begin)
2225     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2226
2227   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2228   for (i = 0; i < count; i++)
2229     {
2230       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2231       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2232       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2233       counter->address = ip6;
2234       counter->packets = clib_net_to_host_u64 (v->packets);
2235       counter->bytes = clib_net_to_host_u64 (v->bytes);
2236       v++;
2237     }
2238 }
2239
2240 static void vl_api_get_first_msg_id_reply_t_handler
2241   (vl_api_get_first_msg_id_reply_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   i32 retval = ntohl (mp->retval);
2245
2246   if (vam->async_mode)
2247     {
2248       vam->async_errors += (retval < 0);
2249     }
2250   else
2251     {
2252       vam->retval = retval;
2253       vam->result_ready = 1;
2254     }
2255   if (retval >= 0)
2256     {
2257       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2258     }
2259 }
2260
2261 static void vl_api_get_first_msg_id_reply_t_handler_json
2262   (vl_api_get_first_msg_id_reply_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t node;
2266
2267   vat_json_init_object (&node);
2268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2269   vat_json_object_add_uint (&node, "first_msg_id",
2270                             (uint) ntohs (mp->first_msg_id));
2271
2272   vat_json_print (vam->ofp, &node);
2273   vat_json_free (&node);
2274
2275   vam->retval = ntohl (mp->retval);
2276   vam->result_ready = 1;
2277 }
2278
2279 static void vl_api_get_node_graph_reply_t_handler
2280   (vl_api_get_node_graph_reply_t * mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   api_main_t *am = &api_main;
2284   i32 retval = ntohl (mp->retval);
2285   u8 *pvt_copy, *reply;
2286   void *oldheap;
2287   vlib_node_t *node;
2288   int i;
2289
2290   if (vam->async_mode)
2291     {
2292       vam->async_errors += (retval < 0);
2293     }
2294   else
2295     {
2296       vam->retval = retval;
2297       vam->result_ready = 1;
2298     }
2299
2300   /* "Should never happen..." */
2301   if (retval != 0)
2302     return;
2303
2304   reply = (u8 *) (mp->reply_in_shmem);
2305   pvt_copy = vec_dup (reply);
2306
2307   /* Toss the shared-memory original... */
2308   pthread_mutex_lock (&am->vlib_rp->mutex);
2309   oldheap = svm_push_data_heap (am->vlib_rp);
2310
2311   vec_free (reply);
2312
2313   svm_pop_heap (oldheap);
2314   pthread_mutex_unlock (&am->vlib_rp->mutex);
2315
2316   if (vam->graph_nodes)
2317     {
2318       hash_free (vam->graph_node_index_by_name);
2319
2320       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2321         {
2322           node = vam->graph_nodes[i];
2323           vec_free (node->name);
2324           vec_free (node->next_nodes);
2325           vec_free (node);
2326         }
2327       vec_free (vam->graph_nodes);
2328     }
2329
2330   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2331   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2332   vec_free (pvt_copy);
2333
2334   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2335     {
2336       node = vam->graph_nodes[i];
2337       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2338     }
2339 }
2340
2341 static void vl_api_get_node_graph_reply_t_handler_json
2342   (vl_api_get_node_graph_reply_t * mp)
2343 {
2344   vat_main_t *vam = &vat_main;
2345   api_main_t *am = &api_main;
2346   void *oldheap;
2347   vat_json_node_t node;
2348   u8 *reply;
2349
2350   /* $$$$ make this real? */
2351   vat_json_init_object (&node);
2352   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2353   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2354
2355   reply = (u8 *) (mp->reply_in_shmem);
2356
2357   /* Toss the shared-memory original... */
2358   pthread_mutex_lock (&am->vlib_rp->mutex);
2359   oldheap = svm_push_data_heap (am->vlib_rp);
2360
2361   vec_free (reply);
2362
2363   svm_pop_heap (oldheap);
2364   pthread_mutex_unlock (&am->vlib_rp->mutex);
2365
2366   vat_json_print (vam->ofp, &node);
2367   vat_json_free (&node);
2368
2369   vam->retval = ntohl (mp->retval);
2370   vam->result_ready = 1;
2371 }
2372
2373 static void
2374 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2375 {
2376   vat_main_t *vam = &vat_main;
2377   u8 *s = 0;
2378
2379   if (mp->local)
2380     {
2381       s = format (s, "%=16d%=16d%=16d",
2382                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2383     }
2384   else
2385     {
2386       s = format (s, "%=16U%=16d%=16d",
2387                   mp->is_ipv6 ? format_ip6_address :
2388                   format_ip4_address,
2389                   mp->ip_address, mp->priority, mp->weight);
2390     }
2391
2392   print (vam->ofp, "%v", s);
2393   vec_free (s);
2394 }
2395
2396 static void
2397 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2398 {
2399   vat_main_t *vam = &vat_main;
2400   vat_json_node_t *node = NULL;
2401   struct in6_addr ip6;
2402   struct in_addr ip4;
2403
2404   if (VAT_JSON_ARRAY != vam->json_tree.type)
2405     {
2406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2407       vat_json_init_array (&vam->json_tree);
2408     }
2409   node = vat_json_array_add (&vam->json_tree);
2410   vat_json_init_object (node);
2411
2412   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2413   vat_json_object_add_uint (node, "priority", mp->priority);
2414   vat_json_object_add_uint (node, "weight", mp->weight);
2415
2416   if (mp->local)
2417     vat_json_object_add_uint (node, "sw_if_index",
2418                               clib_net_to_host_u32 (mp->sw_if_index));
2419   else
2420     {
2421       if (mp->is_ipv6)
2422         {
2423           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2424           vat_json_object_add_ip6 (node, "address", ip6);
2425         }
2426       else
2427         {
2428           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2429           vat_json_object_add_ip4 (node, "address", ip4);
2430         }
2431     }
2432 }
2433
2434 static void
2435 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2436                                           mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   u8 *ls_name = 0;
2440
2441   ls_name = format (0, "%s", mp->ls_name);
2442
2443   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2444          ls_name);
2445   vec_free (ls_name);
2446 }
2447
2448 static void
2449   vl_api_one_locator_set_details_t_handler_json
2450   (vl_api_one_locator_set_details_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   vat_json_node_t *node = 0;
2454   u8 *ls_name = 0;
2455
2456   ls_name = format (0, "%s", mp->ls_name);
2457   vec_add1 (ls_name, 0);
2458
2459   if (VAT_JSON_ARRAY != vam->json_tree.type)
2460     {
2461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2462       vat_json_init_array (&vam->json_tree);
2463     }
2464   node = vat_json_array_add (&vam->json_tree);
2465
2466   vat_json_init_object (node);
2467   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2468   vat_json_object_add_uint (node, "ls_index",
2469                             clib_net_to_host_u32 (mp->ls_index));
2470   vec_free (ls_name);
2471 }
2472
2473 static u8 *
2474 format_lisp_flat_eid (u8 * s, va_list * args)
2475 {
2476   u32 type = va_arg (*args, u32);
2477   u8 *eid = va_arg (*args, u8 *);
2478   u32 eid_len = va_arg (*args, u32);
2479
2480   switch (type)
2481     {
2482     case 0:
2483       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2484     case 1:
2485       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2486     case 2:
2487       return format (s, "%U", format_ethernet_address, eid);
2488     }
2489   return 0;
2490 }
2491
2492 static u8 *
2493 format_lisp_eid_vat (u8 * s, va_list * args)
2494 {
2495   u32 type = va_arg (*args, u32);
2496   u8 *eid = va_arg (*args, u8 *);
2497   u32 eid_len = va_arg (*args, u32);
2498   u8 *seid = va_arg (*args, u8 *);
2499   u32 seid_len = va_arg (*args, u32);
2500   u32 is_src_dst = va_arg (*args, u32);
2501
2502   if (is_src_dst)
2503     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2504
2505   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2506
2507   return s;
2508 }
2509
2510 static void
2511 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   u8 *s = 0, *eid = 0;
2515
2516   if (~0 == mp->locator_set_index)
2517     s = format (0, "action: %d", mp->action);
2518   else
2519     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2520
2521   eid = format (0, "%U", format_lisp_eid_vat,
2522                 mp->eid_type,
2523                 mp->eid,
2524                 mp->eid_prefix_len,
2525                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2526   vec_add1 (eid, 0);
2527
2528   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2529          clib_net_to_host_u32 (mp->vni),
2530          eid,
2531          mp->is_local ? "local" : "remote",
2532          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2533          clib_net_to_host_u16 (mp->key_id), mp->key);
2534
2535   vec_free (s);
2536   vec_free (eid);
2537 }
2538
2539 static void
2540 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2541                                              * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   vat_json_node_t *node = 0;
2545   u8 *eid = 0;
2546
2547   if (VAT_JSON_ARRAY != vam->json_tree.type)
2548     {
2549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2550       vat_json_init_array (&vam->json_tree);
2551     }
2552   node = vat_json_array_add (&vam->json_tree);
2553
2554   vat_json_init_object (node);
2555   if (~0 == mp->locator_set_index)
2556     vat_json_object_add_uint (node, "action", mp->action);
2557   else
2558     vat_json_object_add_uint (node, "locator_set_index",
2559                               clib_net_to_host_u32 (mp->locator_set_index));
2560
2561   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2562   eid = format (0, "%U", format_lisp_eid_vat,
2563                 mp->eid_type,
2564                 mp->eid,
2565                 mp->eid_prefix_len,
2566                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2567   vec_add1 (eid, 0);
2568   vat_json_object_add_string_copy (node, "eid", eid);
2569   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2570   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2571   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2572
2573   if (mp->key_id)
2574     {
2575       vat_json_object_add_uint (node, "key_id",
2576                                 clib_net_to_host_u16 (mp->key_id));
2577       vat_json_object_add_string_copy (node, "key", mp->key);
2578     }
2579   vec_free (eid);
2580 }
2581
2582 static void
2583   vl_api_one_eid_table_map_details_t_handler
2584   (vl_api_one_eid_table_map_details_t * mp)
2585 {
2586   vat_main_t *vam = &vat_main;
2587
2588   u8 *line = format (0, "%=10d%=10d",
2589                      clib_net_to_host_u32 (mp->vni),
2590                      clib_net_to_host_u32 (mp->dp_table));
2591   print (vam->ofp, "%v", line);
2592   vec_free (line);
2593 }
2594
2595 static void
2596   vl_api_one_eid_table_map_details_t_handler_json
2597   (vl_api_one_eid_table_map_details_t * mp)
2598 {
2599   vat_main_t *vam = &vat_main;
2600   vat_json_node_t *node = NULL;
2601
2602   if (VAT_JSON_ARRAY != vam->json_tree.type)
2603     {
2604       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2605       vat_json_init_array (&vam->json_tree);
2606     }
2607   node = vat_json_array_add (&vam->json_tree);
2608   vat_json_init_object (node);
2609   vat_json_object_add_uint (node, "dp_table",
2610                             clib_net_to_host_u32 (mp->dp_table));
2611   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2612 }
2613
2614 static void
2615   vl_api_one_eid_table_vni_details_t_handler
2616   (vl_api_one_eid_table_vni_details_t * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2621   print (vam->ofp, "%v", line);
2622   vec_free (line);
2623 }
2624
2625 static void
2626   vl_api_one_eid_table_vni_details_t_handler_json
2627   (vl_api_one_eid_table_vni_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631
2632   if (VAT_JSON_ARRAY != vam->json_tree.type)
2633     {
2634       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2635       vat_json_init_array (&vam->json_tree);
2636     }
2637   node = vat_json_array_add (&vam->json_tree);
2638   vat_json_init_object (node);
2639   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2640 }
2641
2642 static void
2643   vl_api_show_one_map_register_state_reply_t_handler
2644   (vl_api_show_one_map_register_state_reply_t * mp)
2645 {
2646   vat_main_t *vam = &vat_main;
2647   int retval = clib_net_to_host_u32 (mp->retval);
2648
2649   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2650
2651   vam->retval = retval;
2652   vam->result_ready = 1;
2653 }
2654
2655 static void
2656   vl_api_show_one_map_register_state_reply_t_handler_json
2657   (vl_api_show_one_map_register_state_reply_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t _node, *node = &_node;
2661   int retval = clib_net_to_host_u32 (mp->retval);
2662
2663   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2664
2665   vat_json_init_object (node);
2666   vat_json_object_add_string_copy (node, "state", s);
2667
2668   vat_json_print (vam->ofp, node);
2669   vat_json_free (node);
2670
2671   vam->retval = retval;
2672   vam->result_ready = 1;
2673   vec_free (s);
2674 }
2675
2676 static void
2677   vl_api_show_one_rloc_probe_state_reply_t_handler
2678   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2679 {
2680   vat_main_t *vam = &vat_main;
2681   int retval = clib_net_to_host_u32 (mp->retval);
2682
2683   if (retval)
2684     goto end;
2685
2686   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2687 end:
2688   vam->retval = retval;
2689   vam->result_ready = 1;
2690 }
2691
2692 static void
2693   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2694   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2695 {
2696   vat_main_t *vam = &vat_main;
2697   vat_json_node_t _node, *node = &_node;
2698   int retval = clib_net_to_host_u32 (mp->retval);
2699
2700   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2701   vat_json_init_object (node);
2702   vat_json_object_add_string_copy (node, "state", s);
2703
2704   vat_json_print (vam->ofp, node);
2705   vat_json_free (node);
2706
2707   vam->retval = retval;
2708   vam->result_ready = 1;
2709   vec_free (s);
2710 }
2711
2712 static void
2713 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2714 {
2715   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2716   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2717 }
2718
2719 static void
2720   gpe_fwd_entries_get_reply_t_net_to_host
2721   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2722 {
2723   u32 i;
2724
2725   mp->count = clib_net_to_host_u32 (mp->count);
2726   for (i = 0; i < mp->count; i++)
2727     {
2728       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2729     }
2730 }
2731
2732 static u8 *
2733 format_gpe_encap_mode (u8 * s, va_list * args)
2734 {
2735   u32 mode = va_arg (*args, u32);
2736
2737   switch (mode)
2738     {
2739     case 0:
2740       return format (s, "lisp");
2741     case 1:
2742       return format (s, "vxlan");
2743     }
2744   return 0;
2745 }
2746
2747 static void
2748   vl_api_gpe_get_encap_mode_reply_t_handler
2749   (vl_api_gpe_get_encap_mode_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752
2753   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2754   vam->retval = ntohl (mp->retval);
2755   vam->result_ready = 1;
2756 }
2757
2758 static void
2759   vl_api_gpe_get_encap_mode_reply_t_handler_json
2760   (vl_api_gpe_get_encap_mode_reply_t * mp)
2761 {
2762   vat_main_t *vam = &vat_main;
2763   vat_json_node_t node;
2764
2765   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2766   vec_add1 (encap_mode, 0);
2767
2768   vat_json_init_object (&node);
2769   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2770
2771   vec_free (encap_mode);
2772   vat_json_print (vam->ofp, &node);
2773   vat_json_free (&node);
2774
2775   vam->retval = ntohl (mp->retval);
2776   vam->result_ready = 1;
2777 }
2778
2779 static void
2780   vl_api_gpe_fwd_entry_path_details_t_handler
2781   (vl_api_gpe_fwd_entry_path_details_t * mp)
2782 {
2783   vat_main_t *vam = &vat_main;
2784   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2785
2786   if (mp->lcl_loc.is_ip4)
2787     format_ip_address_fcn = format_ip4_address;
2788   else
2789     format_ip_address_fcn = format_ip6_address;
2790
2791   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2792          format_ip_address_fcn, &mp->lcl_loc,
2793          format_ip_address_fcn, &mp->rmt_loc);
2794 }
2795
2796 static void
2797 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2798 {
2799   struct in6_addr ip6;
2800   struct in_addr ip4;
2801
2802   if (loc->is_ip4)
2803     {
2804       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2805       vat_json_object_add_ip4 (n, "address", ip4);
2806     }
2807   else
2808     {
2809       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2810       vat_json_object_add_ip6 (n, "address", ip6);
2811     }
2812   vat_json_object_add_uint (n, "weight", loc->weight);
2813 }
2814
2815 static void
2816   vl_api_gpe_fwd_entry_path_details_t_handler_json
2817   (vl_api_gpe_fwd_entry_path_details_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   vat_json_node_t *node = NULL;
2821   vat_json_node_t *loc_node;
2822
2823   if (VAT_JSON_ARRAY != vam->json_tree.type)
2824     {
2825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2826       vat_json_init_array (&vam->json_tree);
2827     }
2828   node = vat_json_array_add (&vam->json_tree);
2829   vat_json_init_object (node);
2830
2831   loc_node = vat_json_object_add (node, "local_locator");
2832   vat_json_init_object (loc_node);
2833   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2834
2835   loc_node = vat_json_object_add (node, "remote_locator");
2836   vat_json_init_object (loc_node);
2837   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2838 }
2839
2840 static void
2841   vl_api_gpe_fwd_entries_get_reply_t_handler
2842   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   u32 i;
2846   int retval = clib_net_to_host_u32 (mp->retval);
2847   vl_api_gpe_fwd_entry_t *e;
2848
2849   if (retval)
2850     goto end;
2851
2852   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2853
2854   for (i = 0; i < mp->count; i++)
2855     {
2856       e = &mp->entries[i];
2857       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2858              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2859              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2860     }
2861
2862 end:
2863   vam->retval = retval;
2864   vam->result_ready = 1;
2865 }
2866
2867 static void
2868   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2869   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2870 {
2871   u8 *s = 0;
2872   vat_main_t *vam = &vat_main;
2873   vat_json_node_t *e = 0, root;
2874   u32 i;
2875   int retval = clib_net_to_host_u32 (mp->retval);
2876   vl_api_gpe_fwd_entry_t *fwd;
2877
2878   if (retval)
2879     goto end;
2880
2881   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2882   vat_json_init_array (&root);
2883
2884   for (i = 0; i < mp->count; i++)
2885     {
2886       e = vat_json_array_add (&root);
2887       fwd = &mp->entries[i];
2888
2889       vat_json_init_object (e);
2890       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2891       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2892
2893       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2894                   fwd->leid_prefix_len);
2895       vec_add1 (s, 0);
2896       vat_json_object_add_string_copy (e, "leid", s);
2897       vec_free (s);
2898
2899       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2900                   fwd->reid_prefix_len);
2901       vec_add1 (s, 0);
2902       vat_json_object_add_string_copy (e, "reid", s);
2903       vec_free (s);
2904     }
2905
2906   vat_json_print (vam->ofp, &root);
2907   vat_json_free (&root);
2908
2909 end:
2910   vam->retval = retval;
2911   vam->result_ready = 1;
2912 }
2913
2914 static void
2915   vl_api_one_adjacencies_get_reply_t_handler
2916   (vl_api_one_adjacencies_get_reply_t * mp)
2917 {
2918   vat_main_t *vam = &vat_main;
2919   u32 i, n;
2920   int retval = clib_net_to_host_u32 (mp->retval);
2921   vl_api_one_adjacency_t *a;
2922
2923   if (retval)
2924     goto end;
2925
2926   n = clib_net_to_host_u32 (mp->count);
2927
2928   for (i = 0; i < n; i++)
2929     {
2930       a = &mp->adjacencies[i];
2931       print (vam->ofp, "%U %40U",
2932              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2933              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2934     }
2935
2936 end:
2937   vam->retval = retval;
2938   vam->result_ready = 1;
2939 }
2940
2941 static void
2942   vl_api_one_adjacencies_get_reply_t_handler_json
2943   (vl_api_one_adjacencies_get_reply_t * mp)
2944 {
2945   u8 *s = 0;
2946   vat_main_t *vam = &vat_main;
2947   vat_json_node_t *e = 0, root;
2948   u32 i, n;
2949   int retval = clib_net_to_host_u32 (mp->retval);
2950   vl_api_one_adjacency_t *a;
2951
2952   if (retval)
2953     goto end;
2954
2955   n = clib_net_to_host_u32 (mp->count);
2956   vat_json_init_array (&root);
2957
2958   for (i = 0; i < n; i++)
2959     {
2960       e = vat_json_array_add (&root);
2961       a = &mp->adjacencies[i];
2962
2963       vat_json_init_object (e);
2964       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2965                   a->leid_prefix_len);
2966       vec_add1 (s, 0);
2967       vat_json_object_add_string_copy (e, "leid", s);
2968       vec_free (s);
2969
2970       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2971                   a->reid_prefix_len);
2972       vec_add1 (s, 0);
2973       vat_json_object_add_string_copy (e, "reid", s);
2974       vec_free (s);
2975     }
2976
2977   vat_json_print (vam->ofp, &root);
2978   vat_json_free (&root);
2979
2980 end:
2981   vam->retval = retval;
2982   vam->result_ready = 1;
2983 }
2984
2985 static void
2986 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
2987 {
2988   vat_main_t *vam = &vat_main;
2989
2990   print (vam->ofp, "%=20U",
2991          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2992          mp->ip_address);
2993 }
2994
2995 static void
2996   vl_api_one_map_server_details_t_handler_json
2997   (vl_api_one_map_server_details_t * mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   vat_json_node_t *node = NULL;
3001   struct in6_addr ip6;
3002   struct in_addr ip4;
3003
3004   if (VAT_JSON_ARRAY != vam->json_tree.type)
3005     {
3006       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3007       vat_json_init_array (&vam->json_tree);
3008     }
3009   node = vat_json_array_add (&vam->json_tree);
3010
3011   vat_json_init_object (node);
3012   if (mp->is_ipv6)
3013     {
3014       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3015       vat_json_object_add_ip6 (node, "map-server", ip6);
3016     }
3017   else
3018     {
3019       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3020       vat_json_object_add_ip4 (node, "map-server", ip4);
3021     }
3022 }
3023
3024 static void
3025 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3026                                            * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029
3030   print (vam->ofp, "%=20U",
3031          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3032          mp->ip_address);
3033 }
3034
3035 static void
3036   vl_api_one_map_resolver_details_t_handler_json
3037   (vl_api_one_map_resolver_details_t * mp)
3038 {
3039   vat_main_t *vam = &vat_main;
3040   vat_json_node_t *node = NULL;
3041   struct in6_addr ip6;
3042   struct in_addr ip4;
3043
3044   if (VAT_JSON_ARRAY != vam->json_tree.type)
3045     {
3046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3047       vat_json_init_array (&vam->json_tree);
3048     }
3049   node = vat_json_array_add (&vam->json_tree);
3050
3051   vat_json_init_object (node);
3052   if (mp->is_ipv6)
3053     {
3054       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3055       vat_json_object_add_ip6 (node, "map resolver", ip6);
3056     }
3057   else
3058     {
3059       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3060       vat_json_object_add_ip4 (node, "map resolver", ip4);
3061     }
3062 }
3063
3064 static void
3065 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3066 {
3067   vat_main_t *vam = &vat_main;
3068   i32 retval = ntohl (mp->retval);
3069
3070   if (0 <= retval)
3071     {
3072       print (vam->ofp, "feature: %s\ngpe: %s",
3073              mp->feature_status ? "enabled" : "disabled",
3074              mp->gpe_status ? "enabled" : "disabled");
3075     }
3076
3077   vam->retval = retval;
3078   vam->result_ready = 1;
3079 }
3080
3081 static void
3082   vl_api_show_one_status_reply_t_handler_json
3083   (vl_api_show_one_status_reply_t * mp)
3084 {
3085   vat_main_t *vam = &vat_main;
3086   vat_json_node_t node;
3087   u8 *gpe_status = NULL;
3088   u8 *feature_status = NULL;
3089
3090   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3091   feature_status = format (0, "%s",
3092                            mp->feature_status ? "enabled" : "disabled");
3093   vec_add1 (gpe_status, 0);
3094   vec_add1 (feature_status, 0);
3095
3096   vat_json_init_object (&node);
3097   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3098   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3099
3100   vec_free (gpe_status);
3101   vec_free (feature_status);
3102
3103   vat_json_print (vam->ofp, &node);
3104   vat_json_free (&node);
3105
3106   vam->retval = ntohl (mp->retval);
3107   vam->result_ready = 1;
3108 }
3109
3110 static void
3111   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3112   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3113 {
3114   vat_main_t *vam = &vat_main;
3115   i32 retval = ntohl (mp->retval);
3116
3117   if (retval >= 0)
3118     {
3119       print (vam->ofp, "%=20s", mp->locator_set_name);
3120     }
3121
3122   vam->retval = retval;
3123   vam->result_ready = 1;
3124 }
3125
3126 static void
3127   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3128   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   vat_json_node_t *node = NULL;
3132
3133   if (VAT_JSON_ARRAY != vam->json_tree.type)
3134     {
3135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3136       vat_json_init_array (&vam->json_tree);
3137     }
3138   node = vat_json_array_add (&vam->json_tree);
3139
3140   vat_json_init_object (node);
3141   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3142
3143   vat_json_print (vam->ofp, node);
3144   vat_json_free (node);
3145
3146   vam->retval = ntohl (mp->retval);
3147   vam->result_ready = 1;
3148 }
3149
3150 static u8 *
3151 format_lisp_map_request_mode (u8 * s, va_list * args)
3152 {
3153   u32 mode = va_arg (*args, u32);
3154
3155   switch (mode)
3156     {
3157     case 0:
3158       return format (0, "dst-only");
3159     case 1:
3160       return format (0, "src-dst");
3161     }
3162   return 0;
3163 }
3164
3165 static void
3166   vl_api_show_one_map_request_mode_reply_t_handler
3167   (vl_api_show_one_map_request_mode_reply_t * mp)
3168 {
3169   vat_main_t *vam = &vat_main;
3170   i32 retval = ntohl (mp->retval);
3171
3172   if (0 <= retval)
3173     {
3174       u32 mode = mp->mode;
3175       print (vam->ofp, "map_request_mode: %U",
3176              format_lisp_map_request_mode, mode);
3177     }
3178
3179   vam->retval = retval;
3180   vam->result_ready = 1;
3181 }
3182
3183 static void
3184   vl_api_show_one_map_request_mode_reply_t_handler_json
3185   (vl_api_show_one_map_request_mode_reply_t * mp)
3186 {
3187   vat_main_t *vam = &vat_main;
3188   vat_json_node_t node;
3189   u8 *s = 0;
3190   u32 mode;
3191
3192   mode = mp->mode;
3193   s = format (0, "%U", format_lisp_map_request_mode, mode);
3194   vec_add1 (s, 0);
3195
3196   vat_json_init_object (&node);
3197   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3198   vat_json_print (vam->ofp, &node);
3199   vat_json_free (&node);
3200
3201   vec_free (s);
3202   vam->retval = ntohl (mp->retval);
3203   vam->result_ready = 1;
3204 }
3205
3206 static void
3207 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3208 {
3209   vat_main_t *vam = &vat_main;
3210   i32 retval = ntohl (mp->retval);
3211
3212   if (0 <= retval)
3213     {
3214       print (vam->ofp, "%-20s%-16s",
3215              mp->status ? "enabled" : "disabled",
3216              mp->status ? (char *) mp->locator_set_name : "");
3217     }
3218
3219   vam->retval = retval;
3220   vam->result_ready = 1;
3221 }
3222
3223 static void
3224 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227   vat_json_node_t node;
3228   u8 *status = 0;
3229
3230   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3231   vec_add1 (status, 0);
3232
3233   vat_json_init_object (&node);
3234   vat_json_object_add_string_copy (&node, "status", status);
3235   if (mp->status)
3236     {
3237       vat_json_object_add_string_copy (&node, "locator_set",
3238                                        mp->locator_set_name);
3239     }
3240
3241   vec_free (status);
3242
3243   vat_json_print (vam->ofp, &node);
3244   vat_json_free (&node);
3245
3246   vam->retval = ntohl (mp->retval);
3247   vam->result_ready = 1;
3248 }
3249
3250 static u8 *
3251 format_policer_type (u8 * s, va_list * va)
3252 {
3253   u32 i = va_arg (*va, u32);
3254
3255   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3256     s = format (s, "1r2c");
3257   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3258     s = format (s, "1r3c");
3259   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3260     s = format (s, "2r3c-2698");
3261   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3262     s = format (s, "2r3c-4115");
3263   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3264     s = format (s, "2r3c-mef5cf1");
3265   else
3266     s = format (s, "ILLEGAL");
3267   return s;
3268 }
3269
3270 static u8 *
3271 format_policer_rate_type (u8 * s, va_list * va)
3272 {
3273   u32 i = va_arg (*va, u32);
3274
3275   if (i == SSE2_QOS_RATE_KBPS)
3276     s = format (s, "kbps");
3277   else if (i == SSE2_QOS_RATE_PPS)
3278     s = format (s, "pps");
3279   else
3280     s = format (s, "ILLEGAL");
3281   return s;
3282 }
3283
3284 static u8 *
3285 format_policer_round_type (u8 * s, va_list * va)
3286 {
3287   u32 i = va_arg (*va, u32);
3288
3289   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3290     s = format (s, "closest");
3291   else if (i == SSE2_QOS_ROUND_TO_UP)
3292     s = format (s, "up");
3293   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3294     s = format (s, "down");
3295   else
3296     s = format (s, "ILLEGAL");
3297   return s;
3298 }
3299
3300 static u8 *
3301 format_policer_action_type (u8 * s, va_list * va)
3302 {
3303   u32 i = va_arg (*va, u32);
3304
3305   if (i == SSE2_QOS_ACTION_DROP)
3306     s = format (s, "drop");
3307   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3308     s = format (s, "transmit");
3309   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3310     s = format (s, "mark-and-transmit");
3311   else
3312     s = format (s, "ILLEGAL");
3313   return s;
3314 }
3315
3316 static u8 *
3317 format_dscp (u8 * s, va_list * va)
3318 {
3319   u32 i = va_arg (*va, u32);
3320   char *t = 0;
3321
3322   switch (i)
3323     {
3324 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3325       foreach_vnet_dscp
3326 #undef _
3327     default:
3328       return format (s, "ILLEGAL");
3329     }
3330   s = format (s, "%s", t);
3331   return s;
3332 }
3333
3334 static void
3335 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3336 {
3337   vat_main_t *vam = &vat_main;
3338   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3339
3340   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3341     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3342   else
3343     conform_dscp_str = format (0, "");
3344
3345   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3346     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3347   else
3348     exceed_dscp_str = format (0, "");
3349
3350   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3351     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3352   else
3353     violate_dscp_str = format (0, "");
3354
3355   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3356          "rate type %U, round type %U, %s rate, %s color-aware, "
3357          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3358          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3359          "conform action %U%s, exceed action %U%s, violate action %U%s",
3360          mp->name,
3361          format_policer_type, mp->type,
3362          ntohl (mp->cir),
3363          ntohl (mp->eir),
3364          clib_net_to_host_u64 (mp->cb),
3365          clib_net_to_host_u64 (mp->eb),
3366          format_policer_rate_type, mp->rate_type,
3367          format_policer_round_type, mp->round_type,
3368          mp->single_rate ? "single" : "dual",
3369          mp->color_aware ? "is" : "not",
3370          ntohl (mp->cir_tokens_per_period),
3371          ntohl (mp->pir_tokens_per_period),
3372          ntohl (mp->scale),
3373          ntohl (mp->current_limit),
3374          ntohl (mp->current_bucket),
3375          ntohl (mp->extended_limit),
3376          ntohl (mp->extended_bucket),
3377          clib_net_to_host_u64 (mp->last_update_time),
3378          format_policer_action_type, mp->conform_action_type,
3379          conform_dscp_str,
3380          format_policer_action_type, mp->exceed_action_type,
3381          exceed_dscp_str,
3382          format_policer_action_type, mp->violate_action_type,
3383          violate_dscp_str);
3384
3385   vec_free (conform_dscp_str);
3386   vec_free (exceed_dscp_str);
3387   vec_free (violate_dscp_str);
3388 }
3389
3390 static void vl_api_policer_details_t_handler_json
3391   (vl_api_policer_details_t * mp)
3392 {
3393   vat_main_t *vam = &vat_main;
3394   vat_json_node_t *node;
3395   u8 *rate_type_str, *round_type_str, *type_str;
3396   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3397
3398   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3399   round_type_str =
3400     format (0, "%U", format_policer_round_type, mp->round_type);
3401   type_str = format (0, "%U", format_policer_type, mp->type);
3402   conform_action_str = format (0, "%U", format_policer_action_type,
3403                                mp->conform_action_type);
3404   exceed_action_str = format (0, "%U", format_policer_action_type,
3405                               mp->exceed_action_type);
3406   violate_action_str = format (0, "%U", format_policer_action_type,
3407                                mp->violate_action_type);
3408
3409   if (VAT_JSON_ARRAY != vam->json_tree.type)
3410     {
3411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3412       vat_json_init_array (&vam->json_tree);
3413     }
3414   node = vat_json_array_add (&vam->json_tree);
3415
3416   vat_json_init_object (node);
3417   vat_json_object_add_string_copy (node, "name", mp->name);
3418   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3419   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3420   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3421   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3422   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3423   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3424   vat_json_object_add_string_copy (node, "type", type_str);
3425   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3426   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3427   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3428   vat_json_object_add_uint (node, "cir_tokens_per_period",
3429                             ntohl (mp->cir_tokens_per_period));
3430   vat_json_object_add_uint (node, "eir_tokens_per_period",
3431                             ntohl (mp->pir_tokens_per_period));
3432   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3433   vat_json_object_add_uint (node, "current_bucket",
3434                             ntohl (mp->current_bucket));
3435   vat_json_object_add_uint (node, "extended_limit",
3436                             ntohl (mp->extended_limit));
3437   vat_json_object_add_uint (node, "extended_bucket",
3438                             ntohl (mp->extended_bucket));
3439   vat_json_object_add_uint (node, "last_update_time",
3440                             ntohl (mp->last_update_time));
3441   vat_json_object_add_string_copy (node, "conform_action",
3442                                    conform_action_str);
3443   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3444     {
3445       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3446       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3447       vec_free (dscp_str);
3448     }
3449   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3450   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3451     {
3452       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3453       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3454       vec_free (dscp_str);
3455     }
3456   vat_json_object_add_string_copy (node, "violate_action",
3457                                    violate_action_str);
3458   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3459     {
3460       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3461       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3462       vec_free (dscp_str);
3463     }
3464
3465   vec_free (rate_type_str);
3466   vec_free (round_type_str);
3467   vec_free (type_str);
3468   vec_free (conform_action_str);
3469   vec_free (exceed_action_str);
3470   vec_free (violate_action_str);
3471 }
3472
3473 static void
3474 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3475                                            mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478   int i, count = ntohl (mp->count);
3479
3480   if (count > 0)
3481     print (vam->ofp, "classify table ids (%d) : ", count);
3482   for (i = 0; i < count; i++)
3483     {
3484       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3485       print (vam->ofp, (i < count - 1) ? "," : "");
3486     }
3487   vam->retval = ntohl (mp->retval);
3488   vam->result_ready = 1;
3489 }
3490
3491 static void
3492   vl_api_classify_table_ids_reply_t_handler_json
3493   (vl_api_classify_table_ids_reply_t * mp)
3494 {
3495   vat_main_t *vam = &vat_main;
3496   int i, count = ntohl (mp->count);
3497
3498   if (count > 0)
3499     {
3500       vat_json_node_t node;
3501
3502       vat_json_init_object (&node);
3503       for (i = 0; i < count; i++)
3504         {
3505           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3506         }
3507       vat_json_print (vam->ofp, &node);
3508       vat_json_free (&node);
3509     }
3510   vam->retval = ntohl (mp->retval);
3511   vam->result_ready = 1;
3512 }
3513
3514 static void
3515   vl_api_classify_table_by_interface_reply_t_handler
3516   (vl_api_classify_table_by_interface_reply_t * mp)
3517 {
3518   vat_main_t *vam = &vat_main;
3519   u32 table_id;
3520
3521   table_id = ntohl (mp->l2_table_id);
3522   if (table_id != ~0)
3523     print (vam->ofp, "l2 table id : %d", table_id);
3524   else
3525     print (vam->ofp, "l2 table id : No input ACL tables configured");
3526   table_id = ntohl (mp->ip4_table_id);
3527   if (table_id != ~0)
3528     print (vam->ofp, "ip4 table id : %d", table_id);
3529   else
3530     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3531   table_id = ntohl (mp->ip6_table_id);
3532   if (table_id != ~0)
3533     print (vam->ofp, "ip6 table id : %d", table_id);
3534   else
3535     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3536   vam->retval = ntohl (mp->retval);
3537   vam->result_ready = 1;
3538 }
3539
3540 static void
3541   vl_api_classify_table_by_interface_reply_t_handler_json
3542   (vl_api_classify_table_by_interface_reply_t * mp)
3543 {
3544   vat_main_t *vam = &vat_main;
3545   vat_json_node_t node;
3546
3547   vat_json_init_object (&node);
3548
3549   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3550   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3551   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3552
3553   vat_json_print (vam->ofp, &node);
3554   vat_json_free (&node);
3555
3556   vam->retval = ntohl (mp->retval);
3557   vam->result_ready = 1;
3558 }
3559
3560 static void vl_api_policer_add_del_reply_t_handler
3561   (vl_api_policer_add_del_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   i32 retval = ntohl (mp->retval);
3565   if (vam->async_mode)
3566     {
3567       vam->async_errors += (retval < 0);
3568     }
3569   else
3570     {
3571       vam->retval = retval;
3572       vam->result_ready = 1;
3573       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3574         /*
3575          * Note: this is just barely thread-safe, depends on
3576          * the main thread spinning waiting for an answer...
3577          */
3578         errmsg ("policer index %d", ntohl (mp->policer_index));
3579     }
3580 }
3581
3582 static void vl_api_policer_add_del_reply_t_handler_json
3583   (vl_api_policer_add_del_reply_t * mp)
3584 {
3585   vat_main_t *vam = &vat_main;
3586   vat_json_node_t node;
3587
3588   vat_json_init_object (&node);
3589   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3590   vat_json_object_add_uint (&node, "policer_index",
3591                             ntohl (mp->policer_index));
3592
3593   vat_json_print (vam->ofp, &node);
3594   vat_json_free (&node);
3595
3596   vam->retval = ntohl (mp->retval);
3597   vam->result_ready = 1;
3598 }
3599
3600 /* Format hex dump. */
3601 u8 *
3602 format_hex_bytes (u8 * s, va_list * va)
3603 {
3604   u8 *bytes = va_arg (*va, u8 *);
3605   int n_bytes = va_arg (*va, int);
3606   uword i;
3607
3608   /* Print short or long form depending on byte count. */
3609   uword short_form = n_bytes <= 32;
3610   uword indent = format_get_indent (s);
3611
3612   if (n_bytes == 0)
3613     return s;
3614
3615   for (i = 0; i < n_bytes; i++)
3616     {
3617       if (!short_form && (i % 32) == 0)
3618         s = format (s, "%08x: ", i);
3619       s = format (s, "%02x", bytes[i]);
3620       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3621         s = format (s, "\n%U", format_white_space, indent);
3622     }
3623
3624   return s;
3625 }
3626
3627 static void
3628 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3629                                             * mp)
3630 {
3631   vat_main_t *vam = &vat_main;
3632   i32 retval = ntohl (mp->retval);
3633   if (retval == 0)
3634     {
3635       print (vam->ofp, "classify table info :");
3636       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3637              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3638              ntohl (mp->miss_next_index));
3639       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3640              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3641              ntohl (mp->match_n_vectors));
3642       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3643              ntohl (mp->mask_length));
3644     }
3645   vam->retval = retval;
3646   vam->result_ready = 1;
3647 }
3648
3649 static void
3650   vl_api_classify_table_info_reply_t_handler_json
3651   (vl_api_classify_table_info_reply_t * mp)
3652 {
3653   vat_main_t *vam = &vat_main;
3654   vat_json_node_t node;
3655
3656   i32 retval = ntohl (mp->retval);
3657   if (retval == 0)
3658     {
3659       vat_json_init_object (&node);
3660
3661       vat_json_object_add_int (&node, "sessions",
3662                                ntohl (mp->active_sessions));
3663       vat_json_object_add_int (&node, "nexttbl",
3664                                ntohl (mp->next_table_index));
3665       vat_json_object_add_int (&node, "nextnode",
3666                                ntohl (mp->miss_next_index));
3667       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3668       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3669       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3670       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3671                       ntohl (mp->mask_length), 0);
3672       vat_json_object_add_string_copy (&node, "mask", s);
3673
3674       vat_json_print (vam->ofp, &node);
3675       vat_json_free (&node);
3676     }
3677   vam->retval = ntohl (mp->retval);
3678   vam->result_ready = 1;
3679 }
3680
3681 static void
3682 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3683                                            mp)
3684 {
3685   vat_main_t *vam = &vat_main;
3686
3687   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3688          ntohl (mp->hit_next_index), ntohl (mp->advance),
3689          ntohl (mp->opaque_index));
3690   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3691          ntohl (mp->match_length));
3692 }
3693
3694 static void
3695   vl_api_classify_session_details_t_handler_json
3696   (vl_api_classify_session_details_t * mp)
3697 {
3698   vat_main_t *vam = &vat_main;
3699   vat_json_node_t *node = NULL;
3700
3701   if (VAT_JSON_ARRAY != vam->json_tree.type)
3702     {
3703       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3704       vat_json_init_array (&vam->json_tree);
3705     }
3706   node = vat_json_array_add (&vam->json_tree);
3707
3708   vat_json_init_object (node);
3709   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3710   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3711   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3712   u8 *s =
3713     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3714             0);
3715   vat_json_object_add_string_copy (node, "match", s);
3716 }
3717
3718 static void vl_api_pg_create_interface_reply_t_handler
3719   (vl_api_pg_create_interface_reply_t * mp)
3720 {
3721   vat_main_t *vam = &vat_main;
3722
3723   vam->retval = ntohl (mp->retval);
3724   vam->result_ready = 1;
3725 }
3726
3727 static void vl_api_pg_create_interface_reply_t_handler_json
3728   (vl_api_pg_create_interface_reply_t * mp)
3729 {
3730   vat_main_t *vam = &vat_main;
3731   vat_json_node_t node;
3732
3733   i32 retval = ntohl (mp->retval);
3734   if (retval == 0)
3735     {
3736       vat_json_init_object (&node);
3737
3738       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3739
3740       vat_json_print (vam->ofp, &node);
3741       vat_json_free (&node);
3742     }
3743   vam->retval = ntohl (mp->retval);
3744   vam->result_ready = 1;
3745 }
3746
3747 static void vl_api_policer_classify_details_t_handler
3748   (vl_api_policer_classify_details_t * mp)
3749 {
3750   vat_main_t *vam = &vat_main;
3751
3752   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3753          ntohl (mp->table_index));
3754 }
3755
3756 static void vl_api_policer_classify_details_t_handler_json
3757   (vl_api_policer_classify_details_t * mp)
3758 {
3759   vat_main_t *vam = &vat_main;
3760   vat_json_node_t *node;
3761
3762   if (VAT_JSON_ARRAY != vam->json_tree.type)
3763     {
3764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3765       vat_json_init_array (&vam->json_tree);
3766     }
3767   node = vat_json_array_add (&vam->json_tree);
3768
3769   vat_json_init_object (node);
3770   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3771   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3772 }
3773
3774 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3775   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3776 {
3777   vat_main_t *vam = &vat_main;
3778   i32 retval = ntohl (mp->retval);
3779   if (vam->async_mode)
3780     {
3781       vam->async_errors += (retval < 0);
3782     }
3783   else
3784     {
3785       vam->retval = retval;
3786       vam->sw_if_index = ntohl (mp->sw_if_index);
3787       vam->result_ready = 1;
3788     }
3789 }
3790
3791 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3792   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3793 {
3794   vat_main_t *vam = &vat_main;
3795   vat_json_node_t node;
3796
3797   vat_json_init_object (&node);
3798   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3799   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3800
3801   vat_json_print (vam->ofp, &node);
3802   vat_json_free (&node);
3803
3804   vam->retval = ntohl (mp->retval);
3805   vam->result_ready = 1;
3806 }
3807
3808 static void vl_api_flow_classify_details_t_handler
3809   (vl_api_flow_classify_details_t * mp)
3810 {
3811   vat_main_t *vam = &vat_main;
3812
3813   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3814          ntohl (mp->table_index));
3815 }
3816
3817 static void vl_api_flow_classify_details_t_handler_json
3818   (vl_api_flow_classify_details_t * mp)
3819 {
3820   vat_main_t *vam = &vat_main;
3821   vat_json_node_t *node;
3822
3823   if (VAT_JSON_ARRAY != vam->json_tree.type)
3824     {
3825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3826       vat_json_init_array (&vam->json_tree);
3827     }
3828   node = vat_json_array_add (&vam->json_tree);
3829
3830   vat_json_init_object (node);
3831   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3832   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3833 }
3834
3835
3836
3837 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3838 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3839 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3840 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3841 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3842 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3843 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3844 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3845 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3846 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3847
3848 /*
3849  * Generate boilerplate reply handlers, which
3850  * dig the return value out of the xxx_reply_t API message,
3851  * stick it into vam->retval, and set vam->result_ready
3852  *
3853  * Could also do this by pointing N message decode slots at
3854  * a single function, but that could break in subtle ways.
3855  */
3856
3857 #define foreach_standard_reply_retval_handler           \
3858 _(sw_interface_set_flags_reply)                         \
3859 _(sw_interface_add_del_address_reply)                   \
3860 _(sw_interface_set_table_reply)                         \
3861 _(sw_interface_set_mpls_enable_reply)                   \
3862 _(sw_interface_set_vpath_reply)                         \
3863 _(sw_interface_set_vxlan_bypass_reply)                  \
3864 _(sw_interface_set_l2_bridge_reply)                     \
3865 _(bridge_domain_add_del_reply)                          \
3866 _(sw_interface_set_l2_xconnect_reply)                   \
3867 _(l2fib_add_del_reply)                                  \
3868 _(ip_add_del_route_reply)                               \
3869 _(ip_mroute_add_del_reply)                              \
3870 _(mpls_route_add_del_reply)                             \
3871 _(mpls_ip_bind_unbind_reply)                            \
3872 _(proxy_arp_add_del_reply)                              \
3873 _(proxy_arp_intfc_enable_disable_reply)                 \
3874 _(sw_interface_set_unnumbered_reply)                    \
3875 _(ip_neighbor_add_del_reply)                            \
3876 _(reset_vrf_reply)                                      \
3877 _(oam_add_del_reply)                                    \
3878 _(reset_fib_reply)                                      \
3879 _(dhcp_proxy_config_reply)                              \
3880 _(dhcp_proxy_set_vss_reply)                             \
3881 _(dhcp_client_config_reply)                             \
3882 _(set_ip_flow_hash_reply)                               \
3883 _(sw_interface_ip6_enable_disable_reply)                \
3884 _(sw_interface_ip6_set_link_local_address_reply)        \
3885 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3886 _(sw_interface_ip6nd_ra_config_reply)                   \
3887 _(set_arp_neighbor_limit_reply)                         \
3888 _(l2_patch_add_del_reply)                               \
3889 _(sr_tunnel_add_del_reply)                              \
3890 _(sr_policy_add_del_reply)                              \
3891 _(sr_multicast_map_add_del_reply)                       \
3892 _(classify_add_del_session_reply)                       \
3893 _(classify_set_interface_ip_table_reply)                \
3894 _(classify_set_interface_l2_tables_reply)               \
3895 _(l2tpv3_set_tunnel_cookies_reply)                      \
3896 _(l2tpv3_interface_enable_disable_reply)                \
3897 _(l2tpv3_set_lookup_key_reply)                          \
3898 _(l2_fib_clear_table_reply)                             \
3899 _(l2_interface_efp_filter_reply)                        \
3900 _(l2_interface_vlan_tag_rewrite_reply)                  \
3901 _(modify_vhost_user_if_reply)                           \
3902 _(delete_vhost_user_if_reply)                           \
3903 _(want_ip4_arp_events_reply)                            \
3904 _(want_ip6_nd_events_reply)                             \
3905 _(input_acl_set_interface_reply)                        \
3906 _(ipsec_spd_add_del_reply)                              \
3907 _(ipsec_interface_add_del_spd_reply)                    \
3908 _(ipsec_spd_add_del_entry_reply)                        \
3909 _(ipsec_sad_add_del_entry_reply)                        \
3910 _(ipsec_sa_set_key_reply)                               \
3911 _(ikev2_profile_add_del_reply)                          \
3912 _(ikev2_profile_set_auth_reply)                         \
3913 _(ikev2_profile_set_id_reply)                           \
3914 _(ikev2_profile_set_ts_reply)                           \
3915 _(ikev2_set_local_key_reply)                            \
3916 _(ikev2_set_responder_reply)                            \
3917 _(ikev2_set_ike_transforms_reply)                       \
3918 _(ikev2_set_esp_transforms_reply)                       \
3919 _(ikev2_set_sa_lifetime_reply)                          \
3920 _(ikev2_initiate_sa_init_reply)                         \
3921 _(ikev2_initiate_del_ike_sa_reply)                      \
3922 _(ikev2_initiate_del_child_sa_reply)                    \
3923 _(ikev2_initiate_rekey_child_sa_reply)                  \
3924 _(delete_loopback_reply)                                \
3925 _(bd_ip_mac_add_del_reply)                              \
3926 _(map_del_domain_reply)                                 \
3927 _(map_add_del_rule_reply)                               \
3928 _(want_interface_events_reply)                          \
3929 _(want_stats_reply)                                     \
3930 _(cop_interface_enable_disable_reply)                   \
3931 _(cop_whitelist_enable_disable_reply)                   \
3932 _(sw_interface_clear_stats_reply)                       \
3933 _(ioam_enable_reply)                              \
3934 _(ioam_disable_reply)                              \
3935 _(one_add_del_locator_reply)                            \
3936 _(one_add_del_local_eid_reply)                          \
3937 _(one_add_del_remote_mapping_reply)                     \
3938 _(one_add_del_adjacency_reply)                          \
3939 _(one_add_del_map_resolver_reply)                       \
3940 _(one_add_del_map_server_reply)                         \
3941 _(one_enable_disable_reply)                             \
3942 _(one_rloc_probe_enable_disable_reply)                  \
3943 _(one_map_register_enable_disable_reply)                \
3944 _(one_pitr_set_locator_set_reply)                       \
3945 _(one_map_request_mode_reply)                           \
3946 _(one_add_del_map_request_itr_rlocs_reply)              \
3947 _(one_eid_table_add_del_map_reply)                      \
3948 _(gpe_add_del_fwd_entry_reply)                          \
3949 _(gpe_enable_disable_reply)                             \
3950 _(gpe_set_encap_mode_reply)                             \
3951 _(gpe_add_del_iface_reply)                              \
3952 _(vxlan_gpe_add_del_tunnel_reply)                       \
3953 _(af_packet_delete_reply)                               \
3954 _(policer_classify_set_interface_reply)                 \
3955 _(netmap_create_reply)                                  \
3956 _(netmap_delete_reply)                                  \
3957 _(set_ipfix_exporter_reply)                             \
3958 _(set_ipfix_classify_stream_reply)                      \
3959 _(ipfix_classify_table_add_del_reply)                   \
3960 _(flow_classify_set_interface_reply)                    \
3961 _(sw_interface_span_enable_disable_reply)               \
3962 _(pg_capture_reply)                                     \
3963 _(pg_enable_disable_reply)                              \
3964 _(ip_source_and_port_range_check_add_del_reply)         \
3965 _(ip_source_and_port_range_check_interface_add_del_reply)\
3966 _(delete_subif_reply)                                   \
3967 _(l2_interface_pbb_tag_rewrite_reply)                   \
3968 _(punt_reply)                                           \
3969 _(feature_enable_disable_reply)                         \
3970 _(sw_interface_tag_add_del_reply)                       \
3971 _(sw_interface_set_mtu_reply)
3972
3973 #define _(n)                                    \
3974     static void vl_api_##n##_t_handler          \
3975     (vl_api_##n##_t * mp)                       \
3976     {                                           \
3977         vat_main_t * vam = &vat_main;           \
3978         i32 retval = ntohl(mp->retval);         \
3979         if (vam->async_mode) {                  \
3980             vam->async_errors += (retval < 0);  \
3981         } else {                                \
3982             vam->retval = retval;               \
3983             vam->result_ready = 1;              \
3984         }                                       \
3985     }
3986 foreach_standard_reply_retval_handler;
3987 #undef _
3988
3989 #define _(n)                                    \
3990     static void vl_api_##n##_t_handler_json     \
3991     (vl_api_##n##_t * mp)                       \
3992     {                                           \
3993         vat_main_t * vam = &vat_main;           \
3994         vat_json_node_t node;                   \
3995         vat_json_init_object(&node);            \
3996         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3997         vat_json_print(vam->ofp, &node);        \
3998         vam->retval = ntohl(mp->retval);        \
3999         vam->result_ready = 1;                  \
4000     }
4001 foreach_standard_reply_retval_handler;
4002 #undef _
4003
4004 /*
4005  * Table of message reply handlers, must include boilerplate handlers
4006  * we just generated
4007  */
4008
4009 #define foreach_vpe_api_reply_msg                                       \
4010 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4011 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4012 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4013 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4014 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4015 _(CLI_REPLY, cli_reply)                                                 \
4016 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4017 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4018   sw_interface_add_del_address_reply)                                   \
4019 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4020 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4021 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4022 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4023 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4024   sw_interface_set_l2_xconnect_reply)                                   \
4025 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4026   sw_interface_set_l2_bridge_reply)                                     \
4027 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4028 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4029 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4030 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4031 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4032 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4033 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4034 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4035 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4036 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4037 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4038 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4039 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4040 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4041 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4042 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4043   proxy_arp_intfc_enable_disable_reply)                                 \
4044 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4045 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4046   sw_interface_set_unnumbered_reply)                                    \
4047 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4048 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4049 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4050 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4051 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4052 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4053 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4054 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4055 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4056 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4057 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4058 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4059   sw_interface_ip6_enable_disable_reply)                                \
4060 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4061   sw_interface_ip6_set_link_local_address_reply)                        \
4062 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4063   sw_interface_ip6nd_ra_prefix_reply)                                   \
4064 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4065   sw_interface_ip6nd_ra_config_reply)                                   \
4066 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4067 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4068 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4069 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4070 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4071 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4072 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4073 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4074 classify_set_interface_ip_table_reply)                                  \
4075 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4076   classify_set_interface_l2_tables_reply)                               \
4077 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4078 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4079 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4080 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4081 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4082   l2tpv3_interface_enable_disable_reply)                                \
4083 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4084 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4085 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4086 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4087 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4088 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4089 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4090 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4091 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4092 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4093 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4094 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4095 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4096 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4097 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4098 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4099 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4100 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4101 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4102 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4103 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4104 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4105 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4106 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4107 _(IP_DETAILS, ip_details)                                               \
4108 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4109 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4110 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4111 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4112 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4113 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4114 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4115 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4116 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4117 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4118 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4119 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4120 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4121 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4122 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4123 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4124 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4125 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4126 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4127 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4128 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4129 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4130 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4131 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4132 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4133 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
4134 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4135 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4136 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4137 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4138 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4139 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4140 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4141 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4142 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4143 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4144 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4145 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4146 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4147 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4148 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4149 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4150 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4151 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4152 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4153 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4154 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4155 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4156 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4157   one_map_register_enable_disable_reply)                                \
4158 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4159   one_rloc_probe_enable_disable_reply)                                  \
4160 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4161 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4162 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4163 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4164 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4165 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4166 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4167 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4168 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4169 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4170 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4171 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4172 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4173 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4174 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4175 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4176 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4177 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4178   gpe_fwd_entry_path_details)                                           \
4179 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4180 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4181   one_add_del_map_request_itr_rlocs_reply)                              \
4182 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4183   one_get_map_request_itr_rlocs_reply)                                  \
4184 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4185 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4186 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4187 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4188   show_one_map_register_state_reply)                                    \
4189 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4190 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4191 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4192 _(POLICER_DETAILS, policer_details)                                     \
4193 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4194 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4195 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4196 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4197 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4198 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4199 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4200 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4201 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4202 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4203 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4204 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4205 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4206 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4207 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4208 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4209 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4210 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4211 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4212 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4213 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4214 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4215 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4216 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4217 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4218  ip_source_and_port_range_check_add_del_reply)                          \
4219 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4220  ip_source_and_port_range_check_interface_add_del_reply)                \
4221 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4222 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4223 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4224 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4225 _(PUNT_REPLY, punt_reply)                                               \
4226 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4227 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4228 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4229 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4230 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4231 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4232 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4233 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4234
4235 typedef struct
4236 {
4237   u8 *name;
4238   u32 value;
4239 } name_sort_t;
4240
4241
4242 #define STR_VTR_OP_CASE(op)     \
4243     case L2_VTR_ ## op:         \
4244         return "" # op;
4245
4246 static const char *
4247 str_vtr_op (u32 vtr_op)
4248 {
4249   switch (vtr_op)
4250     {
4251       STR_VTR_OP_CASE (DISABLED);
4252       STR_VTR_OP_CASE (PUSH_1);
4253       STR_VTR_OP_CASE (PUSH_2);
4254       STR_VTR_OP_CASE (POP_1);
4255       STR_VTR_OP_CASE (POP_2);
4256       STR_VTR_OP_CASE (TRANSLATE_1_1);
4257       STR_VTR_OP_CASE (TRANSLATE_1_2);
4258       STR_VTR_OP_CASE (TRANSLATE_2_1);
4259       STR_VTR_OP_CASE (TRANSLATE_2_2);
4260     }
4261
4262   return "UNKNOWN";
4263 }
4264
4265 static int
4266 dump_sub_interface_table (vat_main_t * vam)
4267 {
4268   const sw_interface_subif_t *sub = NULL;
4269
4270   if (vam->json_output)
4271     {
4272       clib_warning
4273         ("JSON output supported only for VPE API calls and dump_stats_table");
4274       return -99;
4275     }
4276
4277   print (vam->ofp,
4278          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4279          "Interface", "sw_if_index",
4280          "sub id", "dot1ad", "tags", "outer id",
4281          "inner id", "exact", "default", "outer any", "inner any");
4282
4283   vec_foreach (sub, vam->sw_if_subif_table)
4284   {
4285     print (vam->ofp,
4286            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4287            sub->interface_name,
4288            sub->sw_if_index,
4289            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4290            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4291            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4292            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4293     if (sub->vtr_op != L2_VTR_DISABLED)
4294       {
4295         print (vam->ofp,
4296                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4297                "tag1: %d tag2: %d ]",
4298                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4299                sub->vtr_tag1, sub->vtr_tag2);
4300       }
4301   }
4302
4303   return 0;
4304 }
4305
4306 static int
4307 name_sort_cmp (void *a1, void *a2)
4308 {
4309   name_sort_t *n1 = a1;
4310   name_sort_t *n2 = a2;
4311
4312   return strcmp ((char *) n1->name, (char *) n2->name);
4313 }
4314
4315 static int
4316 dump_interface_table (vat_main_t * vam)
4317 {
4318   hash_pair_t *p;
4319   name_sort_t *nses = 0, *ns;
4320
4321   if (vam->json_output)
4322     {
4323       clib_warning
4324         ("JSON output supported only for VPE API calls and dump_stats_table");
4325       return -99;
4326     }
4327
4328   /* *INDENT-OFF* */
4329   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4330   ({
4331     vec_add2 (nses, ns, 1);
4332     ns->name = (u8 *)(p->key);
4333     ns->value = (u32) p->value[0];
4334   }));
4335   /* *INDENT-ON* */
4336
4337   vec_sort_with_function (nses, name_sort_cmp);
4338
4339   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4340   vec_foreach (ns, nses)
4341   {
4342     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4343   }
4344   vec_free (nses);
4345   return 0;
4346 }
4347
4348 static int
4349 dump_ip_table (vat_main_t * vam, int is_ipv6)
4350 {
4351   const ip_details_t *det = NULL;
4352   const ip_address_details_t *address = NULL;
4353   u32 i = ~0;
4354
4355   print (vam->ofp, "%-12s", "sw_if_index");
4356
4357   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4358   {
4359     i++;
4360     if (!det->present)
4361       {
4362         continue;
4363       }
4364     print (vam->ofp, "%-12d", i);
4365     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4366     if (!det->addr)
4367       {
4368         continue;
4369       }
4370     vec_foreach (address, det->addr)
4371     {
4372       print (vam->ofp,
4373              "            %-30U%-13d",
4374              is_ipv6 ? format_ip6_address : format_ip4_address,
4375              address->ip, address->prefix_length);
4376     }
4377   }
4378
4379   return 0;
4380 }
4381
4382 static int
4383 dump_ipv4_table (vat_main_t * vam)
4384 {
4385   if (vam->json_output)
4386     {
4387       clib_warning
4388         ("JSON output supported only for VPE API calls and dump_stats_table");
4389       return -99;
4390     }
4391
4392   return dump_ip_table (vam, 0);
4393 }
4394
4395 static int
4396 dump_ipv6_table (vat_main_t * vam)
4397 {
4398   if (vam->json_output)
4399     {
4400       clib_warning
4401         ("JSON output supported only for VPE API calls and dump_stats_table");
4402       return -99;
4403     }
4404
4405   return dump_ip_table (vam, 1);
4406 }
4407
4408 static char *
4409 counter_type_to_str (u8 counter_type, u8 is_combined)
4410 {
4411   if (!is_combined)
4412     {
4413       switch (counter_type)
4414         {
4415         case VNET_INTERFACE_COUNTER_DROP:
4416           return "drop";
4417         case VNET_INTERFACE_COUNTER_PUNT:
4418           return "punt";
4419         case VNET_INTERFACE_COUNTER_IP4:
4420           return "ip4";
4421         case VNET_INTERFACE_COUNTER_IP6:
4422           return "ip6";
4423         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4424           return "rx-no-buf";
4425         case VNET_INTERFACE_COUNTER_RX_MISS:
4426           return "rx-miss";
4427         case VNET_INTERFACE_COUNTER_RX_ERROR:
4428           return "rx-error";
4429         case VNET_INTERFACE_COUNTER_TX_ERROR:
4430           return "tx-error";
4431         default:
4432           return "INVALID-COUNTER-TYPE";
4433         }
4434     }
4435   else
4436     {
4437       switch (counter_type)
4438         {
4439         case VNET_INTERFACE_COUNTER_RX:
4440           return "rx";
4441         case VNET_INTERFACE_COUNTER_TX:
4442           return "tx";
4443         default:
4444           return "INVALID-COUNTER-TYPE";
4445         }
4446     }
4447 }
4448
4449 static int
4450 dump_stats_table (vat_main_t * vam)
4451 {
4452   vat_json_node_t node;
4453   vat_json_node_t *msg_array;
4454   vat_json_node_t *msg;
4455   vat_json_node_t *counter_array;
4456   vat_json_node_t *counter;
4457   interface_counter_t c;
4458   u64 packets;
4459   ip4_fib_counter_t *c4;
4460   ip6_fib_counter_t *c6;
4461   ip4_nbr_counter_t *n4;
4462   ip6_nbr_counter_t *n6;
4463   int i, j;
4464
4465   if (!vam->json_output)
4466     {
4467       clib_warning ("dump_stats_table supported only in JSON format");
4468       return -99;
4469     }
4470
4471   vat_json_init_object (&node);
4472
4473   /* interface counters */
4474   msg_array = vat_json_object_add (&node, "interface_counters");
4475   vat_json_init_array (msg_array);
4476   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4477     {
4478       msg = vat_json_array_add (msg_array);
4479       vat_json_init_object (msg);
4480       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4481                                        (u8 *) counter_type_to_str (i, 0));
4482       vat_json_object_add_int (msg, "is_combined", 0);
4483       counter_array = vat_json_object_add (msg, "data");
4484       vat_json_init_array (counter_array);
4485       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4486         {
4487           packets = vam->simple_interface_counters[i][j];
4488           vat_json_array_add_uint (counter_array, packets);
4489         }
4490     }
4491   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4492     {
4493       msg = vat_json_array_add (msg_array);
4494       vat_json_init_object (msg);
4495       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4496                                        (u8 *) counter_type_to_str (i, 1));
4497       vat_json_object_add_int (msg, "is_combined", 1);
4498       counter_array = vat_json_object_add (msg, "data");
4499       vat_json_init_array (counter_array);
4500       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4501         {
4502           c = vam->combined_interface_counters[i][j];
4503           counter = vat_json_array_add (counter_array);
4504           vat_json_init_object (counter);
4505           vat_json_object_add_uint (counter, "packets", c.packets);
4506           vat_json_object_add_uint (counter, "bytes", c.bytes);
4507         }
4508     }
4509
4510   /* ip4 fib counters */
4511   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4512   vat_json_init_array (msg_array);
4513   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4514     {
4515       msg = vat_json_array_add (msg_array);
4516       vat_json_init_object (msg);
4517       vat_json_object_add_uint (msg, "vrf_id",
4518                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4519       counter_array = vat_json_object_add (msg, "c");
4520       vat_json_init_array (counter_array);
4521       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4522         {
4523           counter = vat_json_array_add (counter_array);
4524           vat_json_init_object (counter);
4525           c4 = &vam->ip4_fib_counters[i][j];
4526           vat_json_object_add_ip4 (counter, "address", c4->address);
4527           vat_json_object_add_uint (counter, "address_length",
4528                                     c4->address_length);
4529           vat_json_object_add_uint (counter, "packets", c4->packets);
4530           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4531         }
4532     }
4533
4534   /* ip6 fib counters */
4535   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4536   vat_json_init_array (msg_array);
4537   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4538     {
4539       msg = vat_json_array_add (msg_array);
4540       vat_json_init_object (msg);
4541       vat_json_object_add_uint (msg, "vrf_id",
4542                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4543       counter_array = vat_json_object_add (msg, "c");
4544       vat_json_init_array (counter_array);
4545       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4546         {
4547           counter = vat_json_array_add (counter_array);
4548           vat_json_init_object (counter);
4549           c6 = &vam->ip6_fib_counters[i][j];
4550           vat_json_object_add_ip6 (counter, "address", c6->address);
4551           vat_json_object_add_uint (counter, "address_length",
4552                                     c6->address_length);
4553           vat_json_object_add_uint (counter, "packets", c6->packets);
4554           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4555         }
4556     }
4557
4558   /* ip4 nbr counters */
4559   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4560   vat_json_init_array (msg_array);
4561   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4562     {
4563       msg = vat_json_array_add (msg_array);
4564       vat_json_init_object (msg);
4565       vat_json_object_add_uint (msg, "sw_if_index", i);
4566       counter_array = vat_json_object_add (msg, "c");
4567       vat_json_init_array (counter_array);
4568       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4569         {
4570           counter = vat_json_array_add (counter_array);
4571           vat_json_init_object (counter);
4572           n4 = &vam->ip4_nbr_counters[i][j];
4573           vat_json_object_add_ip4 (counter, "address", n4->address);
4574           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4575           vat_json_object_add_uint (counter, "packets", n4->packets);
4576           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4577         }
4578     }
4579
4580   /* ip6 nbr counters */
4581   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4582   vat_json_init_array (msg_array);
4583   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4584     {
4585       msg = vat_json_array_add (msg_array);
4586       vat_json_init_object (msg);
4587       vat_json_object_add_uint (msg, "sw_if_index", i);
4588       counter_array = vat_json_object_add (msg, "c");
4589       vat_json_init_array (counter_array);
4590       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4591         {
4592           counter = vat_json_array_add (counter_array);
4593           vat_json_init_object (counter);
4594           n6 = &vam->ip6_nbr_counters[i][j];
4595           vat_json_object_add_ip6 (counter, "address", n6->address);
4596           vat_json_object_add_uint (counter, "packets", n6->packets);
4597           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4598         }
4599     }
4600
4601   vat_json_print (vam->ofp, &node);
4602   vat_json_free (&node);
4603
4604   return 0;
4605 }
4606
4607 int
4608 exec (vat_main_t * vam)
4609 {
4610   api_main_t *am = &api_main;
4611   vl_api_cli_request_t *mp;
4612   f64 timeout;
4613   void *oldheap;
4614   u8 *cmd = 0;
4615   unformat_input_t *i = vam->input;
4616
4617   if (vec_len (i->buffer) == 0)
4618     return -1;
4619
4620   if (vam->exec_mode == 0 && unformat (i, "mode"))
4621     {
4622       vam->exec_mode = 1;
4623       return 0;
4624     }
4625   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4626     {
4627       vam->exec_mode = 0;
4628       return 0;
4629     }
4630
4631
4632   M (CLI_REQUEST, mp);
4633
4634   /*
4635    * Copy cmd into shared memory.
4636    * In order for the CLI command to work, it
4637    * must be a vector ending in \n, not a C-string ending
4638    * in \n\0.
4639    */
4640   pthread_mutex_lock (&am->vlib_rp->mutex);
4641   oldheap = svm_push_data_heap (am->vlib_rp);
4642
4643   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4644   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4645
4646   svm_pop_heap (oldheap);
4647   pthread_mutex_unlock (&am->vlib_rp->mutex);
4648
4649   mp->cmd_in_shmem = (u64) cmd;
4650   S (mp);
4651   timeout = vat_time_now (vam) + 10.0;
4652
4653   while (vat_time_now (vam) < timeout)
4654     {
4655       if (vam->result_ready == 1)
4656         {
4657           u8 *free_me;
4658           if (vam->shmem_result != NULL)
4659             print (vam->ofp, "%s", vam->shmem_result);
4660           pthread_mutex_lock (&am->vlib_rp->mutex);
4661           oldheap = svm_push_data_heap (am->vlib_rp);
4662
4663           free_me = (u8 *) vam->shmem_result;
4664           vec_free (free_me);
4665
4666           svm_pop_heap (oldheap);
4667           pthread_mutex_unlock (&am->vlib_rp->mutex);
4668           return 0;
4669         }
4670     }
4671   return -99;
4672 }
4673
4674 /*
4675  * Future replacement of exec() that passes CLI buffers directly in
4676  * the API messages instead of an additional shared memory area.
4677  */
4678 static int
4679 exec_inband (vat_main_t * vam)
4680 {
4681   vl_api_cli_inband_t *mp;
4682   unformat_input_t *i = vam->input;
4683   int ret;
4684
4685   if (vec_len (i->buffer) == 0)
4686     return -1;
4687
4688   if (vam->exec_mode == 0 && unformat (i, "mode"))
4689     {
4690       vam->exec_mode = 1;
4691       return 0;
4692     }
4693   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4694     {
4695       vam->exec_mode = 0;
4696       return 0;
4697     }
4698
4699   /*
4700    * In order for the CLI command to work, it
4701    * must be a vector ending in \n, not a C-string ending
4702    * in \n\0.
4703    */
4704   u32 len = vec_len (vam->input->buffer);
4705   M2 (CLI_INBAND, mp, len);
4706   clib_memcpy (mp->cmd, vam->input->buffer, len);
4707   mp->length = htonl (len);
4708
4709   S (mp);
4710   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4711   return ret;
4712 }
4713
4714 static int
4715 api_create_loopback (vat_main_t * vam)
4716 {
4717   unformat_input_t *i = vam->input;
4718   vl_api_create_loopback_t *mp;
4719   u8 mac_address[6];
4720   u8 mac_set = 0;
4721   int ret;
4722
4723   memset (mac_address, 0, sizeof (mac_address));
4724
4725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4726     {
4727       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4728         mac_set = 1;
4729       else
4730         break;
4731     }
4732
4733   /* Construct the API message */
4734   M (CREATE_LOOPBACK, mp);
4735   if (mac_set)
4736     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4737
4738   S (mp);
4739   W (ret);
4740   return ret;
4741 }
4742
4743 static int
4744 api_delete_loopback (vat_main_t * vam)
4745 {
4746   unformat_input_t *i = vam->input;
4747   vl_api_delete_loopback_t *mp;
4748   u32 sw_if_index = ~0;
4749   int ret;
4750
4751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4752     {
4753       if (unformat (i, "sw_if_index %d", &sw_if_index))
4754         ;
4755       else
4756         break;
4757     }
4758
4759   if (sw_if_index == ~0)
4760     {
4761       errmsg ("missing sw_if_index");
4762       return -99;
4763     }
4764
4765   /* Construct the API message */
4766   M (DELETE_LOOPBACK, mp);
4767   mp->sw_if_index = ntohl (sw_if_index);
4768
4769   S (mp);
4770   W (ret);
4771   return ret;
4772 }
4773
4774 static int
4775 api_want_stats (vat_main_t * vam)
4776 {
4777   unformat_input_t *i = vam->input;
4778   vl_api_want_stats_t *mp;
4779   int enable = -1;
4780   int ret;
4781
4782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4783     {
4784       if (unformat (i, "enable"))
4785         enable = 1;
4786       else if (unformat (i, "disable"))
4787         enable = 0;
4788       else
4789         break;
4790     }
4791
4792   if (enable == -1)
4793     {
4794       errmsg ("missing enable|disable");
4795       return -99;
4796     }
4797
4798   M (WANT_STATS, mp);
4799   mp->enable_disable = enable;
4800
4801   S (mp);
4802   W (ret);
4803   return ret;
4804 }
4805
4806 static int
4807 api_want_interface_events (vat_main_t * vam)
4808 {
4809   unformat_input_t *i = vam->input;
4810   vl_api_want_interface_events_t *mp;
4811   int enable = -1;
4812   int ret;
4813
4814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4815     {
4816       if (unformat (i, "enable"))
4817         enable = 1;
4818       else if (unformat (i, "disable"))
4819         enable = 0;
4820       else
4821         break;
4822     }
4823
4824   if (enable == -1)
4825     {
4826       errmsg ("missing enable|disable");
4827       return -99;
4828     }
4829
4830   M (WANT_INTERFACE_EVENTS, mp);
4831   mp->enable_disable = enable;
4832
4833   vam->interface_event_display = enable;
4834
4835   S (mp);
4836   W (ret);
4837   return ret;
4838 }
4839
4840
4841 /* Note: non-static, called once to set up the initial intfc table */
4842 int
4843 api_sw_interface_dump (vat_main_t * vam)
4844 {
4845   vl_api_sw_interface_dump_t *mp;
4846   vl_api_control_ping_t *mp_ping;
4847   hash_pair_t *p;
4848   name_sort_t *nses = 0, *ns;
4849   sw_interface_subif_t *sub = NULL;
4850   int ret;
4851
4852   /* Toss the old name table */
4853   /* *INDENT-OFF* */
4854   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4855   ({
4856     vec_add2 (nses, ns, 1);
4857     ns->name = (u8 *)(p->key);
4858     ns->value = (u32) p->value[0];
4859   }));
4860   /* *INDENT-ON* */
4861
4862   hash_free (vam->sw_if_index_by_interface_name);
4863
4864   vec_foreach (ns, nses) vec_free (ns->name);
4865
4866   vec_free (nses);
4867
4868   vec_foreach (sub, vam->sw_if_subif_table)
4869   {
4870     vec_free (sub->interface_name);
4871   }
4872   vec_free (vam->sw_if_subif_table);
4873
4874   /* recreate the interface name hash table */
4875   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4876
4877   /* Get list of ethernets */
4878   M (SW_INTERFACE_DUMP, mp);
4879   mp->name_filter_valid = 1;
4880   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4881   S (mp);
4882
4883   /* and local / loopback interfaces */
4884   M (SW_INTERFACE_DUMP, mp);
4885   mp->name_filter_valid = 1;
4886   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4887   S (mp);
4888
4889   /* and packet-generator interfaces */
4890   M (SW_INTERFACE_DUMP, mp);
4891   mp->name_filter_valid = 1;
4892   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4893   S (mp);
4894
4895   /* and vxlan-gpe tunnel interfaces */
4896   M (SW_INTERFACE_DUMP, mp);
4897   mp->name_filter_valid = 1;
4898   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4899            sizeof (mp->name_filter) - 1);
4900   S (mp);
4901
4902   /* and vxlan tunnel interfaces */
4903   M (SW_INTERFACE_DUMP, mp);
4904   mp->name_filter_valid = 1;
4905   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4906   S (mp);
4907
4908   /* and host (af_packet) interfaces */
4909   M (SW_INTERFACE_DUMP, mp);
4910   mp->name_filter_valid = 1;
4911   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4912   S (mp);
4913
4914   /* and l2tpv3 tunnel interfaces */
4915   M (SW_INTERFACE_DUMP, mp);
4916   mp->name_filter_valid = 1;
4917   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4918            sizeof (mp->name_filter) - 1);
4919   S (mp);
4920
4921   /* and GRE tunnel interfaces */
4922   M (SW_INTERFACE_DUMP, mp);
4923   mp->name_filter_valid = 1;
4924   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4925   S (mp);
4926
4927   /* and LISP-GPE interfaces */
4928   M (SW_INTERFACE_DUMP, mp);
4929   mp->name_filter_valid = 1;
4930   strncpy ((char *) mp->name_filter, "lisp_gpe",
4931            sizeof (mp->name_filter) - 1);
4932   S (mp);
4933
4934   /* and IPSEC tunnel interfaces */
4935   M (SW_INTERFACE_DUMP, mp);
4936   mp->name_filter_valid = 1;
4937   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4938   S (mp);
4939
4940   /* Use a control ping for synchronization */
4941   M (CONTROL_PING, mp_ping);
4942   S (mp_ping);
4943
4944   W (ret);
4945   return ret;
4946 }
4947
4948 static int
4949 api_sw_interface_set_flags (vat_main_t * vam)
4950 {
4951   unformat_input_t *i = vam->input;
4952   vl_api_sw_interface_set_flags_t *mp;
4953   u32 sw_if_index;
4954   u8 sw_if_index_set = 0;
4955   u8 admin_up = 0, link_up = 0;
4956   int ret;
4957
4958   /* Parse args required to build the message */
4959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4960     {
4961       if (unformat (i, "admin-up"))
4962         admin_up = 1;
4963       else if (unformat (i, "admin-down"))
4964         admin_up = 0;
4965       else if (unformat (i, "link-up"))
4966         link_up = 1;
4967       else if (unformat (i, "link-down"))
4968         link_up = 0;
4969       else
4970         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4971         sw_if_index_set = 1;
4972       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4973         sw_if_index_set = 1;
4974       else
4975         break;
4976     }
4977
4978   if (sw_if_index_set == 0)
4979     {
4980       errmsg ("missing interface name or sw_if_index");
4981       return -99;
4982     }
4983
4984   /* Construct the API message */
4985   M (SW_INTERFACE_SET_FLAGS, mp);
4986   mp->sw_if_index = ntohl (sw_if_index);
4987   mp->admin_up_down = admin_up;
4988   mp->link_up_down = link_up;
4989
4990   /* send it... */
4991   S (mp);
4992
4993   /* Wait for a reply, return the good/bad news... */
4994   W (ret);
4995   return ret;
4996 }
4997
4998 static int
4999 api_sw_interface_clear_stats (vat_main_t * vam)
5000 {
5001   unformat_input_t *i = vam->input;
5002   vl_api_sw_interface_clear_stats_t *mp;
5003   u32 sw_if_index;
5004   u8 sw_if_index_set = 0;
5005   int ret;
5006
5007   /* Parse args required to build the message */
5008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5009     {
5010       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5011         sw_if_index_set = 1;
5012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5013         sw_if_index_set = 1;
5014       else
5015         break;
5016     }
5017
5018   /* Construct the API message */
5019   M (SW_INTERFACE_CLEAR_STATS, mp);
5020
5021   if (sw_if_index_set == 1)
5022     mp->sw_if_index = ntohl (sw_if_index);
5023   else
5024     mp->sw_if_index = ~0;
5025
5026   /* send it... */
5027   S (mp);
5028
5029   /* Wait for a reply, return the good/bad news... */
5030   W (ret);
5031   return ret;
5032 }
5033
5034 static int
5035 api_sw_interface_add_del_address (vat_main_t * vam)
5036 {
5037   unformat_input_t *i = vam->input;
5038   vl_api_sw_interface_add_del_address_t *mp;
5039   u32 sw_if_index;
5040   u8 sw_if_index_set = 0;
5041   u8 is_add = 1, del_all = 0;
5042   u32 address_length = 0;
5043   u8 v4_address_set = 0;
5044   u8 v6_address_set = 0;
5045   ip4_address_t v4address;
5046   ip6_address_t v6address;
5047   int ret;
5048
5049   /* Parse args required to build the message */
5050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5051     {
5052       if (unformat (i, "del-all"))
5053         del_all = 1;
5054       else if (unformat (i, "del"))
5055         is_add = 0;
5056       else
5057         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5058         sw_if_index_set = 1;
5059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5060         sw_if_index_set = 1;
5061       else if (unformat (i, "%U/%d",
5062                          unformat_ip4_address, &v4address, &address_length))
5063         v4_address_set = 1;
5064       else if (unformat (i, "%U/%d",
5065                          unformat_ip6_address, &v6address, &address_length))
5066         v6_address_set = 1;
5067       else
5068         break;
5069     }
5070
5071   if (sw_if_index_set == 0)
5072     {
5073       errmsg ("missing interface name or sw_if_index");
5074       return -99;
5075     }
5076   if (v4_address_set && v6_address_set)
5077     {
5078       errmsg ("both v4 and v6 addresses set");
5079       return -99;
5080     }
5081   if (!v4_address_set && !v6_address_set && !del_all)
5082     {
5083       errmsg ("no addresses set");
5084       return -99;
5085     }
5086
5087   /* Construct the API message */
5088   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5089
5090   mp->sw_if_index = ntohl (sw_if_index);
5091   mp->is_add = is_add;
5092   mp->del_all = del_all;
5093   if (v6_address_set)
5094     {
5095       mp->is_ipv6 = 1;
5096       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5097     }
5098   else
5099     {
5100       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5101     }
5102   mp->address_length = address_length;
5103
5104   /* send it... */
5105   S (mp);
5106
5107   /* Wait for a reply, return good/bad news  */
5108   W (ret);
5109   return ret;
5110 }
5111
5112 static int
5113 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5114 {
5115   unformat_input_t *i = vam->input;
5116   vl_api_sw_interface_set_mpls_enable_t *mp;
5117   u32 sw_if_index;
5118   u8 sw_if_index_set = 0;
5119   u8 enable = 1;
5120   int ret;
5121
5122   /* Parse args required to build the message */
5123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5124     {
5125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5126         sw_if_index_set = 1;
5127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5128         sw_if_index_set = 1;
5129       else if (unformat (i, "disable"))
5130         enable = 0;
5131       else if (unformat (i, "dis"))
5132         enable = 0;
5133       else
5134         break;
5135     }
5136
5137   if (sw_if_index_set == 0)
5138     {
5139       errmsg ("missing interface name or sw_if_index");
5140       return -99;
5141     }
5142
5143   /* Construct the API message */
5144   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5145
5146   mp->sw_if_index = ntohl (sw_if_index);
5147   mp->enable = enable;
5148
5149   /* send it... */
5150   S (mp);
5151
5152   /* Wait for a reply... */
5153   W (ret);
5154   return ret;
5155 }
5156
5157 static int
5158 api_sw_interface_set_table (vat_main_t * vam)
5159 {
5160   unformat_input_t *i = vam->input;
5161   vl_api_sw_interface_set_table_t *mp;
5162   u32 sw_if_index, vrf_id = 0;
5163   u8 sw_if_index_set = 0;
5164   u8 is_ipv6 = 0;
5165   int ret;
5166
5167   /* Parse args required to build the message */
5168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5169     {
5170       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5171         sw_if_index_set = 1;
5172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5173         sw_if_index_set = 1;
5174       else if (unformat (i, "vrf %d", &vrf_id))
5175         ;
5176       else if (unformat (i, "ipv6"))
5177         is_ipv6 = 1;
5178       else
5179         break;
5180     }
5181
5182   if (sw_if_index_set == 0)
5183     {
5184       errmsg ("missing interface name or sw_if_index");
5185       return -99;
5186     }
5187
5188   /* Construct the API message */
5189   M (SW_INTERFACE_SET_TABLE, mp);
5190
5191   mp->sw_if_index = ntohl (sw_if_index);
5192   mp->is_ipv6 = is_ipv6;
5193   mp->vrf_id = ntohl (vrf_id);
5194
5195   /* send it... */
5196   S (mp);
5197
5198   /* Wait for a reply... */
5199   W (ret);
5200   return ret;
5201 }
5202
5203 static void vl_api_sw_interface_get_table_reply_t_handler
5204   (vl_api_sw_interface_get_table_reply_t * mp)
5205 {
5206   vat_main_t *vam = &vat_main;
5207
5208   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5209
5210   vam->retval = ntohl (mp->retval);
5211   vam->result_ready = 1;
5212
5213 }
5214
5215 static void vl_api_sw_interface_get_table_reply_t_handler_json
5216   (vl_api_sw_interface_get_table_reply_t * mp)
5217 {
5218   vat_main_t *vam = &vat_main;
5219   vat_json_node_t node;
5220
5221   vat_json_init_object (&node);
5222   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5223   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5224
5225   vat_json_print (vam->ofp, &node);
5226   vat_json_free (&node);
5227
5228   vam->retval = ntohl (mp->retval);
5229   vam->result_ready = 1;
5230 }
5231
5232 static int
5233 api_sw_interface_get_table (vat_main_t * vam)
5234 {
5235   unformat_input_t *i = vam->input;
5236   vl_api_sw_interface_get_table_t *mp;
5237   u32 sw_if_index;
5238   u8 sw_if_index_set = 0;
5239   u8 is_ipv6 = 0;
5240   int ret;
5241
5242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5243     {
5244       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5245         sw_if_index_set = 1;
5246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5247         sw_if_index_set = 1;
5248       else if (unformat (i, "ipv6"))
5249         is_ipv6 = 1;
5250       else
5251         break;
5252     }
5253
5254   if (sw_if_index_set == 0)
5255     {
5256       errmsg ("missing interface name or sw_if_index");
5257       return -99;
5258     }
5259
5260   M (SW_INTERFACE_GET_TABLE, mp);
5261   mp->sw_if_index = htonl (sw_if_index);
5262   mp->is_ipv6 = is_ipv6;
5263
5264   S (mp);
5265   W (ret);
5266   return ret;
5267 }
5268
5269 static int
5270 api_sw_interface_set_vpath (vat_main_t * vam)
5271 {
5272   unformat_input_t *i = vam->input;
5273   vl_api_sw_interface_set_vpath_t *mp;
5274   u32 sw_if_index = 0;
5275   u8 sw_if_index_set = 0;
5276   u8 is_enable = 0;
5277   int ret;
5278
5279   /* Parse args required to build the message */
5280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5281     {
5282       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5283         sw_if_index_set = 1;
5284       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5285         sw_if_index_set = 1;
5286       else if (unformat (i, "enable"))
5287         is_enable = 1;
5288       else if (unformat (i, "disable"))
5289         is_enable = 0;
5290       else
5291         break;
5292     }
5293
5294   if (sw_if_index_set == 0)
5295     {
5296       errmsg ("missing interface name or sw_if_index");
5297       return -99;
5298     }
5299
5300   /* Construct the API message */
5301   M (SW_INTERFACE_SET_VPATH, mp);
5302
5303   mp->sw_if_index = ntohl (sw_if_index);
5304   mp->enable = is_enable;
5305
5306   /* send it... */
5307   S (mp);
5308
5309   /* Wait for a reply... */
5310   W (ret);
5311   return ret;
5312 }
5313
5314 static int
5315 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5316 {
5317   unformat_input_t *i = vam->input;
5318   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5319   u32 sw_if_index = 0;
5320   u8 sw_if_index_set = 0;
5321   u8 is_enable = 1;
5322   u8 is_ipv6 = 0;
5323   int ret;
5324
5325   /* Parse args required to build the message */
5326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5327     {
5328       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5329         sw_if_index_set = 1;
5330       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5331         sw_if_index_set = 1;
5332       else if (unformat (i, "enable"))
5333         is_enable = 1;
5334       else if (unformat (i, "disable"))
5335         is_enable = 0;
5336       else if (unformat (i, "ip4"))
5337         is_ipv6 = 0;
5338       else if (unformat (i, "ip6"))
5339         is_ipv6 = 1;
5340       else
5341         break;
5342     }
5343
5344   if (sw_if_index_set == 0)
5345     {
5346       errmsg ("missing interface name or sw_if_index");
5347       return -99;
5348     }
5349
5350   /* Construct the API message */
5351   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5352
5353   mp->sw_if_index = ntohl (sw_if_index);
5354   mp->enable = is_enable;
5355   mp->is_ipv6 = is_ipv6;
5356
5357   /* send it... */
5358   S (mp);
5359
5360   /* Wait for a reply... */
5361   W (ret);
5362   return ret;
5363 }
5364
5365 static int
5366 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5367 {
5368   unformat_input_t *i = vam->input;
5369   vl_api_sw_interface_set_l2_xconnect_t *mp;
5370   u32 rx_sw_if_index;
5371   u8 rx_sw_if_index_set = 0;
5372   u32 tx_sw_if_index;
5373   u8 tx_sw_if_index_set = 0;
5374   u8 enable = 1;
5375   int ret;
5376
5377   /* Parse args required to build the message */
5378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5379     {
5380       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5381         rx_sw_if_index_set = 1;
5382       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5383         tx_sw_if_index_set = 1;
5384       else if (unformat (i, "rx"))
5385         {
5386           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5387             {
5388               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5389                             &rx_sw_if_index))
5390                 rx_sw_if_index_set = 1;
5391             }
5392           else
5393             break;
5394         }
5395       else if (unformat (i, "tx"))
5396         {
5397           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5398             {
5399               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5400                             &tx_sw_if_index))
5401                 tx_sw_if_index_set = 1;
5402             }
5403           else
5404             break;
5405         }
5406       else if (unformat (i, "enable"))
5407         enable = 1;
5408       else if (unformat (i, "disable"))
5409         enable = 0;
5410       else
5411         break;
5412     }
5413
5414   if (rx_sw_if_index_set == 0)
5415     {
5416       errmsg ("missing rx interface name or rx_sw_if_index");
5417       return -99;
5418     }
5419
5420   if (enable && (tx_sw_if_index_set == 0))
5421     {
5422       errmsg ("missing tx interface name or tx_sw_if_index");
5423       return -99;
5424     }
5425
5426   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5427
5428   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5429   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5430   mp->enable = enable;
5431
5432   S (mp);
5433   W (ret);
5434   return ret;
5435 }
5436
5437 static int
5438 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5439 {
5440   unformat_input_t *i = vam->input;
5441   vl_api_sw_interface_set_l2_bridge_t *mp;
5442   u32 rx_sw_if_index;
5443   u8 rx_sw_if_index_set = 0;
5444   u32 bd_id;
5445   u8 bd_id_set = 0;
5446   u8 bvi = 0;
5447   u32 shg = 0;
5448   u8 enable = 1;
5449   int ret;
5450
5451   /* Parse args required to build the message */
5452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5453     {
5454       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5455         rx_sw_if_index_set = 1;
5456       else if (unformat (i, "bd_id %d", &bd_id))
5457         bd_id_set = 1;
5458       else
5459         if (unformat
5460             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5461         rx_sw_if_index_set = 1;
5462       else if (unformat (i, "shg %d", &shg))
5463         ;
5464       else if (unformat (i, "bvi"))
5465         bvi = 1;
5466       else if (unformat (i, "enable"))
5467         enable = 1;
5468       else if (unformat (i, "disable"))
5469         enable = 0;
5470       else
5471         break;
5472     }
5473
5474   if (rx_sw_if_index_set == 0)
5475     {
5476       errmsg ("missing rx interface name or sw_if_index");
5477       return -99;
5478     }
5479
5480   if (enable && (bd_id_set == 0))
5481     {
5482       errmsg ("missing bridge domain");
5483       return -99;
5484     }
5485
5486   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5487
5488   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5489   mp->bd_id = ntohl (bd_id);
5490   mp->shg = (u8) shg;
5491   mp->bvi = bvi;
5492   mp->enable = enable;
5493
5494   S (mp);
5495   W (ret);
5496   return ret;
5497 }
5498
5499 static int
5500 api_bridge_domain_dump (vat_main_t * vam)
5501 {
5502   unformat_input_t *i = vam->input;
5503   vl_api_bridge_domain_dump_t *mp;
5504   vl_api_control_ping_t *mp_ping;
5505   u32 bd_id = ~0;
5506   int ret;
5507
5508   /* Parse args required to build the message */
5509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5510     {
5511       if (unformat (i, "bd_id %d", &bd_id))
5512         ;
5513       else
5514         break;
5515     }
5516
5517   M (BRIDGE_DOMAIN_DUMP, mp);
5518   mp->bd_id = ntohl (bd_id);
5519   S (mp);
5520
5521   /* Use a control ping for synchronization */
5522   M (CONTROL_PING, mp_ping);
5523   S (mp_ping);
5524
5525   W (ret);
5526   return ret;
5527 }
5528
5529 static int
5530 api_bridge_domain_add_del (vat_main_t * vam)
5531 {
5532   unformat_input_t *i = vam->input;
5533   vl_api_bridge_domain_add_del_t *mp;
5534   u32 bd_id = ~0;
5535   u8 is_add = 1;
5536   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5537   u32 mac_age = 0;
5538   int ret;
5539
5540   /* Parse args required to build the message */
5541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5542     {
5543       if (unformat (i, "bd_id %d", &bd_id))
5544         ;
5545       else if (unformat (i, "flood %d", &flood))
5546         ;
5547       else if (unformat (i, "uu-flood %d", &uu_flood))
5548         ;
5549       else if (unformat (i, "forward %d", &forward))
5550         ;
5551       else if (unformat (i, "learn %d", &learn))
5552         ;
5553       else if (unformat (i, "arp-term %d", &arp_term))
5554         ;
5555       else if (unformat (i, "mac-age %d", &mac_age))
5556         ;
5557       else if (unformat (i, "del"))
5558         {
5559           is_add = 0;
5560           flood = uu_flood = forward = learn = 0;
5561         }
5562       else
5563         break;
5564     }
5565
5566   if (bd_id == ~0)
5567     {
5568       errmsg ("missing bridge domain");
5569       return -99;
5570     }
5571
5572   if (mac_age > 255)
5573     {
5574       errmsg ("mac age must be less than 256 ");
5575       return -99;
5576     }
5577
5578   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5579
5580   mp->bd_id = ntohl (bd_id);
5581   mp->flood = flood;
5582   mp->uu_flood = uu_flood;
5583   mp->forward = forward;
5584   mp->learn = learn;
5585   mp->arp_term = arp_term;
5586   mp->is_add = is_add;
5587   mp->mac_age = (u8) mac_age;
5588
5589   S (mp);
5590   W (ret);
5591   return ret;
5592 }
5593
5594 static int
5595 api_l2fib_add_del (vat_main_t * vam)
5596 {
5597   unformat_input_t *i = vam->input;
5598   vl_api_l2fib_add_del_t *mp;
5599   f64 timeout;
5600   u64 mac = 0;
5601   u8 mac_set = 0;
5602   u32 bd_id;
5603   u8 bd_id_set = 0;
5604   u32 sw_if_index = ~0;
5605   u8 sw_if_index_set = 0;
5606   u8 is_add = 1;
5607   u8 static_mac = 0;
5608   u8 filter_mac = 0;
5609   u8 bvi_mac = 0;
5610   int count = 1;
5611   f64 before = 0;
5612   int j;
5613
5614   /* Parse args required to build the message */
5615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5616     {
5617       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5618         mac_set = 1;
5619       else if (unformat (i, "bd_id %d", &bd_id))
5620         bd_id_set = 1;
5621       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5622         sw_if_index_set = 1;
5623       else if (unformat (i, "sw_if"))
5624         {
5625           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5626             {
5627               if (unformat
5628                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5629                 sw_if_index_set = 1;
5630             }
5631           else
5632             break;
5633         }
5634       else if (unformat (i, "static"))
5635         static_mac = 1;
5636       else if (unformat (i, "filter"))
5637         {
5638           filter_mac = 1;
5639           static_mac = 1;
5640         }
5641       else if (unformat (i, "bvi"))
5642         {
5643           bvi_mac = 1;
5644           static_mac = 1;
5645         }
5646       else if (unformat (i, "del"))
5647         is_add = 0;
5648       else if (unformat (i, "count %d", &count))
5649         ;
5650       else
5651         break;
5652     }
5653
5654   if (mac_set == 0)
5655     {
5656       errmsg ("missing mac address");
5657       return -99;
5658     }
5659
5660   if (bd_id_set == 0)
5661     {
5662       errmsg ("missing bridge domain");
5663       return -99;
5664     }
5665
5666   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5667     {
5668       errmsg ("missing interface name or sw_if_index");
5669       return -99;
5670     }
5671
5672   if (count > 1)
5673     {
5674       /* Turn on async mode */
5675       vam->async_mode = 1;
5676       vam->async_errors = 0;
5677       before = vat_time_now (vam);
5678     }
5679
5680   for (j = 0; j < count; j++)
5681     {
5682       M (L2FIB_ADD_DEL, mp);
5683
5684       mp->mac = mac;
5685       mp->bd_id = ntohl (bd_id);
5686       mp->is_add = is_add;
5687
5688       if (is_add)
5689         {
5690           mp->sw_if_index = ntohl (sw_if_index);
5691           mp->static_mac = static_mac;
5692           mp->filter_mac = filter_mac;
5693           mp->bvi_mac = bvi_mac;
5694         }
5695       increment_mac_address (&mac);
5696       /* send it... */
5697       S (mp);
5698     }
5699
5700   if (count > 1)
5701     {
5702       vl_api_control_ping_t *mp_ping;
5703       f64 after;
5704
5705       /* Shut off async mode */
5706       vam->async_mode = 0;
5707
5708       M (CONTROL_PING, mp_ping);
5709       S (mp_ping);
5710
5711       timeout = vat_time_now (vam) + 1.0;
5712       while (vat_time_now (vam) < timeout)
5713         if (vam->result_ready == 1)
5714           goto out;
5715       vam->retval = -99;
5716
5717     out:
5718       if (vam->retval == -99)
5719         errmsg ("timeout");
5720
5721       if (vam->async_errors > 0)
5722         {
5723           errmsg ("%d asynchronous errors", vam->async_errors);
5724           vam->retval = -98;
5725         }
5726       vam->async_errors = 0;
5727       after = vat_time_now (vam);
5728
5729       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5730              count, after - before, count / (after - before));
5731     }
5732   else
5733     {
5734       int ret;
5735
5736       /* Wait for a reply... */
5737       W (ret);
5738       return ret;
5739     }
5740   /* Return the good/bad news */
5741   return (vam->retval);
5742 }
5743
5744 static int
5745 api_l2_flags (vat_main_t * vam)
5746 {
5747   unformat_input_t *i = vam->input;
5748   vl_api_l2_flags_t *mp;
5749   u32 sw_if_index;
5750   u32 feature_bitmap = 0;
5751   u8 sw_if_index_set = 0;
5752   int ret;
5753
5754   /* Parse args required to build the message */
5755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5756     {
5757       if (unformat (i, "sw_if_index %d", &sw_if_index))
5758         sw_if_index_set = 1;
5759       else if (unformat (i, "sw_if"))
5760         {
5761           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5762             {
5763               if (unformat
5764                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5765                 sw_if_index_set = 1;
5766             }
5767           else
5768             break;
5769         }
5770       else if (unformat (i, "learn"))
5771         feature_bitmap |= L2INPUT_FEAT_LEARN;
5772       else if (unformat (i, "forward"))
5773         feature_bitmap |= L2INPUT_FEAT_FWD;
5774       else if (unformat (i, "flood"))
5775         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5776       else if (unformat (i, "uu-flood"))
5777         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5778       else
5779         break;
5780     }
5781
5782   if (sw_if_index_set == 0)
5783     {
5784       errmsg ("missing interface name or sw_if_index");
5785       return -99;
5786     }
5787
5788   M (L2_FLAGS, mp);
5789
5790   mp->sw_if_index = ntohl (sw_if_index);
5791   mp->feature_bitmap = ntohl (feature_bitmap);
5792
5793   S (mp);
5794   W (ret);
5795   return ret;
5796 }
5797
5798 static int
5799 api_bridge_flags (vat_main_t * vam)
5800 {
5801   unformat_input_t *i = vam->input;
5802   vl_api_bridge_flags_t *mp;
5803   u32 bd_id;
5804   u8 bd_id_set = 0;
5805   u8 is_set = 1;
5806   u32 flags = 0;
5807   int ret;
5808
5809   /* Parse args required to build the message */
5810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5811     {
5812       if (unformat (i, "bd_id %d", &bd_id))
5813         bd_id_set = 1;
5814       else if (unformat (i, "learn"))
5815         flags |= L2_LEARN;
5816       else if (unformat (i, "forward"))
5817         flags |= L2_FWD;
5818       else if (unformat (i, "flood"))
5819         flags |= L2_FLOOD;
5820       else if (unformat (i, "uu-flood"))
5821         flags |= L2_UU_FLOOD;
5822       else if (unformat (i, "arp-term"))
5823         flags |= L2_ARP_TERM;
5824       else if (unformat (i, "off"))
5825         is_set = 0;
5826       else if (unformat (i, "disable"))
5827         is_set = 0;
5828       else
5829         break;
5830     }
5831
5832   if (bd_id_set == 0)
5833     {
5834       errmsg ("missing bridge domain");
5835       return -99;
5836     }
5837
5838   M (BRIDGE_FLAGS, mp);
5839
5840   mp->bd_id = ntohl (bd_id);
5841   mp->feature_bitmap = ntohl (flags);
5842   mp->is_set = is_set;
5843
5844   S (mp);
5845   W (ret);
5846   return ret;
5847 }
5848
5849 static int
5850 api_bd_ip_mac_add_del (vat_main_t * vam)
5851 {
5852   unformat_input_t *i = vam->input;
5853   vl_api_bd_ip_mac_add_del_t *mp;
5854   u32 bd_id;
5855   u8 is_ipv6 = 0;
5856   u8 is_add = 1;
5857   u8 bd_id_set = 0;
5858   u8 ip_set = 0;
5859   u8 mac_set = 0;
5860   ip4_address_t v4addr;
5861   ip6_address_t v6addr;
5862   u8 macaddr[6];
5863   int ret;
5864
5865
5866   /* Parse args required to build the message */
5867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5868     {
5869       if (unformat (i, "bd_id %d", &bd_id))
5870         {
5871           bd_id_set++;
5872         }
5873       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5874         {
5875           ip_set++;
5876         }
5877       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5878         {
5879           ip_set++;
5880           is_ipv6++;
5881         }
5882       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5883         {
5884           mac_set++;
5885         }
5886       else if (unformat (i, "del"))
5887         is_add = 0;
5888       else
5889         break;
5890     }
5891
5892   if (bd_id_set == 0)
5893     {
5894       errmsg ("missing bridge domain");
5895       return -99;
5896     }
5897   else if (ip_set == 0)
5898     {
5899       errmsg ("missing IP address");
5900       return -99;
5901     }
5902   else if (mac_set == 0)
5903     {
5904       errmsg ("missing MAC address");
5905       return -99;
5906     }
5907
5908   M (BD_IP_MAC_ADD_DEL, mp);
5909
5910   mp->bd_id = ntohl (bd_id);
5911   mp->is_ipv6 = is_ipv6;
5912   mp->is_add = is_add;
5913   if (is_ipv6)
5914     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5915   else
5916     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5917   clib_memcpy (mp->mac_address, macaddr, 6);
5918   S (mp);
5919   W (ret);
5920   return ret;
5921 }
5922
5923 static int
5924 api_tap_connect (vat_main_t * vam)
5925 {
5926   unformat_input_t *i = vam->input;
5927   vl_api_tap_connect_t *mp;
5928   u8 mac_address[6];
5929   u8 random_mac = 1;
5930   u8 name_set = 0;
5931   u8 *tap_name;
5932   u8 *tag = 0;
5933   ip4_address_t ip4_address;
5934   u32 ip4_mask_width;
5935   int ip4_address_set = 0;
5936   ip6_address_t ip6_address;
5937   u32 ip6_mask_width;
5938   int ip6_address_set = 0;
5939   int ret;
5940
5941   memset (mac_address, 0, sizeof (mac_address));
5942
5943   /* Parse args required to build the message */
5944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5945     {
5946       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5947         {
5948           random_mac = 0;
5949         }
5950       else if (unformat (i, "random-mac"))
5951         random_mac = 1;
5952       else if (unformat (i, "tapname %s", &tap_name))
5953         name_set = 1;
5954       else if (unformat (i, "tag %s", &tag))
5955         ;
5956       else if (unformat (i, "address %U/%d",
5957                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
5958         ip4_address_set = 1;
5959       else if (unformat (i, "address %U/%d",
5960                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
5961         ip6_address_set = 1;
5962       else
5963         break;
5964     }
5965
5966   if (name_set == 0)
5967     {
5968       errmsg ("missing tap name");
5969       return -99;
5970     }
5971   if (vec_len (tap_name) > 63)
5972     {
5973       errmsg ("tap name too long");
5974       return -99;
5975     }
5976   vec_add1 (tap_name, 0);
5977
5978   if (vec_len (tag) > 63)
5979     {
5980       errmsg ("tag too long");
5981       return -99;
5982     }
5983
5984   /* Construct the API message */
5985   M (TAP_CONNECT, mp);
5986
5987   mp->use_random_mac = random_mac;
5988   clib_memcpy (mp->mac_address, mac_address, 6);
5989   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5990   if (tag)
5991     clib_memcpy (mp->tag, tag, vec_len (tag));
5992
5993   if (ip4_address_set)
5994     {
5995       mp->ip4_address_set = 1;
5996       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
5997       mp->ip4_mask_width = ip4_mask_width;
5998     }
5999   if (ip6_address_set)
6000     {
6001       mp->ip6_address_set = 1;
6002       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6003       mp->ip6_mask_width = ip6_mask_width;
6004     }
6005
6006   vec_free (tap_name);
6007   vec_free (tag);
6008
6009   /* send it... */
6010   S (mp);
6011
6012   /* Wait for a reply... */
6013   W (ret);
6014   return ret;
6015 }
6016
6017 static int
6018 api_tap_modify (vat_main_t * vam)
6019 {
6020   unformat_input_t *i = vam->input;
6021   vl_api_tap_modify_t *mp;
6022   u8 mac_address[6];
6023   u8 random_mac = 1;
6024   u8 name_set = 0;
6025   u8 *tap_name;
6026   u32 sw_if_index = ~0;
6027   u8 sw_if_index_set = 0;
6028   int ret;
6029
6030   memset (mac_address, 0, sizeof (mac_address));
6031
6032   /* Parse args required to build the message */
6033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6034     {
6035       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6036         sw_if_index_set = 1;
6037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6038         sw_if_index_set = 1;
6039       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6040         {
6041           random_mac = 0;
6042         }
6043       else if (unformat (i, "random-mac"))
6044         random_mac = 1;
6045       else if (unformat (i, "tapname %s", &tap_name))
6046         name_set = 1;
6047       else
6048         break;
6049     }
6050
6051   if (sw_if_index_set == 0)
6052     {
6053       errmsg ("missing vpp interface name");
6054       return -99;
6055     }
6056   if (name_set == 0)
6057     {
6058       errmsg ("missing tap name");
6059       return -99;
6060     }
6061   if (vec_len (tap_name) > 63)
6062     {
6063       errmsg ("tap name too long");
6064     }
6065   vec_add1 (tap_name, 0);
6066
6067   /* Construct the API message */
6068   M (TAP_MODIFY, mp);
6069
6070   mp->use_random_mac = random_mac;
6071   mp->sw_if_index = ntohl (sw_if_index);
6072   clib_memcpy (mp->mac_address, mac_address, 6);
6073   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6074   vec_free (tap_name);
6075
6076   /* send it... */
6077   S (mp);
6078
6079   /* Wait for a reply... */
6080   W (ret);
6081   return ret;
6082 }
6083
6084 static int
6085 api_tap_delete (vat_main_t * vam)
6086 {
6087   unformat_input_t *i = vam->input;
6088   vl_api_tap_delete_t *mp;
6089   u32 sw_if_index = ~0;
6090   u8 sw_if_index_set = 0;
6091   int ret;
6092
6093   /* Parse args required to build the message */
6094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6095     {
6096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6097         sw_if_index_set = 1;
6098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6099         sw_if_index_set = 1;
6100       else
6101         break;
6102     }
6103
6104   if (sw_if_index_set == 0)
6105     {
6106       errmsg ("missing vpp interface name");
6107       return -99;
6108     }
6109
6110   /* Construct the API message */
6111   M (TAP_DELETE, mp);
6112
6113   mp->sw_if_index = ntohl (sw_if_index);
6114
6115   /* send it... */
6116   S (mp);
6117
6118   /* Wait for a reply... */
6119   W (ret);
6120   return ret;
6121 }
6122
6123 static int
6124 api_ip_add_del_route (vat_main_t * vam)
6125 {
6126   unformat_input_t *i = vam->input;
6127   vl_api_ip_add_del_route_t *mp;
6128   u32 sw_if_index = ~0, vrf_id = 0;
6129   u8 is_ipv6 = 0;
6130   u8 is_local = 0, is_drop = 0;
6131   u8 is_unreach = 0, is_prohibit = 0;
6132   u8 create_vrf_if_needed = 0;
6133   u8 is_add = 1;
6134   u32 next_hop_weight = 1;
6135   u8 not_last = 0;
6136   u8 is_multipath = 0;
6137   u8 address_set = 0;
6138   u8 address_length_set = 0;
6139   u32 next_hop_table_id = 0;
6140   u32 resolve_attempts = 0;
6141   u32 dst_address_length = 0;
6142   u8 next_hop_set = 0;
6143   ip4_address_t v4_dst_address, v4_next_hop_address;
6144   ip6_address_t v6_dst_address, v6_next_hop_address;
6145   int count = 1;
6146   int j;
6147   f64 before = 0;
6148   u32 random_add_del = 0;
6149   u32 *random_vector = 0;
6150   uword *random_hash;
6151   u32 random_seed = 0xdeaddabe;
6152   u32 classify_table_index = ~0;
6153   u8 is_classify = 0;
6154   u8 resolve_host = 0, resolve_attached = 0;
6155   mpls_label_t *next_hop_out_label_stack = NULL;
6156   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6157   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6158
6159   /* Parse args required to build the message */
6160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6161     {
6162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6163         ;
6164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6165         ;
6166       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6167         {
6168           address_set = 1;
6169           is_ipv6 = 0;
6170         }
6171       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6172         {
6173           address_set = 1;
6174           is_ipv6 = 1;
6175         }
6176       else if (unformat (i, "/%d", &dst_address_length))
6177         {
6178           address_length_set = 1;
6179         }
6180
6181       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6182                                          &v4_next_hop_address))
6183         {
6184           next_hop_set = 1;
6185         }
6186       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6187                                          &v6_next_hop_address))
6188         {
6189           next_hop_set = 1;
6190         }
6191       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6192         ;
6193       else if (unformat (i, "weight %d", &next_hop_weight))
6194         ;
6195       else if (unformat (i, "drop"))
6196         {
6197           is_drop = 1;
6198         }
6199       else if (unformat (i, "null-send-unreach"))
6200         {
6201           is_unreach = 1;
6202         }
6203       else if (unformat (i, "null-send-prohibit"))
6204         {
6205           is_prohibit = 1;
6206         }
6207       else if (unformat (i, "local"))
6208         {
6209           is_local = 1;
6210         }
6211       else if (unformat (i, "classify %d", &classify_table_index))
6212         {
6213           is_classify = 1;
6214         }
6215       else if (unformat (i, "del"))
6216         is_add = 0;
6217       else if (unformat (i, "add"))
6218         is_add = 1;
6219       else if (unformat (i, "not-last"))
6220         not_last = 1;
6221       else if (unformat (i, "resolve-via-host"))
6222         resolve_host = 1;
6223       else if (unformat (i, "resolve-via-attached"))
6224         resolve_attached = 1;
6225       else if (unformat (i, "multipath"))
6226         is_multipath = 1;
6227       else if (unformat (i, "vrf %d", &vrf_id))
6228         ;
6229       else if (unformat (i, "create-vrf"))
6230         create_vrf_if_needed = 1;
6231       else if (unformat (i, "count %d", &count))
6232         ;
6233       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6234         ;
6235       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6236         ;
6237       else if (unformat (i, "out-label %d", &next_hop_out_label))
6238         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6239       else if (unformat (i, "via-label %d", &next_hop_via_label))
6240         ;
6241       else if (unformat (i, "random"))
6242         random_add_del = 1;
6243       else if (unformat (i, "seed %d", &random_seed))
6244         ;
6245       else
6246         {
6247           clib_warning ("parse error '%U'", format_unformat_error, i);
6248           return -99;
6249         }
6250     }
6251
6252   if (!next_hop_set && !is_drop && !is_local &&
6253       !is_classify && !is_unreach && !is_prohibit &&
6254       MPLS_LABEL_INVALID == next_hop_via_label)
6255     {
6256       errmsg
6257         ("next hop / local / drop / unreach / prohibit / classify not set");
6258       return -99;
6259     }
6260
6261   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6262     {
6263       errmsg ("next hop and next-hop via label set");
6264       return -99;
6265     }
6266   if (address_set == 0)
6267     {
6268       errmsg ("missing addresses");
6269       return -99;
6270     }
6271
6272   if (address_length_set == 0)
6273     {
6274       errmsg ("missing address length");
6275       return -99;
6276     }
6277
6278   /* Generate a pile of unique, random routes */
6279   if (random_add_del)
6280     {
6281       u32 this_random_address;
6282       random_hash = hash_create (count, sizeof (uword));
6283
6284       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6285       for (j = 0; j <= count; j++)
6286         {
6287           do
6288             {
6289               this_random_address = random_u32 (&random_seed);
6290               this_random_address =
6291                 clib_host_to_net_u32 (this_random_address);
6292             }
6293           while (hash_get (random_hash, this_random_address));
6294           vec_add1 (random_vector, this_random_address);
6295           hash_set (random_hash, this_random_address, 1);
6296         }
6297       hash_free (random_hash);
6298       v4_dst_address.as_u32 = random_vector[0];
6299     }
6300
6301   if (count > 1)
6302     {
6303       /* Turn on async mode */
6304       vam->async_mode = 1;
6305       vam->async_errors = 0;
6306       before = vat_time_now (vam);
6307     }
6308
6309   for (j = 0; j < count; j++)
6310     {
6311       /* Construct the API message */
6312       M2 (IP_ADD_DEL_ROUTE, mp,
6313           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6314
6315       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6316       mp->table_id = ntohl (vrf_id);
6317       mp->create_vrf_if_needed = create_vrf_if_needed;
6318
6319       mp->is_add = is_add;
6320       mp->is_drop = is_drop;
6321       mp->is_unreach = is_unreach;
6322       mp->is_prohibit = is_prohibit;
6323       mp->is_ipv6 = is_ipv6;
6324       mp->is_local = is_local;
6325       mp->is_classify = is_classify;
6326       mp->is_multipath = is_multipath;
6327       mp->is_resolve_host = resolve_host;
6328       mp->is_resolve_attached = resolve_attached;
6329       mp->not_last = not_last;
6330       mp->next_hop_weight = next_hop_weight;
6331       mp->dst_address_length = dst_address_length;
6332       mp->next_hop_table_id = ntohl (next_hop_table_id);
6333       mp->classify_table_index = ntohl (classify_table_index);
6334       mp->next_hop_via_label = ntohl (next_hop_via_label);
6335       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6336       if (0 != mp->next_hop_n_out_labels)
6337         {
6338           memcpy (mp->next_hop_out_label_stack,
6339                   next_hop_out_label_stack,
6340                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6341           vec_free (next_hop_out_label_stack);
6342         }
6343
6344       if (is_ipv6)
6345         {
6346           clib_memcpy (mp->dst_address, &v6_dst_address,
6347                        sizeof (v6_dst_address));
6348           if (next_hop_set)
6349             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6350                          sizeof (v6_next_hop_address));
6351           increment_v6_address (&v6_dst_address);
6352         }
6353       else
6354         {
6355           clib_memcpy (mp->dst_address, &v4_dst_address,
6356                        sizeof (v4_dst_address));
6357           if (next_hop_set)
6358             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6359                          sizeof (v4_next_hop_address));
6360           if (random_add_del)
6361             v4_dst_address.as_u32 = random_vector[j + 1];
6362           else
6363             increment_v4_address (&v4_dst_address);
6364         }
6365       /* send it... */
6366       S (mp);
6367       /* If we receive SIGTERM, stop now... */
6368       if (vam->do_exit)
6369         break;
6370     }
6371
6372   /* When testing multiple add/del ops, use a control-ping to sync */
6373   if (count > 1)
6374     {
6375       vl_api_control_ping_t *mp_ping;
6376       f64 after;
6377       f64 timeout;
6378
6379       /* Shut off async mode */
6380       vam->async_mode = 0;
6381
6382       M (CONTROL_PING, mp_ping);
6383       S (mp_ping);
6384
6385       timeout = vat_time_now (vam) + 1.0;
6386       while (vat_time_now (vam) < timeout)
6387         if (vam->result_ready == 1)
6388           goto out;
6389       vam->retval = -99;
6390
6391     out:
6392       if (vam->retval == -99)
6393         errmsg ("timeout");
6394
6395       if (vam->async_errors > 0)
6396         {
6397           errmsg ("%d asynchronous errors", vam->async_errors);
6398           vam->retval = -98;
6399         }
6400       vam->async_errors = 0;
6401       after = vat_time_now (vam);
6402
6403       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6404       if (j > 0)
6405         count = j;
6406
6407       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6408              count, after - before, count / (after - before));
6409     }
6410   else
6411     {
6412       int ret;
6413
6414       /* Wait for a reply... */
6415       W (ret);
6416       return ret;
6417     }
6418
6419   /* Return the good/bad news */
6420   return (vam->retval);
6421 }
6422
6423 static int
6424 api_ip_mroute_add_del (vat_main_t * vam)
6425 {
6426   unformat_input_t *i = vam->input;
6427   vl_api_ip_mroute_add_del_t *mp;
6428   u32 sw_if_index = ~0, vrf_id = 0;
6429   u8 is_ipv6 = 0;
6430   u8 is_local = 0;
6431   u8 create_vrf_if_needed = 0;
6432   u8 is_add = 1;
6433   u8 address_set = 0;
6434   u32 grp_address_length = 0;
6435   ip4_address_t v4_grp_address, v4_src_address;
6436   ip6_address_t v6_grp_address, v6_src_address;
6437   mfib_itf_flags_t iflags = 0;
6438   mfib_entry_flags_t eflags = 0;
6439   int ret;
6440
6441   /* Parse args required to build the message */
6442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6443     {
6444       if (unformat (i, "sw_if_index %d", &sw_if_index))
6445         ;
6446       else if (unformat (i, "%U %U",
6447                          unformat_ip4_address, &v4_src_address,
6448                          unformat_ip4_address, &v4_grp_address))
6449         {
6450           grp_address_length = 64;
6451           address_set = 1;
6452           is_ipv6 = 0;
6453         }
6454       else if (unformat (i, "%U %U",
6455                          unformat_ip6_address, &v6_src_address,
6456                          unformat_ip6_address, &v6_grp_address))
6457         {
6458           grp_address_length = 256;
6459           address_set = 1;
6460           is_ipv6 = 1;
6461         }
6462       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6463         {
6464           memset (&v4_src_address, 0, sizeof (v4_src_address));
6465           grp_address_length = 32;
6466           address_set = 1;
6467           is_ipv6 = 0;
6468         }
6469       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6470         {
6471           memset (&v6_src_address, 0, sizeof (v6_src_address));
6472           grp_address_length = 128;
6473           address_set = 1;
6474           is_ipv6 = 1;
6475         }
6476       else if (unformat (i, "/%d", &grp_address_length))
6477         ;
6478       else if (unformat (i, "local"))
6479         {
6480           is_local = 1;
6481         }
6482       else if (unformat (i, "del"))
6483         is_add = 0;
6484       else if (unformat (i, "add"))
6485         is_add = 1;
6486       else if (unformat (i, "vrf %d", &vrf_id))
6487         ;
6488       else if (unformat (i, "create-vrf"))
6489         create_vrf_if_needed = 1;
6490       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6491         ;
6492       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6493         ;
6494       else
6495         {
6496           clib_warning ("parse error '%U'", format_unformat_error, i);
6497           return -99;
6498         }
6499     }
6500
6501   if (address_set == 0)
6502     {
6503       errmsg ("missing addresses\n");
6504       return -99;
6505     }
6506
6507   /* Construct the API message */
6508   M (IP_MROUTE_ADD_DEL, mp);
6509
6510   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6511   mp->table_id = ntohl (vrf_id);
6512   mp->create_vrf_if_needed = create_vrf_if_needed;
6513
6514   mp->is_add = is_add;
6515   mp->is_ipv6 = is_ipv6;
6516   mp->is_local = is_local;
6517   mp->itf_flags = ntohl (iflags);
6518   mp->entry_flags = ntohl (eflags);
6519   mp->grp_address_length = grp_address_length;
6520   mp->grp_address_length = ntohs (mp->grp_address_length);
6521
6522   if (is_ipv6)
6523     {
6524       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6525       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6526     }
6527   else
6528     {
6529       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6530       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6531
6532     }
6533
6534   /* send it... */
6535   S (mp);
6536   /* Wait for a reply... */
6537   W (ret);
6538   return ret;
6539 }
6540
6541 static int
6542 api_mpls_route_add_del (vat_main_t * vam)
6543 {
6544   unformat_input_t *i = vam->input;
6545   vl_api_mpls_route_add_del_t *mp;
6546   u32 sw_if_index = ~0, table_id = 0;
6547   u8 create_table_if_needed = 0;
6548   u8 is_add = 1;
6549   u32 next_hop_weight = 1;
6550   u8 is_multipath = 0;
6551   u32 next_hop_table_id = 0;
6552   u8 next_hop_set = 0;
6553   ip4_address_t v4_next_hop_address = {
6554     .as_u32 = 0,
6555   };
6556   ip6_address_t v6_next_hop_address = { {0} };
6557   int count = 1;
6558   int j;
6559   f64 before = 0;
6560   u32 classify_table_index = ~0;
6561   u8 is_classify = 0;
6562   u8 resolve_host = 0, resolve_attached = 0;
6563   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6564   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6565   mpls_label_t *next_hop_out_label_stack = NULL;
6566   mpls_label_t local_label = MPLS_LABEL_INVALID;
6567   u8 is_eos = 0;
6568   u8 next_hop_proto_is_ip4 = 1;
6569
6570   /* Parse args required to build the message */
6571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6572     {
6573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6574         ;
6575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6576         ;
6577       else if (unformat (i, "%d", &local_label))
6578         ;
6579       else if (unformat (i, "eos"))
6580         is_eos = 1;
6581       else if (unformat (i, "non-eos"))
6582         is_eos = 0;
6583       else if (unformat (i, "via %U", unformat_ip4_address,
6584                          &v4_next_hop_address))
6585         {
6586           next_hop_set = 1;
6587           next_hop_proto_is_ip4 = 1;
6588         }
6589       else if (unformat (i, "via %U", unformat_ip6_address,
6590                          &v6_next_hop_address))
6591         {
6592           next_hop_set = 1;
6593           next_hop_proto_is_ip4 = 0;
6594         }
6595       else if (unformat (i, "weight %d", &next_hop_weight))
6596         ;
6597       else if (unformat (i, "create-table"))
6598         create_table_if_needed = 1;
6599       else if (unformat (i, "classify %d", &classify_table_index))
6600         {
6601           is_classify = 1;
6602         }
6603       else if (unformat (i, "del"))
6604         is_add = 0;
6605       else if (unformat (i, "add"))
6606         is_add = 1;
6607       else if (unformat (i, "resolve-via-host"))
6608         resolve_host = 1;
6609       else if (unformat (i, "resolve-via-attached"))
6610         resolve_attached = 1;
6611       else if (unformat (i, "multipath"))
6612         is_multipath = 1;
6613       else if (unformat (i, "count %d", &count))
6614         ;
6615       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6616         {
6617           next_hop_set = 1;
6618           next_hop_proto_is_ip4 = 1;
6619         }
6620       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6621         {
6622           next_hop_set = 1;
6623           next_hop_proto_is_ip4 = 0;
6624         }
6625       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6626         ;
6627       else if (unformat (i, "via-label %d", &next_hop_via_label))
6628         ;
6629       else if (unformat (i, "out-label %d", &next_hop_out_label))
6630         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6631       else
6632         {
6633           clib_warning ("parse error '%U'", format_unformat_error, i);
6634           return -99;
6635         }
6636     }
6637
6638   if (!next_hop_set && !is_classify)
6639     {
6640       errmsg ("next hop / classify not set");
6641       return -99;
6642     }
6643
6644   if (MPLS_LABEL_INVALID == local_label)
6645     {
6646       errmsg ("missing label");
6647       return -99;
6648     }
6649
6650   if (count > 1)
6651     {
6652       /* Turn on async mode */
6653       vam->async_mode = 1;
6654       vam->async_errors = 0;
6655       before = vat_time_now (vam);
6656     }
6657
6658   for (j = 0; j < count; j++)
6659     {
6660       /* Construct the API message */
6661       M2 (MPLS_ROUTE_ADD_DEL, mp,
6662           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6663
6664       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6665       mp->mr_table_id = ntohl (table_id);
6666       mp->mr_create_table_if_needed = create_table_if_needed;
6667
6668       mp->mr_is_add = is_add;
6669       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6670       mp->mr_is_classify = is_classify;
6671       mp->mr_is_multipath = is_multipath;
6672       mp->mr_is_resolve_host = resolve_host;
6673       mp->mr_is_resolve_attached = resolve_attached;
6674       mp->mr_next_hop_weight = next_hop_weight;
6675       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6676       mp->mr_classify_table_index = ntohl (classify_table_index);
6677       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6678       mp->mr_label = ntohl (local_label);
6679       mp->mr_eos = is_eos;
6680
6681       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6682       if (0 != mp->mr_next_hop_n_out_labels)
6683         {
6684           memcpy (mp->mr_next_hop_out_label_stack,
6685                   next_hop_out_label_stack,
6686                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6687           vec_free (next_hop_out_label_stack);
6688         }
6689
6690       if (next_hop_set)
6691         {
6692           if (next_hop_proto_is_ip4)
6693             {
6694               clib_memcpy (mp->mr_next_hop,
6695                            &v4_next_hop_address,
6696                            sizeof (v4_next_hop_address));
6697             }
6698           else
6699             {
6700               clib_memcpy (mp->mr_next_hop,
6701                            &v6_next_hop_address,
6702                            sizeof (v6_next_hop_address));
6703             }
6704         }
6705       local_label++;
6706
6707       /* send it... */
6708       S (mp);
6709       /* If we receive SIGTERM, stop now... */
6710       if (vam->do_exit)
6711         break;
6712     }
6713
6714   /* When testing multiple add/del ops, use a control-ping to sync */
6715   if (count > 1)
6716     {
6717       vl_api_control_ping_t *mp_ping;
6718       f64 after;
6719       f64 timeout;
6720
6721       /* Shut off async mode */
6722       vam->async_mode = 0;
6723
6724       M (CONTROL_PING, mp_ping);
6725       S (mp_ping);
6726
6727       timeout = vat_time_now (vam) + 1.0;
6728       while (vat_time_now (vam) < timeout)
6729         if (vam->result_ready == 1)
6730           goto out;
6731       vam->retval = -99;
6732
6733     out:
6734       if (vam->retval == -99)
6735         errmsg ("timeout");
6736
6737       if (vam->async_errors > 0)
6738         {
6739           errmsg ("%d asynchronous errors", vam->async_errors);
6740           vam->retval = -98;
6741         }
6742       vam->async_errors = 0;
6743       after = vat_time_now (vam);
6744
6745       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6746       if (j > 0)
6747         count = j;
6748
6749       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6750              count, after - before, count / (after - before));
6751     }
6752   else
6753     {
6754       int ret;
6755
6756       /* Wait for a reply... */
6757       W (ret);
6758       return ret;
6759     }
6760
6761   /* Return the good/bad news */
6762   return (vam->retval);
6763 }
6764
6765 static int
6766 api_mpls_ip_bind_unbind (vat_main_t * vam)
6767 {
6768   unformat_input_t *i = vam->input;
6769   vl_api_mpls_ip_bind_unbind_t *mp;
6770   u32 ip_table_id = 0;
6771   u8 create_table_if_needed = 0;
6772   u8 is_bind = 1;
6773   u8 is_ip4 = 1;
6774   ip4_address_t v4_address;
6775   ip6_address_t v6_address;
6776   u32 address_length;
6777   u8 address_set = 0;
6778   mpls_label_t local_label = MPLS_LABEL_INVALID;
6779   int ret;
6780
6781   /* Parse args required to build the message */
6782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6783     {
6784       if (unformat (i, "%U/%d", unformat_ip4_address,
6785                     &v4_address, &address_length))
6786         {
6787           is_ip4 = 1;
6788           address_set = 1;
6789         }
6790       else if (unformat (i, "%U/%d", unformat_ip6_address,
6791                          &v6_address, &address_length))
6792         {
6793           is_ip4 = 0;
6794           address_set = 1;
6795         }
6796       else if (unformat (i, "%d", &local_label))
6797         ;
6798       else if (unformat (i, "create-table"))
6799         create_table_if_needed = 1;
6800       else if (unformat (i, "table-id %d", &ip_table_id))
6801         ;
6802       else if (unformat (i, "unbind"))
6803         is_bind = 0;
6804       else if (unformat (i, "bind"))
6805         is_bind = 1;
6806       else
6807         {
6808           clib_warning ("parse error '%U'", format_unformat_error, i);
6809           return -99;
6810         }
6811     }
6812
6813   if (!address_set)
6814     {
6815       errmsg ("IP addres not set");
6816       return -99;
6817     }
6818
6819   if (MPLS_LABEL_INVALID == local_label)
6820     {
6821       errmsg ("missing label");
6822       return -99;
6823     }
6824
6825   /* Construct the API message */
6826   M (MPLS_IP_BIND_UNBIND, mp);
6827
6828   mp->mb_create_table_if_needed = create_table_if_needed;
6829   mp->mb_is_bind = is_bind;
6830   mp->mb_is_ip4 = is_ip4;
6831   mp->mb_ip_table_id = ntohl (ip_table_id);
6832   mp->mb_mpls_table_id = 0;
6833   mp->mb_label = ntohl (local_label);
6834   mp->mb_address_length = address_length;
6835
6836   if (is_ip4)
6837     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6838   else
6839     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6840
6841   /* send it... */
6842   S (mp);
6843
6844   /* Wait for a reply... */
6845   W (ret);
6846   return ret;
6847 }
6848
6849 static int
6850 api_proxy_arp_add_del (vat_main_t * vam)
6851 {
6852   unformat_input_t *i = vam->input;
6853   vl_api_proxy_arp_add_del_t *mp;
6854   u32 vrf_id = 0;
6855   u8 is_add = 1;
6856   ip4_address_t lo, hi;
6857   u8 range_set = 0;
6858   int ret;
6859
6860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6861     {
6862       if (unformat (i, "vrf %d", &vrf_id))
6863         ;
6864       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6865                          unformat_ip4_address, &hi))
6866         range_set = 1;
6867       else if (unformat (i, "del"))
6868         is_add = 0;
6869       else
6870         {
6871           clib_warning ("parse error '%U'", format_unformat_error, i);
6872           return -99;
6873         }
6874     }
6875
6876   if (range_set == 0)
6877     {
6878       errmsg ("address range not set");
6879       return -99;
6880     }
6881
6882   M (PROXY_ARP_ADD_DEL, mp);
6883
6884   mp->vrf_id = ntohl (vrf_id);
6885   mp->is_add = is_add;
6886   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6887   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6888
6889   S (mp);
6890   W (ret);
6891   return ret;
6892 }
6893
6894 static int
6895 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6896 {
6897   unformat_input_t *i = vam->input;
6898   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6899   u32 sw_if_index;
6900   u8 enable = 1;
6901   u8 sw_if_index_set = 0;
6902   int ret;
6903
6904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6905     {
6906       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6907         sw_if_index_set = 1;
6908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6909         sw_if_index_set = 1;
6910       else if (unformat (i, "enable"))
6911         enable = 1;
6912       else if (unformat (i, "disable"))
6913         enable = 0;
6914       else
6915         {
6916           clib_warning ("parse error '%U'", format_unformat_error, i);
6917           return -99;
6918         }
6919     }
6920
6921   if (sw_if_index_set == 0)
6922     {
6923       errmsg ("missing interface name or sw_if_index");
6924       return -99;
6925     }
6926
6927   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
6928
6929   mp->sw_if_index = ntohl (sw_if_index);
6930   mp->enable_disable = enable;
6931
6932   S (mp);
6933   W (ret);
6934   return ret;
6935 }
6936
6937 static int
6938 api_mpls_tunnel_add_del (vat_main_t * vam)
6939 {
6940   unformat_input_t *i = vam->input;
6941   vl_api_mpls_tunnel_add_del_t *mp;
6942
6943   u8 is_add = 1;
6944   u8 l2_only = 0;
6945   u32 sw_if_index = ~0;
6946   u32 next_hop_sw_if_index = ~0;
6947   u32 next_hop_proto_is_ip4 = 1;
6948
6949   u32 next_hop_table_id = 0;
6950   ip4_address_t v4_next_hop_address = {
6951     .as_u32 = 0,
6952   };
6953   ip6_address_t v6_next_hop_address = { {0} };
6954   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6955   int ret;
6956
6957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6958     {
6959       if (unformat (i, "add"))
6960         is_add = 1;
6961       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6962         is_add = 0;
6963       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6964         ;
6965       else if (unformat (i, "via %U",
6966                          unformat_ip4_address, &v4_next_hop_address))
6967         {
6968           next_hop_proto_is_ip4 = 1;
6969         }
6970       else if (unformat (i, "via %U",
6971                          unformat_ip6_address, &v6_next_hop_address))
6972         {
6973           next_hop_proto_is_ip4 = 0;
6974         }
6975       else if (unformat (i, "l2-only"))
6976         l2_only = 1;
6977       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6978         ;
6979       else if (unformat (i, "out-label %d", &next_hop_out_label))
6980         vec_add1 (labels, ntohl (next_hop_out_label));
6981       else
6982         {
6983           clib_warning ("parse error '%U'", format_unformat_error, i);
6984           return -99;
6985         }
6986     }
6987
6988   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
6989
6990   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6991   mp->mt_sw_if_index = ntohl (sw_if_index);
6992   mp->mt_is_add = is_add;
6993   mp->mt_l2_only = l2_only;
6994   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6995   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6996
6997   mp->mt_next_hop_n_out_labels = vec_len (labels);
6998
6999   if (0 != mp->mt_next_hop_n_out_labels)
7000     {
7001       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7002                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7003       vec_free (labels);
7004     }
7005
7006   if (next_hop_proto_is_ip4)
7007     {
7008       clib_memcpy (mp->mt_next_hop,
7009                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7010     }
7011   else
7012     {
7013       clib_memcpy (mp->mt_next_hop,
7014                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7015     }
7016
7017   S (mp);
7018   W (ret);
7019   return ret;
7020 }
7021
7022 static int
7023 api_sw_interface_set_unnumbered (vat_main_t * vam)
7024 {
7025   unformat_input_t *i = vam->input;
7026   vl_api_sw_interface_set_unnumbered_t *mp;
7027   u32 sw_if_index;
7028   u32 unnum_sw_index = ~0;
7029   u8 is_add = 1;
7030   u8 sw_if_index_set = 0;
7031   int ret;
7032
7033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7034     {
7035       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7036         sw_if_index_set = 1;
7037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7038         sw_if_index_set = 1;
7039       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7040         ;
7041       else if (unformat (i, "del"))
7042         is_add = 0;
7043       else
7044         {
7045           clib_warning ("parse error '%U'", format_unformat_error, i);
7046           return -99;
7047         }
7048     }
7049
7050   if (sw_if_index_set == 0)
7051     {
7052       errmsg ("missing interface name or sw_if_index");
7053       return -99;
7054     }
7055
7056   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7057
7058   mp->sw_if_index = ntohl (sw_if_index);
7059   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7060   mp->is_add = is_add;
7061
7062   S (mp);
7063   W (ret);
7064   return ret;
7065 }
7066
7067 static int
7068 api_ip_neighbor_add_del (vat_main_t * vam)
7069 {
7070   unformat_input_t *i = vam->input;
7071   vl_api_ip_neighbor_add_del_t *mp;
7072   u32 sw_if_index;
7073   u8 sw_if_index_set = 0;
7074   u32 vrf_id = 0;
7075   u8 is_add = 1;
7076   u8 is_static = 0;
7077   u8 mac_address[6];
7078   u8 mac_set = 0;
7079   u8 v4_address_set = 0;
7080   u8 v6_address_set = 0;
7081   ip4_address_t v4address;
7082   ip6_address_t v6address;
7083   int ret;
7084
7085   memset (mac_address, 0, sizeof (mac_address));
7086
7087   /* Parse args required to build the message */
7088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7089     {
7090       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7091         {
7092           mac_set = 1;
7093         }
7094       else if (unformat (i, "del"))
7095         is_add = 0;
7096       else
7097         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7098         sw_if_index_set = 1;
7099       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7100         sw_if_index_set = 1;
7101       else if (unformat (i, "is_static"))
7102         is_static = 1;
7103       else if (unformat (i, "vrf %d", &vrf_id))
7104         ;
7105       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7106         v4_address_set = 1;
7107       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7108         v6_address_set = 1;
7109       else
7110         {
7111           clib_warning ("parse error '%U'", format_unformat_error, i);
7112           return -99;
7113         }
7114     }
7115
7116   if (sw_if_index_set == 0)
7117     {
7118       errmsg ("missing interface name or sw_if_index");
7119       return -99;
7120     }
7121   if (v4_address_set && v6_address_set)
7122     {
7123       errmsg ("both v4 and v6 addresses set");
7124       return -99;
7125     }
7126   if (!v4_address_set && !v6_address_set)
7127     {
7128       errmsg ("no address set");
7129       return -99;
7130     }
7131
7132   /* Construct the API message */
7133   M (IP_NEIGHBOR_ADD_DEL, mp);
7134
7135   mp->sw_if_index = ntohl (sw_if_index);
7136   mp->is_add = is_add;
7137   mp->vrf_id = ntohl (vrf_id);
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   W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15433   return ret;
15434 }
15435
15436 static int
15437 api_af_packet_delete (vat_main_t * vam)
15438 {
15439   unformat_input_t *i = vam->input;
15440   vl_api_af_packet_delete_t *mp;
15441   u8 *host_if_name = 0;
15442   int ret;
15443
15444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15445     {
15446       if (unformat (i, "name %s", &host_if_name))
15447         vec_add1 (host_if_name, 0);
15448       else
15449         break;
15450     }
15451
15452   if (!vec_len (host_if_name))
15453     {
15454       errmsg ("host-interface name must be specified");
15455       return -99;
15456     }
15457
15458   if (vec_len (host_if_name) > 64)
15459     {
15460       errmsg ("host-interface name too long");
15461       return -99;
15462     }
15463
15464   M (AF_PACKET_DELETE, mp);
15465
15466   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15467   vec_free (host_if_name);
15468
15469   S (mp);
15470   W (ret);
15471   return ret;
15472 }
15473
15474 static int
15475 api_policer_add_del (vat_main_t * vam)
15476 {
15477   unformat_input_t *i = vam->input;
15478   vl_api_policer_add_del_t *mp;
15479   u8 is_add = 1;
15480   u8 *name = 0;
15481   u32 cir = 0;
15482   u32 eir = 0;
15483   u64 cb = 0;
15484   u64 eb = 0;
15485   u8 rate_type = 0;
15486   u8 round_type = 0;
15487   u8 type = 0;
15488   u8 color_aware = 0;
15489   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15490   int ret;
15491
15492   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15493   conform_action.dscp = 0;
15494   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15495   exceed_action.dscp = 0;
15496   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15497   violate_action.dscp = 0;
15498
15499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15500     {
15501       if (unformat (i, "del"))
15502         is_add = 0;
15503       else if (unformat (i, "name %s", &name))
15504         vec_add1 (name, 0);
15505       else if (unformat (i, "cir %u", &cir))
15506         ;
15507       else if (unformat (i, "eir %u", &eir))
15508         ;
15509       else if (unformat (i, "cb %u", &cb))
15510         ;
15511       else if (unformat (i, "eb %u", &eb))
15512         ;
15513       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15514                          &rate_type))
15515         ;
15516       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15517                          &round_type))
15518         ;
15519       else if (unformat (i, "type %U", unformat_policer_type, &type))
15520         ;
15521       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15522                          &conform_action))
15523         ;
15524       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15525                          &exceed_action))
15526         ;
15527       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15528                          &violate_action))
15529         ;
15530       else if (unformat (i, "color-aware"))
15531         color_aware = 1;
15532       else
15533         break;
15534     }
15535
15536   if (!vec_len (name))
15537     {
15538       errmsg ("policer name must be specified");
15539       return -99;
15540     }
15541
15542   if (vec_len (name) > 64)
15543     {
15544       errmsg ("policer name too long");
15545       return -99;
15546     }
15547
15548   M (POLICER_ADD_DEL, mp);
15549
15550   clib_memcpy (mp->name, name, vec_len (name));
15551   vec_free (name);
15552   mp->is_add = is_add;
15553   mp->cir = cir;
15554   mp->eir = eir;
15555   mp->cb = cb;
15556   mp->eb = eb;
15557   mp->rate_type = rate_type;
15558   mp->round_type = round_type;
15559   mp->type = type;
15560   mp->conform_action_type = conform_action.action_type;
15561   mp->conform_dscp = conform_action.dscp;
15562   mp->exceed_action_type = exceed_action.action_type;
15563   mp->exceed_dscp = exceed_action.dscp;
15564   mp->violate_action_type = violate_action.action_type;
15565   mp->violate_dscp = violate_action.dscp;
15566   mp->color_aware = color_aware;
15567
15568   S (mp);
15569   W (ret);
15570   return ret;
15571 }
15572
15573 static int
15574 api_policer_dump (vat_main_t * vam)
15575 {
15576   unformat_input_t *i = vam->input;
15577   vl_api_policer_dump_t *mp;
15578   vl_api_control_ping_t *mp_ping;
15579   u8 *match_name = 0;
15580   u8 match_name_valid = 0;
15581   int ret;
15582
15583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15584     {
15585       if (unformat (i, "name %s", &match_name))
15586         {
15587           vec_add1 (match_name, 0);
15588           match_name_valid = 1;
15589         }
15590       else
15591         break;
15592     }
15593
15594   M (POLICER_DUMP, mp);
15595   mp->match_name_valid = match_name_valid;
15596   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15597   vec_free (match_name);
15598   /* send it... */
15599   S (mp);
15600
15601   /* Use a control ping for synchronization */
15602   M (CONTROL_PING, mp_ping);
15603   S (mp_ping);
15604
15605   /* Wait for a reply... */
15606   W (ret);
15607   return ret;
15608 }
15609
15610 static int
15611 api_policer_classify_set_interface (vat_main_t * vam)
15612 {
15613   unformat_input_t *i = vam->input;
15614   vl_api_policer_classify_set_interface_t *mp;
15615   u32 sw_if_index;
15616   int sw_if_index_set;
15617   u32 ip4_table_index = ~0;
15618   u32 ip6_table_index = ~0;
15619   u32 l2_table_index = ~0;
15620   u8 is_add = 1;
15621   int ret;
15622
15623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15624     {
15625       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15626         sw_if_index_set = 1;
15627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15628         sw_if_index_set = 1;
15629       else if (unformat (i, "del"))
15630         is_add = 0;
15631       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15632         ;
15633       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15634         ;
15635       else if (unformat (i, "l2-table %d", &l2_table_index))
15636         ;
15637       else
15638         {
15639           clib_warning ("parse error '%U'", format_unformat_error, i);
15640           return -99;
15641         }
15642     }
15643
15644   if (sw_if_index_set == 0)
15645     {
15646       errmsg ("missing interface name or sw_if_index");
15647       return -99;
15648     }
15649
15650   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15651
15652   mp->sw_if_index = ntohl (sw_if_index);
15653   mp->ip4_table_index = ntohl (ip4_table_index);
15654   mp->ip6_table_index = ntohl (ip6_table_index);
15655   mp->l2_table_index = ntohl (l2_table_index);
15656   mp->is_add = is_add;
15657
15658   S (mp);
15659   W (ret);
15660   return ret;
15661 }
15662
15663 static int
15664 api_policer_classify_dump (vat_main_t * vam)
15665 {
15666   unformat_input_t *i = vam->input;
15667   vl_api_policer_classify_dump_t *mp;
15668   vl_api_control_ping_t *mp_ping;
15669   u8 type = POLICER_CLASSIFY_N_TABLES;
15670   int ret;
15671
15672   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15673     ;
15674   else
15675     {
15676       errmsg ("classify table type must be specified");
15677       return -99;
15678     }
15679
15680   if (!vam->json_output)
15681     {
15682       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15683     }
15684
15685   M (POLICER_CLASSIFY_DUMP, mp);
15686   mp->type = type;
15687   /* send it... */
15688   S (mp);
15689
15690   /* Use a control ping for synchronization */
15691   M (CONTROL_PING, mp_ping);
15692   S (mp_ping);
15693
15694   /* Wait for a reply... */
15695   W (ret);
15696   return ret;
15697 }
15698
15699 static int
15700 api_netmap_create (vat_main_t * vam)
15701 {
15702   unformat_input_t *i = vam->input;
15703   vl_api_netmap_create_t *mp;
15704   u8 *if_name = 0;
15705   u8 hw_addr[6];
15706   u8 random_hw_addr = 1;
15707   u8 is_pipe = 0;
15708   u8 is_master = 0;
15709   int ret;
15710
15711   memset (hw_addr, 0, sizeof (hw_addr));
15712
15713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15714     {
15715       if (unformat (i, "name %s", &if_name))
15716         vec_add1 (if_name, 0);
15717       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15718         random_hw_addr = 0;
15719       else if (unformat (i, "pipe"))
15720         is_pipe = 1;
15721       else if (unformat (i, "master"))
15722         is_master = 1;
15723       else if (unformat (i, "slave"))
15724         is_master = 0;
15725       else
15726         break;
15727     }
15728
15729   if (!vec_len (if_name))
15730     {
15731       errmsg ("interface name must be specified");
15732       return -99;
15733     }
15734
15735   if (vec_len (if_name) > 64)
15736     {
15737       errmsg ("interface name too long");
15738       return -99;
15739     }
15740
15741   M (NETMAP_CREATE, mp);
15742
15743   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15744   clib_memcpy (mp->hw_addr, hw_addr, 6);
15745   mp->use_random_hw_addr = random_hw_addr;
15746   mp->is_pipe = is_pipe;
15747   mp->is_master = is_master;
15748   vec_free (if_name);
15749
15750   S (mp);
15751   W (ret);
15752   return ret;
15753 }
15754
15755 static int
15756 api_netmap_delete (vat_main_t * vam)
15757 {
15758   unformat_input_t *i = vam->input;
15759   vl_api_netmap_delete_t *mp;
15760   u8 *if_name = 0;
15761   int ret;
15762
15763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15764     {
15765       if (unformat (i, "name %s", &if_name))
15766         vec_add1 (if_name, 0);
15767       else
15768         break;
15769     }
15770
15771   if (!vec_len (if_name))
15772     {
15773       errmsg ("interface name must be specified");
15774       return -99;
15775     }
15776
15777   if (vec_len (if_name) > 64)
15778     {
15779       errmsg ("interface name too long");
15780       return -99;
15781     }
15782
15783   M (NETMAP_DELETE, mp);
15784
15785   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15786   vec_free (if_name);
15787
15788   S (mp);
15789   W (ret);
15790   return ret;
15791 }
15792
15793 static void vl_api_mpls_tunnel_details_t_handler
15794   (vl_api_mpls_tunnel_details_t * mp)
15795 {
15796   vat_main_t *vam = &vat_main;
15797   i32 len = mp->mt_next_hop_n_labels;
15798   i32 i;
15799
15800   print (vam->ofp, "[%d]: via %U %d labels ",
15801          mp->tunnel_index,
15802          format_ip4_address, mp->mt_next_hop,
15803          ntohl (mp->mt_next_hop_sw_if_index));
15804   for (i = 0; i < len; i++)
15805     {
15806       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15807     }
15808   print (vam->ofp, "");
15809 }
15810
15811 static void vl_api_mpls_tunnel_details_t_handler_json
15812   (vl_api_mpls_tunnel_details_t * mp)
15813 {
15814   vat_main_t *vam = &vat_main;
15815   vat_json_node_t *node = NULL;
15816   struct in_addr ip4;
15817   i32 i;
15818   i32 len = mp->mt_next_hop_n_labels;
15819
15820   if (VAT_JSON_ARRAY != vam->json_tree.type)
15821     {
15822       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15823       vat_json_init_array (&vam->json_tree);
15824     }
15825   node = vat_json_array_add (&vam->json_tree);
15826
15827   vat_json_init_object (node);
15828   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15829   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15830   vat_json_object_add_ip4 (node, "next_hop", ip4);
15831   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15832                             ntohl (mp->mt_next_hop_sw_if_index));
15833   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15834   vat_json_object_add_uint (node, "label_count", len);
15835   for (i = 0; i < len; i++)
15836     {
15837       vat_json_object_add_uint (node, "label",
15838                                 ntohl (mp->mt_next_hop_out_labels[i]));
15839     }
15840 }
15841
15842 static int
15843 api_mpls_tunnel_dump (vat_main_t * vam)
15844 {
15845   vl_api_mpls_tunnel_dump_t *mp;
15846   vl_api_control_ping_t *mp_ping;
15847   i32 index = -1;
15848   int ret;
15849
15850   /* Parse args required to build the message */
15851   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15852     {
15853       if (!unformat (vam->input, "tunnel_index %d", &index))
15854         {
15855           index = -1;
15856           break;
15857         }
15858     }
15859
15860   print (vam->ofp, "  tunnel_index %d", index);
15861
15862   M (MPLS_TUNNEL_DUMP, mp);
15863   mp->tunnel_index = htonl (index);
15864   S (mp);
15865
15866   /* Use a control ping for synchronization */
15867   M (CONTROL_PING, mp_ping);
15868   S (mp_ping);
15869
15870   W (ret);
15871   return ret;
15872 }
15873
15874 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15875 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15876
15877 static void
15878 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15879 {
15880   vat_main_t *vam = &vat_main;
15881   int count = ntohl (mp->count);
15882   vl_api_fib_path2_t *fp;
15883   int i;
15884
15885   print (vam->ofp,
15886          "table-id %d, label %u, ess_bit %u",
15887          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15888   fp = mp->path;
15889   for (i = 0; i < count; i++)
15890     {
15891       if (fp->afi == IP46_TYPE_IP6)
15892         print (vam->ofp,
15893                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15894                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15895                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15896                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15897                format_ip6_address, fp->next_hop);
15898       else if (fp->afi == IP46_TYPE_IP4)
15899         print (vam->ofp,
15900                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15901                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15902                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15903                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15904                format_ip4_address, fp->next_hop);
15905       fp++;
15906     }
15907 }
15908
15909 static void vl_api_mpls_fib_details_t_handler_json
15910   (vl_api_mpls_fib_details_t * mp)
15911 {
15912   vat_main_t *vam = &vat_main;
15913   int count = ntohl (mp->count);
15914   vat_json_node_t *node = NULL;
15915   struct in_addr ip4;
15916   struct in6_addr ip6;
15917   vl_api_fib_path2_t *fp;
15918   int i;
15919
15920   if (VAT_JSON_ARRAY != vam->json_tree.type)
15921     {
15922       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15923       vat_json_init_array (&vam->json_tree);
15924     }
15925   node = vat_json_array_add (&vam->json_tree);
15926
15927   vat_json_init_object (node);
15928   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15929   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15930   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15931   vat_json_object_add_uint (node, "path_count", count);
15932   fp = mp->path;
15933   for (i = 0; i < count; i++)
15934     {
15935       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15936       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15937       vat_json_object_add_uint (node, "is_local", fp->is_local);
15938       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15939       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15940       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15941       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15942       if (fp->afi == IP46_TYPE_IP4)
15943         {
15944           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15945           vat_json_object_add_ip4 (node, "next_hop", ip4);
15946         }
15947       else if (fp->afi == IP46_TYPE_IP6)
15948         {
15949           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15950           vat_json_object_add_ip6 (node, "next_hop", ip6);
15951         }
15952     }
15953 }
15954
15955 static int
15956 api_mpls_fib_dump (vat_main_t * vam)
15957 {
15958   vl_api_mpls_fib_dump_t *mp;
15959   vl_api_control_ping_t *mp_ping;
15960   int ret;
15961
15962   M (MPLS_FIB_DUMP, mp);
15963   S (mp);
15964
15965   /* Use a control ping for synchronization */
15966   M (CONTROL_PING, mp_ping);
15967   S (mp_ping);
15968
15969   W (ret);
15970   return ret;
15971 }
15972
15973 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15974 #define vl_api_ip_fib_details_t_print vl_noop_handler
15975
15976 static void
15977 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15978 {
15979   vat_main_t *vam = &vat_main;
15980   int count = ntohl (mp->count);
15981   vl_api_fib_path_t *fp;
15982   int i;
15983
15984   print (vam->ofp,
15985          "table-id %d, prefix %U/%d",
15986          ntohl (mp->table_id), format_ip4_address, mp->address,
15987          mp->address_length);
15988   fp = mp->path;
15989   for (i = 0; i < count; i++)
15990     {
15991       if (fp->afi == IP46_TYPE_IP6)
15992         print (vam->ofp,
15993                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15994                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15995                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15996                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15997                format_ip6_address, fp->next_hop);
15998       else if (fp->afi == IP46_TYPE_IP4)
15999         print (vam->ofp,
16000                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16001                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16002                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16003                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16004                format_ip4_address, fp->next_hop);
16005       fp++;
16006     }
16007 }
16008
16009 static void vl_api_ip_fib_details_t_handler_json
16010   (vl_api_ip_fib_details_t * mp)
16011 {
16012   vat_main_t *vam = &vat_main;
16013   int count = ntohl (mp->count);
16014   vat_json_node_t *node = NULL;
16015   struct in_addr ip4;
16016   struct in6_addr ip6;
16017   vl_api_fib_path_t *fp;
16018   int i;
16019
16020   if (VAT_JSON_ARRAY != vam->json_tree.type)
16021     {
16022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16023       vat_json_init_array (&vam->json_tree);
16024     }
16025   node = vat_json_array_add (&vam->json_tree);
16026
16027   vat_json_init_object (node);
16028   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16029   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16030   vat_json_object_add_ip4 (node, "prefix", ip4);
16031   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16032   vat_json_object_add_uint (node, "path_count", count);
16033   fp = mp->path;
16034   for (i = 0; i < count; i++)
16035     {
16036       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16037       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16038       vat_json_object_add_uint (node, "is_local", fp->is_local);
16039       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16040       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16041       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16042       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16043       if (fp->afi == IP46_TYPE_IP4)
16044         {
16045           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16046           vat_json_object_add_ip4 (node, "next_hop", ip4);
16047         }
16048       else if (fp->afi == IP46_TYPE_IP6)
16049         {
16050           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16051           vat_json_object_add_ip6 (node, "next_hop", ip6);
16052         }
16053     }
16054 }
16055
16056 static int
16057 api_ip_fib_dump (vat_main_t * vam)
16058 {
16059   vl_api_ip_fib_dump_t *mp;
16060   vl_api_control_ping_t *mp_ping;
16061   int ret;
16062
16063   M (IP_FIB_DUMP, mp);
16064   S (mp);
16065
16066   /* Use a control ping for synchronization */
16067   M (CONTROL_PING, mp_ping);
16068   S (mp_ping);
16069
16070   W (ret);
16071   return ret;
16072 }
16073
16074 static int
16075 api_ip_mfib_dump (vat_main_t * vam)
16076 {
16077   vl_api_ip_mfib_dump_t *mp;
16078   vl_api_control_ping_t *mp_ping;
16079   int ret;
16080
16081   M (IP_MFIB_DUMP, mp);
16082   S (mp);
16083
16084   /* Use a control ping for synchronization */
16085   M (CONTROL_PING, mp_ping);
16086   S (mp_ping);
16087
16088   W (ret);
16089   return ret;
16090 }
16091
16092 static void vl_api_ip_neighbor_details_t_handler
16093   (vl_api_ip_neighbor_details_t * mp)
16094 {
16095   vat_main_t *vam = &vat_main;
16096
16097   print (vam->ofp, "%c %U %U",
16098          (mp->is_static) ? 'S' : 'D',
16099          format_ethernet_address, &mp->mac_address,
16100          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16101          &mp->ip_address);
16102 }
16103
16104 static void vl_api_ip_neighbor_details_t_handler_json
16105   (vl_api_ip_neighbor_details_t * mp)
16106 {
16107
16108   vat_main_t *vam = &vat_main;
16109   vat_json_node_t *node;
16110   struct in_addr ip4;
16111   struct in6_addr ip6;
16112
16113   if (VAT_JSON_ARRAY != vam->json_tree.type)
16114     {
16115       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16116       vat_json_init_array (&vam->json_tree);
16117     }
16118   node = vat_json_array_add (&vam->json_tree);
16119
16120   vat_json_init_object (node);
16121   vat_json_object_add_string_copy (node, "flag",
16122                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16123                                    "dynamic");
16124
16125   vat_json_object_add_string_copy (node, "link_layer",
16126                                    format (0, "%U", format_ethernet_address,
16127                                            &mp->mac_address));
16128
16129   if (mp->is_ipv6)
16130     {
16131       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16132       vat_json_object_add_ip6 (node, "ip_address", ip6);
16133     }
16134   else
16135     {
16136       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16137       vat_json_object_add_ip4 (node, "ip_address", ip4);
16138     }
16139 }
16140
16141 static int
16142 api_ip_neighbor_dump (vat_main_t * vam)
16143 {
16144   unformat_input_t *i = vam->input;
16145   vl_api_ip_neighbor_dump_t *mp;
16146   vl_api_control_ping_t *mp_ping;
16147   u8 is_ipv6 = 0;
16148   u32 sw_if_index = ~0;
16149   int ret;
16150
16151   /* Parse args required to build the message */
16152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16153     {
16154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16155         ;
16156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16157         ;
16158       else if (unformat (i, "ip6"))
16159         is_ipv6 = 1;
16160       else
16161         break;
16162     }
16163
16164   if (sw_if_index == ~0)
16165     {
16166       errmsg ("missing interface name or sw_if_index");
16167       return -99;
16168     }
16169
16170   M (IP_NEIGHBOR_DUMP, mp);
16171   mp->is_ipv6 = (u8) is_ipv6;
16172   mp->sw_if_index = ntohl (sw_if_index);
16173   S (mp);
16174
16175   /* Use a control ping for synchronization */
16176   M (CONTROL_PING, mp_ping);
16177   S (mp_ping);
16178
16179   W (ret);
16180   return ret;
16181 }
16182
16183 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16184 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16185
16186 static void
16187 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16188 {
16189   vat_main_t *vam = &vat_main;
16190   int count = ntohl (mp->count);
16191   vl_api_fib_path_t *fp;
16192   int i;
16193
16194   print (vam->ofp,
16195          "table-id %d, prefix %U/%d",
16196          ntohl (mp->table_id), format_ip6_address, mp->address,
16197          mp->address_length);
16198   fp = mp->path;
16199   for (i = 0; i < count; i++)
16200     {
16201       if (fp->afi == IP46_TYPE_IP6)
16202         print (vam->ofp,
16203                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16204                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16205                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16206                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16207                format_ip6_address, fp->next_hop);
16208       else if (fp->afi == IP46_TYPE_IP4)
16209         print (vam->ofp,
16210                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16211                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16212                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16213                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16214                format_ip4_address, fp->next_hop);
16215       fp++;
16216     }
16217 }
16218
16219 static void vl_api_ip6_fib_details_t_handler_json
16220   (vl_api_ip6_fib_details_t * mp)
16221 {
16222   vat_main_t *vam = &vat_main;
16223   int count = ntohl (mp->count);
16224   vat_json_node_t *node = NULL;
16225   struct in_addr ip4;
16226   struct in6_addr ip6;
16227   vl_api_fib_path_t *fp;
16228   int i;
16229
16230   if (VAT_JSON_ARRAY != vam->json_tree.type)
16231     {
16232       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16233       vat_json_init_array (&vam->json_tree);
16234     }
16235   node = vat_json_array_add (&vam->json_tree);
16236
16237   vat_json_init_object (node);
16238   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16239   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16240   vat_json_object_add_ip6 (node, "prefix", ip6);
16241   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16242   vat_json_object_add_uint (node, "path_count", count);
16243   fp = mp->path;
16244   for (i = 0; i < count; i++)
16245     {
16246       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16247       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16248       vat_json_object_add_uint (node, "is_local", fp->is_local);
16249       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16250       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16251       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16252       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16253       if (fp->afi == IP46_TYPE_IP4)
16254         {
16255           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16256           vat_json_object_add_ip4 (node, "next_hop", ip4);
16257         }
16258       else if (fp->afi == IP46_TYPE_IP6)
16259         {
16260           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16261           vat_json_object_add_ip6 (node, "next_hop", ip6);
16262         }
16263     }
16264 }
16265
16266 static int
16267 api_ip6_fib_dump (vat_main_t * vam)
16268 {
16269   vl_api_ip6_fib_dump_t *mp;
16270   vl_api_control_ping_t *mp_ping;
16271   int ret;
16272
16273   M (IP6_FIB_DUMP, mp);
16274   S (mp);
16275
16276   /* Use a control ping for synchronization */
16277   M (CONTROL_PING, mp_ping);
16278   S (mp_ping);
16279
16280   W (ret);
16281   return ret;
16282 }
16283
16284 static int
16285 api_ip6_mfib_dump (vat_main_t * vam)
16286 {
16287   vl_api_ip6_mfib_dump_t *mp;
16288   vl_api_control_ping_t *mp_ping;
16289   int ret;
16290
16291   M (IP6_MFIB_DUMP, mp);
16292   S (mp);
16293
16294   /* Use a control ping for synchronization */
16295   M (CONTROL_PING, mp_ping);
16296   S (mp_ping);
16297
16298   W (ret);
16299   return ret;
16300 }
16301
16302 int
16303 api_classify_table_ids (vat_main_t * vam)
16304 {
16305   vl_api_classify_table_ids_t *mp;
16306   int ret;
16307
16308   /* Construct the API message */
16309   M (CLASSIFY_TABLE_IDS, mp);
16310   mp->context = 0;
16311
16312   S (mp);
16313   W (ret);
16314   return ret;
16315 }
16316
16317 int
16318 api_classify_table_by_interface (vat_main_t * vam)
16319 {
16320   unformat_input_t *input = vam->input;
16321   vl_api_classify_table_by_interface_t *mp;
16322
16323   u32 sw_if_index = ~0;
16324   int ret;
16325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16326     {
16327       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16328         ;
16329       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16330         ;
16331       else
16332         break;
16333     }
16334   if (sw_if_index == ~0)
16335     {
16336       errmsg ("missing interface name or sw_if_index");
16337       return -99;
16338     }
16339
16340   /* Construct the API message */
16341   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16342   mp->context = 0;
16343   mp->sw_if_index = ntohl (sw_if_index);
16344
16345   S (mp);
16346   W (ret);
16347   return ret;
16348 }
16349
16350 int
16351 api_classify_table_info (vat_main_t * vam)
16352 {
16353   unformat_input_t *input = vam->input;
16354   vl_api_classify_table_info_t *mp;
16355
16356   u32 table_id = ~0;
16357   int ret;
16358   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16359     {
16360       if (unformat (input, "table_id %d", &table_id))
16361         ;
16362       else
16363         break;
16364     }
16365   if (table_id == ~0)
16366     {
16367       errmsg ("missing table id");
16368       return -99;
16369     }
16370
16371   /* Construct the API message */
16372   M (CLASSIFY_TABLE_INFO, mp);
16373   mp->context = 0;
16374   mp->table_id = ntohl (table_id);
16375
16376   S (mp);
16377   W (ret);
16378   return ret;
16379 }
16380
16381 int
16382 api_classify_session_dump (vat_main_t * vam)
16383 {
16384   unformat_input_t *input = vam->input;
16385   vl_api_classify_session_dump_t *mp;
16386   vl_api_control_ping_t *mp_ping;
16387
16388   u32 table_id = ~0;
16389   int ret;
16390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16391     {
16392       if (unformat (input, "table_id %d", &table_id))
16393         ;
16394       else
16395         break;
16396     }
16397   if (table_id == ~0)
16398     {
16399       errmsg ("missing table id");
16400       return -99;
16401     }
16402
16403   /* Construct the API message */
16404   M (CLASSIFY_SESSION_DUMP, mp);
16405   mp->context = 0;
16406   mp->table_id = ntohl (table_id);
16407   S (mp);
16408
16409   /* Use a control ping for synchronization */
16410   M (CONTROL_PING, mp_ping);
16411   S (mp_ping);
16412
16413   W (ret);
16414   return ret;
16415 }
16416
16417 static void
16418 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16419 {
16420   vat_main_t *vam = &vat_main;
16421
16422   print (vam->ofp, "collector_address %U, collector_port %d, "
16423          "src_address %U, vrf_id %d, path_mtu %u, "
16424          "template_interval %u, udp_checksum %d",
16425          format_ip4_address, mp->collector_address,
16426          ntohs (mp->collector_port),
16427          format_ip4_address, mp->src_address,
16428          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16429          ntohl (mp->template_interval), mp->udp_checksum);
16430
16431   vam->retval = 0;
16432   vam->result_ready = 1;
16433 }
16434
16435 static void
16436   vl_api_ipfix_exporter_details_t_handler_json
16437   (vl_api_ipfix_exporter_details_t * mp)
16438 {
16439   vat_main_t *vam = &vat_main;
16440   vat_json_node_t node;
16441   struct in_addr collector_address;
16442   struct in_addr src_address;
16443
16444   vat_json_init_object (&node);
16445   clib_memcpy (&collector_address, &mp->collector_address,
16446                sizeof (collector_address));
16447   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16448   vat_json_object_add_uint (&node, "collector_port",
16449                             ntohs (mp->collector_port));
16450   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16451   vat_json_object_add_ip4 (&node, "src_address", src_address);
16452   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16453   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16454   vat_json_object_add_uint (&node, "template_interval",
16455                             ntohl (mp->template_interval));
16456   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16457
16458   vat_json_print (vam->ofp, &node);
16459   vat_json_free (&node);
16460   vam->retval = 0;
16461   vam->result_ready = 1;
16462 }
16463
16464 int
16465 api_ipfix_exporter_dump (vat_main_t * vam)
16466 {
16467   vl_api_ipfix_exporter_dump_t *mp;
16468   int ret;
16469
16470   /* Construct the API message */
16471   M (IPFIX_EXPORTER_DUMP, mp);
16472   mp->context = 0;
16473
16474   S (mp);
16475   W (ret);
16476   return ret;
16477 }
16478
16479 static int
16480 api_ipfix_classify_stream_dump (vat_main_t * vam)
16481 {
16482   vl_api_ipfix_classify_stream_dump_t *mp;
16483   int ret;
16484
16485   /* Construct the API message */
16486   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16487   mp->context = 0;
16488
16489   S (mp);
16490   W (ret);
16491   return ret;
16492   /* NOTREACHED */
16493   return 0;
16494 }
16495
16496 static void
16497   vl_api_ipfix_classify_stream_details_t_handler
16498   (vl_api_ipfix_classify_stream_details_t * mp)
16499 {
16500   vat_main_t *vam = &vat_main;
16501   print (vam->ofp, "domain_id %d, src_port %d",
16502          ntohl (mp->domain_id), ntohs (mp->src_port));
16503   vam->retval = 0;
16504   vam->result_ready = 1;
16505 }
16506
16507 static void
16508   vl_api_ipfix_classify_stream_details_t_handler_json
16509   (vl_api_ipfix_classify_stream_details_t * mp)
16510 {
16511   vat_main_t *vam = &vat_main;
16512   vat_json_node_t node;
16513
16514   vat_json_init_object (&node);
16515   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16516   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16517
16518   vat_json_print (vam->ofp, &node);
16519   vat_json_free (&node);
16520   vam->retval = 0;
16521   vam->result_ready = 1;
16522 }
16523
16524 static int
16525 api_ipfix_classify_table_dump (vat_main_t * vam)
16526 {
16527   vl_api_ipfix_classify_table_dump_t *mp;
16528   vl_api_control_ping_t *mp_ping;
16529   int ret;
16530
16531   if (!vam->json_output)
16532     {
16533       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16534              "transport_protocol");
16535     }
16536
16537   /* Construct the API message */
16538   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16539
16540   /* send it... */
16541   S (mp);
16542
16543   /* Use a control ping for synchronization */
16544   M (CONTROL_PING, mp_ping);
16545   S (mp_ping);
16546
16547   W (ret);
16548   return ret;
16549 }
16550
16551 static void
16552   vl_api_ipfix_classify_table_details_t_handler
16553   (vl_api_ipfix_classify_table_details_t * mp)
16554 {
16555   vat_main_t *vam = &vat_main;
16556   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16557          mp->transport_protocol);
16558 }
16559
16560 static void
16561   vl_api_ipfix_classify_table_details_t_handler_json
16562   (vl_api_ipfix_classify_table_details_t * mp)
16563 {
16564   vat_json_node_t *node = NULL;
16565   vat_main_t *vam = &vat_main;
16566
16567   if (VAT_JSON_ARRAY != vam->json_tree.type)
16568     {
16569       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16570       vat_json_init_array (&vam->json_tree);
16571     }
16572
16573   node = vat_json_array_add (&vam->json_tree);
16574   vat_json_init_object (node);
16575
16576   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16577   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16578   vat_json_object_add_uint (node, "transport_protocol",
16579                             mp->transport_protocol);
16580 }
16581
16582 static int
16583 api_sw_interface_span_enable_disable (vat_main_t * vam)
16584 {
16585   unformat_input_t *i = vam->input;
16586   vl_api_sw_interface_span_enable_disable_t *mp;
16587   u32 src_sw_if_index = ~0;
16588   u32 dst_sw_if_index = ~0;
16589   u8 state = 3;
16590   int ret;
16591
16592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16593     {
16594       if (unformat
16595           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16596         ;
16597       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16598         ;
16599       else
16600         if (unformat
16601             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16602         ;
16603       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16604         ;
16605       else if (unformat (i, "disable"))
16606         state = 0;
16607       else if (unformat (i, "rx"))
16608         state = 1;
16609       else if (unformat (i, "tx"))
16610         state = 2;
16611       else if (unformat (i, "both"))
16612         state = 3;
16613       else
16614         break;
16615     }
16616
16617   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16618
16619   mp->sw_if_index_from = htonl (src_sw_if_index);
16620   mp->sw_if_index_to = htonl (dst_sw_if_index);
16621   mp->state = state;
16622
16623   S (mp);
16624   W (ret);
16625   return ret;
16626 }
16627
16628 static void
16629 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16630                                             * mp)
16631 {
16632   vat_main_t *vam = &vat_main;
16633   u8 *sw_if_from_name = 0;
16634   u8 *sw_if_to_name = 0;
16635   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16636   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16637   char *states[] = { "none", "rx", "tx", "both" };
16638   hash_pair_t *p;
16639
16640   /* *INDENT-OFF* */
16641   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16642   ({
16643     if ((u32) p->value[0] == sw_if_index_from)
16644       {
16645         sw_if_from_name = (u8 *)(p->key);
16646         if (sw_if_to_name)
16647           break;
16648       }
16649     if ((u32) p->value[0] == sw_if_index_to)
16650       {
16651         sw_if_to_name = (u8 *)(p->key);
16652         if (sw_if_from_name)
16653           break;
16654       }
16655   }));
16656   /* *INDENT-ON* */
16657   print (vam->ofp, "%20s => %20s (%s)",
16658          sw_if_from_name, sw_if_to_name, states[mp->state]);
16659 }
16660
16661 static void
16662   vl_api_sw_interface_span_details_t_handler_json
16663   (vl_api_sw_interface_span_details_t * mp)
16664 {
16665   vat_main_t *vam = &vat_main;
16666   vat_json_node_t *node = NULL;
16667   u8 *sw_if_from_name = 0;
16668   u8 *sw_if_to_name = 0;
16669   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16670   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16671   hash_pair_t *p;
16672
16673   /* *INDENT-OFF* */
16674   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16675   ({
16676     if ((u32) p->value[0] == sw_if_index_from)
16677       {
16678         sw_if_from_name = (u8 *)(p->key);
16679         if (sw_if_to_name)
16680           break;
16681       }
16682     if ((u32) p->value[0] == sw_if_index_to)
16683       {
16684         sw_if_to_name = (u8 *)(p->key);
16685         if (sw_if_from_name)
16686           break;
16687       }
16688   }));
16689   /* *INDENT-ON* */
16690
16691   if (VAT_JSON_ARRAY != vam->json_tree.type)
16692     {
16693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16694       vat_json_init_array (&vam->json_tree);
16695     }
16696   node = vat_json_array_add (&vam->json_tree);
16697
16698   vat_json_init_object (node);
16699   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16700   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16701   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16702   if (0 != sw_if_to_name)
16703     {
16704       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16705     }
16706   vat_json_object_add_uint (node, "state", mp->state);
16707 }
16708
16709 static int
16710 api_sw_interface_span_dump (vat_main_t * vam)
16711 {
16712   vl_api_sw_interface_span_dump_t *mp;
16713   vl_api_control_ping_t *mp_ping;
16714   int ret;
16715
16716   M (SW_INTERFACE_SPAN_DUMP, mp);
16717   S (mp);
16718
16719   /* Use a control ping for synchronization */
16720   M (CONTROL_PING, mp_ping);
16721   S (mp_ping);
16722
16723   W (ret);
16724   return ret;
16725 }
16726
16727 int
16728 api_pg_create_interface (vat_main_t * vam)
16729 {
16730   unformat_input_t *input = vam->input;
16731   vl_api_pg_create_interface_t *mp;
16732
16733   u32 if_id = ~0;
16734   int ret;
16735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16736     {
16737       if (unformat (input, "if_id %d", &if_id))
16738         ;
16739       else
16740         break;
16741     }
16742   if (if_id == ~0)
16743     {
16744       errmsg ("missing pg interface index");
16745       return -99;
16746     }
16747
16748   /* Construct the API message */
16749   M (PG_CREATE_INTERFACE, mp);
16750   mp->context = 0;
16751   mp->interface_id = ntohl (if_id);
16752
16753   S (mp);
16754   W (ret);
16755   return ret;
16756 }
16757
16758 int
16759 api_pg_capture (vat_main_t * vam)
16760 {
16761   unformat_input_t *input = vam->input;
16762   vl_api_pg_capture_t *mp;
16763
16764   u32 if_id = ~0;
16765   u8 enable = 1;
16766   u32 count = 1;
16767   u8 pcap_file_set = 0;
16768   u8 *pcap_file = 0;
16769   int ret;
16770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16771     {
16772       if (unformat (input, "if_id %d", &if_id))
16773         ;
16774       else if (unformat (input, "pcap %s", &pcap_file))
16775         pcap_file_set = 1;
16776       else if (unformat (input, "count %d", &count))
16777         ;
16778       else if (unformat (input, "disable"))
16779         enable = 0;
16780       else
16781         break;
16782     }
16783   if (if_id == ~0)
16784     {
16785       errmsg ("missing pg interface index");
16786       return -99;
16787     }
16788   if (pcap_file_set > 0)
16789     {
16790       if (vec_len (pcap_file) > 255)
16791         {
16792           errmsg ("pcap file name is too long");
16793           return -99;
16794         }
16795     }
16796
16797   u32 name_len = vec_len (pcap_file);
16798   /* Construct the API message */
16799   M (PG_CAPTURE, mp);
16800   mp->context = 0;
16801   mp->interface_id = ntohl (if_id);
16802   mp->is_enabled = enable;
16803   mp->count = ntohl (count);
16804   mp->pcap_name_length = ntohl (name_len);
16805   if (pcap_file_set != 0)
16806     {
16807       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16808     }
16809   vec_free (pcap_file);
16810
16811   S (mp);
16812   W (ret);
16813   return ret;
16814 }
16815
16816 int
16817 api_pg_enable_disable (vat_main_t * vam)
16818 {
16819   unformat_input_t *input = vam->input;
16820   vl_api_pg_enable_disable_t *mp;
16821
16822   u8 enable = 1;
16823   u8 stream_name_set = 0;
16824   u8 *stream_name = 0;
16825   int ret;
16826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16827     {
16828       if (unformat (input, "stream %s", &stream_name))
16829         stream_name_set = 1;
16830       else if (unformat (input, "disable"))
16831         enable = 0;
16832       else
16833         break;
16834     }
16835
16836   if (stream_name_set > 0)
16837     {
16838       if (vec_len (stream_name) > 255)
16839         {
16840           errmsg ("stream name too long");
16841           return -99;
16842         }
16843     }
16844
16845   u32 name_len = vec_len (stream_name);
16846   /* Construct the API message */
16847   M (PG_ENABLE_DISABLE, mp);
16848   mp->context = 0;
16849   mp->is_enabled = enable;
16850   if (stream_name_set != 0)
16851     {
16852       mp->stream_name_length = ntohl (name_len);
16853       clib_memcpy (mp->stream_name, stream_name, name_len);
16854     }
16855   vec_free (stream_name);
16856
16857   S (mp);
16858   W (ret);
16859   return ret;
16860 }
16861
16862 int
16863 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16864 {
16865   unformat_input_t *input = vam->input;
16866   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16867
16868   u16 *low_ports = 0;
16869   u16 *high_ports = 0;
16870   u16 this_low;
16871   u16 this_hi;
16872   ip4_address_t ip4_addr;
16873   ip6_address_t ip6_addr;
16874   u32 length;
16875   u32 tmp, tmp2;
16876   u8 prefix_set = 0;
16877   u32 vrf_id = ~0;
16878   u8 is_add = 1;
16879   u8 is_ipv6 = 0;
16880   int ret;
16881
16882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16883     {
16884       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16885         {
16886           prefix_set = 1;
16887         }
16888       else
16889         if (unformat
16890             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16891         {
16892           prefix_set = 1;
16893           is_ipv6 = 1;
16894         }
16895       else if (unformat (input, "vrf %d", &vrf_id))
16896         ;
16897       else if (unformat (input, "del"))
16898         is_add = 0;
16899       else if (unformat (input, "port %d", &tmp))
16900         {
16901           if (tmp == 0 || tmp > 65535)
16902             {
16903               errmsg ("port %d out of range", tmp);
16904               return -99;
16905             }
16906           this_low = tmp;
16907           this_hi = this_low + 1;
16908           vec_add1 (low_ports, this_low);
16909           vec_add1 (high_ports, this_hi);
16910         }
16911       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16912         {
16913           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16914             {
16915               errmsg ("incorrect range parameters");
16916               return -99;
16917             }
16918           this_low = tmp;
16919           /* Note: in debug CLI +1 is added to high before
16920              passing to real fn that does "the work"
16921              (ip_source_and_port_range_check_add_del).
16922              This fn is a wrapper around the binary API fn a
16923              control plane will call, which expects this increment
16924              to have occurred. Hence letting the binary API control
16925              plane fn do the increment for consistency between VAT
16926              and other control planes.
16927            */
16928           this_hi = tmp2;
16929           vec_add1 (low_ports, this_low);
16930           vec_add1 (high_ports, this_hi);
16931         }
16932       else
16933         break;
16934     }
16935
16936   if (prefix_set == 0)
16937     {
16938       errmsg ("<address>/<mask> not specified");
16939       return -99;
16940     }
16941
16942   if (vrf_id == ~0)
16943     {
16944       errmsg ("VRF ID required, not specified");
16945       return -99;
16946     }
16947
16948   if (vrf_id == 0)
16949     {
16950       errmsg
16951         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16952       return -99;
16953     }
16954
16955   if (vec_len (low_ports) == 0)
16956     {
16957       errmsg ("At least one port or port range required");
16958       return -99;
16959     }
16960
16961   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
16962
16963   mp->is_add = is_add;
16964
16965   if (is_ipv6)
16966     {
16967       mp->is_ipv6 = 1;
16968       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16969     }
16970   else
16971     {
16972       mp->is_ipv6 = 0;
16973       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16974     }
16975
16976   mp->mask_length = length;
16977   mp->number_of_ranges = vec_len (low_ports);
16978
16979   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16980   vec_free (low_ports);
16981
16982   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16983   vec_free (high_ports);
16984
16985   mp->vrf_id = ntohl (vrf_id);
16986
16987   S (mp);
16988   W (ret);
16989   return ret;
16990 }
16991
16992 int
16993 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16994 {
16995   unformat_input_t *input = vam->input;
16996   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16997   u32 sw_if_index = ~0;
16998   int vrf_set = 0;
16999   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17000   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17001   u8 is_add = 1;
17002   int ret;
17003
17004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17005     {
17006       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17007         ;
17008       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17009         ;
17010       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17011         vrf_set = 1;
17012       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17013         vrf_set = 1;
17014       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17015         vrf_set = 1;
17016       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17017         vrf_set = 1;
17018       else if (unformat (input, "del"))
17019         is_add = 0;
17020       else
17021         break;
17022     }
17023
17024   if (sw_if_index == ~0)
17025     {
17026       errmsg ("Interface required but not specified");
17027       return -99;
17028     }
17029
17030   if (vrf_set == 0)
17031     {
17032       errmsg ("VRF ID required but not specified");
17033       return -99;
17034     }
17035
17036   if (tcp_out_vrf_id == 0
17037       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17038     {
17039       errmsg
17040         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17041       return -99;
17042     }
17043
17044   /* Construct the API message */
17045   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17046
17047   mp->sw_if_index = ntohl (sw_if_index);
17048   mp->is_add = is_add;
17049   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17050   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17051   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17052   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17053
17054   /* send it... */
17055   S (mp);
17056
17057   /* Wait for a reply... */
17058   W (ret);
17059   return ret;
17060 }
17061
17062 static int
17063 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17064 {
17065   unformat_input_t *i = vam->input;
17066   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17067   u32 local_sa_id = 0;
17068   u32 remote_sa_id = 0;
17069   ip4_address_t src_address;
17070   ip4_address_t dst_address;
17071   u8 is_add = 1;
17072   int ret;
17073
17074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17075     {
17076       if (unformat (i, "local_sa %d", &local_sa_id))
17077         ;
17078       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17079         ;
17080       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17081         ;
17082       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17083         ;
17084       else if (unformat (i, "del"))
17085         is_add = 0;
17086       else
17087         {
17088           clib_warning ("parse error '%U'", format_unformat_error, i);
17089           return -99;
17090         }
17091     }
17092
17093   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17094
17095   mp->local_sa_id = ntohl (local_sa_id);
17096   mp->remote_sa_id = ntohl (remote_sa_id);
17097   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17098   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17099   mp->is_add = is_add;
17100
17101   S (mp);
17102   W (ret);
17103   return ret;
17104 }
17105
17106 static int
17107 api_punt (vat_main_t * vam)
17108 {
17109   unformat_input_t *i = vam->input;
17110   vl_api_punt_t *mp;
17111   u32 ipv = ~0;
17112   u32 protocol = ~0;
17113   u32 port = ~0;
17114   int is_add = 1;
17115   int ret;
17116
17117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17118     {
17119       if (unformat (i, "ip %d", &ipv))
17120         ;
17121       else if (unformat (i, "protocol %d", &protocol))
17122         ;
17123       else if (unformat (i, "port %d", &port))
17124         ;
17125       else if (unformat (i, "del"))
17126         is_add = 0;
17127       else
17128         {
17129           clib_warning ("parse error '%U'", format_unformat_error, i);
17130           return -99;
17131         }
17132     }
17133
17134   M (PUNT, mp);
17135
17136   mp->is_add = (u8) is_add;
17137   mp->ipv = (u8) ipv;
17138   mp->l4_protocol = (u8) protocol;
17139   mp->l4_port = htons ((u16) port);
17140
17141   S (mp);
17142   W (ret);
17143   return ret;
17144 }
17145
17146 static void vl_api_ipsec_gre_tunnel_details_t_handler
17147   (vl_api_ipsec_gre_tunnel_details_t * mp)
17148 {
17149   vat_main_t *vam = &vat_main;
17150
17151   print (vam->ofp, "%11d%15U%15U%14d%14d",
17152          ntohl (mp->sw_if_index),
17153          format_ip4_address, &mp->src_address,
17154          format_ip4_address, &mp->dst_address,
17155          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17156 }
17157
17158 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17159   (vl_api_ipsec_gre_tunnel_details_t * mp)
17160 {
17161   vat_main_t *vam = &vat_main;
17162   vat_json_node_t *node = NULL;
17163   struct in_addr ip4;
17164
17165   if (VAT_JSON_ARRAY != vam->json_tree.type)
17166     {
17167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17168       vat_json_init_array (&vam->json_tree);
17169     }
17170   node = vat_json_array_add (&vam->json_tree);
17171
17172   vat_json_init_object (node);
17173   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17174   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17175   vat_json_object_add_ip4 (node, "src_address", ip4);
17176   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17177   vat_json_object_add_ip4 (node, "dst_address", ip4);
17178   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17179   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17180 }
17181
17182 static int
17183 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17184 {
17185   unformat_input_t *i = vam->input;
17186   vl_api_ipsec_gre_tunnel_dump_t *mp;
17187   vl_api_control_ping_t *mp_ping;
17188   u32 sw_if_index;
17189   u8 sw_if_index_set = 0;
17190   int ret;
17191
17192   /* Parse args required to build the message */
17193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17194     {
17195       if (unformat (i, "sw_if_index %d", &sw_if_index))
17196         sw_if_index_set = 1;
17197       else
17198         break;
17199     }
17200
17201   if (sw_if_index_set == 0)
17202     {
17203       sw_if_index = ~0;
17204     }
17205
17206   if (!vam->json_output)
17207     {
17208       print (vam->ofp, "%11s%15s%15s%14s%14s",
17209              "sw_if_index", "src_address", "dst_address",
17210              "local_sa_id", "remote_sa_id");
17211     }
17212
17213   /* Get list of gre-tunnel interfaces */
17214   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17215
17216   mp->sw_if_index = htonl (sw_if_index);
17217
17218   S (mp);
17219
17220   /* Use a control ping for synchronization */
17221   M (CONTROL_PING, mp_ping);
17222   S (mp_ping);
17223
17224   W (ret);
17225   return ret;
17226 }
17227
17228 static int
17229 api_delete_subif (vat_main_t * vam)
17230 {
17231   unformat_input_t *i = vam->input;
17232   vl_api_delete_subif_t *mp;
17233   u32 sw_if_index = ~0;
17234   int ret;
17235
17236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17237     {
17238       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17239         ;
17240       if (unformat (i, "sw_if_index %d", &sw_if_index))
17241         ;
17242       else
17243         break;
17244     }
17245
17246   if (sw_if_index == ~0)
17247     {
17248       errmsg ("missing sw_if_index");
17249       return -99;
17250     }
17251
17252   /* Construct the API message */
17253   M (DELETE_SUBIF, mp);
17254   mp->sw_if_index = ntohl (sw_if_index);
17255
17256   S (mp);
17257   W (ret);
17258   return ret;
17259 }
17260
17261 #define foreach_pbb_vtr_op      \
17262 _("disable",  L2_VTR_DISABLED)  \
17263 _("pop",  L2_VTR_POP_2)         \
17264 _("push",  L2_VTR_PUSH_2)
17265
17266 static int
17267 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17268 {
17269   unformat_input_t *i = vam->input;
17270   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17271   u32 sw_if_index = ~0, vtr_op = ~0;
17272   u16 outer_tag = ~0;
17273   u8 dmac[6], smac[6];
17274   u8 dmac_set = 0, smac_set = 0;
17275   u16 vlanid = 0;
17276   u32 sid = ~0;
17277   u32 tmp;
17278   int ret;
17279
17280   /* Shut up coverity */
17281   memset (dmac, 0, sizeof (dmac));
17282   memset (smac, 0, sizeof (smac));
17283
17284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17285     {
17286       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17287         ;
17288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17289         ;
17290       else if (unformat (i, "vtr_op %d", &vtr_op))
17291         ;
17292 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17293       foreach_pbb_vtr_op
17294 #undef _
17295         else if (unformat (i, "translate_pbb_stag"))
17296         {
17297           if (unformat (i, "%d", &tmp))
17298             {
17299               vtr_op = L2_VTR_TRANSLATE_2_1;
17300               outer_tag = tmp;
17301             }
17302           else
17303             {
17304               errmsg
17305                 ("translate_pbb_stag operation requires outer tag definition");
17306               return -99;
17307             }
17308         }
17309       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17310         dmac_set++;
17311       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17312         smac_set++;
17313       else if (unformat (i, "sid %d", &sid))
17314         ;
17315       else if (unformat (i, "vlanid %d", &tmp))
17316         vlanid = tmp;
17317       else
17318         {
17319           clib_warning ("parse error '%U'", format_unformat_error, i);
17320           return -99;
17321         }
17322     }
17323
17324   if ((sw_if_index == ~0) || (vtr_op == ~0))
17325     {
17326       errmsg ("missing sw_if_index or vtr operation");
17327       return -99;
17328     }
17329   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17330       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17331     {
17332       errmsg
17333         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17334       return -99;
17335     }
17336
17337   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17338   mp->sw_if_index = ntohl (sw_if_index);
17339   mp->vtr_op = ntohl (vtr_op);
17340   mp->outer_tag = ntohs (outer_tag);
17341   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17342   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17343   mp->b_vlanid = ntohs (vlanid);
17344   mp->i_sid = ntohl (sid);
17345
17346   S (mp);
17347   W (ret);
17348   return ret;
17349 }
17350
17351 static int
17352 api_flow_classify_set_interface (vat_main_t * vam)
17353 {
17354   unformat_input_t *i = vam->input;
17355   vl_api_flow_classify_set_interface_t *mp;
17356   u32 sw_if_index;
17357   int sw_if_index_set;
17358   u32 ip4_table_index = ~0;
17359   u32 ip6_table_index = ~0;
17360   u8 is_add = 1;
17361   int ret;
17362
17363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17364     {
17365       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17366         sw_if_index_set = 1;
17367       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17368         sw_if_index_set = 1;
17369       else if (unformat (i, "del"))
17370         is_add = 0;
17371       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17372         ;
17373       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17374         ;
17375       else
17376         {
17377           clib_warning ("parse error '%U'", format_unformat_error, i);
17378           return -99;
17379         }
17380     }
17381
17382   if (sw_if_index_set == 0)
17383     {
17384       errmsg ("missing interface name or sw_if_index");
17385       return -99;
17386     }
17387
17388   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17389
17390   mp->sw_if_index = ntohl (sw_if_index);
17391   mp->ip4_table_index = ntohl (ip4_table_index);
17392   mp->ip6_table_index = ntohl (ip6_table_index);
17393   mp->is_add = is_add;
17394
17395   S (mp);
17396   W (ret);
17397   return ret;
17398 }
17399
17400 static int
17401 api_flow_classify_dump (vat_main_t * vam)
17402 {
17403   unformat_input_t *i = vam->input;
17404   vl_api_flow_classify_dump_t *mp;
17405   vl_api_control_ping_t *mp_ping;
17406   u8 type = FLOW_CLASSIFY_N_TABLES;
17407   int ret;
17408
17409   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17410     ;
17411   else
17412     {
17413       errmsg ("classify table type must be specified");
17414       return -99;
17415     }
17416
17417   if (!vam->json_output)
17418     {
17419       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17420     }
17421
17422   M (FLOW_CLASSIFY_DUMP, mp);
17423   mp->type = type;
17424   /* send it... */
17425   S (mp);
17426
17427   /* Use a control ping for synchronization */
17428   M (CONTROL_PING, mp_ping);
17429   S (mp_ping);
17430
17431   /* Wait for a reply... */
17432   W (ret);
17433   return ret;
17434 }
17435
17436 static int
17437 api_feature_enable_disable (vat_main_t * vam)
17438 {
17439   unformat_input_t *i = vam->input;
17440   vl_api_feature_enable_disable_t *mp;
17441   u8 *arc_name = 0;
17442   u8 *feature_name = 0;
17443   u32 sw_if_index = ~0;
17444   u8 enable = 1;
17445   int ret;
17446
17447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17448     {
17449       if (unformat (i, "arc_name %s", &arc_name))
17450         ;
17451       else if (unformat (i, "feature_name %s", &feature_name))
17452         ;
17453       else
17454         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17455         ;
17456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17457         ;
17458       else if (unformat (i, "disable"))
17459         enable = 0;
17460       else
17461         break;
17462     }
17463
17464   if (arc_name == 0)
17465     {
17466       errmsg ("missing arc name");
17467       return -99;
17468     }
17469   if (vec_len (arc_name) > 63)
17470     {
17471       errmsg ("arc name too long");
17472     }
17473
17474   if (feature_name == 0)
17475     {
17476       errmsg ("missing feature name");
17477       return -99;
17478     }
17479   if (vec_len (feature_name) > 63)
17480     {
17481       errmsg ("feature name too long");
17482     }
17483
17484   if (sw_if_index == ~0)
17485     {
17486       errmsg ("missing interface name or sw_if_index");
17487       return -99;
17488     }
17489
17490   /* Construct the API message */
17491   M (FEATURE_ENABLE_DISABLE, mp);
17492   mp->sw_if_index = ntohl (sw_if_index);
17493   mp->enable = enable;
17494   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17495   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17496   vec_free (arc_name);
17497   vec_free (feature_name);
17498
17499   S (mp);
17500   W (ret);
17501   return ret;
17502 }
17503
17504 static int
17505 api_sw_interface_tag_add_del (vat_main_t * vam)
17506 {
17507   unformat_input_t *i = vam->input;
17508   vl_api_sw_interface_tag_add_del_t *mp;
17509   u32 sw_if_index = ~0;
17510   u8 *tag = 0;
17511   u8 enable = 1;
17512   int ret;
17513
17514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17515     {
17516       if (unformat (i, "tag %s", &tag))
17517         ;
17518       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17519         ;
17520       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17521         ;
17522       else if (unformat (i, "del"))
17523         enable = 0;
17524       else
17525         break;
17526     }
17527
17528   if (sw_if_index == ~0)
17529     {
17530       errmsg ("missing interface name or sw_if_index");
17531       return -99;
17532     }
17533
17534   if (enable && (tag == 0))
17535     {
17536       errmsg ("no tag specified");
17537       return -99;
17538     }
17539
17540   /* Construct the API message */
17541   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17542   mp->sw_if_index = ntohl (sw_if_index);
17543   mp->is_add = enable;
17544   if (enable)
17545     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17546   vec_free (tag);
17547
17548   S (mp);
17549   W (ret);
17550   return ret;
17551 }
17552
17553 static void vl_api_l2_xconnect_details_t_handler
17554   (vl_api_l2_xconnect_details_t * mp)
17555 {
17556   vat_main_t *vam = &vat_main;
17557
17558   print (vam->ofp, "%15d%15d",
17559          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17560 }
17561
17562 static void vl_api_l2_xconnect_details_t_handler_json
17563   (vl_api_l2_xconnect_details_t * mp)
17564 {
17565   vat_main_t *vam = &vat_main;
17566   vat_json_node_t *node = NULL;
17567
17568   if (VAT_JSON_ARRAY != vam->json_tree.type)
17569     {
17570       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17571       vat_json_init_array (&vam->json_tree);
17572     }
17573   node = vat_json_array_add (&vam->json_tree);
17574
17575   vat_json_init_object (node);
17576   vat_json_object_add_uint (node, "rx_sw_if_index",
17577                             ntohl (mp->rx_sw_if_index));
17578   vat_json_object_add_uint (node, "tx_sw_if_index",
17579                             ntohl (mp->tx_sw_if_index));
17580 }
17581
17582 static int
17583 api_l2_xconnect_dump (vat_main_t * vam)
17584 {
17585   vl_api_l2_xconnect_dump_t *mp;
17586   vl_api_control_ping_t *mp_ping;
17587   int ret;
17588
17589   if (!vam->json_output)
17590     {
17591       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17592     }
17593
17594   M (L2_XCONNECT_DUMP, mp);
17595
17596   S (mp);
17597
17598   /* Use a control ping for synchronization */
17599   M (CONTROL_PING, mp_ping);
17600   S (mp_ping);
17601
17602   W (ret);
17603   return ret;
17604 }
17605
17606 static int
17607 api_sw_interface_set_mtu (vat_main_t * vam)
17608 {
17609   unformat_input_t *i = vam->input;
17610   vl_api_sw_interface_set_mtu_t *mp;
17611   u32 sw_if_index = ~0;
17612   u32 mtu = 0;
17613   int ret;
17614
17615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17616     {
17617       if (unformat (i, "mtu %d", &mtu))
17618         ;
17619       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17620         ;
17621       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17622         ;
17623       else
17624         break;
17625     }
17626
17627   if (sw_if_index == ~0)
17628     {
17629       errmsg ("missing interface name or sw_if_index");
17630       return -99;
17631     }
17632
17633   if (mtu == 0)
17634     {
17635       errmsg ("no mtu specified");
17636       return -99;
17637     }
17638
17639   /* Construct the API message */
17640   M (SW_INTERFACE_SET_MTU, mp);
17641   mp->sw_if_index = ntohl (sw_if_index);
17642   mp->mtu = ntohs ((u16) mtu);
17643
17644   S (mp);
17645   W (ret);
17646   return ret;
17647 }
17648
17649
17650 static int
17651 q_or_quit (vat_main_t * vam)
17652 {
17653 #if VPP_API_TEST_BUILTIN == 0
17654   longjmp (vam->jump_buf, 1);
17655 #endif
17656   return 0;                     /* not so much */
17657 }
17658
17659 static int
17660 q (vat_main_t * vam)
17661 {
17662   return q_or_quit (vam);
17663 }
17664
17665 static int
17666 quit (vat_main_t * vam)
17667 {
17668   return q_or_quit (vam);
17669 }
17670
17671 static int
17672 comment (vat_main_t * vam)
17673 {
17674   return 0;
17675 }
17676
17677 static int
17678 cmd_cmp (void *a1, void *a2)
17679 {
17680   u8 **c1 = a1;
17681   u8 **c2 = a2;
17682
17683   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17684 }
17685
17686 static int
17687 help (vat_main_t * vam)
17688 {
17689   u8 **cmds = 0;
17690   u8 *name = 0;
17691   hash_pair_t *p;
17692   unformat_input_t *i = vam->input;
17693   int j;
17694
17695   if (unformat (i, "%s", &name))
17696     {
17697       uword *hs;
17698
17699       vec_add1 (name, 0);
17700
17701       hs = hash_get_mem (vam->help_by_name, name);
17702       if (hs)
17703         print (vam->ofp, "usage: %s %s", name, hs[0]);
17704       else
17705         print (vam->ofp, "No such msg / command '%s'", name);
17706       vec_free (name);
17707       return 0;
17708     }
17709
17710   print (vam->ofp, "Help is available for the following:");
17711
17712     /* *INDENT-OFF* */
17713     hash_foreach_pair (p, vam->function_by_name,
17714     ({
17715       vec_add1 (cmds, (u8 *)(p->key));
17716     }));
17717     /* *INDENT-ON* */
17718
17719   vec_sort_with_function (cmds, cmd_cmp);
17720
17721   for (j = 0; j < vec_len (cmds); j++)
17722     print (vam->ofp, "%s", cmds[j]);
17723
17724   vec_free (cmds);
17725   return 0;
17726 }
17727
17728 static int
17729 set (vat_main_t * vam)
17730 {
17731   u8 *name = 0, *value = 0;
17732   unformat_input_t *i = vam->input;
17733
17734   if (unformat (i, "%s", &name))
17735     {
17736       /* The input buffer is a vector, not a string. */
17737       value = vec_dup (i->buffer);
17738       vec_delete (value, i->index, 0);
17739       /* Almost certainly has a trailing newline */
17740       if (value[vec_len (value) - 1] == '\n')
17741         value[vec_len (value) - 1] = 0;
17742       /* Make sure it's a proper string, one way or the other */
17743       vec_add1 (value, 0);
17744       (void) clib_macro_set_value (&vam->macro_main,
17745                                    (char *) name, (char *) value);
17746     }
17747   else
17748     errmsg ("usage: set <name> <value>");
17749
17750   vec_free (name);
17751   vec_free (value);
17752   return 0;
17753 }
17754
17755 static int
17756 unset (vat_main_t * vam)
17757 {
17758   u8 *name = 0;
17759
17760   if (unformat (vam->input, "%s", &name))
17761     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17762       errmsg ("unset: %s wasn't set", name);
17763   vec_free (name);
17764   return 0;
17765 }
17766
17767 typedef struct
17768 {
17769   u8 *name;
17770   u8 *value;
17771 } macro_sort_t;
17772
17773
17774 static int
17775 macro_sort_cmp (void *a1, void *a2)
17776 {
17777   macro_sort_t *s1 = a1;
17778   macro_sort_t *s2 = a2;
17779
17780   return strcmp ((char *) (s1->name), (char *) (s2->name));
17781 }
17782
17783 static int
17784 dump_macro_table (vat_main_t * vam)
17785 {
17786   macro_sort_t *sort_me = 0, *sm;
17787   int i;
17788   hash_pair_t *p;
17789
17790     /* *INDENT-OFF* */
17791     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17792     ({
17793       vec_add2 (sort_me, sm, 1);
17794       sm->name = (u8 *)(p->key);
17795       sm->value = (u8 *) (p->value[0]);
17796     }));
17797     /* *INDENT-ON* */
17798
17799   vec_sort_with_function (sort_me, macro_sort_cmp);
17800
17801   if (vec_len (sort_me))
17802     print (vam->ofp, "%-15s%s", "Name", "Value");
17803   else
17804     print (vam->ofp, "The macro table is empty...");
17805
17806   for (i = 0; i < vec_len (sort_me); i++)
17807     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17808   return 0;
17809 }
17810
17811 static int
17812 dump_node_table (vat_main_t * vam)
17813 {
17814   int i, j;
17815   vlib_node_t *node, *next_node;
17816
17817   if (vec_len (vam->graph_nodes) == 0)
17818     {
17819       print (vam->ofp, "Node table empty, issue get_node_graph...");
17820       return 0;
17821     }
17822
17823   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17824     {
17825       node = vam->graph_nodes[i];
17826       print (vam->ofp, "[%d] %s", i, node->name);
17827       for (j = 0; j < vec_len (node->next_nodes); j++)
17828         {
17829           if (node->next_nodes[j] != ~0)
17830             {
17831               next_node = vam->graph_nodes[node->next_nodes[j]];
17832               print (vam->ofp, "  [%d] %s", j, next_node->name);
17833             }
17834         }
17835     }
17836   return 0;
17837 }
17838
17839 static int
17840 value_sort_cmp (void *a1, void *a2)
17841 {
17842   name_sort_t *n1 = a1;
17843   name_sort_t *n2 = a2;
17844
17845   if (n1->value < n2->value)
17846     return -1;
17847   if (n1->value > n2->value)
17848     return 1;
17849   return 0;
17850 }
17851
17852
17853 static int
17854 dump_msg_api_table (vat_main_t * vam)
17855 {
17856   api_main_t *am = &api_main;
17857   name_sort_t *nses = 0, *ns;
17858   hash_pair_t *hp;
17859   int i;
17860
17861   /* *INDENT-OFF* */
17862   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17863   ({
17864     vec_add2 (nses, ns, 1);
17865     ns->name = (u8 *)(hp->key);
17866     ns->value = (u32) hp->value[0];
17867   }));
17868   /* *INDENT-ON* */
17869
17870   vec_sort_with_function (nses, value_sort_cmp);
17871
17872   for (i = 0; i < vec_len (nses); i++)
17873     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17874   vec_free (nses);
17875   return 0;
17876 }
17877
17878 static int
17879 get_msg_id (vat_main_t * vam)
17880 {
17881   u8 *name_and_crc;
17882   u32 message_index;
17883
17884   if (unformat (vam->input, "%s", &name_and_crc))
17885     {
17886       message_index = vl_api_get_msg_index (name_and_crc);
17887       if (message_index == ~0)
17888         {
17889           print (vam->ofp, " '%s' not found", name_and_crc);
17890           return 0;
17891         }
17892       print (vam->ofp, " '%s' has message index %d",
17893              name_and_crc, message_index);
17894       return 0;
17895     }
17896   errmsg ("name_and_crc required...");
17897   return 0;
17898 }
17899
17900 static int
17901 search_node_table (vat_main_t * vam)
17902 {
17903   unformat_input_t *line_input = vam->input;
17904   u8 *node_to_find;
17905   int j;
17906   vlib_node_t *node, *next_node;
17907   uword *p;
17908
17909   if (vam->graph_node_index_by_name == 0)
17910     {
17911       print (vam->ofp, "Node table empty, issue get_node_graph...");
17912       return 0;
17913     }
17914
17915   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17916     {
17917       if (unformat (line_input, "%s", &node_to_find))
17918         {
17919           vec_add1 (node_to_find, 0);
17920           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17921           if (p == 0)
17922             {
17923               print (vam->ofp, "%s not found...", node_to_find);
17924               goto out;
17925             }
17926           node = vam->graph_nodes[p[0]];
17927           print (vam->ofp, "[%d] %s", p[0], node->name);
17928           for (j = 0; j < vec_len (node->next_nodes); j++)
17929             {
17930               if (node->next_nodes[j] != ~0)
17931                 {
17932                   next_node = vam->graph_nodes[node->next_nodes[j]];
17933                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17934                 }
17935             }
17936         }
17937
17938       else
17939         {
17940           clib_warning ("parse error '%U'", format_unformat_error,
17941                         line_input);
17942           return -99;
17943         }
17944
17945     out:
17946       vec_free (node_to_find);
17947
17948     }
17949
17950   return 0;
17951 }
17952
17953
17954 static int
17955 script (vat_main_t * vam)
17956 {
17957 #if (VPP_API_TEST_BUILTIN==0)
17958   u8 *s = 0;
17959   char *save_current_file;
17960   unformat_input_t save_input;
17961   jmp_buf save_jump_buf;
17962   u32 save_line_number;
17963
17964   FILE *new_fp, *save_ifp;
17965
17966   if (unformat (vam->input, "%s", &s))
17967     {
17968       new_fp = fopen ((char *) s, "r");
17969       if (new_fp == 0)
17970         {
17971           errmsg ("Couldn't open script file %s", s);
17972           vec_free (s);
17973           return -99;
17974         }
17975     }
17976   else
17977     {
17978       errmsg ("Missing script name");
17979       return -99;
17980     }
17981
17982   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17983   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17984   save_ifp = vam->ifp;
17985   save_line_number = vam->input_line_number;
17986   save_current_file = (char *) vam->current_file;
17987
17988   vam->input_line_number = 0;
17989   vam->ifp = new_fp;
17990   vam->current_file = s;
17991   do_one_file (vam);
17992
17993   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17994   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17995   vam->ifp = save_ifp;
17996   vam->input_line_number = save_line_number;
17997   vam->current_file = (u8 *) save_current_file;
17998   vec_free (s);
17999
18000   return 0;
18001 #else
18002   clib_warning ("use the exec command...");
18003   return -99;
18004 #endif
18005 }
18006
18007 static int
18008 echo (vat_main_t * vam)
18009 {
18010   print (vam->ofp, "%v", vam->input->buffer);
18011   return 0;
18012 }
18013
18014 /* List of API message constructors, CLI names map to api_xxx */
18015 #define foreach_vpe_api_msg                                             \
18016 _(create_loopback,"[mac <mac-addr>]")                                   \
18017 _(sw_interface_dump,"")                                                 \
18018 _(sw_interface_set_flags,                                               \
18019   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18020 _(sw_interface_add_del_address,                                         \
18021   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18022 _(sw_interface_set_table,                                               \
18023   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18024 _(sw_interface_set_mpls_enable,                                         \
18025   "<intfc> | sw_if_index [disable | dis]")                              \
18026 _(sw_interface_set_vpath,                                               \
18027   "<intfc> | sw_if_index <id> enable | disable")                        \
18028 _(sw_interface_set_vxlan_bypass,                                        \
18029   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18030 _(sw_interface_set_l2_xconnect,                                         \
18031   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18032   "enable | disable")                                                   \
18033 _(sw_interface_set_l2_bridge,                                           \
18034   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18035   "[shg <split-horizon-group>] [bvi]\n"                                 \
18036   "enable | disable")                                                   \
18037 _(bridge_domain_add_del,                                                \
18038   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18039 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18040 _(l2fib_add_del,                                                        \
18041   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18042 _(l2_flags,                                                             \
18043   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18044 _(bridge_flags,                                                         \
18045   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18046 _(tap_connect,                                                          \
18047   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18048 _(tap_modify,                                                           \
18049   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18050 _(tap_delete,                                                           \
18051   "<vpp-if-name> | sw_if_index <id>")                                   \
18052 _(sw_interface_tap_dump, "")                                            \
18053 _(ip_add_del_route,                                                     \
18054   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18055   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18056   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18057   "[multipath] [count <n>]")                                            \
18058 _(ip_mroute_add_del,                                                    \
18059   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18060   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18061 _(mpls_route_add_del,                                                   \
18062   "<label> <eos> 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 _(mpls_ip_bind_unbind,                                                  \
18067   "<label> <addr/len>")                                                 \
18068 _(mpls_tunnel_add_del,                                                  \
18069   " via <addr> [table-id <n>]\n"                                        \
18070   "sw_if_index <id>] [l2]  [del]")                                      \
18071 _(proxy_arp_add_del,                                                    \
18072   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18073 _(proxy_arp_intfc_enable_disable,                                       \
18074   "<intfc> | sw_if_index <id> enable | disable")                        \
18075 _(sw_interface_set_unnumbered,                                          \
18076   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18077 _(ip_neighbor_add_del,                                                  \
18078   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18079   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18080 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18081 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18082 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18083   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18084   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18085   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18086 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18087 _(reset_fib, "vrf <n> [ipv6]")                                          \
18088 _(dhcp_proxy_config,                                                    \
18089   "svr <v46-address> src <v46-address>\n"                               \
18090    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18091 _(dhcp_proxy_set_vss,                                                   \
18092   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18093 _(dhcp_proxy_dump, "ip6")                                               \
18094 _(dhcp_client_config,                                                   \
18095   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18096 _(set_ip_flow_hash,                                                     \
18097   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18098 _(sw_interface_ip6_enable_disable,                                      \
18099   "<intfc> | sw_if_index <id> enable | disable")                        \
18100 _(sw_interface_ip6_set_link_local_address,                              \
18101   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18102 _(sw_interface_ip6nd_ra_prefix,                                         \
18103   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18104   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18105   "[nolink] [isno]")                                                    \
18106 _(sw_interface_ip6nd_ra_config,                                         \
18107   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18108   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18109   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18110 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18111 _(l2_patch_add_del,                                                     \
18112   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18113   "enable | disable")                                                   \
18114 _(sr_tunnel_add_del,                                                    \
18115   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
18116   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
18117   "[policy <policy_name>]")                                             \
18118 _(sr_policy_add_del,                                                    \
18119   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
18120 _(sr_multicast_map_add_del,                                             \
18121   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
18122 _(classify_add_del_table,                                               \
18123   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18124   " [del] [del-chain] mask <mask-value>\n"                              \
18125   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18126   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18127 _(classify_add_del_session,                                             \
18128   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18129   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18130   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18131   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18132 _(classify_set_interface_ip_table,                                      \
18133   "<intfc> | sw_if_index <nn> table <nn>")                              \
18134 _(classify_set_interface_l2_tables,                                     \
18135   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18136   "  [other-table <nn>]")                                               \
18137 _(get_node_index, "node <node-name")                                    \
18138 _(add_node_next, "node <node-name> next <next-node-name>")              \
18139 _(l2tpv3_create_tunnel,                                                 \
18140   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18141   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18142   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18143 _(l2tpv3_set_tunnel_cookies,                                            \
18144   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18145   "[new_remote_cookie <nn>]\n")                                         \
18146 _(l2tpv3_interface_enable_disable,                                      \
18147   "<intfc> | sw_if_index <nn> enable | disable")                        \
18148 _(l2tpv3_set_lookup_key,                                                \
18149   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18150 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18151 _(vxlan_add_del_tunnel,                                                 \
18152   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18153   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18154   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18155 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18156 _(gre_add_del_tunnel,                                                   \
18157   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18158 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18159 _(l2_fib_clear_table, "")                                               \
18160 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18161 _(l2_interface_vlan_tag_rewrite,                                        \
18162   "<intfc> | sw_if_index <nn> \n"                                       \
18163   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18164   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18165 _(create_vhost_user_if,                                                 \
18166         "socket <filename> [server] [renumber <dev_instance>] "         \
18167         "[mac <mac_address>]")                                          \
18168 _(modify_vhost_user_if,                                                 \
18169         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18170         "[server] [renumber <dev_instance>]")                           \
18171 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18172 _(sw_interface_vhost_user_dump, "")                                     \
18173 _(show_version, "")                                                     \
18174 _(vxlan_gpe_add_del_tunnel,                                             \
18175   "local <addr> remote <addr> vni <nn>\n"                               \
18176     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18177   "[next-ethernet] [next-nsh]\n")                                       \
18178 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18179 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18180 _(interface_name_renumber,                                              \
18181   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18182 _(input_acl_set_interface,                                              \
18183   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18184   "  [l2-table <nn>] [del]")                                            \
18185 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18186 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18187 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18188 _(ip_dump, "ipv4 | ipv6")                                               \
18189 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18190 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18191   "  spid_id <n> ")                                                     \
18192 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18193   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18194   "  integ_alg <alg> integ_key <hex>")                                  \
18195 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18196   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18197   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18198   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18199 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18200 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18201 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18202   "(auth_data 0x<data> | auth_data <data>)")                            \
18203 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18204   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18205 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18206   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18207   "(local|remote)")                                                     \
18208 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18209 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18210 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18211 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18212 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18213 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18214 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18215 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18216 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18217 _(delete_loopback,"sw_if_index <nn>")                                   \
18218 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18219 _(map_add_domain,                                                       \
18220   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18221   "ip6-src <ip6addr> "                                                  \
18222   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18223 _(map_del_domain, "index <n>")                                          \
18224 _(map_add_del_rule,                                                     \
18225   "index <n> psid <n> dst <ip6addr> [del]")                             \
18226 _(map_domain_dump, "")                                                  \
18227 _(map_rule_dump, "index <map-domain>")                                  \
18228 _(want_interface_events,  "enable|disable")                             \
18229 _(want_stats,"enable|disable")                                          \
18230 _(get_first_msg_id, "client <name>")                                    \
18231 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18232 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18233   "fib-id <nn> [ip4][ip6][default]")                                    \
18234 _(get_node_graph, " ")                                                  \
18235 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18236 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18237 _(ioam_disable, "")                                                     \
18238 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18239                             " sw_if_index <sw_if_index> p <priority> "  \
18240                             "w <weight>] [del]")                        \
18241 _(one_add_del_locator, "locator-set <locator_name> "                    \
18242                         "iface <intf> | sw_if_index <sw_if_index> "     \
18243                         "p <priority> w <weight> [del]")                \
18244 _(one_add_del_local_eid,"vni <vni> eid "                                \
18245                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18246                          "locator-set <locator_name> [del]"             \
18247                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18248 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18249 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18250 _(one_enable_disable, "enable|disable")                                 \
18251 _(one_map_register_enable_disable, "enable|disable")                    \
18252 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18253 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18254                                "[seid <seid>] "                         \
18255                                "rloc <locator> p <prio> "               \
18256                                "w <weight> [rloc <loc> ... ] "          \
18257                                "action <action> [del-all]")             \
18258 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18259                           "<local-eid>")                                \
18260 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18261 _(one_map_request_mode, "src-dst|dst-only")                             \
18262 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18263 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18264 _(one_locator_set_dump, "[local | remote]")                             \
18265 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18266 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18267                        "[local] | [remote]")                            \
18268 _(one_eid_table_vni_dump, "")                                           \
18269 _(one_eid_table_map_dump, "l2|l3")                                      \
18270 _(one_map_resolver_dump, "")                                            \
18271 _(one_map_server_dump, "")                                              \
18272 _(one_adjacencies_get, "vni <vni>")                                     \
18273 _(show_one_rloc_probe_state, "")                                        \
18274 _(show_one_map_register_state, "")                                      \
18275 _(show_one_status, "")                                                  \
18276 _(one_get_map_request_itr_rlocs, "")                                    \
18277 _(show_one_pitr, "")                                                    \
18278 _(show_one_map_request_mode, "")                                        \
18279 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18280                             " sw_if_index <sw_if_index> p <priority> "  \
18281                             "w <weight>] [del]")                        \
18282 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18283                         "iface <intf> | sw_if_index <sw_if_index> "     \
18284                         "p <priority> w <weight> [del]")                \
18285 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18286                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18287                          "locator-set <locator_name> [del]"             \
18288                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18289 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18290 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18291 _(lisp_enable_disable, "enable|disable")                                \
18292 _(lisp_map_register_enable_disable, "enable|disable")                   \
18293 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18294 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18295                                "[seid <seid>] "                         \
18296                                "rloc <locator> p <prio> "               \
18297                                "w <weight> [rloc <loc> ... ] "          \
18298                                "action <action> [del-all]")             \
18299 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18300                           "<local-eid>")                                \
18301 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18302 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18303 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18304 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18305 _(lisp_locator_set_dump, "[local | remote]")                            \
18306 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18307 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18308                        "[local] | [remote]")                            \
18309 _(lisp_eid_table_vni_dump, "")                                          \
18310 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18311 _(lisp_map_resolver_dump, "")                                           \
18312 _(lisp_map_server_dump, "")                                             \
18313 _(lisp_adjacencies_get, "vni <vni>")                                    \
18314 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18315 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18316 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18317 _(gpe_get_encap_mode, "")                                               \
18318 _(lisp_gpe_add_del_iface, "up|down")                                    \
18319 _(lisp_gpe_enable_disable, "enable|disable")                            \
18320 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18321   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18322 _(show_lisp_rloc_probe_state, "")                                       \
18323 _(show_lisp_map_register_state, "")                                     \
18324 _(show_lisp_status, "")                                                 \
18325 _(lisp_get_map_request_itr_rlocs, "")                                   \
18326 _(show_lisp_pitr, "")                                                   \
18327 _(show_lisp_map_request_mode, "")                                       \
18328 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18329 _(af_packet_delete, "name <host interface name>")                       \
18330 _(policer_add_del, "name <policer name> <params> [del]")                \
18331 _(policer_dump, "[name <policer name>]")                                \
18332 _(policer_classify_set_interface,                                       \
18333   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18334   "  [l2-table <nn>] [del]")                                            \
18335 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18336 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18337     "[master|slave]")                                                   \
18338 _(netmap_delete, "name <interface name>")                               \
18339 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18340 _(mpls_fib_dump, "")                                                    \
18341 _(classify_table_ids, "")                                               \
18342 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18343 _(classify_table_info, "table_id <nn>")                                 \
18344 _(classify_session_dump, "table_id <nn>")                               \
18345 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18346     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18347     "[template_interval <nn>] [udp_checksum]")                          \
18348 _(ipfix_exporter_dump, "")                                              \
18349 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18350 _(ipfix_classify_stream_dump, "")                                       \
18351 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18352 _(ipfix_classify_table_dump, "")                                        \
18353 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18354 _(sw_interface_span_dump, "")                                           \
18355 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18356 _(pg_create_interface, "if_id <nn>")                                    \
18357 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18358 _(pg_enable_disable, "[stream <id>] disable")                           \
18359 _(ip_source_and_port_range_check_add_del,                               \
18360   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18361 _(ip_source_and_port_range_check_interface_add_del,                     \
18362   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18363   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18364 _(ipsec_gre_add_del_tunnel,                                             \
18365   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18366 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18367 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18368 _(l2_interface_pbb_tag_rewrite,                                         \
18369   "<intfc> | sw_if_index <nn> \n"                                       \
18370   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18371   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18372 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18373 _(flow_classify_set_interface,                                          \
18374   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18375 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18376 _(ip_fib_dump, "")                                                      \
18377 _(ip_mfib_dump, "")                                                     \
18378 _(ip6_fib_dump, "")                                                     \
18379 _(ip6_mfib_dump, "")                                                    \
18380 _(feature_enable_disable, "arc_name <arc_name> "                        \
18381   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18382 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18383 "[disable]")                                                            \
18384 _(l2_xconnect_dump, "")                                                 \
18385 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18386 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18387 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18388
18389 /* List of command functions, CLI names map directly to functions */
18390 #define foreach_cli_function                                    \
18391 _(comment, "usage: comment <ignore-rest-of-line>")              \
18392 _(dump_interface_table, "usage: dump_interface_table")          \
18393 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18394 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18395 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18396 _(dump_stats_table, "usage: dump_stats_table")                  \
18397 _(dump_macro_table, "usage: dump_macro_table ")                 \
18398 _(dump_node_table, "usage: dump_node_table")                    \
18399 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18400 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18401 _(echo, "usage: echo <message>")                                \
18402 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18403 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18404 _(help, "usage: help")                                          \
18405 _(q, "usage: quit")                                             \
18406 _(quit, "usage: quit")                                          \
18407 _(search_node_table, "usage: search_node_table <name>...")      \
18408 _(set, "usage: set <variable-name> <value>")                    \
18409 _(script, "usage: script <file-name>")                          \
18410 _(unset, "usage: unset <variable-name>")
18411
18412 #define _(N,n)                                  \
18413     static void vl_api_##n##_t_handler_uni      \
18414     (vl_api_##n##_t * mp)                       \
18415     {                                           \
18416         vat_main_t * vam = &vat_main;           \
18417         if (vam->json_output) {                 \
18418             vl_api_##n##_t_handler_json(mp);    \
18419         } else {                                \
18420             vl_api_##n##_t_handler(mp);         \
18421         }                                       \
18422     }
18423 foreach_vpe_api_reply_msg;
18424 #undef _
18425
18426 void
18427 vat_api_hookup (vat_main_t * vam)
18428 {
18429 #define _(N,n)                                                  \
18430     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18431                            vl_api_##n##_t_handler_uni,          \
18432                            vl_noop_handler,                     \
18433                            vl_api_##n##_t_endian,               \
18434                            vl_api_##n##_t_print,                \
18435                            sizeof(vl_api_##n##_t), 1);
18436   foreach_vpe_api_reply_msg;
18437 #undef _
18438
18439 #if (VPP_API_TEST_BUILTIN==0)
18440   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18441 #endif
18442
18443   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18444
18445   vam->function_by_name = hash_create_string (0, sizeof (uword));
18446
18447   vam->help_by_name = hash_create_string (0, sizeof (uword));
18448
18449   /* API messages we can send */
18450 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18451   foreach_vpe_api_msg;
18452 #undef _
18453
18454   /* Help strings */
18455 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18456   foreach_vpe_api_msg;
18457 #undef _
18458
18459   /* CLI functions */
18460 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18461   foreach_cli_function;
18462 #undef _
18463
18464   /* Help strings */
18465 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18466   foreach_cli_function;
18467 #undef _
18468 }
18469
18470 /*
18471  * fd.io coding-style-patch-verification: ON
18472  *
18473  * Local Variables:
18474  * eval: (c-set-style "gnu")
18475  * End:
18476  */