Implement a loopback instance allocation scheme.
[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_create_loopback_instance_reply_t_handler
729   (vl_api_create_loopback_instance_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_create_loopback_instance_reply_t_handler_json
741   (vl_api_create_loopback_instance_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   vam->retval = ntohl (mp->retval);
753   vam->result_ready = 1;
754 }
755
756 static void vl_api_af_packet_create_reply_t_handler
757   (vl_api_af_packet_create_reply_t * mp)
758 {
759   vat_main_t *vam = &vat_main;
760   i32 retval = ntohl (mp->retval);
761
762   vam->retval = retval;
763   vam->regenerate_interface_table = 1;
764   vam->sw_if_index = ntohl (mp->sw_if_index);
765   vam->result_ready = 1;
766 }
767
768 static void vl_api_af_packet_create_reply_t_handler_json
769   (vl_api_af_packet_create_reply_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   vat_json_node_t node;
773
774   vat_json_init_object (&node);
775   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
776   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
777
778   vat_json_print (vam->ofp, &node);
779   vat_json_free (&node);
780
781   vam->retval = ntohl (mp->retval);
782   vam->result_ready = 1;
783 }
784
785 static void vl_api_create_vlan_subif_reply_t_handler
786   (vl_api_create_vlan_subif_reply_t * mp)
787 {
788   vat_main_t *vam = &vat_main;
789   i32 retval = ntohl (mp->retval);
790
791   vam->retval = retval;
792   vam->regenerate_interface_table = 1;
793   vam->sw_if_index = ntohl (mp->sw_if_index);
794   vam->result_ready = 1;
795 }
796
797 static void vl_api_create_vlan_subif_reply_t_handler_json
798   (vl_api_create_vlan_subif_reply_t * mp)
799 {
800   vat_main_t *vam = &vat_main;
801   vat_json_node_t node;
802
803   vat_json_init_object (&node);
804   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
805   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
806
807   vat_json_print (vam->ofp, &node);
808   vat_json_free (&node);
809
810   vam->retval = ntohl (mp->retval);
811   vam->result_ready = 1;
812 }
813
814 static void vl_api_create_subif_reply_t_handler
815   (vl_api_create_subif_reply_t * mp)
816 {
817   vat_main_t *vam = &vat_main;
818   i32 retval = ntohl (mp->retval);
819
820   vam->retval = retval;
821   vam->regenerate_interface_table = 1;
822   vam->sw_if_index = ntohl (mp->sw_if_index);
823   vam->result_ready = 1;
824 }
825
826 static void vl_api_create_subif_reply_t_handler_json
827   (vl_api_create_subif_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
835
836   vat_json_print (vam->ofp, &node);
837   vat_json_free (&node);
838
839   vam->retval = ntohl (mp->retval);
840   vam->result_ready = 1;
841 }
842
843 static void vl_api_interface_name_renumber_reply_t_handler
844   (vl_api_interface_name_renumber_reply_t * mp)
845 {
846   vat_main_t *vam = &vat_main;
847   i32 retval = ntohl (mp->retval);
848
849   vam->retval = retval;
850   vam->regenerate_interface_table = 1;
851   vam->result_ready = 1;
852 }
853
854 static void vl_api_interface_name_renumber_reply_t_handler_json
855   (vl_api_interface_name_renumber_reply_t * mp)
856 {
857   vat_main_t *vam = &vat_main;
858   vat_json_node_t node;
859
860   vat_json_init_object (&node);
861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
862
863   vat_json_print (vam->ofp, &node);
864   vat_json_free (&node);
865
866   vam->retval = ntohl (mp->retval);
867   vam->result_ready = 1;
868 }
869
870 /*
871  * Special-case: build the interface table, maintain
872  * the next loopback sw_if_index vbl.
873  */
874 static void vl_api_sw_interface_details_t_handler
875   (vl_api_sw_interface_details_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   u8 *s = format (0, "%s%c", mp->interface_name, 0);
879
880   hash_set_mem (vam->sw_if_index_by_interface_name, s,
881                 ntohl (mp->sw_if_index));
882
883   /* In sub interface case, fill the sub interface table entry */
884   if (mp->sw_if_index != mp->sup_sw_if_index)
885     {
886       sw_interface_subif_t *sub = NULL;
887
888       vec_add2 (vam->sw_if_subif_table, sub, 1);
889
890       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
891       strncpy ((char *) sub->interface_name, (char *) s,
892                vec_len (sub->interface_name));
893       sub->sw_if_index = ntohl (mp->sw_if_index);
894       sub->sub_id = ntohl (mp->sub_id);
895
896       sub->sub_dot1ad = mp->sub_dot1ad;
897       sub->sub_number_of_tags = mp->sub_number_of_tags;
898       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
899       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
900       sub->sub_exact_match = mp->sub_exact_match;
901       sub->sub_default = mp->sub_default;
902       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
903       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
904
905       /* vlan tag rewrite */
906       sub->vtr_op = ntohl (mp->vtr_op);
907       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
908       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
909       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
910     }
911 }
912
913 static void vl_api_sw_interface_details_t_handler_json
914   (vl_api_sw_interface_details_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   vat_json_node_t *node = NULL;
918
919   if (VAT_JSON_ARRAY != vam->json_tree.type)
920     {
921       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
922       vat_json_init_array (&vam->json_tree);
923     }
924   node = vat_json_array_add (&vam->json_tree);
925
926   vat_json_init_object (node);
927   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
928   vat_json_object_add_uint (node, "sup_sw_if_index",
929                             ntohl (mp->sup_sw_if_index));
930   vat_json_object_add_uint (node, "l2_address_length",
931                             ntohl (mp->l2_address_length));
932   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
933                              sizeof (mp->l2_address));
934   vat_json_object_add_string_copy (node, "interface_name",
935                                    mp->interface_name);
936   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
937   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
938   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
939   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
940   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
941   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
942   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
943   vat_json_object_add_uint (node, "sub_number_of_tags",
944                             mp->sub_number_of_tags);
945   vat_json_object_add_uint (node, "sub_outer_vlan_id",
946                             ntohs (mp->sub_outer_vlan_id));
947   vat_json_object_add_uint (node, "sub_inner_vlan_id",
948                             ntohs (mp->sub_inner_vlan_id));
949   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
950   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
951   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
952                             mp->sub_outer_vlan_id_any);
953   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
954                             mp->sub_inner_vlan_id_any);
955   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
956   vat_json_object_add_uint (node, "vtr_push_dot1q",
957                             ntohl (mp->vtr_push_dot1q));
958   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
959   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
960   if (mp->sub_dot1ah)
961     {
962       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
963                                        format (0, "%U",
964                                                format_ethernet_address,
965                                                &mp->b_dmac));
966       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
967                                        format (0, "%U",
968                                                format_ethernet_address,
969                                                &mp->b_smac));
970       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
971       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
972     }
973 }
974
975 #if VPP_API_TEST_BUILTIN == 0
976 static void vl_api_sw_interface_set_flags_t_handler
977   (vl_api_sw_interface_set_flags_t * mp)
978 {
979   vat_main_t *vam = &vat_main;
980   if (vam->interface_event_display)
981     errmsg ("interface flags: sw_if_index %d %s %s",
982             ntohl (mp->sw_if_index),
983             mp->admin_up_down ? "admin-up" : "admin-down",
984             mp->link_up_down ? "link-up" : "link-down");
985 }
986 #endif
987
988 static void vl_api_sw_interface_set_flags_t_handler_json
989   (vl_api_sw_interface_set_flags_t * mp)
990 {
991   /* JSON output not supported */
992 }
993
994 static void
995 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
996 {
997   vat_main_t *vam = &vat_main;
998   i32 retval = ntohl (mp->retval);
999
1000   vam->retval = retval;
1001   vam->shmem_result = (u8 *) mp->reply_in_shmem;
1002   vam->result_ready = 1;
1003 }
1004
1005 static void
1006 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   vat_json_node_t node;
1010   api_main_t *am = &api_main;
1011   void *oldheap;
1012   u8 *reply;
1013
1014   vat_json_init_object (&node);
1015   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1016   vat_json_object_add_uint (&node, "reply_in_shmem",
1017                             ntohl (mp->reply_in_shmem));
1018   /* Toss the shared-memory original... */
1019   pthread_mutex_lock (&am->vlib_rp->mutex);
1020   oldheap = svm_push_data_heap (am->vlib_rp);
1021
1022   reply = (u8 *) (mp->reply_in_shmem);
1023   vec_free (reply);
1024
1025   svm_pop_heap (oldheap);
1026   pthread_mutex_unlock (&am->vlib_rp->mutex);
1027
1028   vat_json_print (vam->ofp, &node);
1029   vat_json_free (&node);
1030
1031   vam->retval = ntohl (mp->retval);
1032   vam->result_ready = 1;
1033 }
1034
1035 static void
1036 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1037 {
1038   vat_main_t *vam = &vat_main;
1039   i32 retval = ntohl (mp->retval);
1040
1041   vam->retval = retval;
1042   vam->cmd_reply = mp->reply;
1043   vam->result_ready = 1;
1044 }
1045
1046 static void
1047 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1048 {
1049   vat_main_t *vam = &vat_main;
1050   vat_json_node_t node;
1051
1052   vat_json_init_object (&node);
1053   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1054   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1055
1056   vat_json_print (vam->ofp, &node);
1057   vat_json_free (&node);
1058
1059   vam->retval = ntohl (mp->retval);
1060   vam->result_ready = 1;
1061 }
1062
1063 static void vl_api_classify_add_del_table_reply_t_handler
1064   (vl_api_classify_add_del_table_reply_t * mp)
1065 {
1066   vat_main_t *vam = &vat_main;
1067   i32 retval = ntohl (mp->retval);
1068   if (vam->async_mode)
1069     {
1070       vam->async_errors += (retval < 0);
1071     }
1072   else
1073     {
1074       vam->retval = retval;
1075       if (retval == 0 &&
1076           ((mp->new_table_index != 0xFFFFFFFF) ||
1077            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1078            (mp->match_n_vectors != 0xFFFFFFFF)))
1079         /*
1080          * Note: this is just barely thread-safe, depends on
1081          * the main thread spinning waiting for an answer...
1082          */
1083         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1084                 ntohl (mp->new_table_index),
1085                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1086       vam->result_ready = 1;
1087     }
1088 }
1089
1090 static void vl_api_classify_add_del_table_reply_t_handler_json
1091   (vl_api_classify_add_del_table_reply_t * mp)
1092 {
1093   vat_main_t *vam = &vat_main;
1094   vat_json_node_t node;
1095
1096   vat_json_init_object (&node);
1097   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1098   vat_json_object_add_uint (&node, "new_table_index",
1099                             ntohl (mp->new_table_index));
1100   vat_json_object_add_uint (&node, "skip_n_vectors",
1101                             ntohl (mp->skip_n_vectors));
1102   vat_json_object_add_uint (&node, "match_n_vectors",
1103                             ntohl (mp->match_n_vectors));
1104
1105   vat_json_print (vam->ofp, &node);
1106   vat_json_free (&node);
1107
1108   vam->retval = ntohl (mp->retval);
1109   vam->result_ready = 1;
1110 }
1111
1112 static void vl_api_get_node_index_reply_t_handler
1113   (vl_api_get_node_index_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117   if (vam->async_mode)
1118     {
1119       vam->async_errors += (retval < 0);
1120     }
1121   else
1122     {
1123       vam->retval = retval;
1124       if (retval == 0)
1125         errmsg ("node index %d", ntohl (mp->node_index));
1126       vam->result_ready = 1;
1127     }
1128 }
1129
1130 static void vl_api_get_node_index_reply_t_handler_json
1131   (vl_api_get_node_index_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   vat_json_node_t node;
1135
1136   vat_json_init_object (&node);
1137   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1138   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1139
1140   vat_json_print (vam->ofp, &node);
1141   vat_json_free (&node);
1142
1143   vam->retval = ntohl (mp->retval);
1144   vam->result_ready = 1;
1145 }
1146
1147 static void vl_api_get_next_index_reply_t_handler
1148   (vl_api_get_next_index_reply_t * mp)
1149 {
1150   vat_main_t *vam = &vat_main;
1151   i32 retval = ntohl (mp->retval);
1152   if (vam->async_mode)
1153     {
1154       vam->async_errors += (retval < 0);
1155     }
1156   else
1157     {
1158       vam->retval = retval;
1159       if (retval == 0)
1160         errmsg ("next node index %d", ntohl (mp->next_index));
1161       vam->result_ready = 1;
1162     }
1163 }
1164
1165 static void vl_api_get_next_index_reply_t_handler_json
1166   (vl_api_get_next_index_reply_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   vat_json_node_t node;
1170
1171   vat_json_init_object (&node);
1172   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1173   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1174
1175   vat_json_print (vam->ofp, &node);
1176   vat_json_free (&node);
1177
1178   vam->retval = ntohl (mp->retval);
1179   vam->result_ready = 1;
1180 }
1181
1182 static void vl_api_add_node_next_reply_t_handler
1183   (vl_api_add_node_next_reply_t * mp)
1184 {
1185   vat_main_t *vam = &vat_main;
1186   i32 retval = ntohl (mp->retval);
1187   if (vam->async_mode)
1188     {
1189       vam->async_errors += (retval < 0);
1190     }
1191   else
1192     {
1193       vam->retval = retval;
1194       if (retval == 0)
1195         errmsg ("next index %d", ntohl (mp->next_index));
1196       vam->result_ready = 1;
1197     }
1198 }
1199
1200 static void vl_api_add_node_next_reply_t_handler_json
1201   (vl_api_add_node_next_reply_t * mp)
1202 {
1203   vat_main_t *vam = &vat_main;
1204   vat_json_node_t node;
1205
1206   vat_json_init_object (&node);
1207   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1208   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1209
1210   vat_json_print (vam->ofp, &node);
1211   vat_json_free (&node);
1212
1213   vam->retval = ntohl (mp->retval);
1214   vam->result_ready = 1;
1215 }
1216
1217 static void vl_api_show_version_reply_t_handler
1218   (vl_api_show_version_reply_t * mp)
1219 {
1220   vat_main_t *vam = &vat_main;
1221   i32 retval = ntohl (mp->retval);
1222
1223   if (retval >= 0)
1224     {
1225       errmsg ("        program: %s", mp->program);
1226       errmsg ("        version: %s", mp->version);
1227       errmsg ("     build date: %s", mp->build_date);
1228       errmsg ("build directory: %s", mp->build_directory);
1229     }
1230   vam->retval = retval;
1231   vam->result_ready = 1;
1232 }
1233
1234 static void vl_api_show_version_reply_t_handler_json
1235   (vl_api_show_version_reply_t * mp)
1236 {
1237   vat_main_t *vam = &vat_main;
1238   vat_json_node_t node;
1239
1240   vat_json_init_object (&node);
1241   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1242   vat_json_object_add_string_copy (&node, "program", mp->program);
1243   vat_json_object_add_string_copy (&node, "version", mp->version);
1244   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1245   vat_json_object_add_string_copy (&node, "build_directory",
1246                                    mp->build_directory);
1247
1248   vat_json_print (vam->ofp, &node);
1249   vat_json_free (&node);
1250
1251   vam->retval = ntohl (mp->retval);
1252   vam->result_ready = 1;
1253 }
1254
1255 static void
1256 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1257 {
1258   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1274           mp->mac_ip ? "mac/ip binding" : "address resolution",
1275           format_ip6_address, mp->address,
1276           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1277 }
1278
1279 static void
1280 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1281 {
1282   /* JSON output not supported */
1283 }
1284
1285 /*
1286  * Special-case: build the bridge domain table, maintain
1287  * the next bd id vbl.
1288  */
1289 static void vl_api_bridge_domain_details_t_handler
1290   (vl_api_bridge_domain_details_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1294
1295   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1296          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1297
1298   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1299          ntohl (mp->bd_id), mp->learn, mp->forward,
1300          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1301
1302   if (n_sw_ifs)
1303     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1304 }
1305
1306 static void vl_api_bridge_domain_details_t_handler_json
1307   (vl_api_bridge_domain_details_t * mp)
1308 {
1309   vat_main_t *vam = &vat_main;
1310   vat_json_node_t *node, *array = NULL;
1311
1312   if (VAT_JSON_ARRAY != vam->json_tree.type)
1313     {
1314       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1315       vat_json_init_array (&vam->json_tree);
1316     }
1317   node = vat_json_array_add (&vam->json_tree);
1318
1319   vat_json_init_object (node);
1320   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1321   vat_json_object_add_uint (node, "flood", mp->flood);
1322   vat_json_object_add_uint (node, "forward", mp->forward);
1323   vat_json_object_add_uint (node, "learn", mp->learn);
1324   vat_json_object_add_uint (node, "bvi_sw_if_index",
1325                             ntohl (mp->bvi_sw_if_index));
1326   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1327   array = vat_json_object_add (node, "sw_if");
1328   vat_json_init_array (array);
1329 }
1330
1331 /*
1332  * Special-case: build the bridge domain sw if table.
1333  */
1334 static void vl_api_bridge_domain_sw_if_details_t_handler
1335   (vl_api_bridge_domain_sw_if_details_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   hash_pair_t *p;
1339   u8 *sw_if_name = 0;
1340   u32 sw_if_index;
1341
1342   sw_if_index = ntohl (mp->sw_if_index);
1343   /* *INDENT-OFF* */
1344   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1345   ({
1346     if ((u32) p->value[0] == sw_if_index)
1347       {
1348         sw_if_name = (u8 *)(p->key);
1349         break;
1350       }
1351   }));
1352   /* *INDENT-ON* */
1353
1354   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1355          mp->shg, sw_if_name ? (char *) sw_if_name :
1356          "sw_if_index not found!");
1357 }
1358
1359 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1360   (vl_api_bridge_domain_sw_if_details_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t *node = NULL;
1364   uword last_index = 0;
1365
1366   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1367   ASSERT (vec_len (vam->json_tree.array) >= 1);
1368   last_index = vec_len (vam->json_tree.array) - 1;
1369   node = &vam->json_tree.array[last_index];
1370   node = vat_json_object_get_element (node, "sw_if");
1371   ASSERT (NULL != node);
1372   node = vat_json_array_add (node);
1373
1374   vat_json_init_object (node);
1375   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1376   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1377   vat_json_object_add_uint (node, "shg", mp->shg);
1378 }
1379
1380 static void vl_api_control_ping_reply_t_handler
1381   (vl_api_control_ping_reply_t * mp)
1382 {
1383   vat_main_t *vam = &vat_main;
1384   i32 retval = ntohl (mp->retval);
1385   if (vam->async_mode)
1386     {
1387       vam->async_errors += (retval < 0);
1388     }
1389   else
1390     {
1391       vam->retval = retval;
1392       vam->result_ready = 1;
1393     }
1394 }
1395
1396 static void vl_api_control_ping_reply_t_handler_json
1397   (vl_api_control_ping_reply_t * mp)
1398 {
1399   vat_main_t *vam = &vat_main;
1400   i32 retval = ntohl (mp->retval);
1401
1402   if (VAT_JSON_NONE != vam->json_tree.type)
1403     {
1404       vat_json_print (vam->ofp, &vam->json_tree);
1405       vat_json_free (&vam->json_tree);
1406       vam->json_tree.type = VAT_JSON_NONE;
1407     }
1408   else
1409     {
1410       /* just print [] */
1411       vat_json_init_array (&vam->json_tree);
1412       vat_json_print (vam->ofp, &vam->json_tree);
1413       vam->json_tree.type = VAT_JSON_NONE;
1414     }
1415
1416   vam->retval = retval;
1417   vam->result_ready = 1;
1418 }
1419
1420 static void
1421 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1422 {
1423   vat_main_t *vam = &vat_main;
1424   i32 retval = ntohl (mp->retval);
1425   if (vam->async_mode)
1426     {
1427       vam->async_errors += (retval < 0);
1428     }
1429   else
1430     {
1431       vam->retval = retval;
1432       vam->result_ready = 1;
1433     }
1434 }
1435
1436 static void vl_api_l2_flags_reply_t_handler_json
1437   (vl_api_l2_flags_reply_t * mp)
1438 {
1439   vat_main_t *vam = &vat_main;
1440   vat_json_node_t node;
1441
1442   vat_json_init_object (&node);
1443   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1444   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1445                             ntohl (mp->resulting_feature_bitmap));
1446
1447   vat_json_print (vam->ofp, &node);
1448   vat_json_free (&node);
1449
1450   vam->retval = ntohl (mp->retval);
1451   vam->result_ready = 1;
1452 }
1453
1454 static void vl_api_bridge_flags_reply_t_handler
1455   (vl_api_bridge_flags_reply_t * mp)
1456 {
1457   vat_main_t *vam = &vat_main;
1458   i32 retval = ntohl (mp->retval);
1459   if (vam->async_mode)
1460     {
1461       vam->async_errors += (retval < 0);
1462     }
1463   else
1464     {
1465       vam->retval = retval;
1466       vam->result_ready = 1;
1467     }
1468 }
1469
1470 static void vl_api_bridge_flags_reply_t_handler_json
1471   (vl_api_bridge_flags_reply_t * mp)
1472 {
1473   vat_main_t *vam = &vat_main;
1474   vat_json_node_t node;
1475
1476   vat_json_init_object (&node);
1477   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1478   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1479                             ntohl (mp->resulting_feature_bitmap));
1480
1481   vat_json_print (vam->ofp, &node);
1482   vat_json_free (&node);
1483
1484   vam->retval = ntohl (mp->retval);
1485   vam->result_ready = 1;
1486 }
1487
1488 static void vl_api_tap_connect_reply_t_handler
1489   (vl_api_tap_connect_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   i32 retval = ntohl (mp->retval);
1493   if (vam->async_mode)
1494     {
1495       vam->async_errors += (retval < 0);
1496     }
1497   else
1498     {
1499       vam->retval = retval;
1500       vam->sw_if_index = ntohl (mp->sw_if_index);
1501       vam->result_ready = 1;
1502     }
1503
1504 }
1505
1506 static void vl_api_tap_connect_reply_t_handler_json
1507   (vl_api_tap_connect_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   vat_json_node_t node;
1511
1512   vat_json_init_object (&node);
1513   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1514   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1515
1516   vat_json_print (vam->ofp, &node);
1517   vat_json_free (&node);
1518
1519   vam->retval = ntohl (mp->retval);
1520   vam->result_ready = 1;
1521
1522 }
1523
1524 static void
1525 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   i32 retval = ntohl (mp->retval);
1529   if (vam->async_mode)
1530     {
1531       vam->async_errors += (retval < 0);
1532     }
1533   else
1534     {
1535       vam->retval = retval;
1536       vam->sw_if_index = ntohl (mp->sw_if_index);
1537       vam->result_ready = 1;
1538     }
1539 }
1540
1541 static void vl_api_tap_modify_reply_t_handler_json
1542   (vl_api_tap_modify_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   vat_json_node_t node;
1546
1547   vat_json_init_object (&node);
1548   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1549   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1550
1551   vat_json_print (vam->ofp, &node);
1552   vat_json_free (&node);
1553
1554   vam->retval = ntohl (mp->retval);
1555   vam->result_ready = 1;
1556 }
1557
1558 static void
1559 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1560 {
1561   vat_main_t *vam = &vat_main;
1562   i32 retval = ntohl (mp->retval);
1563   if (vam->async_mode)
1564     {
1565       vam->async_errors += (retval < 0);
1566     }
1567   else
1568     {
1569       vam->retval = retval;
1570       vam->result_ready = 1;
1571     }
1572 }
1573
1574 static void vl_api_tap_delete_reply_t_handler_json
1575   (vl_api_tap_delete_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   vat_json_node_t node;
1579
1580   vat_json_init_object (&node);
1581   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1582
1583   vat_json_print (vam->ofp, &node);
1584   vat_json_free (&node);
1585
1586   vam->retval = ntohl (mp->retval);
1587   vam->result_ready = 1;
1588 }
1589
1590 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1591   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   i32 retval = ntohl (mp->retval);
1595   if (vam->async_mode)
1596     {
1597       vam->async_errors += (retval < 0);
1598     }
1599   else
1600     {
1601       vam->retval = retval;
1602       vam->result_ready = 1;
1603     }
1604 }
1605
1606 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1607   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1608 {
1609   vat_main_t *vam = &vat_main;
1610   vat_json_node_t node;
1611
1612   vat_json_init_object (&node);
1613   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1614   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1615                             ntohl (mp->sw_if_index));
1616
1617   vat_json_print (vam->ofp, &node);
1618   vat_json_free (&node);
1619
1620   vam->retval = ntohl (mp->retval);
1621   vam->result_ready = 1;
1622 }
1623
1624 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1625   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->sw_if_index = ntohl (mp->sw_if_index);
1637       vam->result_ready = 1;
1638     }
1639 }
1640
1641 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1642   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   vat_json_node_t node;
1646
1647   vat_json_init_object (&node);
1648   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1649   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1650
1651   vat_json_print (vam->ofp, &node);
1652   vat_json_free (&node);
1653
1654   vam->retval = ntohl (mp->retval);
1655   vam->result_ready = 1;
1656 }
1657
1658
1659 static void vl_api_one_add_del_locator_set_reply_t_handler
1660   (vl_api_one_add_del_locator_set_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   i32 retval = ntohl (mp->retval);
1664   if (vam->async_mode)
1665     {
1666       vam->async_errors += (retval < 0);
1667     }
1668   else
1669     {
1670       vam->retval = retval;
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1676   (vl_api_one_add_del_locator_set_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1693   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   i32 retval = ntohl (mp->retval);
1697   if (vam->async_mode)
1698     {
1699       vam->async_errors += (retval < 0);
1700     }
1701   else
1702     {
1703       vam->retval = retval;
1704       vam->sw_if_index = ntohl (mp->sw_if_index);
1705       vam->result_ready = 1;
1706     }
1707 }
1708
1709 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1710   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   vat_json_node_t node;
1714
1715   vat_json_init_object (&node);
1716   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1717   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1718
1719   vat_json_print (vam->ofp, &node);
1720   vat_json_free (&node);
1721
1722   vam->retval = ntohl (mp->retval);
1723   vam->result_ready = 1;
1724 }
1725
1726 static void vl_api_gre_add_del_tunnel_reply_t_handler
1727   (vl_api_gre_add_del_tunnel_reply_t * mp)
1728 {
1729   vat_main_t *vam = &vat_main;
1730   i32 retval = ntohl (mp->retval);
1731   if (vam->async_mode)
1732     {
1733       vam->async_errors += (retval < 0);
1734     }
1735   else
1736     {
1737       vam->retval = retval;
1738       vam->sw_if_index = ntohl (mp->sw_if_index);
1739       vam->result_ready = 1;
1740     }
1741 }
1742
1743 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1744   (vl_api_gre_add_del_tunnel_reply_t * mp)
1745 {
1746   vat_main_t *vam = &vat_main;
1747   vat_json_node_t node;
1748
1749   vat_json_init_object (&node);
1750   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1751   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1752
1753   vat_json_print (vam->ofp, &node);
1754   vat_json_free (&node);
1755
1756   vam->retval = ntohl (mp->retval);
1757   vam->result_ready = 1;
1758 }
1759
1760 static void vl_api_create_vhost_user_if_reply_t_handler
1761   (vl_api_create_vhost_user_if_reply_t * mp)
1762 {
1763   vat_main_t *vam = &vat_main;
1764   i32 retval = ntohl (mp->retval);
1765   if (vam->async_mode)
1766     {
1767       vam->async_errors += (retval < 0);
1768     }
1769   else
1770     {
1771       vam->retval = retval;
1772       vam->sw_if_index = ntohl (mp->sw_if_index);
1773       vam->result_ready = 1;
1774     }
1775 }
1776
1777 static void vl_api_create_vhost_user_if_reply_t_handler_json
1778   (vl_api_create_vhost_user_if_reply_t * mp)
1779 {
1780   vat_main_t *vam = &vat_main;
1781   vat_json_node_t node;
1782
1783   vat_json_init_object (&node);
1784   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1785   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1786
1787   vat_json_print (vam->ofp, &node);
1788   vat_json_free (&node);
1789
1790   vam->retval = ntohl (mp->retval);
1791   vam->result_ready = 1;
1792 }
1793
1794 static void vl_api_ip_address_details_t_handler
1795   (vl_api_ip_address_details_t * mp)
1796 {
1797   vat_main_t *vam = &vat_main;
1798   static ip_address_details_t empty_ip_address_details = { {0} };
1799   ip_address_details_t *address = NULL;
1800   ip_details_t *current_ip_details = NULL;
1801   ip_details_t *details = NULL;
1802
1803   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1804
1805   if (!details || vam->current_sw_if_index >= vec_len (details)
1806       || !details[vam->current_sw_if_index].present)
1807     {
1808       errmsg ("ip address details arrived but not stored");
1809       errmsg ("ip_dump should be called first");
1810       return;
1811     }
1812
1813   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1814
1815 #define addresses (current_ip_details->addr)
1816
1817   vec_validate_init_empty (addresses, vec_len (addresses),
1818                            empty_ip_address_details);
1819
1820   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1821
1822   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1823   address->prefix_length = mp->prefix_length;
1824 #undef addresses
1825 }
1826
1827 static void vl_api_ip_address_details_t_handler_json
1828   (vl_api_ip_address_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   vat_json_node_t *node = NULL;
1832   struct in6_addr ip6;
1833   struct in_addr ip4;
1834
1835   if (VAT_JSON_ARRAY != vam->json_tree.type)
1836     {
1837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1838       vat_json_init_array (&vam->json_tree);
1839     }
1840   node = vat_json_array_add (&vam->json_tree);
1841
1842   vat_json_init_object (node);
1843   if (vam->is_ipv6)
1844     {
1845       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1846       vat_json_object_add_ip6 (node, "ip", ip6);
1847     }
1848   else
1849     {
1850       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1851       vat_json_object_add_ip4 (node, "ip", ip4);
1852     }
1853   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1854 }
1855
1856 static void
1857 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   static ip_details_t empty_ip_details = { 0 };
1861   ip_details_t *ip = NULL;
1862   u32 sw_if_index = ~0;
1863
1864   sw_if_index = ntohl (mp->sw_if_index);
1865
1866   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1867                            sw_if_index, empty_ip_details);
1868
1869   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1870                          sw_if_index);
1871
1872   ip->present = 1;
1873 }
1874
1875 static void
1876 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1877 {
1878   vat_main_t *vam = &vat_main;
1879
1880   if (VAT_JSON_ARRAY != vam->json_tree.type)
1881     {
1882       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1883       vat_json_init_array (&vam->json_tree);
1884     }
1885   vat_json_array_add_uint (&vam->json_tree,
1886                            clib_net_to_host_u32 (mp->sw_if_index));
1887 }
1888
1889 static void vl_api_map_domain_details_t_handler_json
1890   (vl_api_map_domain_details_t * mp)
1891 {
1892   vat_json_node_t *node = NULL;
1893   vat_main_t *vam = &vat_main;
1894   struct in6_addr ip6;
1895   struct in_addr ip4;
1896
1897   if (VAT_JSON_ARRAY != vam->json_tree.type)
1898     {
1899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1900       vat_json_init_array (&vam->json_tree);
1901     }
1902
1903   node = vat_json_array_add (&vam->json_tree);
1904   vat_json_init_object (node);
1905
1906   vat_json_object_add_uint (node, "domain_index",
1907                             clib_net_to_host_u32 (mp->domain_index));
1908   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1909   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1910   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1911   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1912   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1913   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1914   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1915   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1916   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1917   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1918   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1919   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1920   vat_json_object_add_uint (node, "flags", mp->flags);
1921   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1922   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1923 }
1924
1925 static void vl_api_map_domain_details_t_handler
1926   (vl_api_map_domain_details_t * mp)
1927 {
1928   vat_main_t *vam = &vat_main;
1929
1930   if (mp->is_translation)
1931     {
1932       print (vam->ofp,
1933              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1934              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1935              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1936              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1937              clib_net_to_host_u32 (mp->domain_index));
1938     }
1939   else
1940     {
1941       print (vam->ofp,
1942              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1943              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1944              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1945              format_ip6_address, mp->ip6_src,
1946              clib_net_to_host_u32 (mp->domain_index));
1947     }
1948   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1949          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1950          mp->is_translation ? "map-t" : "");
1951 }
1952
1953 static void vl_api_map_rule_details_t_handler_json
1954   (vl_api_map_rule_details_t * mp)
1955 {
1956   struct in6_addr ip6;
1957   vat_json_node_t *node = NULL;
1958   vat_main_t *vam = &vat_main;
1959
1960   if (VAT_JSON_ARRAY != vam->json_tree.type)
1961     {
1962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1963       vat_json_init_array (&vam->json_tree);
1964     }
1965
1966   node = vat_json_array_add (&vam->json_tree);
1967   vat_json_init_object (node);
1968
1969   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1970   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1971   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1972 }
1973
1974 static void
1975 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1979          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1980 }
1981
1982 static void
1983 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1984 {
1985   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1986           "router_addr %U host_mac %U",
1987           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1988           format_ip4_address, &mp->host_address,
1989           format_ip4_address, &mp->router_address,
1990           format_ethernet_address, mp->host_mac);
1991 }
1992
1993 static void vl_api_dhcp_compl_event_t_handler_json
1994   (vl_api_dhcp_compl_event_t * mp)
1995 {
1996   /* JSON output not supported */
1997 }
1998
1999 static void
2000 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2001                               u32 counter)
2002 {
2003   vat_main_t *vam = &vat_main;
2004   static u64 default_counter = 0;
2005
2006   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2007                            NULL);
2008   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2009                            sw_if_index, default_counter);
2010   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2011 }
2012
2013 static void
2014 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2015                                 interface_counter_t counter)
2016 {
2017   vat_main_t *vam = &vat_main;
2018   static interface_counter_t default_counter = { 0, };
2019
2020   vec_validate_init_empty (vam->combined_interface_counters,
2021                            vnet_counter_type, NULL);
2022   vec_validate_init_empty (vam->combined_interface_counters
2023                            [vnet_counter_type], sw_if_index, default_counter);
2024   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2025 }
2026
2027 static void vl_api_vnet_interface_counters_t_handler
2028   (vl_api_vnet_interface_counters_t * mp)
2029 {
2030   /* not supported */
2031 }
2032
2033 static void vl_api_vnet_interface_counters_t_handler_json
2034   (vl_api_vnet_interface_counters_t * mp)
2035 {
2036   interface_counter_t counter;
2037   vlib_counter_t *v;
2038   u64 *v_packets;
2039   u64 packets;
2040   u32 count;
2041   u32 first_sw_if_index;
2042   int i;
2043
2044   count = ntohl (mp->count);
2045   first_sw_if_index = ntohl (mp->first_sw_if_index);
2046
2047   if (!mp->is_combined)
2048     {
2049       v_packets = (u64 *) & mp->data;
2050       for (i = 0; i < count; i++)
2051         {
2052           packets =
2053             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2054           set_simple_interface_counter (mp->vnet_counter_type,
2055                                         first_sw_if_index + i, packets);
2056           v_packets++;
2057         }
2058     }
2059   else
2060     {
2061       v = (vlib_counter_t *) & mp->data;
2062       for (i = 0; i < count; i++)
2063         {
2064           counter.packets =
2065             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2066           counter.bytes =
2067             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2068           set_combined_interface_counter (mp->vnet_counter_type,
2069                                           first_sw_if_index + i, counter);
2070           v++;
2071         }
2072     }
2073 }
2074
2075 static u32
2076 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2077 {
2078   vat_main_t *vam = &vat_main;
2079   u32 i;
2080
2081   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2082     {
2083       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2084         {
2085           return i;
2086         }
2087     }
2088   return ~0;
2089 }
2090
2091 static u32
2092 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2093 {
2094   vat_main_t *vam = &vat_main;
2095   u32 i;
2096
2097   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2098     {
2099       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2100         {
2101           return i;
2102         }
2103     }
2104   return ~0;
2105 }
2106
2107 static void vl_api_vnet_ip4_fib_counters_t_handler
2108   (vl_api_vnet_ip4_fib_counters_t * mp)
2109 {
2110   /* not supported */
2111 }
2112
2113 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2114   (vl_api_vnet_ip4_fib_counters_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117   vl_api_ip4_fib_counter_t *v;
2118   ip4_fib_counter_t *counter;
2119   struct in_addr ip4;
2120   u32 vrf_id;
2121   u32 vrf_index;
2122   u32 count;
2123   int i;
2124
2125   vrf_id = ntohl (mp->vrf_id);
2126   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2127   if (~0 == vrf_index)
2128     {
2129       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2130       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2131       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2132       vec_validate (vam->ip4_fib_counters, vrf_index);
2133       vam->ip4_fib_counters[vrf_index] = NULL;
2134     }
2135
2136   vec_free (vam->ip4_fib_counters[vrf_index]);
2137   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2138   count = ntohl (mp->count);
2139   for (i = 0; i < count; i++)
2140     {
2141       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2142       counter = &vam->ip4_fib_counters[vrf_index][i];
2143       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2144       counter->address = ip4;
2145       counter->address_length = v->address_length;
2146       counter->packets = clib_net_to_host_u64 (v->packets);
2147       counter->bytes = clib_net_to_host_u64 (v->bytes);
2148       v++;
2149     }
2150 }
2151
2152 static void vl_api_vnet_ip4_nbr_counters_t_handler
2153   (vl_api_vnet_ip4_nbr_counters_t * mp)
2154 {
2155   /* not supported */
2156 }
2157
2158 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2159   (vl_api_vnet_ip4_nbr_counters_t * mp)
2160 {
2161   vat_main_t *vam = &vat_main;
2162   vl_api_ip4_nbr_counter_t *v;
2163   ip4_nbr_counter_t *counter;
2164   u32 sw_if_index;
2165   u32 count;
2166   int i;
2167
2168   sw_if_index = ntohl (mp->sw_if_index);
2169   count = ntohl (mp->count);
2170   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2171
2172   if (mp->begin)
2173     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2174
2175   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2176   for (i = 0; i < count; i++)
2177     {
2178       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2179       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2180       counter->address.s_addr = v->address;
2181       counter->packets = clib_net_to_host_u64 (v->packets);
2182       counter->bytes = clib_net_to_host_u64 (v->bytes);
2183       counter->linkt = v->link_type;
2184       v++;
2185     }
2186 }
2187
2188 static void vl_api_vnet_ip6_fib_counters_t_handler
2189   (vl_api_vnet_ip6_fib_counters_t * mp)
2190 {
2191   /* not supported */
2192 }
2193
2194 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2195   (vl_api_vnet_ip6_fib_counters_t * mp)
2196 {
2197   vat_main_t *vam = &vat_main;
2198   vl_api_ip6_fib_counter_t *v;
2199   ip6_fib_counter_t *counter;
2200   struct in6_addr ip6;
2201   u32 vrf_id;
2202   u32 vrf_index;
2203   u32 count;
2204   int i;
2205
2206   vrf_id = ntohl (mp->vrf_id);
2207   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2208   if (~0 == vrf_index)
2209     {
2210       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2211       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2212       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2213       vec_validate (vam->ip6_fib_counters, vrf_index);
2214       vam->ip6_fib_counters[vrf_index] = NULL;
2215     }
2216
2217   vec_free (vam->ip6_fib_counters[vrf_index]);
2218   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2219   count = ntohl (mp->count);
2220   for (i = 0; i < count; i++)
2221     {
2222       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2223       counter = &vam->ip6_fib_counters[vrf_index][i];
2224       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2225       counter->address = ip6;
2226       counter->address_length = v->address_length;
2227       counter->packets = clib_net_to_host_u64 (v->packets);
2228       counter->bytes = clib_net_to_host_u64 (v->bytes);
2229       v++;
2230     }
2231 }
2232
2233 static void vl_api_vnet_ip6_nbr_counters_t_handler
2234   (vl_api_vnet_ip6_nbr_counters_t * mp)
2235 {
2236   /* not supported */
2237 }
2238
2239 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2240   (vl_api_vnet_ip6_nbr_counters_t * mp)
2241 {
2242   vat_main_t *vam = &vat_main;
2243   vl_api_ip6_nbr_counter_t *v;
2244   ip6_nbr_counter_t *counter;
2245   struct in6_addr ip6;
2246   u32 sw_if_index;
2247   u32 count;
2248   int i;
2249
2250   sw_if_index = ntohl (mp->sw_if_index);
2251   count = ntohl (mp->count);
2252   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2253
2254   if (mp->begin)
2255     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2256
2257   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2258   for (i = 0; i < count; i++)
2259     {
2260       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2261       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2262       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2263       counter->address = ip6;
2264       counter->packets = clib_net_to_host_u64 (v->packets);
2265       counter->bytes = clib_net_to_host_u64 (v->bytes);
2266       v++;
2267     }
2268 }
2269
2270 static void vl_api_get_first_msg_id_reply_t_handler
2271   (vl_api_get_first_msg_id_reply_t * mp)
2272 {
2273   vat_main_t *vam = &vat_main;
2274   i32 retval = ntohl (mp->retval);
2275
2276   if (vam->async_mode)
2277     {
2278       vam->async_errors += (retval < 0);
2279     }
2280   else
2281     {
2282       vam->retval = retval;
2283       vam->result_ready = 1;
2284     }
2285   if (retval >= 0)
2286     {
2287       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2288     }
2289 }
2290
2291 static void vl_api_get_first_msg_id_reply_t_handler_json
2292   (vl_api_get_first_msg_id_reply_t * mp)
2293 {
2294   vat_main_t *vam = &vat_main;
2295   vat_json_node_t node;
2296
2297   vat_json_init_object (&node);
2298   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2299   vat_json_object_add_uint (&node, "first_msg_id",
2300                             (uint) ntohs (mp->first_msg_id));
2301
2302   vat_json_print (vam->ofp, &node);
2303   vat_json_free (&node);
2304
2305   vam->retval = ntohl (mp->retval);
2306   vam->result_ready = 1;
2307 }
2308
2309 static void vl_api_get_node_graph_reply_t_handler
2310   (vl_api_get_node_graph_reply_t * mp)
2311 {
2312   vat_main_t *vam = &vat_main;
2313   api_main_t *am = &api_main;
2314   i32 retval = ntohl (mp->retval);
2315   u8 *pvt_copy, *reply;
2316   void *oldheap;
2317   vlib_node_t *node;
2318   int i;
2319
2320   if (vam->async_mode)
2321     {
2322       vam->async_errors += (retval < 0);
2323     }
2324   else
2325     {
2326       vam->retval = retval;
2327       vam->result_ready = 1;
2328     }
2329
2330   /* "Should never happen..." */
2331   if (retval != 0)
2332     return;
2333
2334   reply = (u8 *) (mp->reply_in_shmem);
2335   pvt_copy = vec_dup (reply);
2336
2337   /* Toss the shared-memory original... */
2338   pthread_mutex_lock (&am->vlib_rp->mutex);
2339   oldheap = svm_push_data_heap (am->vlib_rp);
2340
2341   vec_free (reply);
2342
2343   svm_pop_heap (oldheap);
2344   pthread_mutex_unlock (&am->vlib_rp->mutex);
2345
2346   if (vam->graph_nodes)
2347     {
2348       hash_free (vam->graph_node_index_by_name);
2349
2350       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2351         {
2352           node = vam->graph_nodes[i];
2353           vec_free (node->name);
2354           vec_free (node->next_nodes);
2355           vec_free (node);
2356         }
2357       vec_free (vam->graph_nodes);
2358     }
2359
2360   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2361   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2362   vec_free (pvt_copy);
2363
2364   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2365     {
2366       node = vam->graph_nodes[i];
2367       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2368     }
2369 }
2370
2371 static void vl_api_get_node_graph_reply_t_handler_json
2372   (vl_api_get_node_graph_reply_t * mp)
2373 {
2374   vat_main_t *vam = &vat_main;
2375   api_main_t *am = &api_main;
2376   void *oldheap;
2377   vat_json_node_t node;
2378   u8 *reply;
2379
2380   /* $$$$ make this real? */
2381   vat_json_init_object (&node);
2382   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2383   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2384
2385   reply = (u8 *) (mp->reply_in_shmem);
2386
2387   /* Toss the shared-memory original... */
2388   pthread_mutex_lock (&am->vlib_rp->mutex);
2389   oldheap = svm_push_data_heap (am->vlib_rp);
2390
2391   vec_free (reply);
2392
2393   svm_pop_heap (oldheap);
2394   pthread_mutex_unlock (&am->vlib_rp->mutex);
2395
2396   vat_json_print (vam->ofp, &node);
2397   vat_json_free (&node);
2398
2399   vam->retval = ntohl (mp->retval);
2400   vam->result_ready = 1;
2401 }
2402
2403 static void
2404 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2405 {
2406   vat_main_t *vam = &vat_main;
2407   u8 *s = 0;
2408
2409   if (mp->local)
2410     {
2411       s = format (s, "%=16d%=16d%=16d",
2412                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2413     }
2414   else
2415     {
2416       s = format (s, "%=16U%=16d%=16d",
2417                   mp->is_ipv6 ? format_ip6_address :
2418                   format_ip4_address,
2419                   mp->ip_address, mp->priority, mp->weight);
2420     }
2421
2422   print (vam->ofp, "%v", s);
2423   vec_free (s);
2424 }
2425
2426 static void
2427 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   vat_json_node_t *node = NULL;
2431   struct in6_addr ip6;
2432   struct in_addr ip4;
2433
2434   if (VAT_JSON_ARRAY != vam->json_tree.type)
2435     {
2436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2437       vat_json_init_array (&vam->json_tree);
2438     }
2439   node = vat_json_array_add (&vam->json_tree);
2440   vat_json_init_object (node);
2441
2442   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2443   vat_json_object_add_uint (node, "priority", mp->priority);
2444   vat_json_object_add_uint (node, "weight", mp->weight);
2445
2446   if (mp->local)
2447     vat_json_object_add_uint (node, "sw_if_index",
2448                               clib_net_to_host_u32 (mp->sw_if_index));
2449   else
2450     {
2451       if (mp->is_ipv6)
2452         {
2453           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2454           vat_json_object_add_ip6 (node, "address", ip6);
2455         }
2456       else
2457         {
2458           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2459           vat_json_object_add_ip4 (node, "address", ip4);
2460         }
2461     }
2462 }
2463
2464 static void
2465 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2466                                           mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   u8 *ls_name = 0;
2470
2471   ls_name = format (0, "%s", mp->ls_name);
2472
2473   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2474          ls_name);
2475   vec_free (ls_name);
2476 }
2477
2478 static void
2479   vl_api_one_locator_set_details_t_handler_json
2480   (vl_api_one_locator_set_details_t * mp)
2481 {
2482   vat_main_t *vam = &vat_main;
2483   vat_json_node_t *node = 0;
2484   u8 *ls_name = 0;
2485
2486   ls_name = format (0, "%s", mp->ls_name);
2487   vec_add1 (ls_name, 0);
2488
2489   if (VAT_JSON_ARRAY != vam->json_tree.type)
2490     {
2491       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2492       vat_json_init_array (&vam->json_tree);
2493     }
2494   node = vat_json_array_add (&vam->json_tree);
2495
2496   vat_json_init_object (node);
2497   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2498   vat_json_object_add_uint (node, "ls_index",
2499                             clib_net_to_host_u32 (mp->ls_index));
2500   vec_free (ls_name);
2501 }
2502
2503 static u8 *
2504 format_lisp_flat_eid (u8 * s, va_list * args)
2505 {
2506   u32 type = va_arg (*args, u32);
2507   u8 *eid = va_arg (*args, u8 *);
2508   u32 eid_len = va_arg (*args, u32);
2509
2510   switch (type)
2511     {
2512     case 0:
2513       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2514     case 1:
2515       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2516     case 2:
2517       return format (s, "%U", format_ethernet_address, eid);
2518     }
2519   return 0;
2520 }
2521
2522 static u8 *
2523 format_lisp_eid_vat (u8 * s, va_list * args)
2524 {
2525   u32 type = va_arg (*args, u32);
2526   u8 *eid = va_arg (*args, u8 *);
2527   u32 eid_len = va_arg (*args, u32);
2528   u8 *seid = va_arg (*args, u8 *);
2529   u32 seid_len = va_arg (*args, u32);
2530   u32 is_src_dst = va_arg (*args, u32);
2531
2532   if (is_src_dst)
2533     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2534
2535   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2536
2537   return s;
2538 }
2539
2540 static void
2541 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   u8 *s = 0, *eid = 0;
2545
2546   if (~0 == mp->locator_set_index)
2547     s = format (0, "action: %d", mp->action);
2548   else
2549     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2550
2551   eid = format (0, "%U", format_lisp_eid_vat,
2552                 mp->eid_type,
2553                 mp->eid,
2554                 mp->eid_prefix_len,
2555                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2556   vec_add1 (eid, 0);
2557
2558   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2559          clib_net_to_host_u32 (mp->vni),
2560          eid,
2561          mp->is_local ? "local" : "remote",
2562          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2563          clib_net_to_host_u16 (mp->key_id), mp->key);
2564
2565   vec_free (s);
2566   vec_free (eid);
2567 }
2568
2569 static void
2570 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2571                                              * mp)
2572 {
2573   vat_main_t *vam = &vat_main;
2574   vat_json_node_t *node = 0;
2575   u8 *eid = 0;
2576
2577   if (VAT_JSON_ARRAY != vam->json_tree.type)
2578     {
2579       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2580       vat_json_init_array (&vam->json_tree);
2581     }
2582   node = vat_json_array_add (&vam->json_tree);
2583
2584   vat_json_init_object (node);
2585   if (~0 == mp->locator_set_index)
2586     vat_json_object_add_uint (node, "action", mp->action);
2587   else
2588     vat_json_object_add_uint (node, "locator_set_index",
2589                               clib_net_to_host_u32 (mp->locator_set_index));
2590
2591   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2592   eid = format (0, "%U", format_lisp_eid_vat,
2593                 mp->eid_type,
2594                 mp->eid,
2595                 mp->eid_prefix_len,
2596                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2597   vec_add1 (eid, 0);
2598   vat_json_object_add_string_copy (node, "eid", eid);
2599   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2600   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2601   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2602
2603   if (mp->key_id)
2604     {
2605       vat_json_object_add_uint (node, "key_id",
2606                                 clib_net_to_host_u16 (mp->key_id));
2607       vat_json_object_add_string_copy (node, "key", mp->key);
2608     }
2609   vec_free (eid);
2610 }
2611
2612 static void
2613   vl_api_one_eid_table_map_details_t_handler
2614   (vl_api_one_eid_table_map_details_t * mp)
2615 {
2616   vat_main_t *vam = &vat_main;
2617
2618   u8 *line = format (0, "%=10d%=10d",
2619                      clib_net_to_host_u32 (mp->vni),
2620                      clib_net_to_host_u32 (mp->dp_table));
2621   print (vam->ofp, "%v", line);
2622   vec_free (line);
2623 }
2624
2625 static void
2626   vl_api_one_eid_table_map_details_t_handler_json
2627   (vl_api_one_eid_table_map_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, "dp_table",
2640                             clib_net_to_host_u32 (mp->dp_table));
2641   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2642 }
2643
2644 static void
2645   vl_api_one_eid_table_vni_details_t_handler
2646   (vl_api_one_eid_table_vni_details_t * mp)
2647 {
2648   vat_main_t *vam = &vat_main;
2649
2650   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2651   print (vam->ofp, "%v", line);
2652   vec_free (line);
2653 }
2654
2655 static void
2656   vl_api_one_eid_table_vni_details_t_handler_json
2657   (vl_api_one_eid_table_vni_details_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t *node = NULL;
2661
2662   if (VAT_JSON_ARRAY != vam->json_tree.type)
2663     {
2664       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2665       vat_json_init_array (&vam->json_tree);
2666     }
2667   node = vat_json_array_add (&vam->json_tree);
2668   vat_json_init_object (node);
2669   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2670 }
2671
2672 static void
2673   vl_api_show_one_map_register_state_reply_t_handler
2674   (vl_api_show_one_map_register_state_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   int retval = clib_net_to_host_u32 (mp->retval);
2678
2679   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2680
2681   vam->retval = retval;
2682   vam->result_ready = 1;
2683 }
2684
2685 static void
2686   vl_api_show_one_map_register_state_reply_t_handler_json
2687   (vl_api_show_one_map_register_state_reply_t * mp)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   vat_json_node_t _node, *node = &_node;
2691   int retval = clib_net_to_host_u32 (mp->retval);
2692
2693   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2694
2695   vat_json_init_object (node);
2696   vat_json_object_add_string_copy (node, "state", s);
2697
2698   vat_json_print (vam->ofp, node);
2699   vat_json_free (node);
2700
2701   vam->retval = retval;
2702   vam->result_ready = 1;
2703   vec_free (s);
2704 }
2705
2706 static void
2707   vl_api_show_one_rloc_probe_state_reply_t_handler
2708   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2709 {
2710   vat_main_t *vam = &vat_main;
2711   int retval = clib_net_to_host_u32 (mp->retval);
2712
2713   if (retval)
2714     goto end;
2715
2716   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2717 end:
2718   vam->retval = retval;
2719   vam->result_ready = 1;
2720 }
2721
2722 static void
2723   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2724   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2725 {
2726   vat_main_t *vam = &vat_main;
2727   vat_json_node_t _node, *node = &_node;
2728   int retval = clib_net_to_host_u32 (mp->retval);
2729
2730   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2731   vat_json_init_object (node);
2732   vat_json_object_add_string_copy (node, "state", s);
2733
2734   vat_json_print (vam->ofp, node);
2735   vat_json_free (node);
2736
2737   vam->retval = retval;
2738   vam->result_ready = 1;
2739   vec_free (s);
2740 }
2741
2742 static void
2743 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2744 {
2745   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2746   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2747 }
2748
2749 static void
2750   gpe_fwd_entries_get_reply_t_net_to_host
2751   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2752 {
2753   u32 i;
2754
2755   mp->count = clib_net_to_host_u32 (mp->count);
2756   for (i = 0; i < mp->count; i++)
2757     {
2758       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2759     }
2760 }
2761
2762 static u8 *
2763 format_gpe_encap_mode (u8 * s, va_list * args)
2764 {
2765   u32 mode = va_arg (*args, u32);
2766
2767   switch (mode)
2768     {
2769     case 0:
2770       return format (s, "lisp");
2771     case 1:
2772       return format (s, "vxlan");
2773     }
2774   return 0;
2775 }
2776
2777 static void
2778   vl_api_gpe_get_encap_mode_reply_t_handler
2779   (vl_api_gpe_get_encap_mode_reply_t * mp)
2780 {
2781   vat_main_t *vam = &vat_main;
2782
2783   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2784   vam->retval = ntohl (mp->retval);
2785   vam->result_ready = 1;
2786 }
2787
2788 static void
2789   vl_api_gpe_get_encap_mode_reply_t_handler_json
2790   (vl_api_gpe_get_encap_mode_reply_t * mp)
2791 {
2792   vat_main_t *vam = &vat_main;
2793   vat_json_node_t node;
2794
2795   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2796   vec_add1 (encap_mode, 0);
2797
2798   vat_json_init_object (&node);
2799   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2800
2801   vec_free (encap_mode);
2802   vat_json_print (vam->ofp, &node);
2803   vat_json_free (&node);
2804
2805   vam->retval = ntohl (mp->retval);
2806   vam->result_ready = 1;
2807 }
2808
2809 static void
2810   vl_api_gpe_fwd_entry_path_details_t_handler
2811   (vl_api_gpe_fwd_entry_path_details_t * mp)
2812 {
2813   vat_main_t *vam = &vat_main;
2814   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2815
2816   if (mp->lcl_loc.is_ip4)
2817     format_ip_address_fcn = format_ip4_address;
2818   else
2819     format_ip_address_fcn = format_ip6_address;
2820
2821   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2822          format_ip_address_fcn, &mp->lcl_loc,
2823          format_ip_address_fcn, &mp->rmt_loc);
2824 }
2825
2826 static void
2827 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2828 {
2829   struct in6_addr ip6;
2830   struct in_addr ip4;
2831
2832   if (loc->is_ip4)
2833     {
2834       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2835       vat_json_object_add_ip4 (n, "address", ip4);
2836     }
2837   else
2838     {
2839       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2840       vat_json_object_add_ip6 (n, "address", ip6);
2841     }
2842   vat_json_object_add_uint (n, "weight", loc->weight);
2843 }
2844
2845 static void
2846   vl_api_gpe_fwd_entry_path_details_t_handler_json
2847   (vl_api_gpe_fwd_entry_path_details_t * mp)
2848 {
2849   vat_main_t *vam = &vat_main;
2850   vat_json_node_t *node = NULL;
2851   vat_json_node_t *loc_node;
2852
2853   if (VAT_JSON_ARRAY != vam->json_tree.type)
2854     {
2855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2856       vat_json_init_array (&vam->json_tree);
2857     }
2858   node = vat_json_array_add (&vam->json_tree);
2859   vat_json_init_object (node);
2860
2861   loc_node = vat_json_object_add (node, "local_locator");
2862   vat_json_init_object (loc_node);
2863   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2864
2865   loc_node = vat_json_object_add (node, "remote_locator");
2866   vat_json_init_object (loc_node);
2867   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2868 }
2869
2870 static void
2871   vl_api_gpe_fwd_entries_get_reply_t_handler
2872   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2873 {
2874   vat_main_t *vam = &vat_main;
2875   u32 i;
2876   int retval = clib_net_to_host_u32 (mp->retval);
2877   vl_api_gpe_fwd_entry_t *e;
2878
2879   if (retval)
2880     goto end;
2881
2882   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2883
2884   for (i = 0; i < mp->count; i++)
2885     {
2886       e = &mp->entries[i];
2887       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2888              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2889              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2890     }
2891
2892 end:
2893   vam->retval = retval;
2894   vam->result_ready = 1;
2895 }
2896
2897 static void
2898   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2899   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2900 {
2901   u8 *s = 0;
2902   vat_main_t *vam = &vat_main;
2903   vat_json_node_t *e = 0, root;
2904   u32 i;
2905   int retval = clib_net_to_host_u32 (mp->retval);
2906   vl_api_gpe_fwd_entry_t *fwd;
2907
2908   if (retval)
2909     goto end;
2910
2911   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2912   vat_json_init_array (&root);
2913
2914   for (i = 0; i < mp->count; i++)
2915     {
2916       e = vat_json_array_add (&root);
2917       fwd = &mp->entries[i];
2918
2919       vat_json_init_object (e);
2920       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2921       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2922
2923       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2924                   fwd->leid_prefix_len);
2925       vec_add1 (s, 0);
2926       vat_json_object_add_string_copy (e, "leid", s);
2927       vec_free (s);
2928
2929       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2930                   fwd->reid_prefix_len);
2931       vec_add1 (s, 0);
2932       vat_json_object_add_string_copy (e, "reid", s);
2933       vec_free (s);
2934     }
2935
2936   vat_json_print (vam->ofp, &root);
2937   vat_json_free (&root);
2938
2939 end:
2940   vam->retval = retval;
2941   vam->result_ready = 1;
2942 }
2943
2944 static void
2945   vl_api_one_adjacencies_get_reply_t_handler
2946   (vl_api_one_adjacencies_get_reply_t * mp)
2947 {
2948   vat_main_t *vam = &vat_main;
2949   u32 i, n;
2950   int retval = clib_net_to_host_u32 (mp->retval);
2951   vl_api_one_adjacency_t *a;
2952
2953   if (retval)
2954     goto end;
2955
2956   n = clib_net_to_host_u32 (mp->count);
2957
2958   for (i = 0; i < n; i++)
2959     {
2960       a = &mp->adjacencies[i];
2961       print (vam->ofp, "%U %40U",
2962              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2963              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2964     }
2965
2966 end:
2967   vam->retval = retval;
2968   vam->result_ready = 1;
2969 }
2970
2971 static void
2972   vl_api_one_adjacencies_get_reply_t_handler_json
2973   (vl_api_one_adjacencies_get_reply_t * mp)
2974 {
2975   u8 *s = 0;
2976   vat_main_t *vam = &vat_main;
2977   vat_json_node_t *e = 0, root;
2978   u32 i, n;
2979   int retval = clib_net_to_host_u32 (mp->retval);
2980   vl_api_one_adjacency_t *a;
2981
2982   if (retval)
2983     goto end;
2984
2985   n = clib_net_to_host_u32 (mp->count);
2986   vat_json_init_array (&root);
2987
2988   for (i = 0; i < n; i++)
2989     {
2990       e = vat_json_array_add (&root);
2991       a = &mp->adjacencies[i];
2992
2993       vat_json_init_object (e);
2994       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2995                   a->leid_prefix_len);
2996       vec_add1 (s, 0);
2997       vat_json_object_add_string_copy (e, "leid", s);
2998       vec_free (s);
2999
3000       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3001                   a->reid_prefix_len);
3002       vec_add1 (s, 0);
3003       vat_json_object_add_string_copy (e, "reid", s);
3004       vec_free (s);
3005     }
3006
3007   vat_json_print (vam->ofp, &root);
3008   vat_json_free (&root);
3009
3010 end:
3011   vam->retval = retval;
3012   vam->result_ready = 1;
3013 }
3014
3015 static void
3016 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3017 {
3018   vat_main_t *vam = &vat_main;
3019
3020   print (vam->ofp, "%=20U",
3021          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3022          mp->ip_address);
3023 }
3024
3025 static void
3026   vl_api_one_map_server_details_t_handler_json
3027   (vl_api_one_map_server_details_t * mp)
3028 {
3029   vat_main_t *vam = &vat_main;
3030   vat_json_node_t *node = NULL;
3031   struct in6_addr ip6;
3032   struct in_addr ip4;
3033
3034   if (VAT_JSON_ARRAY != vam->json_tree.type)
3035     {
3036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3037       vat_json_init_array (&vam->json_tree);
3038     }
3039   node = vat_json_array_add (&vam->json_tree);
3040
3041   vat_json_init_object (node);
3042   if (mp->is_ipv6)
3043     {
3044       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3045       vat_json_object_add_ip6 (node, "map-server", ip6);
3046     }
3047   else
3048     {
3049       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3050       vat_json_object_add_ip4 (node, "map-server", ip4);
3051     }
3052 }
3053
3054 static void
3055 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3056                                            * mp)
3057 {
3058   vat_main_t *vam = &vat_main;
3059
3060   print (vam->ofp, "%=20U",
3061          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3062          mp->ip_address);
3063 }
3064
3065 static void
3066   vl_api_one_map_resolver_details_t_handler_json
3067   (vl_api_one_map_resolver_details_t * mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   vat_json_node_t *node = NULL;
3071   struct in6_addr ip6;
3072   struct in_addr ip4;
3073
3074   if (VAT_JSON_ARRAY != vam->json_tree.type)
3075     {
3076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3077       vat_json_init_array (&vam->json_tree);
3078     }
3079   node = vat_json_array_add (&vam->json_tree);
3080
3081   vat_json_init_object (node);
3082   if (mp->is_ipv6)
3083     {
3084       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3085       vat_json_object_add_ip6 (node, "map resolver", ip6);
3086     }
3087   else
3088     {
3089       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3090       vat_json_object_add_ip4 (node, "map resolver", ip4);
3091     }
3092 }
3093
3094 static void
3095 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3096 {
3097   vat_main_t *vam = &vat_main;
3098   i32 retval = ntohl (mp->retval);
3099
3100   if (0 <= retval)
3101     {
3102       print (vam->ofp, "feature: %s\ngpe: %s",
3103              mp->feature_status ? "enabled" : "disabled",
3104              mp->gpe_status ? "enabled" : "disabled");
3105     }
3106
3107   vam->retval = retval;
3108   vam->result_ready = 1;
3109 }
3110
3111 static void
3112   vl_api_show_one_status_reply_t_handler_json
3113   (vl_api_show_one_status_reply_t * mp)
3114 {
3115   vat_main_t *vam = &vat_main;
3116   vat_json_node_t node;
3117   u8 *gpe_status = NULL;
3118   u8 *feature_status = NULL;
3119
3120   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3121   feature_status = format (0, "%s",
3122                            mp->feature_status ? "enabled" : "disabled");
3123   vec_add1 (gpe_status, 0);
3124   vec_add1 (feature_status, 0);
3125
3126   vat_json_init_object (&node);
3127   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3128   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3129
3130   vec_free (gpe_status);
3131   vec_free (feature_status);
3132
3133   vat_json_print (vam->ofp, &node);
3134   vat_json_free (&node);
3135
3136   vam->retval = ntohl (mp->retval);
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3142   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   i32 retval = ntohl (mp->retval);
3146
3147   if (retval >= 0)
3148     {
3149       print (vam->ofp, "%=20s", mp->locator_set_name);
3150     }
3151
3152   vam->retval = retval;
3153   vam->result_ready = 1;
3154 }
3155
3156 static void
3157   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3158   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3159 {
3160   vat_main_t *vam = &vat_main;
3161   vat_json_node_t *node = NULL;
3162
3163   if (VAT_JSON_ARRAY != vam->json_tree.type)
3164     {
3165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3166       vat_json_init_array (&vam->json_tree);
3167     }
3168   node = vat_json_array_add (&vam->json_tree);
3169
3170   vat_json_init_object (node);
3171   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3172
3173   vat_json_print (vam->ofp, node);
3174   vat_json_free (node);
3175
3176   vam->retval = ntohl (mp->retval);
3177   vam->result_ready = 1;
3178 }
3179
3180 static u8 *
3181 format_lisp_map_request_mode (u8 * s, va_list * args)
3182 {
3183   u32 mode = va_arg (*args, u32);
3184
3185   switch (mode)
3186     {
3187     case 0:
3188       return format (0, "dst-only");
3189     case 1:
3190       return format (0, "src-dst");
3191     }
3192   return 0;
3193 }
3194
3195 static void
3196   vl_api_show_one_map_request_mode_reply_t_handler
3197   (vl_api_show_one_map_request_mode_reply_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200   i32 retval = ntohl (mp->retval);
3201
3202   if (0 <= retval)
3203     {
3204       u32 mode = mp->mode;
3205       print (vam->ofp, "map_request_mode: %U",
3206              format_lisp_map_request_mode, mode);
3207     }
3208
3209   vam->retval = retval;
3210   vam->result_ready = 1;
3211 }
3212
3213 static void
3214   vl_api_show_one_map_request_mode_reply_t_handler_json
3215   (vl_api_show_one_map_request_mode_reply_t * mp)
3216 {
3217   vat_main_t *vam = &vat_main;
3218   vat_json_node_t node;
3219   u8 *s = 0;
3220   u32 mode;
3221
3222   mode = mp->mode;
3223   s = format (0, "%U", format_lisp_map_request_mode, mode);
3224   vec_add1 (s, 0);
3225
3226   vat_json_init_object (&node);
3227   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3228   vat_json_print (vam->ofp, &node);
3229   vat_json_free (&node);
3230
3231   vec_free (s);
3232   vam->retval = ntohl (mp->retval);
3233   vam->result_ready = 1;
3234 }
3235
3236 static void
3237 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   i32 retval = ntohl (mp->retval);
3241
3242   if (0 <= retval)
3243     {
3244       print (vam->ofp, "%-20s%-16s",
3245              mp->status ? "enabled" : "disabled",
3246              mp->status ? (char *) mp->locator_set_name : "");
3247     }
3248
3249   vam->retval = retval;
3250   vam->result_ready = 1;
3251 }
3252
3253 static void
3254 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3255 {
3256   vat_main_t *vam = &vat_main;
3257   vat_json_node_t node;
3258   u8 *status = 0;
3259
3260   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3261   vec_add1 (status, 0);
3262
3263   vat_json_init_object (&node);
3264   vat_json_object_add_string_copy (&node, "status", status);
3265   if (mp->status)
3266     {
3267       vat_json_object_add_string_copy (&node, "locator_set",
3268                                        mp->locator_set_name);
3269     }
3270
3271   vec_free (status);
3272
3273   vat_json_print (vam->ofp, &node);
3274   vat_json_free (&node);
3275
3276   vam->retval = ntohl (mp->retval);
3277   vam->result_ready = 1;
3278 }
3279
3280 static u8 *
3281 format_policer_type (u8 * s, va_list * va)
3282 {
3283   u32 i = va_arg (*va, u32);
3284
3285   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3286     s = format (s, "1r2c");
3287   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3288     s = format (s, "1r3c");
3289   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3290     s = format (s, "2r3c-2698");
3291   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3292     s = format (s, "2r3c-4115");
3293   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3294     s = format (s, "2r3c-mef5cf1");
3295   else
3296     s = format (s, "ILLEGAL");
3297   return s;
3298 }
3299
3300 static u8 *
3301 format_policer_rate_type (u8 * s, va_list * va)
3302 {
3303   u32 i = va_arg (*va, u32);
3304
3305   if (i == SSE2_QOS_RATE_KBPS)
3306     s = format (s, "kbps");
3307   else if (i == SSE2_QOS_RATE_PPS)
3308     s = format (s, "pps");
3309   else
3310     s = format (s, "ILLEGAL");
3311   return s;
3312 }
3313
3314 static u8 *
3315 format_policer_round_type (u8 * s, va_list * va)
3316 {
3317   u32 i = va_arg (*va, u32);
3318
3319   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3320     s = format (s, "closest");
3321   else if (i == SSE2_QOS_ROUND_TO_UP)
3322     s = format (s, "up");
3323   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3324     s = format (s, "down");
3325   else
3326     s = format (s, "ILLEGAL");
3327   return s;
3328 }
3329
3330 static u8 *
3331 format_policer_action_type (u8 * s, va_list * va)
3332 {
3333   u32 i = va_arg (*va, u32);
3334
3335   if (i == SSE2_QOS_ACTION_DROP)
3336     s = format (s, "drop");
3337   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3338     s = format (s, "transmit");
3339   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3340     s = format (s, "mark-and-transmit");
3341   else
3342     s = format (s, "ILLEGAL");
3343   return s;
3344 }
3345
3346 static u8 *
3347 format_dscp (u8 * s, va_list * va)
3348 {
3349   u32 i = va_arg (*va, u32);
3350   char *t = 0;
3351
3352   switch (i)
3353     {
3354 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3355       foreach_vnet_dscp
3356 #undef _
3357     default:
3358       return format (s, "ILLEGAL");
3359     }
3360   s = format (s, "%s", t);
3361   return s;
3362 }
3363
3364 static void
3365 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3366 {
3367   vat_main_t *vam = &vat_main;
3368   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3369
3370   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3371     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3372   else
3373     conform_dscp_str = format (0, "");
3374
3375   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3376     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3377   else
3378     exceed_dscp_str = format (0, "");
3379
3380   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3381     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3382   else
3383     violate_dscp_str = format (0, "");
3384
3385   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3386          "rate type %U, round type %U, %s rate, %s color-aware, "
3387          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3388          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3389          "conform action %U%s, exceed action %U%s, violate action %U%s",
3390          mp->name,
3391          format_policer_type, mp->type,
3392          ntohl (mp->cir),
3393          ntohl (mp->eir),
3394          clib_net_to_host_u64 (mp->cb),
3395          clib_net_to_host_u64 (mp->eb),
3396          format_policer_rate_type, mp->rate_type,
3397          format_policer_round_type, mp->round_type,
3398          mp->single_rate ? "single" : "dual",
3399          mp->color_aware ? "is" : "not",
3400          ntohl (mp->cir_tokens_per_period),
3401          ntohl (mp->pir_tokens_per_period),
3402          ntohl (mp->scale),
3403          ntohl (mp->current_limit),
3404          ntohl (mp->current_bucket),
3405          ntohl (mp->extended_limit),
3406          ntohl (mp->extended_bucket),
3407          clib_net_to_host_u64 (mp->last_update_time),
3408          format_policer_action_type, mp->conform_action_type,
3409          conform_dscp_str,
3410          format_policer_action_type, mp->exceed_action_type,
3411          exceed_dscp_str,
3412          format_policer_action_type, mp->violate_action_type,
3413          violate_dscp_str);
3414
3415   vec_free (conform_dscp_str);
3416   vec_free (exceed_dscp_str);
3417   vec_free (violate_dscp_str);
3418 }
3419
3420 static void vl_api_policer_details_t_handler_json
3421   (vl_api_policer_details_t * mp)
3422 {
3423   vat_main_t *vam = &vat_main;
3424   vat_json_node_t *node;
3425   u8 *rate_type_str, *round_type_str, *type_str;
3426   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3427
3428   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3429   round_type_str =
3430     format (0, "%U", format_policer_round_type, mp->round_type);
3431   type_str = format (0, "%U", format_policer_type, mp->type);
3432   conform_action_str = format (0, "%U", format_policer_action_type,
3433                                mp->conform_action_type);
3434   exceed_action_str = format (0, "%U", format_policer_action_type,
3435                               mp->exceed_action_type);
3436   violate_action_str = format (0, "%U", format_policer_action_type,
3437                                mp->violate_action_type);
3438
3439   if (VAT_JSON_ARRAY != vam->json_tree.type)
3440     {
3441       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3442       vat_json_init_array (&vam->json_tree);
3443     }
3444   node = vat_json_array_add (&vam->json_tree);
3445
3446   vat_json_init_object (node);
3447   vat_json_object_add_string_copy (node, "name", mp->name);
3448   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3449   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3450   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3451   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3452   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3453   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3454   vat_json_object_add_string_copy (node, "type", type_str);
3455   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3456   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3457   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3458   vat_json_object_add_uint (node, "cir_tokens_per_period",
3459                             ntohl (mp->cir_tokens_per_period));
3460   vat_json_object_add_uint (node, "eir_tokens_per_period",
3461                             ntohl (mp->pir_tokens_per_period));
3462   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3463   vat_json_object_add_uint (node, "current_bucket",
3464                             ntohl (mp->current_bucket));
3465   vat_json_object_add_uint (node, "extended_limit",
3466                             ntohl (mp->extended_limit));
3467   vat_json_object_add_uint (node, "extended_bucket",
3468                             ntohl (mp->extended_bucket));
3469   vat_json_object_add_uint (node, "last_update_time",
3470                             ntohl (mp->last_update_time));
3471   vat_json_object_add_string_copy (node, "conform_action",
3472                                    conform_action_str);
3473   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3474     {
3475       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3476       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3477       vec_free (dscp_str);
3478     }
3479   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3480   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3481     {
3482       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3483       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3484       vec_free (dscp_str);
3485     }
3486   vat_json_object_add_string_copy (node, "violate_action",
3487                                    violate_action_str);
3488   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3489     {
3490       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3491       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3492       vec_free (dscp_str);
3493     }
3494
3495   vec_free (rate_type_str);
3496   vec_free (round_type_str);
3497   vec_free (type_str);
3498   vec_free (conform_action_str);
3499   vec_free (exceed_action_str);
3500   vec_free (violate_action_str);
3501 }
3502
3503 static void
3504 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3505                                            mp)
3506 {
3507   vat_main_t *vam = &vat_main;
3508   int i, count = ntohl (mp->count);
3509
3510   if (count > 0)
3511     print (vam->ofp, "classify table ids (%d) : ", count);
3512   for (i = 0; i < count; i++)
3513     {
3514       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3515       print (vam->ofp, (i < count - 1) ? "," : "");
3516     }
3517   vam->retval = ntohl (mp->retval);
3518   vam->result_ready = 1;
3519 }
3520
3521 static void
3522   vl_api_classify_table_ids_reply_t_handler_json
3523   (vl_api_classify_table_ids_reply_t * mp)
3524 {
3525   vat_main_t *vam = &vat_main;
3526   int i, count = ntohl (mp->count);
3527
3528   if (count > 0)
3529     {
3530       vat_json_node_t node;
3531
3532       vat_json_init_object (&node);
3533       for (i = 0; i < count; i++)
3534         {
3535           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3536         }
3537       vat_json_print (vam->ofp, &node);
3538       vat_json_free (&node);
3539     }
3540   vam->retval = ntohl (mp->retval);
3541   vam->result_ready = 1;
3542 }
3543
3544 static void
3545   vl_api_classify_table_by_interface_reply_t_handler
3546   (vl_api_classify_table_by_interface_reply_t * mp)
3547 {
3548   vat_main_t *vam = &vat_main;
3549   u32 table_id;
3550
3551   table_id = ntohl (mp->l2_table_id);
3552   if (table_id != ~0)
3553     print (vam->ofp, "l2 table id : %d", table_id);
3554   else
3555     print (vam->ofp, "l2 table id : No input ACL tables configured");
3556   table_id = ntohl (mp->ip4_table_id);
3557   if (table_id != ~0)
3558     print (vam->ofp, "ip4 table id : %d", table_id);
3559   else
3560     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3561   table_id = ntohl (mp->ip6_table_id);
3562   if (table_id != ~0)
3563     print (vam->ofp, "ip6 table id : %d", table_id);
3564   else
3565     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3566   vam->retval = ntohl (mp->retval);
3567   vam->result_ready = 1;
3568 }
3569
3570 static void
3571   vl_api_classify_table_by_interface_reply_t_handler_json
3572   (vl_api_classify_table_by_interface_reply_t * mp)
3573 {
3574   vat_main_t *vam = &vat_main;
3575   vat_json_node_t node;
3576
3577   vat_json_init_object (&node);
3578
3579   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3580   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3581   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3582
3583   vat_json_print (vam->ofp, &node);
3584   vat_json_free (&node);
3585
3586   vam->retval = ntohl (mp->retval);
3587   vam->result_ready = 1;
3588 }
3589
3590 static void vl_api_policer_add_del_reply_t_handler
3591   (vl_api_policer_add_del_reply_t * mp)
3592 {
3593   vat_main_t *vam = &vat_main;
3594   i32 retval = ntohl (mp->retval);
3595   if (vam->async_mode)
3596     {
3597       vam->async_errors += (retval < 0);
3598     }
3599   else
3600     {
3601       vam->retval = retval;
3602       vam->result_ready = 1;
3603       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3604         /*
3605          * Note: this is just barely thread-safe, depends on
3606          * the main thread spinning waiting for an answer...
3607          */
3608         errmsg ("policer index %d", ntohl (mp->policer_index));
3609     }
3610 }
3611
3612 static void vl_api_policer_add_del_reply_t_handler_json
3613   (vl_api_policer_add_del_reply_t * mp)
3614 {
3615   vat_main_t *vam = &vat_main;
3616   vat_json_node_t node;
3617
3618   vat_json_init_object (&node);
3619   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3620   vat_json_object_add_uint (&node, "policer_index",
3621                             ntohl (mp->policer_index));
3622
3623   vat_json_print (vam->ofp, &node);
3624   vat_json_free (&node);
3625
3626   vam->retval = ntohl (mp->retval);
3627   vam->result_ready = 1;
3628 }
3629
3630 /* Format hex dump. */
3631 u8 *
3632 format_hex_bytes (u8 * s, va_list * va)
3633 {
3634   u8 *bytes = va_arg (*va, u8 *);
3635   int n_bytes = va_arg (*va, int);
3636   uword i;
3637
3638   /* Print short or long form depending on byte count. */
3639   uword short_form = n_bytes <= 32;
3640   uword indent = format_get_indent (s);
3641
3642   if (n_bytes == 0)
3643     return s;
3644
3645   for (i = 0; i < n_bytes; i++)
3646     {
3647       if (!short_form && (i % 32) == 0)
3648         s = format (s, "%08x: ", i);
3649       s = format (s, "%02x", bytes[i]);
3650       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3651         s = format (s, "\n%U", format_white_space, indent);
3652     }
3653
3654   return s;
3655 }
3656
3657 static void
3658 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3659                                             * mp)
3660 {
3661   vat_main_t *vam = &vat_main;
3662   i32 retval = ntohl (mp->retval);
3663   if (retval == 0)
3664     {
3665       print (vam->ofp, "classify table info :");
3666       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3667              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3668              ntohl (mp->miss_next_index));
3669       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3670              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3671              ntohl (mp->match_n_vectors));
3672       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3673              ntohl (mp->mask_length));
3674     }
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_classify_table_info_reply_t_handler_json
3681   (vl_api_classify_table_info_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   vat_json_node_t node;
3685
3686   i32 retval = ntohl (mp->retval);
3687   if (retval == 0)
3688     {
3689       vat_json_init_object (&node);
3690
3691       vat_json_object_add_int (&node, "sessions",
3692                                ntohl (mp->active_sessions));
3693       vat_json_object_add_int (&node, "nexttbl",
3694                                ntohl (mp->next_table_index));
3695       vat_json_object_add_int (&node, "nextnode",
3696                                ntohl (mp->miss_next_index));
3697       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3698       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3699       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3700       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3701                       ntohl (mp->mask_length), 0);
3702       vat_json_object_add_string_copy (&node, "mask", s);
3703
3704       vat_json_print (vam->ofp, &node);
3705       vat_json_free (&node);
3706     }
3707   vam->retval = ntohl (mp->retval);
3708   vam->result_ready = 1;
3709 }
3710
3711 static void
3712 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3713                                            mp)
3714 {
3715   vat_main_t *vam = &vat_main;
3716
3717   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3718          ntohl (mp->hit_next_index), ntohl (mp->advance),
3719          ntohl (mp->opaque_index));
3720   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3721          ntohl (mp->match_length));
3722 }
3723
3724 static void
3725   vl_api_classify_session_details_t_handler_json
3726   (vl_api_classify_session_details_t * mp)
3727 {
3728   vat_main_t *vam = &vat_main;
3729   vat_json_node_t *node = NULL;
3730
3731   if (VAT_JSON_ARRAY != vam->json_tree.type)
3732     {
3733       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3734       vat_json_init_array (&vam->json_tree);
3735     }
3736   node = vat_json_array_add (&vam->json_tree);
3737
3738   vat_json_init_object (node);
3739   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3740   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3741   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3742   u8 *s =
3743     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3744             0);
3745   vat_json_object_add_string_copy (node, "match", s);
3746 }
3747
3748 static void vl_api_pg_create_interface_reply_t_handler
3749   (vl_api_pg_create_interface_reply_t * mp)
3750 {
3751   vat_main_t *vam = &vat_main;
3752
3753   vam->retval = ntohl (mp->retval);
3754   vam->result_ready = 1;
3755 }
3756
3757 static void vl_api_pg_create_interface_reply_t_handler_json
3758   (vl_api_pg_create_interface_reply_t * mp)
3759 {
3760   vat_main_t *vam = &vat_main;
3761   vat_json_node_t node;
3762
3763   i32 retval = ntohl (mp->retval);
3764   if (retval == 0)
3765     {
3766       vat_json_init_object (&node);
3767
3768       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3769
3770       vat_json_print (vam->ofp, &node);
3771       vat_json_free (&node);
3772     }
3773   vam->retval = ntohl (mp->retval);
3774   vam->result_ready = 1;
3775 }
3776
3777 static void vl_api_policer_classify_details_t_handler
3778   (vl_api_policer_classify_details_t * mp)
3779 {
3780   vat_main_t *vam = &vat_main;
3781
3782   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3783          ntohl (mp->table_index));
3784 }
3785
3786 static void vl_api_policer_classify_details_t_handler_json
3787   (vl_api_policer_classify_details_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   vat_json_node_t *node;
3791
3792   if (VAT_JSON_ARRAY != vam->json_tree.type)
3793     {
3794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3795       vat_json_init_array (&vam->json_tree);
3796     }
3797   node = vat_json_array_add (&vam->json_tree);
3798
3799   vat_json_init_object (node);
3800   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3801   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3802 }
3803
3804 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3805   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3806 {
3807   vat_main_t *vam = &vat_main;
3808   i32 retval = ntohl (mp->retval);
3809   if (vam->async_mode)
3810     {
3811       vam->async_errors += (retval < 0);
3812     }
3813   else
3814     {
3815       vam->retval = retval;
3816       vam->sw_if_index = ntohl (mp->sw_if_index);
3817       vam->result_ready = 1;
3818     }
3819 }
3820
3821 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3822   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3823 {
3824   vat_main_t *vam = &vat_main;
3825   vat_json_node_t node;
3826
3827   vat_json_init_object (&node);
3828   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3829   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3830
3831   vat_json_print (vam->ofp, &node);
3832   vat_json_free (&node);
3833
3834   vam->retval = ntohl (mp->retval);
3835   vam->result_ready = 1;
3836 }
3837
3838 static void vl_api_flow_classify_details_t_handler
3839   (vl_api_flow_classify_details_t * mp)
3840 {
3841   vat_main_t *vam = &vat_main;
3842
3843   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3844          ntohl (mp->table_index));
3845 }
3846
3847 static void vl_api_flow_classify_details_t_handler_json
3848   (vl_api_flow_classify_details_t * mp)
3849 {
3850   vat_main_t *vam = &vat_main;
3851   vat_json_node_t *node;
3852
3853   if (VAT_JSON_ARRAY != vam->json_tree.type)
3854     {
3855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3856       vat_json_init_array (&vam->json_tree);
3857     }
3858   node = vat_json_array_add (&vam->json_tree);
3859
3860   vat_json_init_object (node);
3861   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3862   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3863 }
3864
3865
3866
3867 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3868 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3869 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3870 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3871 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3872 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3873 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3874 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3875 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3876 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3877
3878 /*
3879  * Generate boilerplate reply handlers, which
3880  * dig the return value out of the xxx_reply_t API message,
3881  * stick it into vam->retval, and set vam->result_ready
3882  *
3883  * Could also do this by pointing N message decode slots at
3884  * a single function, but that could break in subtle ways.
3885  */
3886
3887 #define foreach_standard_reply_retval_handler           \
3888 _(sw_interface_set_flags_reply)                         \
3889 _(sw_interface_add_del_address_reply)                   \
3890 _(sw_interface_set_table_reply)                         \
3891 _(sw_interface_set_mpls_enable_reply)                   \
3892 _(sw_interface_set_vpath_reply)                         \
3893 _(sw_interface_set_vxlan_bypass_reply)                  \
3894 _(sw_interface_set_l2_bridge_reply)                     \
3895 _(bridge_domain_add_del_reply)                          \
3896 _(sw_interface_set_l2_xconnect_reply)                   \
3897 _(l2fib_add_del_reply)                                  \
3898 _(ip_add_del_route_reply)                               \
3899 _(ip_mroute_add_del_reply)                              \
3900 _(mpls_route_add_del_reply)                             \
3901 _(mpls_ip_bind_unbind_reply)                            \
3902 _(proxy_arp_add_del_reply)                              \
3903 _(proxy_arp_intfc_enable_disable_reply)                 \
3904 _(sw_interface_set_unnumbered_reply)                    \
3905 _(ip_neighbor_add_del_reply)                            \
3906 _(reset_vrf_reply)                                      \
3907 _(oam_add_del_reply)                                    \
3908 _(reset_fib_reply)                                      \
3909 _(dhcp_proxy_config_reply)                              \
3910 _(dhcp_proxy_set_vss_reply)                             \
3911 _(dhcp_client_config_reply)                             \
3912 _(set_ip_flow_hash_reply)                               \
3913 _(sw_interface_ip6_enable_disable_reply)                \
3914 _(sw_interface_ip6_set_link_local_address_reply)        \
3915 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3916 _(sw_interface_ip6nd_ra_config_reply)                   \
3917 _(set_arp_neighbor_limit_reply)                         \
3918 _(l2_patch_add_del_reply)                               \
3919 _(sr_tunnel_add_del_reply)                              \
3920 _(sr_policy_add_del_reply)                              \
3921 _(sr_multicast_map_add_del_reply)                       \
3922 _(classify_add_del_session_reply)                       \
3923 _(classify_set_interface_ip_table_reply)                \
3924 _(classify_set_interface_l2_tables_reply)               \
3925 _(l2tpv3_set_tunnel_cookies_reply)                      \
3926 _(l2tpv3_interface_enable_disable_reply)                \
3927 _(l2tpv3_set_lookup_key_reply)                          \
3928 _(l2_fib_clear_table_reply)                             \
3929 _(l2_interface_efp_filter_reply)                        \
3930 _(l2_interface_vlan_tag_rewrite_reply)                  \
3931 _(modify_vhost_user_if_reply)                           \
3932 _(delete_vhost_user_if_reply)                           \
3933 _(want_ip4_arp_events_reply)                            \
3934 _(want_ip6_nd_events_reply)                             \
3935 _(input_acl_set_interface_reply)                        \
3936 _(ipsec_spd_add_del_reply)                              \
3937 _(ipsec_interface_add_del_spd_reply)                    \
3938 _(ipsec_spd_add_del_entry_reply)                        \
3939 _(ipsec_sad_add_del_entry_reply)                        \
3940 _(ipsec_sa_set_key_reply)                               \
3941 _(ikev2_profile_add_del_reply)                          \
3942 _(ikev2_profile_set_auth_reply)                         \
3943 _(ikev2_profile_set_id_reply)                           \
3944 _(ikev2_profile_set_ts_reply)                           \
3945 _(ikev2_set_local_key_reply)                            \
3946 _(ikev2_set_responder_reply)                            \
3947 _(ikev2_set_ike_transforms_reply)                       \
3948 _(ikev2_set_esp_transforms_reply)                       \
3949 _(ikev2_set_sa_lifetime_reply)                          \
3950 _(ikev2_initiate_sa_init_reply)                         \
3951 _(ikev2_initiate_del_ike_sa_reply)                      \
3952 _(ikev2_initiate_del_child_sa_reply)                    \
3953 _(ikev2_initiate_rekey_child_sa_reply)                  \
3954 _(delete_loopback_reply)                                \
3955 _(bd_ip_mac_add_del_reply)                              \
3956 _(map_del_domain_reply)                                 \
3957 _(map_add_del_rule_reply)                               \
3958 _(want_interface_events_reply)                          \
3959 _(want_stats_reply)                                     \
3960 _(cop_interface_enable_disable_reply)                   \
3961 _(cop_whitelist_enable_disable_reply)                   \
3962 _(sw_interface_clear_stats_reply)                       \
3963 _(ioam_enable_reply)                              \
3964 _(ioam_disable_reply)                              \
3965 _(one_add_del_locator_reply)                            \
3966 _(one_add_del_local_eid_reply)                          \
3967 _(one_add_del_remote_mapping_reply)                     \
3968 _(one_add_del_adjacency_reply)                          \
3969 _(one_add_del_map_resolver_reply)                       \
3970 _(one_add_del_map_server_reply)                         \
3971 _(one_enable_disable_reply)                             \
3972 _(one_rloc_probe_enable_disable_reply)                  \
3973 _(one_map_register_enable_disable_reply)                \
3974 _(one_pitr_set_locator_set_reply)                       \
3975 _(one_map_request_mode_reply)                           \
3976 _(one_add_del_map_request_itr_rlocs_reply)              \
3977 _(one_eid_table_add_del_map_reply)                      \
3978 _(gpe_add_del_fwd_entry_reply)                          \
3979 _(gpe_enable_disable_reply)                             \
3980 _(gpe_set_encap_mode_reply)                             \
3981 _(gpe_add_del_iface_reply)                              \
3982 _(vxlan_gpe_add_del_tunnel_reply)                       \
3983 _(af_packet_delete_reply)                               \
3984 _(policer_classify_set_interface_reply)                 \
3985 _(netmap_create_reply)                                  \
3986 _(netmap_delete_reply)                                  \
3987 _(set_ipfix_exporter_reply)                             \
3988 _(set_ipfix_classify_stream_reply)                      \
3989 _(ipfix_classify_table_add_del_reply)                   \
3990 _(flow_classify_set_interface_reply)                    \
3991 _(sw_interface_span_enable_disable_reply)               \
3992 _(pg_capture_reply)                                     \
3993 _(pg_enable_disable_reply)                              \
3994 _(ip_source_and_port_range_check_add_del_reply)         \
3995 _(ip_source_and_port_range_check_interface_add_del_reply)\
3996 _(delete_subif_reply)                                   \
3997 _(l2_interface_pbb_tag_rewrite_reply)                   \
3998 _(punt_reply)                                           \
3999 _(feature_enable_disable_reply)                         \
4000 _(sw_interface_tag_add_del_reply)                       \
4001 _(sw_interface_set_mtu_reply)
4002
4003 #define _(n)                                    \
4004     static void vl_api_##n##_t_handler          \
4005     (vl_api_##n##_t * mp)                       \
4006     {                                           \
4007         vat_main_t * vam = &vat_main;           \
4008         i32 retval = ntohl(mp->retval);         \
4009         if (vam->async_mode) {                  \
4010             vam->async_errors += (retval < 0);  \
4011         } else {                                \
4012             vam->retval = retval;               \
4013             vam->result_ready = 1;              \
4014         }                                       \
4015     }
4016 foreach_standard_reply_retval_handler;
4017 #undef _
4018
4019 #define _(n)                                    \
4020     static void vl_api_##n##_t_handler_json     \
4021     (vl_api_##n##_t * mp)                       \
4022     {                                           \
4023         vat_main_t * vam = &vat_main;           \
4024         vat_json_node_t node;                   \
4025         vat_json_init_object(&node);            \
4026         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4027         vat_json_print(vam->ofp, &node);        \
4028         vam->retval = ntohl(mp->retval);        \
4029         vam->result_ready = 1;                  \
4030     }
4031 foreach_standard_reply_retval_handler;
4032 #undef _
4033
4034 /*
4035  * Table of message reply handlers, must include boilerplate handlers
4036  * we just generated
4037  */
4038
4039 #define foreach_vpe_api_reply_msg                                       \
4040 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4041 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4042 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4043 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4044 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4045 _(CLI_REPLY, cli_reply)                                                 \
4046 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4047 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4048   sw_interface_add_del_address_reply)                                   \
4049 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4050 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4051 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4052 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4053 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4054   sw_interface_set_l2_xconnect_reply)                                   \
4055 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4056   sw_interface_set_l2_bridge_reply)                                     \
4057 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4058 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4059 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4060 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4061 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4062 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4063 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4064 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4065 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4066 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4067 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4068 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4069 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4070 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4071 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4072 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4073   proxy_arp_intfc_enable_disable_reply)                                 \
4074 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4075 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4076   sw_interface_set_unnumbered_reply)                                    \
4077 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4078 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4079 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4080 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4081 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4082 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4083 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4084 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4085 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4086 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4087 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4088 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4089   sw_interface_ip6_enable_disable_reply)                                \
4090 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4091   sw_interface_ip6_set_link_local_address_reply)                        \
4092 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4093   sw_interface_ip6nd_ra_prefix_reply)                                   \
4094 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4095   sw_interface_ip6nd_ra_config_reply)                                   \
4096 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4097 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4098 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4099 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4100 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4101 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4102 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4103 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4104 classify_set_interface_ip_table_reply)                                  \
4105 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4106   classify_set_interface_l2_tables_reply)                               \
4107 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4108 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4109 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4110 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4111 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4112   l2tpv3_interface_enable_disable_reply)                                \
4113 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4114 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4115 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4116 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4117 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4118 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4119 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4120 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4121 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4122 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4123 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4124 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4125 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4126 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4127 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4128 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4129 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4130 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4131 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4132 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4133 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4134 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4135 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4136 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4137 _(IP_DETAILS, ip_details)                                               \
4138 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4139 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4140 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4141 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4142 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4143 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4144 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4145 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4146 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4147 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4148 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4149 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4150 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4151 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4152 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4153 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4154 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4155 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4156 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4157 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4158 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4159 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4160 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4161 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4162 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4163 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4164 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4165 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4166 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4167 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4168 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4169 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4170 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4171 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4172 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4173 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4174 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4175 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4176 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4177 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4178 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4179 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4180 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4181 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4182   one_map_register_enable_disable_reply)                                \
4183 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4184   one_rloc_probe_enable_disable_reply)                                  \
4185 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4186 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4187 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4188 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4189 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4190 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4191 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4192 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4193 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4194 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4195 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4196 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4197 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4198 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4199 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4200 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4201 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4202 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4203   gpe_fwd_entry_path_details)                                           \
4204 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4205 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4206   one_add_del_map_request_itr_rlocs_reply)                              \
4207 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4208   one_get_map_request_itr_rlocs_reply)                                  \
4209 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4210 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4211 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4212 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4213   show_one_map_register_state_reply)                                    \
4214 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4215 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4216 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4217 _(POLICER_DETAILS, policer_details)                                     \
4218 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4219 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4220 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4221 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4222 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4223 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4224 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4225 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4226 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4227 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4228 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4229 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4230 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4231 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4232 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4233 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4234 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4235 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4236 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4237 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4238 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4239 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4240 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4241 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4242 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4243  ip_source_and_port_range_check_add_del_reply)                          \
4244 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4245  ip_source_and_port_range_check_interface_add_del_reply)                \
4246 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4247 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4248 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4249 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4250 _(PUNT_REPLY, punt_reply)                                               \
4251 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4252 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4253 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4254 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4255 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4256 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4257 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4258 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4259
4260 #define foreach_standalone_reply_msg                                    \
4261 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4262 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4263 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4264 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4265 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4266 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4267
4268 typedef struct
4269 {
4270   u8 *name;
4271   u32 value;
4272 } name_sort_t;
4273
4274
4275 #define STR_VTR_OP_CASE(op)     \
4276     case L2_VTR_ ## op:         \
4277         return "" # op;
4278
4279 static const char *
4280 str_vtr_op (u32 vtr_op)
4281 {
4282   switch (vtr_op)
4283     {
4284       STR_VTR_OP_CASE (DISABLED);
4285       STR_VTR_OP_CASE (PUSH_1);
4286       STR_VTR_OP_CASE (PUSH_2);
4287       STR_VTR_OP_CASE (POP_1);
4288       STR_VTR_OP_CASE (POP_2);
4289       STR_VTR_OP_CASE (TRANSLATE_1_1);
4290       STR_VTR_OP_CASE (TRANSLATE_1_2);
4291       STR_VTR_OP_CASE (TRANSLATE_2_1);
4292       STR_VTR_OP_CASE (TRANSLATE_2_2);
4293     }
4294
4295   return "UNKNOWN";
4296 }
4297
4298 static int
4299 dump_sub_interface_table (vat_main_t * vam)
4300 {
4301   const sw_interface_subif_t *sub = NULL;
4302
4303   if (vam->json_output)
4304     {
4305       clib_warning
4306         ("JSON output supported only for VPE API calls and dump_stats_table");
4307       return -99;
4308     }
4309
4310   print (vam->ofp,
4311          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4312          "Interface", "sw_if_index",
4313          "sub id", "dot1ad", "tags", "outer id",
4314          "inner id", "exact", "default", "outer any", "inner any");
4315
4316   vec_foreach (sub, vam->sw_if_subif_table)
4317   {
4318     print (vam->ofp,
4319            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4320            sub->interface_name,
4321            sub->sw_if_index,
4322            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4323            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4324            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4325            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4326     if (sub->vtr_op != L2_VTR_DISABLED)
4327       {
4328         print (vam->ofp,
4329                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4330                "tag1: %d tag2: %d ]",
4331                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4332                sub->vtr_tag1, sub->vtr_tag2);
4333       }
4334   }
4335
4336   return 0;
4337 }
4338
4339 static int
4340 name_sort_cmp (void *a1, void *a2)
4341 {
4342   name_sort_t *n1 = a1;
4343   name_sort_t *n2 = a2;
4344
4345   return strcmp ((char *) n1->name, (char *) n2->name);
4346 }
4347
4348 static int
4349 dump_interface_table (vat_main_t * vam)
4350 {
4351   hash_pair_t *p;
4352   name_sort_t *nses = 0, *ns;
4353
4354   if (vam->json_output)
4355     {
4356       clib_warning
4357         ("JSON output supported only for VPE API calls and dump_stats_table");
4358       return -99;
4359     }
4360
4361   /* *INDENT-OFF* */
4362   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4363   ({
4364     vec_add2 (nses, ns, 1);
4365     ns->name = (u8 *)(p->key);
4366     ns->value = (u32) p->value[0];
4367   }));
4368   /* *INDENT-ON* */
4369
4370   vec_sort_with_function (nses, name_sort_cmp);
4371
4372   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4373   vec_foreach (ns, nses)
4374   {
4375     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4376   }
4377   vec_free (nses);
4378   return 0;
4379 }
4380
4381 static int
4382 dump_ip_table (vat_main_t * vam, int is_ipv6)
4383 {
4384   const ip_details_t *det = NULL;
4385   const ip_address_details_t *address = NULL;
4386   u32 i = ~0;
4387
4388   print (vam->ofp, "%-12s", "sw_if_index");
4389
4390   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4391   {
4392     i++;
4393     if (!det->present)
4394       {
4395         continue;
4396       }
4397     print (vam->ofp, "%-12d", i);
4398     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4399     if (!det->addr)
4400       {
4401         continue;
4402       }
4403     vec_foreach (address, det->addr)
4404     {
4405       print (vam->ofp,
4406              "            %-30U%-13d",
4407              is_ipv6 ? format_ip6_address : format_ip4_address,
4408              address->ip, address->prefix_length);
4409     }
4410   }
4411
4412   return 0;
4413 }
4414
4415 static int
4416 dump_ipv4_table (vat_main_t * vam)
4417 {
4418   if (vam->json_output)
4419     {
4420       clib_warning
4421         ("JSON output supported only for VPE API calls and dump_stats_table");
4422       return -99;
4423     }
4424
4425   return dump_ip_table (vam, 0);
4426 }
4427
4428 static int
4429 dump_ipv6_table (vat_main_t * vam)
4430 {
4431   if (vam->json_output)
4432     {
4433       clib_warning
4434         ("JSON output supported only for VPE API calls and dump_stats_table");
4435       return -99;
4436     }
4437
4438   return dump_ip_table (vam, 1);
4439 }
4440
4441 static char *
4442 counter_type_to_str (u8 counter_type, u8 is_combined)
4443 {
4444   if (!is_combined)
4445     {
4446       switch (counter_type)
4447         {
4448         case VNET_INTERFACE_COUNTER_DROP:
4449           return "drop";
4450         case VNET_INTERFACE_COUNTER_PUNT:
4451           return "punt";
4452         case VNET_INTERFACE_COUNTER_IP4:
4453           return "ip4";
4454         case VNET_INTERFACE_COUNTER_IP6:
4455           return "ip6";
4456         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4457           return "rx-no-buf";
4458         case VNET_INTERFACE_COUNTER_RX_MISS:
4459           return "rx-miss";
4460         case VNET_INTERFACE_COUNTER_RX_ERROR:
4461           return "rx-error";
4462         case VNET_INTERFACE_COUNTER_TX_ERROR:
4463           return "tx-error";
4464         default:
4465           return "INVALID-COUNTER-TYPE";
4466         }
4467     }
4468   else
4469     {
4470       switch (counter_type)
4471         {
4472         case VNET_INTERFACE_COUNTER_RX:
4473           return "rx";
4474         case VNET_INTERFACE_COUNTER_TX:
4475           return "tx";
4476         default:
4477           return "INVALID-COUNTER-TYPE";
4478         }
4479     }
4480 }
4481
4482 static int
4483 dump_stats_table (vat_main_t * vam)
4484 {
4485   vat_json_node_t node;
4486   vat_json_node_t *msg_array;
4487   vat_json_node_t *msg;
4488   vat_json_node_t *counter_array;
4489   vat_json_node_t *counter;
4490   interface_counter_t c;
4491   u64 packets;
4492   ip4_fib_counter_t *c4;
4493   ip6_fib_counter_t *c6;
4494   ip4_nbr_counter_t *n4;
4495   ip6_nbr_counter_t *n6;
4496   int i, j;
4497
4498   if (!vam->json_output)
4499     {
4500       clib_warning ("dump_stats_table supported only in JSON format");
4501       return -99;
4502     }
4503
4504   vat_json_init_object (&node);
4505
4506   /* interface counters */
4507   msg_array = vat_json_object_add (&node, "interface_counters");
4508   vat_json_init_array (msg_array);
4509   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4510     {
4511       msg = vat_json_array_add (msg_array);
4512       vat_json_init_object (msg);
4513       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4514                                        (u8 *) counter_type_to_str (i, 0));
4515       vat_json_object_add_int (msg, "is_combined", 0);
4516       counter_array = vat_json_object_add (msg, "data");
4517       vat_json_init_array (counter_array);
4518       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4519         {
4520           packets = vam->simple_interface_counters[i][j];
4521           vat_json_array_add_uint (counter_array, packets);
4522         }
4523     }
4524   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4525     {
4526       msg = vat_json_array_add (msg_array);
4527       vat_json_init_object (msg);
4528       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4529                                        (u8 *) counter_type_to_str (i, 1));
4530       vat_json_object_add_int (msg, "is_combined", 1);
4531       counter_array = vat_json_object_add (msg, "data");
4532       vat_json_init_array (counter_array);
4533       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4534         {
4535           c = vam->combined_interface_counters[i][j];
4536           counter = vat_json_array_add (counter_array);
4537           vat_json_init_object (counter);
4538           vat_json_object_add_uint (counter, "packets", c.packets);
4539           vat_json_object_add_uint (counter, "bytes", c.bytes);
4540         }
4541     }
4542
4543   /* ip4 fib counters */
4544   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4545   vat_json_init_array (msg_array);
4546   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4547     {
4548       msg = vat_json_array_add (msg_array);
4549       vat_json_init_object (msg);
4550       vat_json_object_add_uint (msg, "vrf_id",
4551                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4552       counter_array = vat_json_object_add (msg, "c");
4553       vat_json_init_array (counter_array);
4554       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4555         {
4556           counter = vat_json_array_add (counter_array);
4557           vat_json_init_object (counter);
4558           c4 = &vam->ip4_fib_counters[i][j];
4559           vat_json_object_add_ip4 (counter, "address", c4->address);
4560           vat_json_object_add_uint (counter, "address_length",
4561                                     c4->address_length);
4562           vat_json_object_add_uint (counter, "packets", c4->packets);
4563           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4564         }
4565     }
4566
4567   /* ip6 fib counters */
4568   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4569   vat_json_init_array (msg_array);
4570   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4571     {
4572       msg = vat_json_array_add (msg_array);
4573       vat_json_init_object (msg);
4574       vat_json_object_add_uint (msg, "vrf_id",
4575                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4576       counter_array = vat_json_object_add (msg, "c");
4577       vat_json_init_array (counter_array);
4578       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4579         {
4580           counter = vat_json_array_add (counter_array);
4581           vat_json_init_object (counter);
4582           c6 = &vam->ip6_fib_counters[i][j];
4583           vat_json_object_add_ip6 (counter, "address", c6->address);
4584           vat_json_object_add_uint (counter, "address_length",
4585                                     c6->address_length);
4586           vat_json_object_add_uint (counter, "packets", c6->packets);
4587           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4588         }
4589     }
4590
4591   /* ip4 nbr counters */
4592   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4593   vat_json_init_array (msg_array);
4594   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4595     {
4596       msg = vat_json_array_add (msg_array);
4597       vat_json_init_object (msg);
4598       vat_json_object_add_uint (msg, "sw_if_index", i);
4599       counter_array = vat_json_object_add (msg, "c");
4600       vat_json_init_array (counter_array);
4601       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4602         {
4603           counter = vat_json_array_add (counter_array);
4604           vat_json_init_object (counter);
4605           n4 = &vam->ip4_nbr_counters[i][j];
4606           vat_json_object_add_ip4 (counter, "address", n4->address);
4607           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4608           vat_json_object_add_uint (counter, "packets", n4->packets);
4609           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4610         }
4611     }
4612
4613   /* ip6 nbr counters */
4614   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4615   vat_json_init_array (msg_array);
4616   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4617     {
4618       msg = vat_json_array_add (msg_array);
4619       vat_json_init_object (msg);
4620       vat_json_object_add_uint (msg, "sw_if_index", i);
4621       counter_array = vat_json_object_add (msg, "c");
4622       vat_json_init_array (counter_array);
4623       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4624         {
4625           counter = vat_json_array_add (counter_array);
4626           vat_json_init_object (counter);
4627           n6 = &vam->ip6_nbr_counters[i][j];
4628           vat_json_object_add_ip6 (counter, "address", n6->address);
4629           vat_json_object_add_uint (counter, "packets", n6->packets);
4630           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4631         }
4632     }
4633
4634   vat_json_print (vam->ofp, &node);
4635   vat_json_free (&node);
4636
4637   return 0;
4638 }
4639
4640 int
4641 exec (vat_main_t * vam)
4642 {
4643   api_main_t *am = &api_main;
4644   vl_api_cli_request_t *mp;
4645   f64 timeout;
4646   void *oldheap;
4647   u8 *cmd = 0;
4648   unformat_input_t *i = vam->input;
4649
4650   if (vec_len (i->buffer) == 0)
4651     return -1;
4652
4653   if (vam->exec_mode == 0 && unformat (i, "mode"))
4654     {
4655       vam->exec_mode = 1;
4656       return 0;
4657     }
4658   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4659     {
4660       vam->exec_mode = 0;
4661       return 0;
4662     }
4663
4664
4665   M (CLI_REQUEST, mp);
4666
4667   /*
4668    * Copy cmd into shared memory.
4669    * In order for the CLI command to work, it
4670    * must be a vector ending in \n, not a C-string ending
4671    * in \n\0.
4672    */
4673   pthread_mutex_lock (&am->vlib_rp->mutex);
4674   oldheap = svm_push_data_heap (am->vlib_rp);
4675
4676   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4677   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4678
4679   svm_pop_heap (oldheap);
4680   pthread_mutex_unlock (&am->vlib_rp->mutex);
4681
4682   mp->cmd_in_shmem = (u64) cmd;
4683   S (mp);
4684   timeout = vat_time_now (vam) + 10.0;
4685
4686   while (vat_time_now (vam) < timeout)
4687     {
4688       if (vam->result_ready == 1)
4689         {
4690           u8 *free_me;
4691           if (vam->shmem_result != NULL)
4692             print (vam->ofp, "%s", vam->shmem_result);
4693           pthread_mutex_lock (&am->vlib_rp->mutex);
4694           oldheap = svm_push_data_heap (am->vlib_rp);
4695
4696           free_me = (u8 *) vam->shmem_result;
4697           vec_free (free_me);
4698
4699           svm_pop_heap (oldheap);
4700           pthread_mutex_unlock (&am->vlib_rp->mutex);
4701           return 0;
4702         }
4703     }
4704   return -99;
4705 }
4706
4707 /*
4708  * Future replacement of exec() that passes CLI buffers directly in
4709  * the API messages instead of an additional shared memory area.
4710  */
4711 static int
4712 exec_inband (vat_main_t * vam)
4713 {
4714   vl_api_cli_inband_t *mp;
4715   unformat_input_t *i = vam->input;
4716   int ret;
4717
4718   if (vec_len (i->buffer) == 0)
4719     return -1;
4720
4721   if (vam->exec_mode == 0 && unformat (i, "mode"))
4722     {
4723       vam->exec_mode = 1;
4724       return 0;
4725     }
4726   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4727     {
4728       vam->exec_mode = 0;
4729       return 0;
4730     }
4731
4732   /*
4733    * In order for the CLI command to work, it
4734    * must be a vector ending in \n, not a C-string ending
4735    * in \n\0.
4736    */
4737   u32 len = vec_len (vam->input->buffer);
4738   M2 (CLI_INBAND, mp, len);
4739   clib_memcpy (mp->cmd, vam->input->buffer, len);
4740   mp->length = htonl (len);
4741
4742   S (mp);
4743   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4744   return ret;
4745 }
4746
4747 static int
4748 api_create_loopback (vat_main_t * vam)
4749 {
4750   unformat_input_t *i = vam->input;
4751   vl_api_create_loopback_t *mp;
4752   vl_api_create_loopback_instance_t *mp_lbi;
4753   u8 mac_address[6];
4754   u8 mac_set = 0;
4755   u8 is_specified = 0;
4756   u32 user_instance = 0;
4757   int ret;
4758
4759   memset (mac_address, 0, sizeof (mac_address));
4760
4761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4762     {
4763       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4764         mac_set = 1;
4765       if (unformat (i, "instance %d", &user_instance))
4766         is_specified = 1;
4767       else
4768         break;
4769     }
4770
4771   if (is_specified)
4772     {
4773       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
4774       mp_lbi->is_specified = is_specified;
4775       if (is_specified)
4776         mp_lbi->user_instance = htonl (user_instance);
4777       if (mac_set)
4778         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
4779       S (mp_lbi);
4780     }
4781   else
4782     {
4783       /* Construct the API message */
4784       M (CREATE_LOOPBACK, mp);
4785       if (mac_set)
4786         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4787       S (mp);
4788     }
4789
4790   W (ret);
4791   return ret;
4792 }
4793
4794 static int
4795 api_delete_loopback (vat_main_t * vam)
4796 {
4797   unformat_input_t *i = vam->input;
4798   vl_api_delete_loopback_t *mp;
4799   u32 sw_if_index = ~0;
4800   int ret;
4801
4802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4803     {
4804       if (unformat (i, "sw_if_index %d", &sw_if_index))
4805         ;
4806       else
4807         break;
4808     }
4809
4810   if (sw_if_index == ~0)
4811     {
4812       errmsg ("missing sw_if_index");
4813       return -99;
4814     }
4815
4816   /* Construct the API message */
4817   M (DELETE_LOOPBACK, mp);
4818   mp->sw_if_index = ntohl (sw_if_index);
4819
4820   S (mp);
4821   W (ret);
4822   return ret;
4823 }
4824
4825 static int
4826 api_want_stats (vat_main_t * vam)
4827 {
4828   unformat_input_t *i = vam->input;
4829   vl_api_want_stats_t *mp;
4830   int enable = -1;
4831   int ret;
4832
4833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4834     {
4835       if (unformat (i, "enable"))
4836         enable = 1;
4837       else if (unformat (i, "disable"))
4838         enable = 0;
4839       else
4840         break;
4841     }
4842
4843   if (enable == -1)
4844     {
4845       errmsg ("missing enable|disable");
4846       return -99;
4847     }
4848
4849   M (WANT_STATS, mp);
4850   mp->enable_disable = enable;
4851
4852   S (mp);
4853   W (ret);
4854   return ret;
4855 }
4856
4857 static int
4858 api_want_interface_events (vat_main_t * vam)
4859 {
4860   unformat_input_t *i = vam->input;
4861   vl_api_want_interface_events_t *mp;
4862   int enable = -1;
4863   int ret;
4864
4865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4866     {
4867       if (unformat (i, "enable"))
4868         enable = 1;
4869       else if (unformat (i, "disable"))
4870         enable = 0;
4871       else
4872         break;
4873     }
4874
4875   if (enable == -1)
4876     {
4877       errmsg ("missing enable|disable");
4878       return -99;
4879     }
4880
4881   M (WANT_INTERFACE_EVENTS, mp);
4882   mp->enable_disable = enable;
4883
4884   vam->interface_event_display = enable;
4885
4886   S (mp);
4887   W (ret);
4888   return ret;
4889 }
4890
4891
4892 /* Note: non-static, called once to set up the initial intfc table */
4893 int
4894 api_sw_interface_dump (vat_main_t * vam)
4895 {
4896   vl_api_sw_interface_dump_t *mp;
4897   vl_api_control_ping_t *mp_ping;
4898   hash_pair_t *p;
4899   name_sort_t *nses = 0, *ns;
4900   sw_interface_subif_t *sub = NULL;
4901   int ret;
4902
4903   /* Toss the old name table */
4904   /* *INDENT-OFF* */
4905   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4906   ({
4907     vec_add2 (nses, ns, 1);
4908     ns->name = (u8 *)(p->key);
4909     ns->value = (u32) p->value[0];
4910   }));
4911   /* *INDENT-ON* */
4912
4913   hash_free (vam->sw_if_index_by_interface_name);
4914
4915   vec_foreach (ns, nses) vec_free (ns->name);
4916
4917   vec_free (nses);
4918
4919   vec_foreach (sub, vam->sw_if_subif_table)
4920   {
4921     vec_free (sub->interface_name);
4922   }
4923   vec_free (vam->sw_if_subif_table);
4924
4925   /* recreate the interface name hash table */
4926   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4927
4928   /* Get list of ethernets */
4929   M (SW_INTERFACE_DUMP, mp);
4930   mp->name_filter_valid = 1;
4931   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4932   S (mp);
4933
4934   /* and local / loopback interfaces */
4935   M (SW_INTERFACE_DUMP, mp);
4936   mp->name_filter_valid = 1;
4937   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4938   S (mp);
4939
4940   /* and packet-generator interfaces */
4941   M (SW_INTERFACE_DUMP, mp);
4942   mp->name_filter_valid = 1;
4943   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4944   S (mp);
4945
4946   /* and vxlan-gpe tunnel interfaces */
4947   M (SW_INTERFACE_DUMP, mp);
4948   mp->name_filter_valid = 1;
4949   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4950            sizeof (mp->name_filter) - 1);
4951   S (mp);
4952
4953   /* and vxlan tunnel interfaces */
4954   M (SW_INTERFACE_DUMP, mp);
4955   mp->name_filter_valid = 1;
4956   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4957   S (mp);
4958
4959   /* and host (af_packet) interfaces */
4960   M (SW_INTERFACE_DUMP, mp);
4961   mp->name_filter_valid = 1;
4962   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4963   S (mp);
4964
4965   /* and l2tpv3 tunnel interfaces */
4966   M (SW_INTERFACE_DUMP, mp);
4967   mp->name_filter_valid = 1;
4968   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4969            sizeof (mp->name_filter) - 1);
4970   S (mp);
4971
4972   /* and GRE tunnel interfaces */
4973   M (SW_INTERFACE_DUMP, mp);
4974   mp->name_filter_valid = 1;
4975   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4976   S (mp);
4977
4978   /* and LISP-GPE interfaces */
4979   M (SW_INTERFACE_DUMP, mp);
4980   mp->name_filter_valid = 1;
4981   strncpy ((char *) mp->name_filter, "lisp_gpe",
4982            sizeof (mp->name_filter) - 1);
4983   S (mp);
4984
4985   /* and IPSEC tunnel interfaces */
4986   M (SW_INTERFACE_DUMP, mp);
4987   mp->name_filter_valid = 1;
4988   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4989   S (mp);
4990
4991   /* Use a control ping for synchronization */
4992   M (CONTROL_PING, mp_ping);
4993   S (mp_ping);
4994
4995   W (ret);
4996   return ret;
4997 }
4998
4999 static int
5000 api_sw_interface_set_flags (vat_main_t * vam)
5001 {
5002   unformat_input_t *i = vam->input;
5003   vl_api_sw_interface_set_flags_t *mp;
5004   u32 sw_if_index;
5005   u8 sw_if_index_set = 0;
5006   u8 admin_up = 0, link_up = 0;
5007   int ret;
5008
5009   /* Parse args required to build the message */
5010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5011     {
5012       if (unformat (i, "admin-up"))
5013         admin_up = 1;
5014       else if (unformat (i, "admin-down"))
5015         admin_up = 0;
5016       else if (unformat (i, "link-up"))
5017         link_up = 1;
5018       else if (unformat (i, "link-down"))
5019         link_up = 0;
5020       else
5021         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5022         sw_if_index_set = 1;
5023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5024         sw_if_index_set = 1;
5025       else
5026         break;
5027     }
5028
5029   if (sw_if_index_set == 0)
5030     {
5031       errmsg ("missing interface name or sw_if_index");
5032       return -99;
5033     }
5034
5035   /* Construct the API message */
5036   M (SW_INTERFACE_SET_FLAGS, mp);
5037   mp->sw_if_index = ntohl (sw_if_index);
5038   mp->admin_up_down = admin_up;
5039   mp->link_up_down = link_up;
5040
5041   /* send it... */
5042   S (mp);
5043
5044   /* Wait for a reply, return the good/bad news... */
5045   W (ret);
5046   return ret;
5047 }
5048
5049 static int
5050 api_sw_interface_clear_stats (vat_main_t * vam)
5051 {
5052   unformat_input_t *i = vam->input;
5053   vl_api_sw_interface_clear_stats_t *mp;
5054   u32 sw_if_index;
5055   u8 sw_if_index_set = 0;
5056   int ret;
5057
5058   /* Parse args required to build the message */
5059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5060     {
5061       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5062         sw_if_index_set = 1;
5063       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5064         sw_if_index_set = 1;
5065       else
5066         break;
5067     }
5068
5069   /* Construct the API message */
5070   M (SW_INTERFACE_CLEAR_STATS, mp);
5071
5072   if (sw_if_index_set == 1)
5073     mp->sw_if_index = ntohl (sw_if_index);
5074   else
5075     mp->sw_if_index = ~0;
5076
5077   /* send it... */
5078   S (mp);
5079
5080   /* Wait for a reply, return the good/bad news... */
5081   W (ret);
5082   return ret;
5083 }
5084
5085 static int
5086 api_sw_interface_add_del_address (vat_main_t * vam)
5087 {
5088   unformat_input_t *i = vam->input;
5089   vl_api_sw_interface_add_del_address_t *mp;
5090   u32 sw_if_index;
5091   u8 sw_if_index_set = 0;
5092   u8 is_add = 1, del_all = 0;
5093   u32 address_length = 0;
5094   u8 v4_address_set = 0;
5095   u8 v6_address_set = 0;
5096   ip4_address_t v4address;
5097   ip6_address_t v6address;
5098   int ret;
5099
5100   /* Parse args required to build the message */
5101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5102     {
5103       if (unformat (i, "del-all"))
5104         del_all = 1;
5105       else if (unformat (i, "del"))
5106         is_add = 0;
5107       else
5108         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5109         sw_if_index_set = 1;
5110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5111         sw_if_index_set = 1;
5112       else if (unformat (i, "%U/%d",
5113                          unformat_ip4_address, &v4address, &address_length))
5114         v4_address_set = 1;
5115       else if (unformat (i, "%U/%d",
5116                          unformat_ip6_address, &v6address, &address_length))
5117         v6_address_set = 1;
5118       else
5119         break;
5120     }
5121
5122   if (sw_if_index_set == 0)
5123     {
5124       errmsg ("missing interface name or sw_if_index");
5125       return -99;
5126     }
5127   if (v4_address_set && v6_address_set)
5128     {
5129       errmsg ("both v4 and v6 addresses set");
5130       return -99;
5131     }
5132   if (!v4_address_set && !v6_address_set && !del_all)
5133     {
5134       errmsg ("no addresses set");
5135       return -99;
5136     }
5137
5138   /* Construct the API message */
5139   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5140
5141   mp->sw_if_index = ntohl (sw_if_index);
5142   mp->is_add = is_add;
5143   mp->del_all = del_all;
5144   if (v6_address_set)
5145     {
5146       mp->is_ipv6 = 1;
5147       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5148     }
5149   else
5150     {
5151       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5152     }
5153   mp->address_length = address_length;
5154
5155   /* send it... */
5156   S (mp);
5157
5158   /* Wait for a reply, return good/bad news  */
5159   W (ret);
5160   return ret;
5161 }
5162
5163 static int
5164 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5165 {
5166   unformat_input_t *i = vam->input;
5167   vl_api_sw_interface_set_mpls_enable_t *mp;
5168   u32 sw_if_index;
5169   u8 sw_if_index_set = 0;
5170   u8 enable = 1;
5171   int ret;
5172
5173   /* Parse args required to build the message */
5174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5175     {
5176       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5177         sw_if_index_set = 1;
5178       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5179         sw_if_index_set = 1;
5180       else if (unformat (i, "disable"))
5181         enable = 0;
5182       else if (unformat (i, "dis"))
5183         enable = 0;
5184       else
5185         break;
5186     }
5187
5188   if (sw_if_index_set == 0)
5189     {
5190       errmsg ("missing interface name or sw_if_index");
5191       return -99;
5192     }
5193
5194   /* Construct the API message */
5195   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5196
5197   mp->sw_if_index = ntohl (sw_if_index);
5198   mp->enable = enable;
5199
5200   /* send it... */
5201   S (mp);
5202
5203   /* Wait for a reply... */
5204   W (ret);
5205   return ret;
5206 }
5207
5208 static int
5209 api_sw_interface_set_table (vat_main_t * vam)
5210 {
5211   unformat_input_t *i = vam->input;
5212   vl_api_sw_interface_set_table_t *mp;
5213   u32 sw_if_index, vrf_id = 0;
5214   u8 sw_if_index_set = 0;
5215   u8 is_ipv6 = 0;
5216   int ret;
5217
5218   /* Parse args required to build the message */
5219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5220     {
5221       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5222         sw_if_index_set = 1;
5223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5224         sw_if_index_set = 1;
5225       else if (unformat (i, "vrf %d", &vrf_id))
5226         ;
5227       else if (unformat (i, "ipv6"))
5228         is_ipv6 = 1;
5229       else
5230         break;
5231     }
5232
5233   if (sw_if_index_set == 0)
5234     {
5235       errmsg ("missing interface name or sw_if_index");
5236       return -99;
5237     }
5238
5239   /* Construct the API message */
5240   M (SW_INTERFACE_SET_TABLE, mp);
5241
5242   mp->sw_if_index = ntohl (sw_if_index);
5243   mp->is_ipv6 = is_ipv6;
5244   mp->vrf_id = ntohl (vrf_id);
5245
5246   /* send it... */
5247   S (mp);
5248
5249   /* Wait for a reply... */
5250   W (ret);
5251   return ret;
5252 }
5253
5254 static void vl_api_sw_interface_get_table_reply_t_handler
5255   (vl_api_sw_interface_get_table_reply_t * mp)
5256 {
5257   vat_main_t *vam = &vat_main;
5258
5259   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5260
5261   vam->retval = ntohl (mp->retval);
5262   vam->result_ready = 1;
5263
5264 }
5265
5266 static void vl_api_sw_interface_get_table_reply_t_handler_json
5267   (vl_api_sw_interface_get_table_reply_t * mp)
5268 {
5269   vat_main_t *vam = &vat_main;
5270   vat_json_node_t node;
5271
5272   vat_json_init_object (&node);
5273   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5274   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5275
5276   vat_json_print (vam->ofp, &node);
5277   vat_json_free (&node);
5278
5279   vam->retval = ntohl (mp->retval);
5280   vam->result_ready = 1;
5281 }
5282
5283 static int
5284 api_sw_interface_get_table (vat_main_t * vam)
5285 {
5286   unformat_input_t *i = vam->input;
5287   vl_api_sw_interface_get_table_t *mp;
5288   u32 sw_if_index;
5289   u8 sw_if_index_set = 0;
5290   u8 is_ipv6 = 0;
5291   int ret;
5292
5293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5294     {
5295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5296         sw_if_index_set = 1;
5297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5298         sw_if_index_set = 1;
5299       else if (unformat (i, "ipv6"))
5300         is_ipv6 = 1;
5301       else
5302         break;
5303     }
5304
5305   if (sw_if_index_set == 0)
5306     {
5307       errmsg ("missing interface name or sw_if_index");
5308       return -99;
5309     }
5310
5311   M (SW_INTERFACE_GET_TABLE, mp);
5312   mp->sw_if_index = htonl (sw_if_index);
5313   mp->is_ipv6 = is_ipv6;
5314
5315   S (mp);
5316   W (ret);
5317   return ret;
5318 }
5319
5320 static int
5321 api_sw_interface_set_vpath (vat_main_t * vam)
5322 {
5323   unformat_input_t *i = vam->input;
5324   vl_api_sw_interface_set_vpath_t *mp;
5325   u32 sw_if_index = 0;
5326   u8 sw_if_index_set = 0;
5327   u8 is_enable = 0;
5328   int ret;
5329
5330   /* Parse args required to build the message */
5331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5332     {
5333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5334         sw_if_index_set = 1;
5335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5336         sw_if_index_set = 1;
5337       else if (unformat (i, "enable"))
5338         is_enable = 1;
5339       else if (unformat (i, "disable"))
5340         is_enable = 0;
5341       else
5342         break;
5343     }
5344
5345   if (sw_if_index_set == 0)
5346     {
5347       errmsg ("missing interface name or sw_if_index");
5348       return -99;
5349     }
5350
5351   /* Construct the API message */
5352   M (SW_INTERFACE_SET_VPATH, mp);
5353
5354   mp->sw_if_index = ntohl (sw_if_index);
5355   mp->enable = is_enable;
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_vxlan_bypass (vat_main_t * vam)
5367 {
5368   unformat_input_t *i = vam->input;
5369   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5370   u32 sw_if_index = 0;
5371   u8 sw_if_index_set = 0;
5372   u8 is_enable = 1;
5373   u8 is_ipv6 = 0;
5374   int ret;
5375
5376   /* Parse args required to build the message */
5377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5378     {
5379       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5380         sw_if_index_set = 1;
5381       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5382         sw_if_index_set = 1;
5383       else if (unformat (i, "enable"))
5384         is_enable = 1;
5385       else if (unformat (i, "disable"))
5386         is_enable = 0;
5387       else if (unformat (i, "ip4"))
5388         is_ipv6 = 0;
5389       else if (unformat (i, "ip6"))
5390         is_ipv6 = 1;
5391       else
5392         break;
5393     }
5394
5395   if (sw_if_index_set == 0)
5396     {
5397       errmsg ("missing interface name or sw_if_index");
5398       return -99;
5399     }
5400
5401   /* Construct the API message */
5402   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5403
5404   mp->sw_if_index = ntohl (sw_if_index);
5405   mp->enable = is_enable;
5406   mp->is_ipv6 = is_ipv6;
5407
5408   /* send it... */
5409   S (mp);
5410
5411   /* Wait for a reply... */
5412   W (ret);
5413   return ret;
5414 }
5415
5416 static int
5417 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5418 {
5419   unformat_input_t *i = vam->input;
5420   vl_api_sw_interface_set_l2_xconnect_t *mp;
5421   u32 rx_sw_if_index;
5422   u8 rx_sw_if_index_set = 0;
5423   u32 tx_sw_if_index;
5424   u8 tx_sw_if_index_set = 0;
5425   u8 enable = 1;
5426   int ret;
5427
5428   /* Parse args required to build the message */
5429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5430     {
5431       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5432         rx_sw_if_index_set = 1;
5433       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5434         tx_sw_if_index_set = 1;
5435       else if (unformat (i, "rx"))
5436         {
5437           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5438             {
5439               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5440                             &rx_sw_if_index))
5441                 rx_sw_if_index_set = 1;
5442             }
5443           else
5444             break;
5445         }
5446       else if (unformat (i, "tx"))
5447         {
5448           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5449             {
5450               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5451                             &tx_sw_if_index))
5452                 tx_sw_if_index_set = 1;
5453             }
5454           else
5455             break;
5456         }
5457       else if (unformat (i, "enable"))
5458         enable = 1;
5459       else if (unformat (i, "disable"))
5460         enable = 0;
5461       else
5462         break;
5463     }
5464
5465   if (rx_sw_if_index_set == 0)
5466     {
5467       errmsg ("missing rx interface name or rx_sw_if_index");
5468       return -99;
5469     }
5470
5471   if (enable && (tx_sw_if_index_set == 0))
5472     {
5473       errmsg ("missing tx interface name or tx_sw_if_index");
5474       return -99;
5475     }
5476
5477   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5478
5479   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5480   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5481   mp->enable = enable;
5482
5483   S (mp);
5484   W (ret);
5485   return ret;
5486 }
5487
5488 static int
5489 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5490 {
5491   unformat_input_t *i = vam->input;
5492   vl_api_sw_interface_set_l2_bridge_t *mp;
5493   u32 rx_sw_if_index;
5494   u8 rx_sw_if_index_set = 0;
5495   u32 bd_id;
5496   u8 bd_id_set = 0;
5497   u8 bvi = 0;
5498   u32 shg = 0;
5499   u8 enable = 1;
5500   int ret;
5501
5502   /* Parse args required to build the message */
5503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5504     {
5505       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5506         rx_sw_if_index_set = 1;
5507       else if (unformat (i, "bd_id %d", &bd_id))
5508         bd_id_set = 1;
5509       else
5510         if (unformat
5511             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5512         rx_sw_if_index_set = 1;
5513       else if (unformat (i, "shg %d", &shg))
5514         ;
5515       else if (unformat (i, "bvi"))
5516         bvi = 1;
5517       else if (unformat (i, "enable"))
5518         enable = 1;
5519       else if (unformat (i, "disable"))
5520         enable = 0;
5521       else
5522         break;
5523     }
5524
5525   if (rx_sw_if_index_set == 0)
5526     {
5527       errmsg ("missing rx interface name or sw_if_index");
5528       return -99;
5529     }
5530
5531   if (enable && (bd_id_set == 0))
5532     {
5533       errmsg ("missing bridge domain");
5534       return -99;
5535     }
5536
5537   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5538
5539   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5540   mp->bd_id = ntohl (bd_id);
5541   mp->shg = (u8) shg;
5542   mp->bvi = bvi;
5543   mp->enable = enable;
5544
5545   S (mp);
5546   W (ret);
5547   return ret;
5548 }
5549
5550 static int
5551 api_bridge_domain_dump (vat_main_t * vam)
5552 {
5553   unformat_input_t *i = vam->input;
5554   vl_api_bridge_domain_dump_t *mp;
5555   vl_api_control_ping_t *mp_ping;
5556   u32 bd_id = ~0;
5557   int ret;
5558
5559   /* Parse args required to build the message */
5560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5561     {
5562       if (unformat (i, "bd_id %d", &bd_id))
5563         ;
5564       else
5565         break;
5566     }
5567
5568   M (BRIDGE_DOMAIN_DUMP, mp);
5569   mp->bd_id = ntohl (bd_id);
5570   S (mp);
5571
5572   /* Use a control ping for synchronization */
5573   M (CONTROL_PING, mp_ping);
5574   S (mp_ping);
5575
5576   W (ret);
5577   return ret;
5578 }
5579
5580 static int
5581 api_bridge_domain_add_del (vat_main_t * vam)
5582 {
5583   unformat_input_t *i = vam->input;
5584   vl_api_bridge_domain_add_del_t *mp;
5585   u32 bd_id = ~0;
5586   u8 is_add = 1;
5587   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5588   u32 mac_age = 0;
5589   int ret;
5590
5591   /* Parse args required to build the message */
5592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5593     {
5594       if (unformat (i, "bd_id %d", &bd_id))
5595         ;
5596       else if (unformat (i, "flood %d", &flood))
5597         ;
5598       else if (unformat (i, "uu-flood %d", &uu_flood))
5599         ;
5600       else if (unformat (i, "forward %d", &forward))
5601         ;
5602       else if (unformat (i, "learn %d", &learn))
5603         ;
5604       else if (unformat (i, "arp-term %d", &arp_term))
5605         ;
5606       else if (unformat (i, "mac-age %d", &mac_age))
5607         ;
5608       else if (unformat (i, "del"))
5609         {
5610           is_add = 0;
5611           flood = uu_flood = forward = learn = 0;
5612         }
5613       else
5614         break;
5615     }
5616
5617   if (bd_id == ~0)
5618     {
5619       errmsg ("missing bridge domain");
5620       return -99;
5621     }
5622
5623   if (mac_age > 255)
5624     {
5625       errmsg ("mac age must be less than 256 ");
5626       return -99;
5627     }
5628
5629   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5630
5631   mp->bd_id = ntohl (bd_id);
5632   mp->flood = flood;
5633   mp->uu_flood = uu_flood;
5634   mp->forward = forward;
5635   mp->learn = learn;
5636   mp->arp_term = arp_term;
5637   mp->is_add = is_add;
5638   mp->mac_age = (u8) mac_age;
5639
5640   S (mp);
5641   W (ret);
5642   return ret;
5643 }
5644
5645 static int
5646 api_l2fib_add_del (vat_main_t * vam)
5647 {
5648   unformat_input_t *i = vam->input;
5649   vl_api_l2fib_add_del_t *mp;
5650   f64 timeout;
5651   u64 mac = 0;
5652   u8 mac_set = 0;
5653   u32 bd_id;
5654   u8 bd_id_set = 0;
5655   u32 sw_if_index = ~0;
5656   u8 sw_if_index_set = 0;
5657   u8 is_add = 1;
5658   u8 static_mac = 0;
5659   u8 filter_mac = 0;
5660   u8 bvi_mac = 0;
5661   int count = 1;
5662   f64 before = 0;
5663   int j;
5664
5665   /* Parse args required to build the message */
5666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5667     {
5668       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5669         mac_set = 1;
5670       else if (unformat (i, "bd_id %d", &bd_id))
5671         bd_id_set = 1;
5672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5673         sw_if_index_set = 1;
5674       else if (unformat (i, "sw_if"))
5675         {
5676           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5677             {
5678               if (unformat
5679                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5680                 sw_if_index_set = 1;
5681             }
5682           else
5683             break;
5684         }
5685       else if (unformat (i, "static"))
5686         static_mac = 1;
5687       else if (unformat (i, "filter"))
5688         {
5689           filter_mac = 1;
5690           static_mac = 1;
5691         }
5692       else if (unformat (i, "bvi"))
5693         {
5694           bvi_mac = 1;
5695           static_mac = 1;
5696         }
5697       else if (unformat (i, "del"))
5698         is_add = 0;
5699       else if (unformat (i, "count %d", &count))
5700         ;
5701       else
5702         break;
5703     }
5704
5705   if (mac_set == 0)
5706     {
5707       errmsg ("missing mac address");
5708       return -99;
5709     }
5710
5711   if (bd_id_set == 0)
5712     {
5713       errmsg ("missing bridge domain");
5714       return -99;
5715     }
5716
5717   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5718     {
5719       errmsg ("missing interface name or sw_if_index");
5720       return -99;
5721     }
5722
5723   if (count > 1)
5724     {
5725       /* Turn on async mode */
5726       vam->async_mode = 1;
5727       vam->async_errors = 0;
5728       before = vat_time_now (vam);
5729     }
5730
5731   for (j = 0; j < count; j++)
5732     {
5733       M (L2FIB_ADD_DEL, mp);
5734
5735       mp->mac = mac;
5736       mp->bd_id = ntohl (bd_id);
5737       mp->is_add = is_add;
5738
5739       if (is_add)
5740         {
5741           mp->sw_if_index = ntohl (sw_if_index);
5742           mp->static_mac = static_mac;
5743           mp->filter_mac = filter_mac;
5744           mp->bvi_mac = bvi_mac;
5745         }
5746       increment_mac_address (&mac);
5747       /* send it... */
5748       S (mp);
5749     }
5750
5751   if (count > 1)
5752     {
5753       vl_api_control_ping_t *mp_ping;
5754       f64 after;
5755
5756       /* Shut off async mode */
5757       vam->async_mode = 0;
5758
5759       M (CONTROL_PING, mp_ping);
5760       S (mp_ping);
5761
5762       timeout = vat_time_now (vam) + 1.0;
5763       while (vat_time_now (vam) < timeout)
5764         if (vam->result_ready == 1)
5765           goto out;
5766       vam->retval = -99;
5767
5768     out:
5769       if (vam->retval == -99)
5770         errmsg ("timeout");
5771
5772       if (vam->async_errors > 0)
5773         {
5774           errmsg ("%d asynchronous errors", vam->async_errors);
5775           vam->retval = -98;
5776         }
5777       vam->async_errors = 0;
5778       after = vat_time_now (vam);
5779
5780       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5781              count, after - before, count / (after - before));
5782     }
5783   else
5784     {
5785       int ret;
5786
5787       /* Wait for a reply... */
5788       W (ret);
5789       return ret;
5790     }
5791   /* Return the good/bad news */
5792   return (vam->retval);
5793 }
5794
5795 static int
5796 api_l2_flags (vat_main_t * vam)
5797 {
5798   unformat_input_t *i = vam->input;
5799   vl_api_l2_flags_t *mp;
5800   u32 sw_if_index;
5801   u32 feature_bitmap = 0;
5802   u8 sw_if_index_set = 0;
5803   int ret;
5804
5805   /* Parse args required to build the message */
5806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5807     {
5808       if (unformat (i, "sw_if_index %d", &sw_if_index))
5809         sw_if_index_set = 1;
5810       else if (unformat (i, "sw_if"))
5811         {
5812           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5813             {
5814               if (unformat
5815                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5816                 sw_if_index_set = 1;
5817             }
5818           else
5819             break;
5820         }
5821       else if (unformat (i, "learn"))
5822         feature_bitmap |= L2INPUT_FEAT_LEARN;
5823       else if (unformat (i, "forward"))
5824         feature_bitmap |= L2INPUT_FEAT_FWD;
5825       else if (unformat (i, "flood"))
5826         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5827       else if (unformat (i, "uu-flood"))
5828         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5829       else
5830         break;
5831     }
5832
5833   if (sw_if_index_set == 0)
5834     {
5835       errmsg ("missing interface name or sw_if_index");
5836       return -99;
5837     }
5838
5839   M (L2_FLAGS, mp);
5840
5841   mp->sw_if_index = ntohl (sw_if_index);
5842   mp->feature_bitmap = ntohl (feature_bitmap);
5843
5844   S (mp);
5845   W (ret);
5846   return ret;
5847 }
5848
5849 static int
5850 api_bridge_flags (vat_main_t * vam)
5851 {
5852   unformat_input_t *i = vam->input;
5853   vl_api_bridge_flags_t *mp;
5854   u32 bd_id;
5855   u8 bd_id_set = 0;
5856   u8 is_set = 1;
5857   u32 flags = 0;
5858   int ret;
5859
5860   /* Parse args required to build the message */
5861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5862     {
5863       if (unformat (i, "bd_id %d", &bd_id))
5864         bd_id_set = 1;
5865       else if (unformat (i, "learn"))
5866         flags |= L2_LEARN;
5867       else if (unformat (i, "forward"))
5868         flags |= L2_FWD;
5869       else if (unformat (i, "flood"))
5870         flags |= L2_FLOOD;
5871       else if (unformat (i, "uu-flood"))
5872         flags |= L2_UU_FLOOD;
5873       else if (unformat (i, "arp-term"))
5874         flags |= L2_ARP_TERM;
5875       else if (unformat (i, "off"))
5876         is_set = 0;
5877       else if (unformat (i, "disable"))
5878         is_set = 0;
5879       else
5880         break;
5881     }
5882
5883   if (bd_id_set == 0)
5884     {
5885       errmsg ("missing bridge domain");
5886       return -99;
5887     }
5888
5889   M (BRIDGE_FLAGS, mp);
5890
5891   mp->bd_id = ntohl (bd_id);
5892   mp->feature_bitmap = ntohl (flags);
5893   mp->is_set = is_set;
5894
5895   S (mp);
5896   W (ret);
5897   return ret;
5898 }
5899
5900 static int
5901 api_bd_ip_mac_add_del (vat_main_t * vam)
5902 {
5903   unformat_input_t *i = vam->input;
5904   vl_api_bd_ip_mac_add_del_t *mp;
5905   u32 bd_id;
5906   u8 is_ipv6 = 0;
5907   u8 is_add = 1;
5908   u8 bd_id_set = 0;
5909   u8 ip_set = 0;
5910   u8 mac_set = 0;
5911   ip4_address_t v4addr;
5912   ip6_address_t v6addr;
5913   u8 macaddr[6];
5914   int ret;
5915
5916
5917   /* Parse args required to build the message */
5918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5919     {
5920       if (unformat (i, "bd_id %d", &bd_id))
5921         {
5922           bd_id_set++;
5923         }
5924       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5925         {
5926           ip_set++;
5927         }
5928       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5929         {
5930           ip_set++;
5931           is_ipv6++;
5932         }
5933       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5934         {
5935           mac_set++;
5936         }
5937       else if (unformat (i, "del"))
5938         is_add = 0;
5939       else
5940         break;
5941     }
5942
5943   if (bd_id_set == 0)
5944     {
5945       errmsg ("missing bridge domain");
5946       return -99;
5947     }
5948   else if (ip_set == 0)
5949     {
5950       errmsg ("missing IP address");
5951       return -99;
5952     }
5953   else if (mac_set == 0)
5954     {
5955       errmsg ("missing MAC address");
5956       return -99;
5957     }
5958
5959   M (BD_IP_MAC_ADD_DEL, mp);
5960
5961   mp->bd_id = ntohl (bd_id);
5962   mp->is_ipv6 = is_ipv6;
5963   mp->is_add = is_add;
5964   if (is_ipv6)
5965     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5966   else
5967     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5968   clib_memcpy (mp->mac_address, macaddr, 6);
5969   S (mp);
5970   W (ret);
5971   return ret;
5972 }
5973
5974 static int
5975 api_tap_connect (vat_main_t * vam)
5976 {
5977   unformat_input_t *i = vam->input;
5978   vl_api_tap_connect_t *mp;
5979   u8 mac_address[6];
5980   u8 random_mac = 1;
5981   u8 name_set = 0;
5982   u8 *tap_name;
5983   u8 *tag = 0;
5984   ip4_address_t ip4_address;
5985   u32 ip4_mask_width;
5986   int ip4_address_set = 0;
5987   ip6_address_t ip6_address;
5988   u32 ip6_mask_width;
5989   int ip6_address_set = 0;
5990   int ret;
5991
5992   memset (mac_address, 0, sizeof (mac_address));
5993
5994   /* Parse args required to build the message */
5995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5996     {
5997       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5998         {
5999           random_mac = 0;
6000         }
6001       else if (unformat (i, "random-mac"))
6002         random_mac = 1;
6003       else if (unformat (i, "tapname %s", &tap_name))
6004         name_set = 1;
6005       else if (unformat (i, "tag %s", &tag))
6006         ;
6007       else if (unformat (i, "address %U/%d",
6008                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6009         ip4_address_set = 1;
6010       else if (unformat (i, "address %U/%d",
6011                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6012         ip6_address_set = 1;
6013       else
6014         break;
6015     }
6016
6017   if (name_set == 0)
6018     {
6019       errmsg ("missing tap name");
6020       return -99;
6021     }
6022   if (vec_len (tap_name) > 63)
6023     {
6024       errmsg ("tap name too long");
6025       return -99;
6026     }
6027   vec_add1 (tap_name, 0);
6028
6029   if (vec_len (tag) > 63)
6030     {
6031       errmsg ("tag too long");
6032       return -99;
6033     }
6034
6035   /* Construct the API message */
6036   M (TAP_CONNECT, mp);
6037
6038   mp->use_random_mac = random_mac;
6039   clib_memcpy (mp->mac_address, mac_address, 6);
6040   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6041   if (tag)
6042     clib_memcpy (mp->tag, tag, vec_len (tag));
6043
6044   if (ip4_address_set)
6045     {
6046       mp->ip4_address_set = 1;
6047       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6048       mp->ip4_mask_width = ip4_mask_width;
6049     }
6050   if (ip6_address_set)
6051     {
6052       mp->ip6_address_set = 1;
6053       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6054       mp->ip6_mask_width = ip6_mask_width;
6055     }
6056
6057   vec_free (tap_name);
6058   vec_free (tag);
6059
6060   /* send it... */
6061   S (mp);
6062
6063   /* Wait for a reply... */
6064   W (ret);
6065   return ret;
6066 }
6067
6068 static int
6069 api_tap_modify (vat_main_t * vam)
6070 {
6071   unformat_input_t *i = vam->input;
6072   vl_api_tap_modify_t *mp;
6073   u8 mac_address[6];
6074   u8 random_mac = 1;
6075   u8 name_set = 0;
6076   u8 *tap_name;
6077   u32 sw_if_index = ~0;
6078   u8 sw_if_index_set = 0;
6079   int ret;
6080
6081   memset (mac_address, 0, sizeof (mac_address));
6082
6083   /* Parse args required to build the message */
6084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6085     {
6086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6087         sw_if_index_set = 1;
6088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6089         sw_if_index_set = 1;
6090       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6091         {
6092           random_mac = 0;
6093         }
6094       else if (unformat (i, "random-mac"))
6095         random_mac = 1;
6096       else if (unformat (i, "tapname %s", &tap_name))
6097         name_set = 1;
6098       else
6099         break;
6100     }
6101
6102   if (sw_if_index_set == 0)
6103     {
6104       errmsg ("missing vpp interface name");
6105       return -99;
6106     }
6107   if (name_set == 0)
6108     {
6109       errmsg ("missing tap name");
6110       return -99;
6111     }
6112   if (vec_len (tap_name) > 63)
6113     {
6114       errmsg ("tap name too long");
6115     }
6116   vec_add1 (tap_name, 0);
6117
6118   /* Construct the API message */
6119   M (TAP_MODIFY, mp);
6120
6121   mp->use_random_mac = random_mac;
6122   mp->sw_if_index = ntohl (sw_if_index);
6123   clib_memcpy (mp->mac_address, mac_address, 6);
6124   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6125   vec_free (tap_name);
6126
6127   /* send it... */
6128   S (mp);
6129
6130   /* Wait for a reply... */
6131   W (ret);
6132   return ret;
6133 }
6134
6135 static int
6136 api_tap_delete (vat_main_t * vam)
6137 {
6138   unformat_input_t *i = vam->input;
6139   vl_api_tap_delete_t *mp;
6140   u32 sw_if_index = ~0;
6141   u8 sw_if_index_set = 0;
6142   int ret;
6143
6144   /* Parse args required to build the message */
6145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6146     {
6147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6148         sw_if_index_set = 1;
6149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6150         sw_if_index_set = 1;
6151       else
6152         break;
6153     }
6154
6155   if (sw_if_index_set == 0)
6156     {
6157       errmsg ("missing vpp interface name");
6158       return -99;
6159     }
6160
6161   /* Construct the API message */
6162   M (TAP_DELETE, mp);
6163
6164   mp->sw_if_index = ntohl (sw_if_index);
6165
6166   /* send it... */
6167   S (mp);
6168
6169   /* Wait for a reply... */
6170   W (ret);
6171   return ret;
6172 }
6173
6174 static int
6175 api_ip_add_del_route (vat_main_t * vam)
6176 {
6177   unformat_input_t *i = vam->input;
6178   vl_api_ip_add_del_route_t *mp;
6179   u32 sw_if_index = ~0, vrf_id = 0;
6180   u8 is_ipv6 = 0;
6181   u8 is_local = 0, is_drop = 0;
6182   u8 is_unreach = 0, is_prohibit = 0;
6183   u8 create_vrf_if_needed = 0;
6184   u8 is_add = 1;
6185   u32 next_hop_weight = 1;
6186   u8 not_last = 0;
6187   u8 is_multipath = 0;
6188   u8 address_set = 0;
6189   u8 address_length_set = 0;
6190   u32 next_hop_table_id = 0;
6191   u32 resolve_attempts = 0;
6192   u32 dst_address_length = 0;
6193   u8 next_hop_set = 0;
6194   ip4_address_t v4_dst_address, v4_next_hop_address;
6195   ip6_address_t v6_dst_address, v6_next_hop_address;
6196   int count = 1;
6197   int j;
6198   f64 before = 0;
6199   u32 random_add_del = 0;
6200   u32 *random_vector = 0;
6201   uword *random_hash;
6202   u32 random_seed = 0xdeaddabe;
6203   u32 classify_table_index = ~0;
6204   u8 is_classify = 0;
6205   u8 resolve_host = 0, resolve_attached = 0;
6206   mpls_label_t *next_hop_out_label_stack = NULL;
6207   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6208   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6209
6210   /* Parse args required to build the message */
6211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6212     {
6213       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6214         ;
6215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6216         ;
6217       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6218         {
6219           address_set = 1;
6220           is_ipv6 = 0;
6221         }
6222       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6223         {
6224           address_set = 1;
6225           is_ipv6 = 1;
6226         }
6227       else if (unformat (i, "/%d", &dst_address_length))
6228         {
6229           address_length_set = 1;
6230         }
6231
6232       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6233                                          &v4_next_hop_address))
6234         {
6235           next_hop_set = 1;
6236         }
6237       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6238                                          &v6_next_hop_address))
6239         {
6240           next_hop_set = 1;
6241         }
6242       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6243         ;
6244       else if (unformat (i, "weight %d", &next_hop_weight))
6245         ;
6246       else if (unformat (i, "drop"))
6247         {
6248           is_drop = 1;
6249         }
6250       else if (unformat (i, "null-send-unreach"))
6251         {
6252           is_unreach = 1;
6253         }
6254       else if (unformat (i, "null-send-prohibit"))
6255         {
6256           is_prohibit = 1;
6257         }
6258       else if (unformat (i, "local"))
6259         {
6260           is_local = 1;
6261         }
6262       else if (unformat (i, "classify %d", &classify_table_index))
6263         {
6264           is_classify = 1;
6265         }
6266       else if (unformat (i, "del"))
6267         is_add = 0;
6268       else if (unformat (i, "add"))
6269         is_add = 1;
6270       else if (unformat (i, "not-last"))
6271         not_last = 1;
6272       else if (unformat (i, "resolve-via-host"))
6273         resolve_host = 1;
6274       else if (unformat (i, "resolve-via-attached"))
6275         resolve_attached = 1;
6276       else if (unformat (i, "multipath"))
6277         is_multipath = 1;
6278       else if (unformat (i, "vrf %d", &vrf_id))
6279         ;
6280       else if (unformat (i, "create-vrf"))
6281         create_vrf_if_needed = 1;
6282       else if (unformat (i, "count %d", &count))
6283         ;
6284       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6285         ;
6286       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6287         ;
6288       else if (unformat (i, "out-label %d", &next_hop_out_label))
6289         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6290       else if (unformat (i, "via-label %d", &next_hop_via_label))
6291         ;
6292       else if (unformat (i, "random"))
6293         random_add_del = 1;
6294       else if (unformat (i, "seed %d", &random_seed))
6295         ;
6296       else
6297         {
6298           clib_warning ("parse error '%U'", format_unformat_error, i);
6299           return -99;
6300         }
6301     }
6302
6303   if (!next_hop_set && !is_drop && !is_local &&
6304       !is_classify && !is_unreach && !is_prohibit &&
6305       MPLS_LABEL_INVALID == next_hop_via_label)
6306     {
6307       errmsg
6308         ("next hop / local / drop / unreach / prohibit / classify not set");
6309       return -99;
6310     }
6311
6312   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6313     {
6314       errmsg ("next hop and next-hop via label set");
6315       return -99;
6316     }
6317   if (address_set == 0)
6318     {
6319       errmsg ("missing addresses");
6320       return -99;
6321     }
6322
6323   if (address_length_set == 0)
6324     {
6325       errmsg ("missing address length");
6326       return -99;
6327     }
6328
6329   /* Generate a pile of unique, random routes */
6330   if (random_add_del)
6331     {
6332       u32 this_random_address;
6333       random_hash = hash_create (count, sizeof (uword));
6334
6335       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6336       for (j = 0; j <= count; j++)
6337         {
6338           do
6339             {
6340               this_random_address = random_u32 (&random_seed);
6341               this_random_address =
6342                 clib_host_to_net_u32 (this_random_address);
6343             }
6344           while (hash_get (random_hash, this_random_address));
6345           vec_add1 (random_vector, this_random_address);
6346           hash_set (random_hash, this_random_address, 1);
6347         }
6348       hash_free (random_hash);
6349       v4_dst_address.as_u32 = random_vector[0];
6350     }
6351
6352   if (count > 1)
6353     {
6354       /* Turn on async mode */
6355       vam->async_mode = 1;
6356       vam->async_errors = 0;
6357       before = vat_time_now (vam);
6358     }
6359
6360   for (j = 0; j < count; j++)
6361     {
6362       /* Construct the API message */
6363       M2 (IP_ADD_DEL_ROUTE, mp,
6364           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6365
6366       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6367       mp->table_id = ntohl (vrf_id);
6368       mp->create_vrf_if_needed = create_vrf_if_needed;
6369
6370       mp->is_add = is_add;
6371       mp->is_drop = is_drop;
6372       mp->is_unreach = is_unreach;
6373       mp->is_prohibit = is_prohibit;
6374       mp->is_ipv6 = is_ipv6;
6375       mp->is_local = is_local;
6376       mp->is_classify = is_classify;
6377       mp->is_multipath = is_multipath;
6378       mp->is_resolve_host = resolve_host;
6379       mp->is_resolve_attached = resolve_attached;
6380       mp->not_last = not_last;
6381       mp->next_hop_weight = next_hop_weight;
6382       mp->dst_address_length = dst_address_length;
6383       mp->next_hop_table_id = ntohl (next_hop_table_id);
6384       mp->classify_table_index = ntohl (classify_table_index);
6385       mp->next_hop_via_label = ntohl (next_hop_via_label);
6386       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6387       if (0 != mp->next_hop_n_out_labels)
6388         {
6389           memcpy (mp->next_hop_out_label_stack,
6390                   next_hop_out_label_stack,
6391                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6392           vec_free (next_hop_out_label_stack);
6393         }
6394
6395       if (is_ipv6)
6396         {
6397           clib_memcpy (mp->dst_address, &v6_dst_address,
6398                        sizeof (v6_dst_address));
6399           if (next_hop_set)
6400             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6401                          sizeof (v6_next_hop_address));
6402           increment_v6_address (&v6_dst_address);
6403         }
6404       else
6405         {
6406           clib_memcpy (mp->dst_address, &v4_dst_address,
6407                        sizeof (v4_dst_address));
6408           if (next_hop_set)
6409             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6410                          sizeof (v4_next_hop_address));
6411           if (random_add_del)
6412             v4_dst_address.as_u32 = random_vector[j + 1];
6413           else
6414             increment_v4_address (&v4_dst_address);
6415         }
6416       /* send it... */
6417       S (mp);
6418       /* If we receive SIGTERM, stop now... */
6419       if (vam->do_exit)
6420         break;
6421     }
6422
6423   /* When testing multiple add/del ops, use a control-ping to sync */
6424   if (count > 1)
6425     {
6426       vl_api_control_ping_t *mp_ping;
6427       f64 after;
6428       f64 timeout;
6429
6430       /* Shut off async mode */
6431       vam->async_mode = 0;
6432
6433       M (CONTROL_PING, mp_ping);
6434       S (mp_ping);
6435
6436       timeout = vat_time_now (vam) + 1.0;
6437       while (vat_time_now (vam) < timeout)
6438         if (vam->result_ready == 1)
6439           goto out;
6440       vam->retval = -99;
6441
6442     out:
6443       if (vam->retval == -99)
6444         errmsg ("timeout");
6445
6446       if (vam->async_errors > 0)
6447         {
6448           errmsg ("%d asynchronous errors", vam->async_errors);
6449           vam->retval = -98;
6450         }
6451       vam->async_errors = 0;
6452       after = vat_time_now (vam);
6453
6454       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6455       if (j > 0)
6456         count = j;
6457
6458       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6459              count, after - before, count / (after - before));
6460     }
6461   else
6462     {
6463       int ret;
6464
6465       /* Wait for a reply... */
6466       W (ret);
6467       return ret;
6468     }
6469
6470   /* Return the good/bad news */
6471   return (vam->retval);
6472 }
6473
6474 static int
6475 api_ip_mroute_add_del (vat_main_t * vam)
6476 {
6477   unformat_input_t *i = vam->input;
6478   vl_api_ip_mroute_add_del_t *mp;
6479   u32 sw_if_index = ~0, vrf_id = 0;
6480   u8 is_ipv6 = 0;
6481   u8 is_local = 0;
6482   u8 create_vrf_if_needed = 0;
6483   u8 is_add = 1;
6484   u8 address_set = 0;
6485   u32 grp_address_length = 0;
6486   ip4_address_t v4_grp_address, v4_src_address;
6487   ip6_address_t v6_grp_address, v6_src_address;
6488   mfib_itf_flags_t iflags = 0;
6489   mfib_entry_flags_t eflags = 0;
6490   int ret;
6491
6492   /* Parse args required to build the message */
6493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6494     {
6495       if (unformat (i, "sw_if_index %d", &sw_if_index))
6496         ;
6497       else if (unformat (i, "%U %U",
6498                          unformat_ip4_address, &v4_src_address,
6499                          unformat_ip4_address, &v4_grp_address))
6500         {
6501           grp_address_length = 64;
6502           address_set = 1;
6503           is_ipv6 = 0;
6504         }
6505       else if (unformat (i, "%U %U",
6506                          unformat_ip6_address, &v6_src_address,
6507                          unformat_ip6_address, &v6_grp_address))
6508         {
6509           grp_address_length = 256;
6510           address_set = 1;
6511           is_ipv6 = 1;
6512         }
6513       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6514         {
6515           memset (&v4_src_address, 0, sizeof (v4_src_address));
6516           grp_address_length = 32;
6517           address_set = 1;
6518           is_ipv6 = 0;
6519         }
6520       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6521         {
6522           memset (&v6_src_address, 0, sizeof (v6_src_address));
6523           grp_address_length = 128;
6524           address_set = 1;
6525           is_ipv6 = 1;
6526         }
6527       else if (unformat (i, "/%d", &grp_address_length))
6528         ;
6529       else if (unformat (i, "local"))
6530         {
6531           is_local = 1;
6532         }
6533       else if (unformat (i, "del"))
6534         is_add = 0;
6535       else if (unformat (i, "add"))
6536         is_add = 1;
6537       else if (unformat (i, "vrf %d", &vrf_id))
6538         ;
6539       else if (unformat (i, "create-vrf"))
6540         create_vrf_if_needed = 1;
6541       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6542         ;
6543       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6544         ;
6545       else
6546         {
6547           clib_warning ("parse error '%U'", format_unformat_error, i);
6548           return -99;
6549         }
6550     }
6551
6552   if (address_set == 0)
6553     {
6554       errmsg ("missing addresses\n");
6555       return -99;
6556     }
6557
6558   /* Construct the API message */
6559   M (IP_MROUTE_ADD_DEL, mp);
6560
6561   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6562   mp->table_id = ntohl (vrf_id);
6563   mp->create_vrf_if_needed = create_vrf_if_needed;
6564
6565   mp->is_add = is_add;
6566   mp->is_ipv6 = is_ipv6;
6567   mp->is_local = is_local;
6568   mp->itf_flags = ntohl (iflags);
6569   mp->entry_flags = ntohl (eflags);
6570   mp->grp_address_length = grp_address_length;
6571   mp->grp_address_length = ntohs (mp->grp_address_length);
6572
6573   if (is_ipv6)
6574     {
6575       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6576       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6577     }
6578   else
6579     {
6580       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6581       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6582
6583     }
6584
6585   /* send it... */
6586   S (mp);
6587   /* Wait for a reply... */
6588   W (ret);
6589   return ret;
6590 }
6591
6592 static int
6593 api_mpls_route_add_del (vat_main_t * vam)
6594 {
6595   unformat_input_t *i = vam->input;
6596   vl_api_mpls_route_add_del_t *mp;
6597   u32 sw_if_index = ~0, table_id = 0;
6598   u8 create_table_if_needed = 0;
6599   u8 is_add = 1;
6600   u32 next_hop_weight = 1;
6601   u8 is_multipath = 0;
6602   u32 next_hop_table_id = 0;
6603   u8 next_hop_set = 0;
6604   ip4_address_t v4_next_hop_address = {
6605     .as_u32 = 0,
6606   };
6607   ip6_address_t v6_next_hop_address = { {0} };
6608   int count = 1;
6609   int j;
6610   f64 before = 0;
6611   u32 classify_table_index = ~0;
6612   u8 is_classify = 0;
6613   u8 resolve_host = 0, resolve_attached = 0;
6614   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6615   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6616   mpls_label_t *next_hop_out_label_stack = NULL;
6617   mpls_label_t local_label = MPLS_LABEL_INVALID;
6618   u8 is_eos = 0;
6619   u8 next_hop_proto_is_ip4 = 1;
6620
6621   /* Parse args required to build the message */
6622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6623     {
6624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6625         ;
6626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6627         ;
6628       else if (unformat (i, "%d", &local_label))
6629         ;
6630       else if (unformat (i, "eos"))
6631         is_eos = 1;
6632       else if (unformat (i, "non-eos"))
6633         is_eos = 0;
6634       else if (unformat (i, "via %U", unformat_ip4_address,
6635                          &v4_next_hop_address))
6636         {
6637           next_hop_set = 1;
6638           next_hop_proto_is_ip4 = 1;
6639         }
6640       else if (unformat (i, "via %U", unformat_ip6_address,
6641                          &v6_next_hop_address))
6642         {
6643           next_hop_set = 1;
6644           next_hop_proto_is_ip4 = 0;
6645         }
6646       else if (unformat (i, "weight %d", &next_hop_weight))
6647         ;
6648       else if (unformat (i, "create-table"))
6649         create_table_if_needed = 1;
6650       else if (unformat (i, "classify %d", &classify_table_index))
6651         {
6652           is_classify = 1;
6653         }
6654       else if (unformat (i, "del"))
6655         is_add = 0;
6656       else if (unformat (i, "add"))
6657         is_add = 1;
6658       else if (unformat (i, "resolve-via-host"))
6659         resolve_host = 1;
6660       else if (unformat (i, "resolve-via-attached"))
6661         resolve_attached = 1;
6662       else if (unformat (i, "multipath"))
6663         is_multipath = 1;
6664       else if (unformat (i, "count %d", &count))
6665         ;
6666       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6667         {
6668           next_hop_set = 1;
6669           next_hop_proto_is_ip4 = 1;
6670         }
6671       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6672         {
6673           next_hop_set = 1;
6674           next_hop_proto_is_ip4 = 0;
6675         }
6676       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6677         ;
6678       else if (unformat (i, "via-label %d", &next_hop_via_label))
6679         ;
6680       else if (unformat (i, "out-label %d", &next_hop_out_label))
6681         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6682       else
6683         {
6684           clib_warning ("parse error '%U'", format_unformat_error, i);
6685           return -99;
6686         }
6687     }
6688
6689   if (!next_hop_set && !is_classify)
6690     {
6691       errmsg ("next hop / classify not set");
6692       return -99;
6693     }
6694
6695   if (MPLS_LABEL_INVALID == local_label)
6696     {
6697       errmsg ("missing label");
6698       return -99;
6699     }
6700
6701   if (count > 1)
6702     {
6703       /* Turn on async mode */
6704       vam->async_mode = 1;
6705       vam->async_errors = 0;
6706       before = vat_time_now (vam);
6707     }
6708
6709   for (j = 0; j < count; j++)
6710     {
6711       /* Construct the API message */
6712       M2 (MPLS_ROUTE_ADD_DEL, mp,
6713           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6714
6715       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6716       mp->mr_table_id = ntohl (table_id);
6717       mp->mr_create_table_if_needed = create_table_if_needed;
6718
6719       mp->mr_is_add = is_add;
6720       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6721       mp->mr_is_classify = is_classify;
6722       mp->mr_is_multipath = is_multipath;
6723       mp->mr_is_resolve_host = resolve_host;
6724       mp->mr_is_resolve_attached = resolve_attached;
6725       mp->mr_next_hop_weight = next_hop_weight;
6726       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6727       mp->mr_classify_table_index = ntohl (classify_table_index);
6728       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6729       mp->mr_label = ntohl (local_label);
6730       mp->mr_eos = is_eos;
6731
6732       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6733       if (0 != mp->mr_next_hop_n_out_labels)
6734         {
6735           memcpy (mp->mr_next_hop_out_label_stack,
6736                   next_hop_out_label_stack,
6737                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6738           vec_free (next_hop_out_label_stack);
6739         }
6740
6741       if (next_hop_set)
6742         {
6743           if (next_hop_proto_is_ip4)
6744             {
6745               clib_memcpy (mp->mr_next_hop,
6746                            &v4_next_hop_address,
6747                            sizeof (v4_next_hop_address));
6748             }
6749           else
6750             {
6751               clib_memcpy (mp->mr_next_hop,
6752                            &v6_next_hop_address,
6753                            sizeof (v6_next_hop_address));
6754             }
6755         }
6756       local_label++;
6757
6758       /* send it... */
6759       S (mp);
6760       /* If we receive SIGTERM, stop now... */
6761       if (vam->do_exit)
6762         break;
6763     }
6764
6765   /* When testing multiple add/del ops, use a control-ping to sync */
6766   if (count > 1)
6767     {
6768       vl_api_control_ping_t *mp_ping;
6769       f64 after;
6770       f64 timeout;
6771
6772       /* Shut off async mode */
6773       vam->async_mode = 0;
6774
6775       M (CONTROL_PING, mp_ping);
6776       S (mp_ping);
6777
6778       timeout = vat_time_now (vam) + 1.0;
6779       while (vat_time_now (vam) < timeout)
6780         if (vam->result_ready == 1)
6781           goto out;
6782       vam->retval = -99;
6783
6784     out:
6785       if (vam->retval == -99)
6786         errmsg ("timeout");
6787
6788       if (vam->async_errors > 0)
6789         {
6790           errmsg ("%d asynchronous errors", vam->async_errors);
6791           vam->retval = -98;
6792         }
6793       vam->async_errors = 0;
6794       after = vat_time_now (vam);
6795
6796       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6797       if (j > 0)
6798         count = j;
6799
6800       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6801              count, after - before, count / (after - before));
6802     }
6803   else
6804     {
6805       int ret;
6806
6807       /* Wait for a reply... */
6808       W (ret);
6809       return ret;
6810     }
6811
6812   /* Return the good/bad news */
6813   return (vam->retval);
6814 }
6815
6816 static int
6817 api_mpls_ip_bind_unbind (vat_main_t * vam)
6818 {
6819   unformat_input_t *i = vam->input;
6820   vl_api_mpls_ip_bind_unbind_t *mp;
6821   u32 ip_table_id = 0;
6822   u8 create_table_if_needed = 0;
6823   u8 is_bind = 1;
6824   u8 is_ip4 = 1;
6825   ip4_address_t v4_address;
6826   ip6_address_t v6_address;
6827   u32 address_length;
6828   u8 address_set = 0;
6829   mpls_label_t local_label = MPLS_LABEL_INVALID;
6830   int ret;
6831
6832   /* Parse args required to build the message */
6833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6834     {
6835       if (unformat (i, "%U/%d", unformat_ip4_address,
6836                     &v4_address, &address_length))
6837         {
6838           is_ip4 = 1;
6839           address_set = 1;
6840         }
6841       else if (unformat (i, "%U/%d", unformat_ip6_address,
6842                          &v6_address, &address_length))
6843         {
6844           is_ip4 = 0;
6845           address_set = 1;
6846         }
6847       else if (unformat (i, "%d", &local_label))
6848         ;
6849       else if (unformat (i, "create-table"))
6850         create_table_if_needed = 1;
6851       else if (unformat (i, "table-id %d", &ip_table_id))
6852         ;
6853       else if (unformat (i, "unbind"))
6854         is_bind = 0;
6855       else if (unformat (i, "bind"))
6856         is_bind = 1;
6857       else
6858         {
6859           clib_warning ("parse error '%U'", format_unformat_error, i);
6860           return -99;
6861         }
6862     }
6863
6864   if (!address_set)
6865     {
6866       errmsg ("IP addres not set");
6867       return -99;
6868     }
6869
6870   if (MPLS_LABEL_INVALID == local_label)
6871     {
6872       errmsg ("missing label");
6873       return -99;
6874     }
6875
6876   /* Construct the API message */
6877   M (MPLS_IP_BIND_UNBIND, mp);
6878
6879   mp->mb_create_table_if_needed = create_table_if_needed;
6880   mp->mb_is_bind = is_bind;
6881   mp->mb_is_ip4 = is_ip4;
6882   mp->mb_ip_table_id = ntohl (ip_table_id);
6883   mp->mb_mpls_table_id = 0;
6884   mp->mb_label = ntohl (local_label);
6885   mp->mb_address_length = address_length;
6886
6887   if (is_ip4)
6888     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6889   else
6890     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6891
6892   /* send it... */
6893   S (mp);
6894
6895   /* Wait for a reply... */
6896   W (ret);
6897   return ret;
6898 }
6899
6900 static int
6901 api_proxy_arp_add_del (vat_main_t * vam)
6902 {
6903   unformat_input_t *i = vam->input;
6904   vl_api_proxy_arp_add_del_t *mp;
6905   u32 vrf_id = 0;
6906   u8 is_add = 1;
6907   ip4_address_t lo, hi;
6908   u8 range_set = 0;
6909   int ret;
6910
6911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6912     {
6913       if (unformat (i, "vrf %d", &vrf_id))
6914         ;
6915       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6916                          unformat_ip4_address, &hi))
6917         range_set = 1;
6918       else if (unformat (i, "del"))
6919         is_add = 0;
6920       else
6921         {
6922           clib_warning ("parse error '%U'", format_unformat_error, i);
6923           return -99;
6924         }
6925     }
6926
6927   if (range_set == 0)
6928     {
6929       errmsg ("address range not set");
6930       return -99;
6931     }
6932
6933   M (PROXY_ARP_ADD_DEL, mp);
6934
6935   mp->vrf_id = ntohl (vrf_id);
6936   mp->is_add = is_add;
6937   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6938   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6939
6940   S (mp);
6941   W (ret);
6942   return ret;
6943 }
6944
6945 static int
6946 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6947 {
6948   unformat_input_t *i = vam->input;
6949   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6950   u32 sw_if_index;
6951   u8 enable = 1;
6952   u8 sw_if_index_set = 0;
6953   int ret;
6954
6955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6956     {
6957       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6958         sw_if_index_set = 1;
6959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6960         sw_if_index_set = 1;
6961       else if (unformat (i, "enable"))
6962         enable = 1;
6963       else if (unformat (i, "disable"))
6964         enable = 0;
6965       else
6966         {
6967           clib_warning ("parse error '%U'", format_unformat_error, i);
6968           return -99;
6969         }
6970     }
6971
6972   if (sw_if_index_set == 0)
6973     {
6974       errmsg ("missing interface name or sw_if_index");
6975       return -99;
6976     }
6977
6978   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
6979
6980   mp->sw_if_index = ntohl (sw_if_index);
6981   mp->enable_disable = enable;
6982
6983   S (mp);
6984   W (ret);
6985   return ret;
6986 }
6987
6988 static int
6989 api_mpls_tunnel_add_del (vat_main_t * vam)
6990 {
6991   unformat_input_t *i = vam->input;
6992   vl_api_mpls_tunnel_add_del_t *mp;
6993
6994   u8 is_add = 1;
6995   u8 l2_only = 0;
6996   u32 sw_if_index = ~0;
6997   u32 next_hop_sw_if_index = ~0;
6998   u32 next_hop_proto_is_ip4 = 1;
6999
7000   u32 next_hop_table_id = 0;
7001   ip4_address_t v4_next_hop_address = {
7002     .as_u32 = 0,
7003   };
7004   ip6_address_t v6_next_hop_address = { {0} };
7005   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7006   int ret;
7007
7008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7009     {
7010       if (unformat (i, "add"))
7011         is_add = 1;
7012       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7013         is_add = 0;
7014       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7015         ;
7016       else if (unformat (i, "via %U",
7017                          unformat_ip4_address, &v4_next_hop_address))
7018         {
7019           next_hop_proto_is_ip4 = 1;
7020         }
7021       else if (unformat (i, "via %U",
7022                          unformat_ip6_address, &v6_next_hop_address))
7023         {
7024           next_hop_proto_is_ip4 = 0;
7025         }
7026       else if (unformat (i, "l2-only"))
7027         l2_only = 1;
7028       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7029         ;
7030       else if (unformat (i, "out-label %d", &next_hop_out_label))
7031         vec_add1 (labels, ntohl (next_hop_out_label));
7032       else
7033         {
7034           clib_warning ("parse error '%U'", format_unformat_error, i);
7035           return -99;
7036         }
7037     }
7038
7039   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7040
7041   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7042   mp->mt_sw_if_index = ntohl (sw_if_index);
7043   mp->mt_is_add = is_add;
7044   mp->mt_l2_only = l2_only;
7045   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7046   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7047
7048   mp->mt_next_hop_n_out_labels = vec_len (labels);
7049
7050   if (0 != mp->mt_next_hop_n_out_labels)
7051     {
7052       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7053                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7054       vec_free (labels);
7055     }
7056
7057   if (next_hop_proto_is_ip4)
7058     {
7059       clib_memcpy (mp->mt_next_hop,
7060                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7061     }
7062   else
7063     {
7064       clib_memcpy (mp->mt_next_hop,
7065                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7066     }
7067
7068   S (mp);
7069   W (ret);
7070   return ret;
7071 }
7072
7073 static int
7074 api_sw_interface_set_unnumbered (vat_main_t * vam)
7075 {
7076   unformat_input_t *i = vam->input;
7077   vl_api_sw_interface_set_unnumbered_t *mp;
7078   u32 sw_if_index;
7079   u32 unnum_sw_index = ~0;
7080   u8 is_add = 1;
7081   u8 sw_if_index_set = 0;
7082   int ret;
7083
7084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7085     {
7086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7087         sw_if_index_set = 1;
7088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7089         sw_if_index_set = 1;
7090       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7091         ;
7092       else if (unformat (i, "del"))
7093         is_add = 0;
7094       else
7095         {
7096           clib_warning ("parse error '%U'", format_unformat_error, i);
7097           return -99;
7098         }
7099     }
7100
7101   if (sw_if_index_set == 0)
7102     {
7103       errmsg ("missing interface name or sw_if_index");
7104       return -99;
7105     }
7106
7107   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7108
7109   mp->sw_if_index = ntohl (sw_if_index);
7110   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7111   mp->is_add = is_add;
7112
7113   S (mp);
7114   W (ret);
7115   return ret;
7116 }
7117
7118 static int
7119 api_ip_neighbor_add_del (vat_main_t * vam)
7120 {
7121   unformat_input_t *i = vam->input;
7122   vl_api_ip_neighbor_add_del_t *mp;
7123   u32 sw_if_index;
7124   u8 sw_if_index_set = 0;
7125   u8 is_add = 1;
7126   u8 is_static = 0;
7127   u8 mac_address[6];
7128   u8 mac_set = 0;
7129   u8 v4_address_set = 0;
7130   u8 v6_address_set = 0;
7131   ip4_address_t v4address;
7132   ip6_address_t v6address;
7133   int ret;
7134
7135   memset (mac_address, 0, sizeof (mac_address));
7136
7137   /* Parse args required to build the message */
7138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7139     {
7140       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7141         {
7142           mac_set = 1;
7143         }
7144       else if (unformat (i, "del"))
7145         is_add = 0;
7146       else
7147         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7148         sw_if_index_set = 1;
7149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7150         sw_if_index_set = 1;
7151       else if (unformat (i, "is_static"))
7152         is_static = 1;
7153       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7154         v4_address_set = 1;
7155       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7156         v6_address_set = 1;
7157       else
7158         {
7159           clib_warning ("parse error '%U'", format_unformat_error, i);
7160           return -99;
7161         }
7162     }
7163
7164   if (sw_if_index_set == 0)
7165     {
7166       errmsg ("missing interface name or sw_if_index");
7167       return -99;
7168     }
7169   if (v4_address_set && v6_address_set)
7170     {
7171       errmsg ("both v4 and v6 addresses set");
7172       return -99;
7173     }
7174   if (!v4_address_set && !v6_address_set)
7175     {
7176       errmsg ("no address set");
7177       return -99;
7178     }
7179
7180   /* Construct the API message */
7181   M (IP_NEIGHBOR_ADD_DEL, mp);
7182
7183   mp->sw_if_index = ntohl (sw_if_index);
7184   mp->is_add = is_add;
7185   mp->is_static = is_static;
7186   if (mac_set)
7187     clib_memcpy (mp->mac_address, mac_address, 6);
7188   if (v6_address_set)
7189     {
7190       mp->is_ipv6 = 1;
7191       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7192     }
7193   else
7194     {
7195       /* mp->is_ipv6 = 0; via memset in M macro above */
7196       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7197     }
7198
7199   /* send it... */
7200   S (mp);
7201
7202   /* Wait for a reply, return good/bad news  */
7203   W (ret);
7204   return ret;
7205 }
7206
7207 static int
7208 api_reset_vrf (vat_main_t * vam)
7209 {
7210   unformat_input_t *i = vam->input;
7211   vl_api_reset_vrf_t *mp;
7212   u32 vrf_id = 0;
7213   u8 is_ipv6 = 0;
7214   u8 vrf_id_set = 0;
7215   int ret;
7216
7217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218     {
7219       if (unformat (i, "vrf %d", &vrf_id))
7220         vrf_id_set = 1;
7221       else if (unformat (i, "ipv6"))
7222         is_ipv6 = 1;
7223       else
7224         {
7225           clib_warning ("parse error '%U'", format_unformat_error, i);
7226           return -99;
7227         }
7228     }
7229
7230   if (vrf_id_set == 0)
7231     {
7232       errmsg ("missing vrf id");
7233       return -99;
7234     }
7235
7236   M (RESET_VRF, mp);
7237
7238   mp->vrf_id = ntohl (vrf_id);
7239   mp->is_ipv6 = is_ipv6;
7240
7241   S (mp);
7242   W (ret);
7243   return ret;
7244 }
7245
7246 static int
7247 api_create_vlan_subif (vat_main_t * vam)
7248 {
7249   unformat_input_t *i = vam->input;
7250   vl_api_create_vlan_subif_t *mp;
7251   u32 sw_if_index;
7252   u8 sw_if_index_set = 0;
7253   u32 vlan_id;
7254   u8 vlan_id_set = 0;
7255   int ret;
7256
7257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7258     {
7259       if (unformat (i, "sw_if_index %d", &sw_if_index))
7260         sw_if_index_set = 1;
7261       else
7262         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7263         sw_if_index_set = 1;
7264       else if (unformat (i, "vlan %d", &vlan_id))
7265         vlan_id_set = 1;
7266       else
7267         {
7268           clib_warning ("parse error '%U'", format_unformat_error, i);
7269           return -99;
7270         }
7271     }
7272
7273   if (sw_if_index_set == 0)
7274     {
7275       errmsg ("missing interface name or sw_if_index");
7276       return -99;
7277     }
7278
7279   if (vlan_id_set == 0)
7280     {
7281       errmsg ("missing vlan_id");
7282       return -99;
7283     }
7284   M (CREATE_VLAN_SUBIF, mp);
7285
7286   mp->sw_if_index = ntohl (sw_if_index);
7287   mp->vlan_id = ntohl (vlan_id);
7288
7289   S (mp);
7290   W (ret);
7291   return ret;
7292 }
7293
7294 #define foreach_create_subif_bit                \
7295 _(no_tags)                                      \
7296 _(one_tag)                                      \
7297 _(two_tags)                                     \
7298 _(dot1ad)                                       \
7299 _(exact_match)                                  \
7300 _(default_sub)                                  \
7301 _(outer_vlan_id_any)                            \
7302 _(inner_vlan_id_any)
7303
7304 static int
7305 api_create_subif (vat_main_t * vam)
7306 {
7307   unformat_input_t *i = vam->input;
7308   vl_api_create_subif_t *mp;
7309   u32 sw_if_index;
7310   u8 sw_if_index_set = 0;
7311   u32 sub_id;
7312   u8 sub_id_set = 0;
7313   u32 no_tags = 0;
7314   u32 one_tag = 0;
7315   u32 two_tags = 0;
7316   u32 dot1ad = 0;
7317   u32 exact_match = 0;
7318   u32 default_sub = 0;
7319   u32 outer_vlan_id_any = 0;
7320   u32 inner_vlan_id_any = 0;
7321   u32 tmp;
7322   u16 outer_vlan_id = 0;
7323   u16 inner_vlan_id = 0;
7324   int ret;
7325
7326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7327     {
7328       if (unformat (i, "sw_if_index %d", &sw_if_index))
7329         sw_if_index_set = 1;
7330       else
7331         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7332         sw_if_index_set = 1;
7333       else if (unformat (i, "sub_id %d", &sub_id))
7334         sub_id_set = 1;
7335       else if (unformat (i, "outer_vlan_id %d", &tmp))
7336         outer_vlan_id = tmp;
7337       else if (unformat (i, "inner_vlan_id %d", &tmp))
7338         inner_vlan_id = tmp;
7339
7340 #define _(a) else if (unformat (i, #a)) a = 1 ;
7341       foreach_create_subif_bit
7342 #undef _
7343         else
7344         {
7345           clib_warning ("parse error '%U'", format_unformat_error, i);
7346           return -99;
7347         }
7348     }
7349
7350   if (sw_if_index_set == 0)
7351     {
7352       errmsg ("missing interface name or sw_if_index");
7353       return -99;
7354     }
7355
7356   if (sub_id_set == 0)
7357     {
7358       errmsg ("missing sub_id");
7359       return -99;
7360     }
7361   M (CREATE_SUBIF, mp);
7362
7363   mp->sw_if_index = ntohl (sw_if_index);
7364   mp->sub_id = ntohl (sub_id);
7365
7366 #define _(a) mp->a = a;
7367   foreach_create_subif_bit;
7368 #undef _
7369
7370   mp->outer_vlan_id = ntohs (outer_vlan_id);
7371   mp->inner_vlan_id = ntohs (inner_vlan_id);
7372
7373   S (mp);
7374   W (ret);
7375   return ret;
7376 }
7377
7378 static int
7379 api_oam_add_del (vat_main_t * vam)
7380 {
7381   unformat_input_t *i = vam->input;
7382   vl_api_oam_add_del_t *mp;
7383   u32 vrf_id = 0;
7384   u8 is_add = 1;
7385   ip4_address_t src, dst;
7386   u8 src_set = 0;
7387   u8 dst_set = 0;
7388   int ret;
7389
7390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7391     {
7392       if (unformat (i, "vrf %d", &vrf_id))
7393         ;
7394       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7395         src_set = 1;
7396       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7397         dst_set = 1;
7398       else if (unformat (i, "del"))
7399         is_add = 0;
7400       else
7401         {
7402           clib_warning ("parse error '%U'", format_unformat_error, i);
7403           return -99;
7404         }
7405     }
7406
7407   if (src_set == 0)
7408     {
7409       errmsg ("missing src addr");
7410       return -99;
7411     }
7412
7413   if (dst_set == 0)
7414     {
7415       errmsg ("missing dst addr");
7416       return -99;
7417     }
7418
7419   M (OAM_ADD_DEL, mp);
7420
7421   mp->vrf_id = ntohl (vrf_id);
7422   mp->is_add = is_add;
7423   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7424   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7425
7426   S (mp);
7427   W (ret);
7428   return ret;
7429 }
7430
7431 static int
7432 api_reset_fib (vat_main_t * vam)
7433 {
7434   unformat_input_t *i = vam->input;
7435   vl_api_reset_fib_t *mp;
7436   u32 vrf_id = 0;
7437   u8 is_ipv6 = 0;
7438   u8 vrf_id_set = 0;
7439
7440   int ret;
7441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7442     {
7443       if (unformat (i, "vrf %d", &vrf_id))
7444         vrf_id_set = 1;
7445       else if (unformat (i, "ipv6"))
7446         is_ipv6 = 1;
7447       else
7448         {
7449           clib_warning ("parse error '%U'", format_unformat_error, i);
7450           return -99;
7451         }
7452     }
7453
7454   if (vrf_id_set == 0)
7455     {
7456       errmsg ("missing vrf id");
7457       return -99;
7458     }
7459
7460   M (RESET_FIB, mp);
7461
7462   mp->vrf_id = ntohl (vrf_id);
7463   mp->is_ipv6 = is_ipv6;
7464
7465   S (mp);
7466   W (ret);
7467   return ret;
7468 }
7469
7470 static int
7471 api_dhcp_proxy_config (vat_main_t * vam)
7472 {
7473   unformat_input_t *i = vam->input;
7474   vl_api_dhcp_proxy_config_t *mp;
7475   u32 rx_vrf_id = 0;
7476   u32 server_vrf_id = 0;
7477   u8 is_add = 1;
7478   u8 v4_address_set = 0;
7479   u8 v6_address_set = 0;
7480   ip4_address_t v4address;
7481   ip6_address_t v6address;
7482   u8 v4_src_address_set = 0;
7483   u8 v6_src_address_set = 0;
7484   ip4_address_t v4srcaddress;
7485   ip6_address_t v6srcaddress;
7486   int ret;
7487
7488   /* Parse args required to build the message */
7489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7490     {
7491       if (unformat (i, "del"))
7492         is_add = 0;
7493       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7494         ;
7495       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7496         ;
7497       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7498         v4_address_set = 1;
7499       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7500         v6_address_set = 1;
7501       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7502         v4_src_address_set = 1;
7503       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7504         v6_src_address_set = 1;
7505       else
7506         break;
7507     }
7508
7509   if (v4_address_set && v6_address_set)
7510     {
7511       errmsg ("both v4 and v6 server addresses set");
7512       return -99;
7513     }
7514   if (!v4_address_set && !v6_address_set)
7515     {
7516       errmsg ("no server addresses set");
7517       return -99;
7518     }
7519
7520   if (v4_src_address_set && v6_src_address_set)
7521     {
7522       errmsg ("both v4 and v6  src addresses set");
7523       return -99;
7524     }
7525   if (!v4_src_address_set && !v6_src_address_set)
7526     {
7527       errmsg ("no src addresses set");
7528       return -99;
7529     }
7530
7531   if (!(v4_src_address_set && v4_address_set) &&
7532       !(v6_src_address_set && v6_address_set))
7533     {
7534       errmsg ("no matching server and src addresses set");
7535       return -99;
7536     }
7537
7538   /* Construct the API message */
7539   M (DHCP_PROXY_CONFIG, mp);
7540
7541   mp->is_add = is_add;
7542   mp->rx_vrf_id = ntohl (rx_vrf_id);
7543   mp->server_vrf_id = ntohl (server_vrf_id);
7544   if (v6_address_set)
7545     {
7546       mp->is_ipv6 = 1;
7547       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7548       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7549     }
7550   else
7551     {
7552       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7553       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7554     }
7555
7556   /* send it... */
7557   S (mp);
7558
7559   /* Wait for a reply, return good/bad news  */
7560   W (ret);
7561   return ret;
7562 }
7563
7564 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7565 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7566
7567 static void
7568 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7569 {
7570   vat_main_t *vam = &vat_main;
7571
7572   if (mp->is_ipv6)
7573     print (vam->ofp,
7574            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7575            ntohl (mp->rx_vrf_id),
7576            ntohl (mp->server_vrf_id),
7577            format_ip6_address, mp->dhcp_server,
7578            format_ip6_address, mp->dhcp_src_address,
7579            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7580   else
7581     print (vam->ofp,
7582            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7583            ntohl (mp->rx_vrf_id),
7584            ntohl (mp->server_vrf_id),
7585            format_ip4_address, mp->dhcp_server,
7586            format_ip4_address, mp->dhcp_src_address,
7587            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7588 }
7589
7590 static void vl_api_dhcp_proxy_details_t_handler_json
7591   (vl_api_dhcp_proxy_details_t * mp)
7592 {
7593   vat_main_t *vam = &vat_main;
7594   vat_json_node_t *node = NULL;
7595   struct in_addr ip4;
7596   struct in6_addr ip6;
7597
7598   if (VAT_JSON_ARRAY != vam->json_tree.type)
7599     {
7600       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7601       vat_json_init_array (&vam->json_tree);
7602     }
7603   node = vat_json_array_add (&vam->json_tree);
7604
7605   vat_json_init_object (node);
7606   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7607   vat_json_object_add_uint (node, "server-table-id",
7608                             ntohl (mp->server_vrf_id));
7609   if (mp->is_ipv6)
7610     {
7611       clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7612       vat_json_object_add_ip6 (node, "server_address", ip6);
7613       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7614       vat_json_object_add_ip6 (node, "src_address", ip6);
7615     }
7616   else
7617     {
7618       clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7619       vat_json_object_add_ip4 (node, "server_address", ip4);
7620       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7621       vat_json_object_add_ip4 (node, "src_address", ip4);
7622     }
7623   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7624   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7625 }
7626
7627 static int
7628 api_dhcp_proxy_dump (vat_main_t * vam)
7629 {
7630   unformat_input_t *i = vam->input;
7631   vl_api_control_ping_t *mp_ping;
7632   vl_api_dhcp_proxy_dump_t *mp;
7633   u8 is_ipv6 = 0;
7634   int ret;
7635
7636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7637     {
7638       if (unformat (i, "ipv6"))
7639         is_ipv6 = 1;
7640       else
7641         {
7642           clib_warning ("parse error '%U'", format_unformat_error, i);
7643           return -99;
7644         }
7645     }
7646
7647   M (DHCP_PROXY_DUMP, mp);
7648
7649   mp->is_ip6 = is_ipv6;
7650   S (mp);
7651
7652   /* Use a control ping for synchronization */
7653   M (CONTROL_PING, mp_ping);
7654   S (mp_ping);
7655
7656   W (ret);
7657   return ret;
7658 }
7659
7660 static int
7661 api_dhcp_proxy_set_vss (vat_main_t * vam)
7662 {
7663   unformat_input_t *i = vam->input;
7664   vl_api_dhcp_proxy_set_vss_t *mp;
7665   u8 is_ipv6 = 0;
7666   u8 is_add = 1;
7667   u32 tbl_id;
7668   u8 tbl_id_set = 0;
7669   u32 oui;
7670   u8 oui_set = 0;
7671   u32 fib_id;
7672   u8 fib_id_set = 0;
7673   int ret;
7674
7675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7676     {
7677       if (unformat (i, "tbl_id %d", &tbl_id))
7678         tbl_id_set = 1;
7679       if (unformat (i, "fib_id %d", &fib_id))
7680         fib_id_set = 1;
7681       if (unformat (i, "oui %d", &oui))
7682         oui_set = 1;
7683       else if (unformat (i, "ipv6"))
7684         is_ipv6 = 1;
7685       else if (unformat (i, "del"))
7686         is_add = 0;
7687       else
7688         {
7689           clib_warning ("parse error '%U'", format_unformat_error, i);
7690           return -99;
7691         }
7692     }
7693
7694   if (tbl_id_set == 0)
7695     {
7696       errmsg ("missing tbl id");
7697       return -99;
7698     }
7699
7700   if (fib_id_set == 0)
7701     {
7702       errmsg ("missing fib id");
7703       return -99;
7704     }
7705   if (oui_set == 0)
7706     {
7707       errmsg ("missing oui");
7708       return -99;
7709     }
7710
7711   M (DHCP_PROXY_SET_VSS, mp);
7712   mp->tbl_id = ntohl (tbl_id);
7713   mp->fib_id = ntohl (fib_id);
7714   mp->oui = ntohl (oui);
7715   mp->is_ipv6 = is_ipv6;
7716   mp->is_add = is_add;
7717
7718   S (mp);
7719   W (ret);
7720   return ret;
7721 }
7722
7723 static int
7724 api_dhcp_client_config (vat_main_t * vam)
7725 {
7726   unformat_input_t *i = vam->input;
7727   vl_api_dhcp_client_config_t *mp;
7728   u32 sw_if_index;
7729   u8 sw_if_index_set = 0;
7730   u8 is_add = 1;
7731   u8 *hostname = 0;
7732   u8 disable_event = 0;
7733   int ret;
7734
7735   /* Parse args required to build the message */
7736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7737     {
7738       if (unformat (i, "del"))
7739         is_add = 0;
7740       else
7741         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7742         sw_if_index_set = 1;
7743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7744         sw_if_index_set = 1;
7745       else if (unformat (i, "hostname %s", &hostname))
7746         ;
7747       else if (unformat (i, "disable_event"))
7748         disable_event = 1;
7749       else
7750         break;
7751     }
7752
7753   if (sw_if_index_set == 0)
7754     {
7755       errmsg ("missing interface name or sw_if_index");
7756       return -99;
7757     }
7758
7759   if (vec_len (hostname) > 63)
7760     {
7761       errmsg ("hostname too long");
7762     }
7763   vec_add1 (hostname, 0);
7764
7765   /* Construct the API message */
7766   M (DHCP_CLIENT_CONFIG, mp);
7767
7768   mp->sw_if_index = ntohl (sw_if_index);
7769   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7770   vec_free (hostname);
7771   mp->is_add = is_add;
7772   mp->want_dhcp_event = disable_event ? 0 : 1;
7773   mp->pid = getpid ();
7774
7775   /* send it... */
7776   S (mp);
7777
7778   /* Wait for a reply, return good/bad news  */
7779   W (ret);
7780   return ret;
7781 }
7782
7783 static int
7784 api_set_ip_flow_hash (vat_main_t * vam)
7785 {
7786   unformat_input_t *i = vam->input;
7787   vl_api_set_ip_flow_hash_t *mp;
7788   u32 vrf_id = 0;
7789   u8 is_ipv6 = 0;
7790   u8 vrf_id_set = 0;
7791   u8 src = 0;
7792   u8 dst = 0;
7793   u8 sport = 0;
7794   u8 dport = 0;
7795   u8 proto = 0;
7796   u8 reverse = 0;
7797   int ret;
7798
7799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7800     {
7801       if (unformat (i, "vrf %d", &vrf_id))
7802         vrf_id_set = 1;
7803       else if (unformat (i, "ipv6"))
7804         is_ipv6 = 1;
7805       else if (unformat (i, "src"))
7806         src = 1;
7807       else if (unformat (i, "dst"))
7808         dst = 1;
7809       else if (unformat (i, "sport"))
7810         sport = 1;
7811       else if (unformat (i, "dport"))
7812         dport = 1;
7813       else if (unformat (i, "proto"))
7814         proto = 1;
7815       else if (unformat (i, "reverse"))
7816         reverse = 1;
7817
7818       else
7819         {
7820           clib_warning ("parse error '%U'", format_unformat_error, i);
7821           return -99;
7822         }
7823     }
7824
7825   if (vrf_id_set == 0)
7826     {
7827       errmsg ("missing vrf id");
7828       return -99;
7829     }
7830
7831   M (SET_IP_FLOW_HASH, mp);
7832   mp->src = src;
7833   mp->dst = dst;
7834   mp->sport = sport;
7835   mp->dport = dport;
7836   mp->proto = proto;
7837   mp->reverse = reverse;
7838   mp->vrf_id = ntohl (vrf_id);
7839   mp->is_ipv6 = is_ipv6;
7840
7841   S (mp);
7842   W (ret);
7843   return ret;
7844 }
7845
7846 static int
7847 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7848 {
7849   unformat_input_t *i = vam->input;
7850   vl_api_sw_interface_ip6_enable_disable_t *mp;
7851   u32 sw_if_index;
7852   u8 sw_if_index_set = 0;
7853   u8 enable = 0;
7854   int ret;
7855
7856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7857     {
7858       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7859         sw_if_index_set = 1;
7860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7861         sw_if_index_set = 1;
7862       else if (unformat (i, "enable"))
7863         enable = 1;
7864       else if (unformat (i, "disable"))
7865         enable = 0;
7866       else
7867         {
7868           clib_warning ("parse error '%U'", format_unformat_error, i);
7869           return -99;
7870         }
7871     }
7872
7873   if (sw_if_index_set == 0)
7874     {
7875       errmsg ("missing interface name or sw_if_index");
7876       return -99;
7877     }
7878
7879   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7880
7881   mp->sw_if_index = ntohl (sw_if_index);
7882   mp->enable = enable;
7883
7884   S (mp);
7885   W (ret);
7886   return ret;
7887 }
7888
7889 static int
7890 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7891 {
7892   unformat_input_t *i = vam->input;
7893   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7894   u32 sw_if_index;
7895   u8 sw_if_index_set = 0;
7896   u8 v6_address_set = 0;
7897   ip6_address_t v6address;
7898   int ret;
7899
7900   /* Parse args required to build the message */
7901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7902     {
7903       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7904         sw_if_index_set = 1;
7905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7906         sw_if_index_set = 1;
7907       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7908         v6_address_set = 1;
7909       else
7910         break;
7911     }
7912
7913   if (sw_if_index_set == 0)
7914     {
7915       errmsg ("missing interface name or sw_if_index");
7916       return -99;
7917     }
7918   if (!v6_address_set)
7919     {
7920       errmsg ("no address set");
7921       return -99;
7922     }
7923
7924   /* Construct the API message */
7925   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
7926
7927   mp->sw_if_index = ntohl (sw_if_index);
7928   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7929
7930   /* send it... */
7931   S (mp);
7932
7933   /* Wait for a reply, return good/bad news  */
7934   W (ret);
7935   return ret;
7936 }
7937
7938
7939 static int
7940 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7941 {
7942   unformat_input_t *i = vam->input;
7943   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7944   u32 sw_if_index;
7945   u8 sw_if_index_set = 0;
7946   u32 address_length = 0;
7947   u8 v6_address_set = 0;
7948   ip6_address_t v6address;
7949   u8 use_default = 0;
7950   u8 no_advertise = 0;
7951   u8 off_link = 0;
7952   u8 no_autoconfig = 0;
7953   u8 no_onlink = 0;
7954   u8 is_no = 0;
7955   u32 val_lifetime = 0;
7956   u32 pref_lifetime = 0;
7957   int ret;
7958
7959   /* Parse args required to build the message */
7960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7961     {
7962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7963         sw_if_index_set = 1;
7964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7965         sw_if_index_set = 1;
7966       else if (unformat (i, "%U/%d",
7967                          unformat_ip6_address, &v6address, &address_length))
7968         v6_address_set = 1;
7969       else if (unformat (i, "val_life %d", &val_lifetime))
7970         ;
7971       else if (unformat (i, "pref_life %d", &pref_lifetime))
7972         ;
7973       else if (unformat (i, "def"))
7974         use_default = 1;
7975       else if (unformat (i, "noadv"))
7976         no_advertise = 1;
7977       else if (unformat (i, "offl"))
7978         off_link = 1;
7979       else if (unformat (i, "noauto"))
7980         no_autoconfig = 1;
7981       else if (unformat (i, "nolink"))
7982         no_onlink = 1;
7983       else if (unformat (i, "isno"))
7984         is_no = 1;
7985       else
7986         {
7987           clib_warning ("parse error '%U'", format_unformat_error, i);
7988           return -99;
7989         }
7990     }
7991
7992   if (sw_if_index_set == 0)
7993     {
7994       errmsg ("missing interface name or sw_if_index");
7995       return -99;
7996     }
7997   if (!v6_address_set)
7998     {
7999       errmsg ("no address set");
8000       return -99;
8001     }
8002
8003   /* Construct the API message */
8004   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8005
8006   mp->sw_if_index = ntohl (sw_if_index);
8007   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8008   mp->address_length = address_length;
8009   mp->use_default = use_default;
8010   mp->no_advertise = no_advertise;
8011   mp->off_link = off_link;
8012   mp->no_autoconfig = no_autoconfig;
8013   mp->no_onlink = no_onlink;
8014   mp->is_no = is_no;
8015   mp->val_lifetime = ntohl (val_lifetime);
8016   mp->pref_lifetime = ntohl (pref_lifetime);
8017
8018   /* send it... */
8019   S (mp);
8020
8021   /* Wait for a reply, return good/bad news  */
8022   W (ret);
8023   return ret;
8024 }
8025
8026 static int
8027 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8028 {
8029   unformat_input_t *i = vam->input;
8030   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8031   u32 sw_if_index;
8032   u8 sw_if_index_set = 0;
8033   u8 suppress = 0;
8034   u8 managed = 0;
8035   u8 other = 0;
8036   u8 ll_option = 0;
8037   u8 send_unicast = 0;
8038   u8 cease = 0;
8039   u8 is_no = 0;
8040   u8 default_router = 0;
8041   u32 max_interval = 0;
8042   u32 min_interval = 0;
8043   u32 lifetime = 0;
8044   u32 initial_count = 0;
8045   u32 initial_interval = 0;
8046   int ret;
8047
8048
8049   /* Parse args required to build the message */
8050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8051     {
8052       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8053         sw_if_index_set = 1;
8054       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8055         sw_if_index_set = 1;
8056       else if (unformat (i, "maxint %d", &max_interval))
8057         ;
8058       else if (unformat (i, "minint %d", &min_interval))
8059         ;
8060       else if (unformat (i, "life %d", &lifetime))
8061         ;
8062       else if (unformat (i, "count %d", &initial_count))
8063         ;
8064       else if (unformat (i, "interval %d", &initial_interval))
8065         ;
8066       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8067         suppress = 1;
8068       else if (unformat (i, "managed"))
8069         managed = 1;
8070       else if (unformat (i, "other"))
8071         other = 1;
8072       else if (unformat (i, "ll"))
8073         ll_option = 1;
8074       else if (unformat (i, "send"))
8075         send_unicast = 1;
8076       else if (unformat (i, "cease"))
8077         cease = 1;
8078       else if (unformat (i, "isno"))
8079         is_no = 1;
8080       else if (unformat (i, "def"))
8081         default_router = 1;
8082       else
8083         {
8084           clib_warning ("parse error '%U'", format_unformat_error, i);
8085           return -99;
8086         }
8087     }
8088
8089   if (sw_if_index_set == 0)
8090     {
8091       errmsg ("missing interface name or sw_if_index");
8092       return -99;
8093     }
8094
8095   /* Construct the API message */
8096   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8097
8098   mp->sw_if_index = ntohl (sw_if_index);
8099   mp->max_interval = ntohl (max_interval);
8100   mp->min_interval = ntohl (min_interval);
8101   mp->lifetime = ntohl (lifetime);
8102   mp->initial_count = ntohl (initial_count);
8103   mp->initial_interval = ntohl (initial_interval);
8104   mp->suppress = suppress;
8105   mp->managed = managed;
8106   mp->other = other;
8107   mp->ll_option = ll_option;
8108   mp->send_unicast = send_unicast;
8109   mp->cease = cease;
8110   mp->is_no = is_no;
8111   mp->default_router = default_router;
8112
8113   /* send it... */
8114   S (mp);
8115
8116   /* Wait for a reply, return good/bad news  */
8117   W (ret);
8118   return ret;
8119 }
8120
8121 static int
8122 api_set_arp_neighbor_limit (vat_main_t * vam)
8123 {
8124   unformat_input_t *i = vam->input;
8125   vl_api_set_arp_neighbor_limit_t *mp;
8126   u32 arp_nbr_limit;
8127   u8 limit_set = 0;
8128   u8 is_ipv6 = 0;
8129   int ret;
8130
8131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8132     {
8133       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8134         limit_set = 1;
8135       else if (unformat (i, "ipv6"))
8136         is_ipv6 = 1;
8137       else
8138         {
8139           clib_warning ("parse error '%U'", format_unformat_error, i);
8140           return -99;
8141         }
8142     }
8143
8144   if (limit_set == 0)
8145     {
8146       errmsg ("missing limit value");
8147       return -99;
8148     }
8149
8150   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8151
8152   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8153   mp->is_ipv6 = is_ipv6;
8154
8155   S (mp);
8156   W (ret);
8157   return ret;
8158 }
8159
8160 static int
8161 api_l2_patch_add_del (vat_main_t * vam)
8162 {
8163   unformat_input_t *i = vam->input;
8164   vl_api_l2_patch_add_del_t *mp;
8165   u32 rx_sw_if_index;
8166   u8 rx_sw_if_index_set = 0;
8167   u32 tx_sw_if_index;
8168   u8 tx_sw_if_index_set = 0;
8169   u8 is_add = 1;
8170   int ret;
8171
8172   /* Parse args required to build the message */
8173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8174     {
8175       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8176         rx_sw_if_index_set = 1;
8177       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8178         tx_sw_if_index_set = 1;
8179       else if (unformat (i, "rx"))
8180         {
8181           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8182             {
8183               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8184                             &rx_sw_if_index))
8185                 rx_sw_if_index_set = 1;
8186             }
8187           else
8188             break;
8189         }
8190       else if (unformat (i, "tx"))
8191         {
8192           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8193             {
8194               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8195                             &tx_sw_if_index))
8196                 tx_sw_if_index_set = 1;
8197             }
8198           else
8199             break;
8200         }
8201       else if (unformat (i, "del"))
8202         is_add = 0;
8203       else
8204         break;
8205     }
8206
8207   if (rx_sw_if_index_set == 0)
8208     {
8209       errmsg ("missing rx interface name or rx_sw_if_index");
8210       return -99;
8211     }
8212
8213   if (tx_sw_if_index_set == 0)
8214     {
8215       errmsg ("missing tx interface name or tx_sw_if_index");
8216       return -99;
8217     }
8218
8219   M (L2_PATCH_ADD_DEL, mp);
8220
8221   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8222   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8223   mp->is_add = is_add;
8224
8225   S (mp);
8226   W (ret);
8227   return ret;
8228 }
8229
8230 static int
8231 api_ioam_enable (vat_main_t * vam)
8232 {
8233   unformat_input_t *input = vam->input;
8234   vl_api_ioam_enable_t *mp;
8235   u32 id = 0;
8236   int has_trace_option = 0;
8237   int has_pot_option = 0;
8238   int has_seqno_option = 0;
8239   int has_analyse_option = 0;
8240   int ret;
8241
8242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8243     {
8244       if (unformat (input, "trace"))
8245         has_trace_option = 1;
8246       else if (unformat (input, "pot"))
8247         has_pot_option = 1;
8248       else if (unformat (input, "seqno"))
8249         has_seqno_option = 1;
8250       else if (unformat (input, "analyse"))
8251         has_analyse_option = 1;
8252       else
8253         break;
8254     }
8255   M (IOAM_ENABLE, mp);
8256   mp->id = htons (id);
8257   mp->seqno = has_seqno_option;
8258   mp->analyse = has_analyse_option;
8259   mp->pot_enable = has_pot_option;
8260   mp->trace_enable = has_trace_option;
8261
8262   S (mp);
8263   W (ret);
8264   return ret;
8265 }
8266
8267
8268 static int
8269 api_ioam_disable (vat_main_t * vam)
8270 {
8271   vl_api_ioam_disable_t *mp;
8272   int ret;
8273
8274   M (IOAM_DISABLE, mp);
8275   S (mp);
8276   W (ret);
8277   return ret;
8278 }
8279
8280 static int
8281 api_sr_tunnel_add_del (vat_main_t * vam)
8282 {
8283   unformat_input_t *i = vam->input;
8284   vl_api_sr_tunnel_add_del_t *mp;
8285   int is_del = 0;
8286   int pl_index;
8287   ip6_address_t src_address;
8288   int src_address_set = 0;
8289   ip6_address_t dst_address;
8290   u32 dst_mask_width;
8291   int dst_address_set = 0;
8292   u16 flags = 0;
8293   u32 rx_table_id = 0;
8294   u32 tx_table_id = 0;
8295   ip6_address_t *segments = 0;
8296   ip6_address_t *this_seg;
8297   ip6_address_t *tags = 0;
8298   ip6_address_t *this_tag;
8299   ip6_address_t next_address, tag;
8300   u8 *name = 0;
8301   u8 *policy_name = 0;
8302   int ret;
8303
8304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8305     {
8306       if (unformat (i, "del"))
8307         is_del = 1;
8308       else if (unformat (i, "name %s", &name))
8309         ;
8310       else if (unformat (i, "policy %s", &policy_name))
8311         ;
8312       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8313         ;
8314       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8315         ;
8316       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8317         src_address_set = 1;
8318       else if (unformat (i, "dst %U/%d",
8319                          unformat_ip6_address, &dst_address, &dst_mask_width))
8320         dst_address_set = 1;
8321       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8322         {
8323           vec_add2 (segments, this_seg, 1);
8324           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8325                        sizeof (*this_seg));
8326         }
8327       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8328         {
8329           vec_add2 (tags, this_tag, 1);
8330           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8331         }
8332       else if (unformat (i, "clean"))
8333         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8334       else if (unformat (i, "protected"))
8335         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8336       else if (unformat (i, "InPE %d", &pl_index))
8337         {
8338           if (pl_index <= 0 || pl_index > 4)
8339             {
8340             pl_index_range_error:
8341               errmsg ("pl index %d out of range", pl_index);
8342               return -99;
8343             }
8344           flags |=
8345             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8346         }
8347       else if (unformat (i, "EgPE %d", &pl_index))
8348         {
8349           if (pl_index <= 0 || pl_index > 4)
8350             goto pl_index_range_error;
8351           flags |=
8352             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8353         }
8354       else if (unformat (i, "OrgSrc %d", &pl_index))
8355         {
8356           if (pl_index <= 0 || pl_index > 4)
8357             goto pl_index_range_error;
8358           flags |=
8359             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8360         }
8361       else
8362         break;
8363     }
8364
8365   if (!src_address_set)
8366     {
8367       errmsg ("src address required");
8368       return -99;
8369     }
8370
8371   if (!dst_address_set)
8372     {
8373       errmsg ("dst address required");
8374       return -99;
8375     }
8376
8377   if (!segments)
8378     {
8379       errmsg ("at least one sr segment required");
8380       return -99;
8381     }
8382
8383   M2 (SR_TUNNEL_ADD_DEL, mp,
8384       vec_len (segments) * sizeof (ip6_address_t)
8385       + vec_len (tags) * sizeof (ip6_address_t));
8386
8387   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8388   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8389   mp->dst_mask_width = dst_mask_width;
8390   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8391   mp->n_segments = vec_len (segments);
8392   mp->n_tags = vec_len (tags);
8393   mp->is_add = is_del == 0;
8394   clib_memcpy (mp->segs_and_tags, segments,
8395                vec_len (segments) * sizeof (ip6_address_t));
8396   clib_memcpy (mp->segs_and_tags +
8397                vec_len (segments) * sizeof (ip6_address_t), tags,
8398                vec_len (tags) * sizeof (ip6_address_t));
8399
8400   mp->outer_vrf_id = ntohl (rx_table_id);
8401   mp->inner_vrf_id = ntohl (tx_table_id);
8402   memcpy (mp->name, name, vec_len (name));
8403   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8404
8405   vec_free (segments);
8406   vec_free (tags);
8407
8408   S (mp);
8409   W (ret);
8410   return ret;
8411 }
8412
8413 static int
8414 api_sr_policy_add_del (vat_main_t * vam)
8415 {
8416   unformat_input_t *input = vam->input;
8417   vl_api_sr_policy_add_del_t *mp;
8418   int is_del = 0;
8419   u8 *name = 0;
8420   u8 *tunnel_name = 0;
8421   u8 **tunnel_names = 0;
8422
8423   int name_set = 0;
8424   int tunnel_set = 0;
8425   int j = 0;
8426   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8427   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8428   int ret;
8429
8430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8431     {
8432       if (unformat (input, "del"))
8433         is_del = 1;
8434       else if (unformat (input, "name %s", &name))
8435         name_set = 1;
8436       else if (unformat (input, "tunnel %s", &tunnel_name))
8437         {
8438           if (tunnel_name)
8439             {
8440               vec_add1 (tunnel_names, tunnel_name);
8441               /* For serializer:
8442                  - length = #bytes to store in serial vector
8443                  - +1 = byte to store that length
8444                */
8445               tunnel_names_length += (vec_len (tunnel_name) + 1);
8446               tunnel_set = 1;
8447               tunnel_name = 0;
8448             }
8449         }
8450       else
8451         break;
8452     }
8453
8454   if (!name_set)
8455     {
8456       errmsg ("policy name required");
8457       return -99;
8458     }
8459
8460   if ((!tunnel_set) && (!is_del))
8461     {
8462       errmsg ("tunnel name required");
8463       return -99;
8464     }
8465
8466   M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
8467
8468
8469
8470   mp->is_add = !is_del;
8471
8472   memcpy (mp->name, name, vec_len (name));
8473   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8474   u8 *serial_orig = 0;
8475   vec_validate (serial_orig, tunnel_names_length);
8476   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8477   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8478
8479   for (j = 0; j < vec_len (tunnel_names); j++)
8480     {
8481       tun_name_len = vec_len (tunnel_names[j]);
8482       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8483       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8484       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8485       serial_orig += tun_name_len;      // Advance past the copy
8486     }
8487   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8488
8489   vec_free (tunnel_names);
8490   vec_free (tunnel_name);
8491
8492   S (mp);
8493   W (ret);
8494   return ret;
8495 }
8496
8497 static int
8498 api_sr_multicast_map_add_del (vat_main_t * vam)
8499 {
8500   unformat_input_t *input = vam->input;
8501   vl_api_sr_multicast_map_add_del_t *mp;
8502   int is_del = 0;
8503   ip6_address_t multicast_address;
8504   u8 *policy_name = 0;
8505   int multicast_address_set = 0;
8506   int ret;
8507
8508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8509     {
8510       if (unformat (input, "del"))
8511         is_del = 1;
8512       else
8513         if (unformat
8514             (input, "address %U", unformat_ip6_address, &multicast_address))
8515         multicast_address_set = 1;
8516       else if (unformat (input, "sr-policy %s", &policy_name))
8517         ;
8518       else
8519         break;
8520     }
8521
8522   if (!is_del && !policy_name)
8523     {
8524       errmsg ("sr-policy name required");
8525       return -99;
8526     }
8527
8528
8529   if (!multicast_address_set)
8530     {
8531       errmsg ("address required");
8532       return -99;
8533     }
8534
8535   M (SR_MULTICAST_MAP_ADD_DEL, mp);
8536
8537   mp->is_add = !is_del;
8538   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8539   clib_memcpy (mp->multicast_address, &multicast_address,
8540                sizeof (mp->multicast_address));
8541
8542
8543   vec_free (policy_name);
8544
8545   S (mp);
8546   W (ret);
8547   return ret;
8548 }
8549
8550
8551 #define foreach_tcp_proto_field                 \
8552 _(src_port)                                     \
8553 _(dst_port)
8554
8555 #define foreach_udp_proto_field                 \
8556 _(src_port)                                     \
8557 _(dst_port)
8558
8559 #define foreach_ip4_proto_field                 \
8560 _(src_address)                                  \
8561 _(dst_address)                                  \
8562 _(tos)                                          \
8563 _(length)                                       \
8564 _(fragment_id)                                  \
8565 _(ttl)                                          \
8566 _(protocol)                                     \
8567 _(checksum)
8568
8569 typedef struct
8570 {
8571   u16 src_port, dst_port;
8572 } tcpudp_header_t;
8573
8574 #if VPP_API_TEST_BUILTIN == 0
8575 uword
8576 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8577 {
8578   u8 **maskp = va_arg (*args, u8 **);
8579   u8 *mask = 0;
8580   u8 found_something = 0;
8581   tcp_header_t *tcp;
8582
8583 #define _(a) u8 a=0;
8584   foreach_tcp_proto_field;
8585 #undef _
8586
8587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8588     {
8589       if (0);
8590 #define _(a) else if (unformat (input, #a)) a=1;
8591       foreach_tcp_proto_field
8592 #undef _
8593         else
8594         break;
8595     }
8596
8597 #define _(a) found_something += a;
8598   foreach_tcp_proto_field;
8599 #undef _
8600
8601   if (found_something == 0)
8602     return 0;
8603
8604   vec_validate (mask, sizeof (*tcp) - 1);
8605
8606   tcp = (tcp_header_t *) mask;
8607
8608 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8609   foreach_tcp_proto_field;
8610 #undef _
8611
8612   *maskp = mask;
8613   return 1;
8614 }
8615
8616 uword
8617 unformat_udp_mask (unformat_input_t * input, va_list * args)
8618 {
8619   u8 **maskp = va_arg (*args, u8 **);
8620   u8 *mask = 0;
8621   u8 found_something = 0;
8622   udp_header_t *udp;
8623
8624 #define _(a) u8 a=0;
8625   foreach_udp_proto_field;
8626 #undef _
8627
8628   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8629     {
8630       if (0);
8631 #define _(a) else if (unformat (input, #a)) a=1;
8632       foreach_udp_proto_field
8633 #undef _
8634         else
8635         break;
8636     }
8637
8638 #define _(a) found_something += a;
8639   foreach_udp_proto_field;
8640 #undef _
8641
8642   if (found_something == 0)
8643     return 0;
8644
8645   vec_validate (mask, sizeof (*udp) - 1);
8646
8647   udp = (udp_header_t *) mask;
8648
8649 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8650   foreach_udp_proto_field;
8651 #undef _
8652
8653   *maskp = mask;
8654   return 1;
8655 }
8656
8657 uword
8658 unformat_l4_mask (unformat_input_t * input, va_list * args)
8659 {
8660   u8 **maskp = va_arg (*args, u8 **);
8661   u16 src_port = 0, dst_port = 0;
8662   tcpudp_header_t *tcpudp;
8663
8664   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8665     {
8666       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8667         return 1;
8668       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8669         return 1;
8670       else if (unformat (input, "src_port"))
8671         src_port = 0xFFFF;
8672       else if (unformat (input, "dst_port"))
8673         dst_port = 0xFFFF;
8674       else
8675         return 0;
8676     }
8677
8678   if (!src_port && !dst_port)
8679     return 0;
8680
8681   u8 *mask = 0;
8682   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8683
8684   tcpudp = (tcpudp_header_t *) mask;
8685   tcpudp->src_port = src_port;
8686   tcpudp->dst_port = dst_port;
8687
8688   *maskp = mask;
8689
8690   return 1;
8691 }
8692
8693 uword
8694 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8695 {
8696   u8 **maskp = va_arg (*args, u8 **);
8697   u8 *mask = 0;
8698   u8 found_something = 0;
8699   ip4_header_t *ip;
8700
8701 #define _(a) u8 a=0;
8702   foreach_ip4_proto_field;
8703 #undef _
8704   u8 version = 0;
8705   u8 hdr_length = 0;
8706
8707
8708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8709     {
8710       if (unformat (input, "version"))
8711         version = 1;
8712       else if (unformat (input, "hdr_length"))
8713         hdr_length = 1;
8714       else if (unformat (input, "src"))
8715         src_address = 1;
8716       else if (unformat (input, "dst"))
8717         dst_address = 1;
8718       else if (unformat (input, "proto"))
8719         protocol = 1;
8720
8721 #define _(a) else if (unformat (input, #a)) a=1;
8722       foreach_ip4_proto_field
8723 #undef _
8724         else
8725         break;
8726     }
8727
8728 #define _(a) found_something += a;
8729   foreach_ip4_proto_field;
8730 #undef _
8731
8732   if (found_something == 0)
8733     return 0;
8734
8735   vec_validate (mask, sizeof (*ip) - 1);
8736
8737   ip = (ip4_header_t *) mask;
8738
8739 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8740   foreach_ip4_proto_field;
8741 #undef _
8742
8743   ip->ip_version_and_header_length = 0;
8744
8745   if (version)
8746     ip->ip_version_and_header_length |= 0xF0;
8747
8748   if (hdr_length)
8749     ip->ip_version_and_header_length |= 0x0F;
8750
8751   *maskp = mask;
8752   return 1;
8753 }
8754
8755 #define foreach_ip6_proto_field                 \
8756 _(src_address)                                  \
8757 _(dst_address)                                  \
8758 _(payload_length)                               \
8759 _(hop_limit)                                    \
8760 _(protocol)
8761
8762 uword
8763 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8764 {
8765   u8 **maskp = va_arg (*args, u8 **);
8766   u8 *mask = 0;
8767   u8 found_something = 0;
8768   ip6_header_t *ip;
8769   u32 ip_version_traffic_class_and_flow_label;
8770
8771 #define _(a) u8 a=0;
8772   foreach_ip6_proto_field;
8773 #undef _
8774   u8 version = 0;
8775   u8 traffic_class = 0;
8776   u8 flow_label = 0;
8777
8778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8779     {
8780       if (unformat (input, "version"))
8781         version = 1;
8782       else if (unformat (input, "traffic-class"))
8783         traffic_class = 1;
8784       else if (unformat (input, "flow-label"))
8785         flow_label = 1;
8786       else if (unformat (input, "src"))
8787         src_address = 1;
8788       else if (unformat (input, "dst"))
8789         dst_address = 1;
8790       else if (unformat (input, "proto"))
8791         protocol = 1;
8792
8793 #define _(a) else if (unformat (input, #a)) a=1;
8794       foreach_ip6_proto_field
8795 #undef _
8796         else
8797         break;
8798     }
8799
8800 #define _(a) found_something += a;
8801   foreach_ip6_proto_field;
8802 #undef _
8803
8804   if (found_something == 0)
8805     return 0;
8806
8807   vec_validate (mask, sizeof (*ip) - 1);
8808
8809   ip = (ip6_header_t *) mask;
8810
8811 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8812   foreach_ip6_proto_field;
8813 #undef _
8814
8815   ip_version_traffic_class_and_flow_label = 0;
8816
8817   if (version)
8818     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8819
8820   if (traffic_class)
8821     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8822
8823   if (flow_label)
8824     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8825
8826   ip->ip_version_traffic_class_and_flow_label =
8827     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8828
8829   *maskp = mask;
8830   return 1;
8831 }
8832
8833 uword
8834 unformat_l3_mask (unformat_input_t * input, va_list * args)
8835 {
8836   u8 **maskp = va_arg (*args, u8 **);
8837
8838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8839     {
8840       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8841         return 1;
8842       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8843         return 1;
8844       else
8845         break;
8846     }
8847   return 0;
8848 }
8849
8850 uword
8851 unformat_l2_mask (unformat_input_t * input, va_list * args)
8852 {
8853   u8 **maskp = va_arg (*args, u8 **);
8854   u8 *mask = 0;
8855   u8 src = 0;
8856   u8 dst = 0;
8857   u8 proto = 0;
8858   u8 tag1 = 0;
8859   u8 tag2 = 0;
8860   u8 ignore_tag1 = 0;
8861   u8 ignore_tag2 = 0;
8862   u8 cos1 = 0;
8863   u8 cos2 = 0;
8864   u8 dot1q = 0;
8865   u8 dot1ad = 0;
8866   int len = 14;
8867
8868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8869     {
8870       if (unformat (input, "src"))
8871         src = 1;
8872       else if (unformat (input, "dst"))
8873         dst = 1;
8874       else if (unformat (input, "proto"))
8875         proto = 1;
8876       else if (unformat (input, "tag1"))
8877         tag1 = 1;
8878       else if (unformat (input, "tag2"))
8879         tag2 = 1;
8880       else if (unformat (input, "ignore-tag1"))
8881         ignore_tag1 = 1;
8882       else if (unformat (input, "ignore-tag2"))
8883         ignore_tag2 = 1;
8884       else if (unformat (input, "cos1"))
8885         cos1 = 1;
8886       else if (unformat (input, "cos2"))
8887         cos2 = 1;
8888       else if (unformat (input, "dot1q"))
8889         dot1q = 1;
8890       else if (unformat (input, "dot1ad"))
8891         dot1ad = 1;
8892       else
8893         break;
8894     }
8895   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8896        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8897     return 0;
8898
8899   if (tag1 || ignore_tag1 || cos1 || dot1q)
8900     len = 18;
8901   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8902     len = 22;
8903
8904   vec_validate (mask, len - 1);
8905
8906   if (dst)
8907     memset (mask, 0xff, 6);
8908
8909   if (src)
8910     memset (mask + 6, 0xff, 6);
8911
8912   if (tag2 || dot1ad)
8913     {
8914       /* inner vlan tag */
8915       if (tag2)
8916         {
8917           mask[19] = 0xff;
8918           mask[18] = 0x0f;
8919         }
8920       if (cos2)
8921         mask[18] |= 0xe0;
8922       if (proto)
8923         mask[21] = mask[20] = 0xff;
8924       if (tag1)
8925         {
8926           mask[15] = 0xff;
8927           mask[14] = 0x0f;
8928         }
8929       if (cos1)
8930         mask[14] |= 0xe0;
8931       *maskp = mask;
8932       return 1;
8933     }
8934   if (tag1 | dot1q)
8935     {
8936       if (tag1)
8937         {
8938           mask[15] = 0xff;
8939           mask[14] = 0x0f;
8940         }
8941       if (cos1)
8942         mask[14] |= 0xe0;
8943       if (proto)
8944         mask[16] = mask[17] = 0xff;
8945
8946       *maskp = mask;
8947       return 1;
8948     }
8949   if (cos2)
8950     mask[18] |= 0xe0;
8951   if (cos1)
8952     mask[14] |= 0xe0;
8953   if (proto)
8954     mask[12] = mask[13] = 0xff;
8955
8956   *maskp = mask;
8957   return 1;
8958 }
8959
8960 uword
8961 unformat_classify_mask (unformat_input_t * input, va_list * args)
8962 {
8963   u8 **maskp = va_arg (*args, u8 **);
8964   u32 *skipp = va_arg (*args, u32 *);
8965   u32 *matchp = va_arg (*args, u32 *);
8966   u32 match;
8967   u8 *mask = 0;
8968   u8 *l2 = 0;
8969   u8 *l3 = 0;
8970   u8 *l4 = 0;
8971   int i;
8972
8973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8974     {
8975       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8976         ;
8977       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8978         ;
8979       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8980         ;
8981       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8982         ;
8983       else
8984         break;
8985     }
8986
8987   if (l4 && !l3)
8988     {
8989       vec_free (mask);
8990       vec_free (l2);
8991       vec_free (l4);
8992       return 0;
8993     }
8994
8995   if (mask || l2 || l3 || l4)
8996     {
8997       if (l2 || l3 || l4)
8998         {
8999           /* "With a free Ethernet header in every package" */
9000           if (l2 == 0)
9001             vec_validate (l2, 13);
9002           mask = l2;
9003           if (vec_len (l3))
9004             {
9005               vec_append (mask, l3);
9006               vec_free (l3);
9007             }
9008           if (vec_len (l4))
9009             {
9010               vec_append (mask, l4);
9011               vec_free (l4);
9012             }
9013         }
9014
9015       /* Scan forward looking for the first significant mask octet */
9016       for (i = 0; i < vec_len (mask); i++)
9017         if (mask[i])
9018           break;
9019
9020       /* compute (skip, match) params */
9021       *skipp = i / sizeof (u32x4);
9022       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9023
9024       /* Pad mask to an even multiple of the vector size */
9025       while (vec_len (mask) % sizeof (u32x4))
9026         vec_add1 (mask, 0);
9027
9028       match = vec_len (mask) / sizeof (u32x4);
9029
9030       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9031         {
9032           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9033           if (*tmp || *(tmp + 1))
9034             break;
9035           match--;
9036         }
9037       if (match == 0)
9038         clib_warning ("BUG: match 0");
9039
9040       _vec_len (mask) = match * sizeof (u32x4);
9041
9042       *matchp = match;
9043       *maskp = mask;
9044
9045       return 1;
9046     }
9047
9048   return 0;
9049 }
9050 #endif /* VPP_API_TEST_BUILTIN */
9051
9052 #define foreach_l2_next                         \
9053 _(drop, DROP)                                   \
9054 _(ethernet, ETHERNET_INPUT)                     \
9055 _(ip4, IP4_INPUT)                               \
9056 _(ip6, IP6_INPUT)
9057
9058 uword
9059 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9060 {
9061   u32 *miss_next_indexp = va_arg (*args, u32 *);
9062   u32 next_index = 0;
9063   u32 tmp;
9064
9065 #define _(n,N) \
9066   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9067   foreach_l2_next;
9068 #undef _
9069
9070   if (unformat (input, "%d", &tmp))
9071     {
9072       next_index = tmp;
9073       goto out;
9074     }
9075
9076   return 0;
9077
9078 out:
9079   *miss_next_indexp = next_index;
9080   return 1;
9081 }
9082
9083 #define foreach_ip_next                         \
9084 _(drop, DROP)                                   \
9085 _(local, LOCAL)                                 \
9086 _(rewrite, REWRITE)
9087
9088 uword
9089 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9090 {
9091   u32 *miss_next_indexp = va_arg (*args, u32 *);
9092   u32 next_index = 0;
9093   u32 tmp;
9094
9095 #define _(n,N) \
9096   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9097   foreach_ip_next;
9098 #undef _
9099
9100   if (unformat (input, "%d", &tmp))
9101     {
9102       next_index = tmp;
9103       goto out;
9104     }
9105
9106   return 0;
9107
9108 out:
9109   *miss_next_indexp = next_index;
9110   return 1;
9111 }
9112
9113 #define foreach_acl_next                        \
9114 _(deny, DENY)
9115
9116 uword
9117 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9118 {
9119   u32 *miss_next_indexp = va_arg (*args, u32 *);
9120   u32 next_index = 0;
9121   u32 tmp;
9122
9123 #define _(n,N) \
9124   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9125   foreach_acl_next;
9126 #undef _
9127
9128   if (unformat (input, "permit"))
9129     {
9130       next_index = ~0;
9131       goto out;
9132     }
9133   else if (unformat (input, "%d", &tmp))
9134     {
9135       next_index = tmp;
9136       goto out;
9137     }
9138
9139   return 0;
9140
9141 out:
9142   *miss_next_indexp = next_index;
9143   return 1;
9144 }
9145
9146 uword
9147 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9148 {
9149   u32 *r = va_arg (*args, u32 *);
9150
9151   if (unformat (input, "conform-color"))
9152     *r = POLICE_CONFORM;
9153   else if (unformat (input, "exceed-color"))
9154     *r = POLICE_EXCEED;
9155   else
9156     return 0;
9157
9158   return 1;
9159 }
9160
9161 static int
9162 api_classify_add_del_table (vat_main_t * vam)
9163 {
9164   unformat_input_t *i = vam->input;
9165   vl_api_classify_add_del_table_t *mp;
9166
9167   u32 nbuckets = 2;
9168   u32 skip = ~0;
9169   u32 match = ~0;
9170   int is_add = 1;
9171   int del_chain = 0;
9172   u32 table_index = ~0;
9173   u32 next_table_index = ~0;
9174   u32 miss_next_index = ~0;
9175   u32 memory_size = 32 << 20;
9176   u8 *mask = 0;
9177   u32 current_data_flag = 0;
9178   int current_data_offset = 0;
9179   int ret;
9180
9181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9182     {
9183       if (unformat (i, "del"))
9184         is_add = 0;
9185       else if (unformat (i, "del-chain"))
9186         {
9187           is_add = 0;
9188           del_chain = 1;
9189         }
9190       else if (unformat (i, "buckets %d", &nbuckets))
9191         ;
9192       else if (unformat (i, "memory_size %d", &memory_size))
9193         ;
9194       else if (unformat (i, "skip %d", &skip))
9195         ;
9196       else if (unformat (i, "match %d", &match))
9197         ;
9198       else if (unformat (i, "table %d", &table_index))
9199         ;
9200       else if (unformat (i, "mask %U", unformat_classify_mask,
9201                          &mask, &skip, &match))
9202         ;
9203       else if (unformat (i, "next-table %d", &next_table_index))
9204         ;
9205       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9206                          &miss_next_index))
9207         ;
9208       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9209                          &miss_next_index))
9210         ;
9211       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9212                          &miss_next_index))
9213         ;
9214       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9215         ;
9216       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9217         ;
9218       else
9219         break;
9220     }
9221
9222   if (is_add && mask == 0)
9223     {
9224       errmsg ("Mask required");
9225       return -99;
9226     }
9227
9228   if (is_add && skip == ~0)
9229     {
9230       errmsg ("skip count required");
9231       return -99;
9232     }
9233
9234   if (is_add && match == ~0)
9235     {
9236       errmsg ("match count required");
9237       return -99;
9238     }
9239
9240   if (!is_add && table_index == ~0)
9241     {
9242       errmsg ("table index required for delete");
9243       return -99;
9244     }
9245
9246   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9247
9248   mp->is_add = is_add;
9249   mp->del_chain = del_chain;
9250   mp->table_index = ntohl (table_index);
9251   mp->nbuckets = ntohl (nbuckets);
9252   mp->memory_size = ntohl (memory_size);
9253   mp->skip_n_vectors = ntohl (skip);
9254   mp->match_n_vectors = ntohl (match);
9255   mp->next_table_index = ntohl (next_table_index);
9256   mp->miss_next_index = ntohl (miss_next_index);
9257   mp->current_data_flag = ntohl (current_data_flag);
9258   mp->current_data_offset = ntohl (current_data_offset);
9259   clib_memcpy (mp->mask, mask, vec_len (mask));
9260
9261   vec_free (mask);
9262
9263   S (mp);
9264   W (ret);
9265   return ret;
9266 }
9267
9268 #if VPP_API_TEST_BUILTIN == 0
9269 uword
9270 unformat_l4_match (unformat_input_t * input, va_list * args)
9271 {
9272   u8 **matchp = va_arg (*args, u8 **);
9273
9274   u8 *proto_header = 0;
9275   int src_port = 0;
9276   int dst_port = 0;
9277
9278   tcpudp_header_t h;
9279
9280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9281     {
9282       if (unformat (input, "src_port %d", &src_port))
9283         ;
9284       else if (unformat (input, "dst_port %d", &dst_port))
9285         ;
9286       else
9287         return 0;
9288     }
9289
9290   h.src_port = clib_host_to_net_u16 (src_port);
9291   h.dst_port = clib_host_to_net_u16 (dst_port);
9292   vec_validate (proto_header, sizeof (h) - 1);
9293   memcpy (proto_header, &h, sizeof (h));
9294
9295   *matchp = proto_header;
9296
9297   return 1;
9298 }
9299
9300 uword
9301 unformat_ip4_match (unformat_input_t * input, va_list * args)
9302 {
9303   u8 **matchp = va_arg (*args, u8 **);
9304   u8 *match = 0;
9305   ip4_header_t *ip;
9306   int version = 0;
9307   u32 version_val;
9308   int hdr_length = 0;
9309   u32 hdr_length_val;
9310   int src = 0, dst = 0;
9311   ip4_address_t src_val, dst_val;
9312   int proto = 0;
9313   u32 proto_val;
9314   int tos = 0;
9315   u32 tos_val;
9316   int length = 0;
9317   u32 length_val;
9318   int fragment_id = 0;
9319   u32 fragment_id_val;
9320   int ttl = 0;
9321   int ttl_val;
9322   int checksum = 0;
9323   u32 checksum_val;
9324
9325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9326     {
9327       if (unformat (input, "version %d", &version_val))
9328         version = 1;
9329       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9330         hdr_length = 1;
9331       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9332         src = 1;
9333       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9334         dst = 1;
9335       else if (unformat (input, "proto %d", &proto_val))
9336         proto = 1;
9337       else if (unformat (input, "tos %d", &tos_val))
9338         tos = 1;
9339       else if (unformat (input, "length %d", &length_val))
9340         length = 1;
9341       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9342         fragment_id = 1;
9343       else if (unformat (input, "ttl %d", &ttl_val))
9344         ttl = 1;
9345       else if (unformat (input, "checksum %d", &checksum_val))
9346         checksum = 1;
9347       else
9348         break;
9349     }
9350
9351   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9352       + ttl + checksum == 0)
9353     return 0;
9354
9355   /*
9356    * Aligned because we use the real comparison functions
9357    */
9358   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9359
9360   ip = (ip4_header_t *) match;
9361
9362   /* These are realistically matched in practice */
9363   if (src)
9364     ip->src_address.as_u32 = src_val.as_u32;
9365
9366   if (dst)
9367     ip->dst_address.as_u32 = dst_val.as_u32;
9368
9369   if (proto)
9370     ip->protocol = proto_val;
9371
9372
9373   /* These are not, but they're included for completeness */
9374   if (version)
9375     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9376
9377   if (hdr_length)
9378     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9379
9380   if (tos)
9381     ip->tos = tos_val;
9382
9383   if (length)
9384     ip->length = clib_host_to_net_u16 (length_val);
9385
9386   if (ttl)
9387     ip->ttl = ttl_val;
9388
9389   if (checksum)
9390     ip->checksum = clib_host_to_net_u16 (checksum_val);
9391
9392   *matchp = match;
9393   return 1;
9394 }
9395
9396 uword
9397 unformat_ip6_match (unformat_input_t * input, va_list * args)
9398 {
9399   u8 **matchp = va_arg (*args, u8 **);
9400   u8 *match = 0;
9401   ip6_header_t *ip;
9402   int version = 0;
9403   u32 version_val;
9404   u8 traffic_class = 0;
9405   u32 traffic_class_val = 0;
9406   u8 flow_label = 0;
9407   u8 flow_label_val;
9408   int src = 0, dst = 0;
9409   ip6_address_t src_val, dst_val;
9410   int proto = 0;
9411   u32 proto_val;
9412   int payload_length = 0;
9413   u32 payload_length_val;
9414   int hop_limit = 0;
9415   int hop_limit_val;
9416   u32 ip_version_traffic_class_and_flow_label;
9417
9418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9419     {
9420       if (unformat (input, "version %d", &version_val))
9421         version = 1;
9422       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9423         traffic_class = 1;
9424       else if (unformat (input, "flow_label %d", &flow_label_val))
9425         flow_label = 1;
9426       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9427         src = 1;
9428       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9429         dst = 1;
9430       else if (unformat (input, "proto %d", &proto_val))
9431         proto = 1;
9432       else if (unformat (input, "payload_length %d", &payload_length_val))
9433         payload_length = 1;
9434       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9435         hop_limit = 1;
9436       else
9437         break;
9438     }
9439
9440   if (version + traffic_class + flow_label + src + dst + proto +
9441       payload_length + hop_limit == 0)
9442     return 0;
9443
9444   /*
9445    * Aligned because we use the real comparison functions
9446    */
9447   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9448
9449   ip = (ip6_header_t *) match;
9450
9451   if (src)
9452     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9453
9454   if (dst)
9455     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9456
9457   if (proto)
9458     ip->protocol = proto_val;
9459
9460   ip_version_traffic_class_and_flow_label = 0;
9461
9462   if (version)
9463     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9464
9465   if (traffic_class)
9466     ip_version_traffic_class_and_flow_label |=
9467       (traffic_class_val & 0xFF) << 20;
9468
9469   if (flow_label)
9470     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9471
9472   ip->ip_version_traffic_class_and_flow_label =
9473     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9474
9475   if (payload_length)
9476     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9477
9478   if (hop_limit)
9479     ip->hop_limit = hop_limit_val;
9480
9481   *matchp = match;
9482   return 1;
9483 }
9484
9485 uword
9486 unformat_l3_match (unformat_input_t * input, va_list * args)
9487 {
9488   u8 **matchp = va_arg (*args, u8 **);
9489
9490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9491     {
9492       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9493         return 1;
9494       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9495         return 1;
9496       else
9497         break;
9498     }
9499   return 0;
9500 }
9501
9502 uword
9503 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9504 {
9505   u8 *tagp = va_arg (*args, u8 *);
9506   u32 tag;
9507
9508   if (unformat (input, "%d", &tag))
9509     {
9510       tagp[0] = (tag >> 8) & 0x0F;
9511       tagp[1] = tag & 0xFF;
9512       return 1;
9513     }
9514
9515   return 0;
9516 }
9517
9518 uword
9519 unformat_l2_match (unformat_input_t * input, va_list * args)
9520 {
9521   u8 **matchp = va_arg (*args, u8 **);
9522   u8 *match = 0;
9523   u8 src = 0;
9524   u8 src_val[6];
9525   u8 dst = 0;
9526   u8 dst_val[6];
9527   u8 proto = 0;
9528   u16 proto_val;
9529   u8 tag1 = 0;
9530   u8 tag1_val[2];
9531   u8 tag2 = 0;
9532   u8 tag2_val[2];
9533   int len = 14;
9534   u8 ignore_tag1 = 0;
9535   u8 ignore_tag2 = 0;
9536   u8 cos1 = 0;
9537   u8 cos2 = 0;
9538   u32 cos1_val = 0;
9539   u32 cos2_val = 0;
9540
9541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9542     {
9543       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9544         src = 1;
9545       else
9546         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9547         dst = 1;
9548       else if (unformat (input, "proto %U",
9549                          unformat_ethernet_type_host_byte_order, &proto_val))
9550         proto = 1;
9551       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9552         tag1 = 1;
9553       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9554         tag2 = 1;
9555       else if (unformat (input, "ignore-tag1"))
9556         ignore_tag1 = 1;
9557       else if (unformat (input, "ignore-tag2"))
9558         ignore_tag2 = 1;
9559       else if (unformat (input, "cos1 %d", &cos1_val))
9560         cos1 = 1;
9561       else if (unformat (input, "cos2 %d", &cos2_val))
9562         cos2 = 1;
9563       else
9564         break;
9565     }
9566   if ((src + dst + proto + tag1 + tag2 +
9567        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9568     return 0;
9569
9570   if (tag1 || ignore_tag1 || cos1)
9571     len = 18;
9572   if (tag2 || ignore_tag2 || cos2)
9573     len = 22;
9574
9575   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9576
9577   if (dst)
9578     clib_memcpy (match, dst_val, 6);
9579
9580   if (src)
9581     clib_memcpy (match + 6, src_val, 6);
9582
9583   if (tag2)
9584     {
9585       /* inner vlan tag */
9586       match[19] = tag2_val[1];
9587       match[18] = tag2_val[0];
9588       if (cos2)
9589         match[18] |= (cos2_val & 0x7) << 5;
9590       if (proto)
9591         {
9592           match[21] = proto_val & 0xff;
9593           match[20] = proto_val >> 8;
9594         }
9595       if (tag1)
9596         {
9597           match[15] = tag1_val[1];
9598           match[14] = tag1_val[0];
9599         }
9600       if (cos1)
9601         match[14] |= (cos1_val & 0x7) << 5;
9602       *matchp = match;
9603       return 1;
9604     }
9605   if (tag1)
9606     {
9607       match[15] = tag1_val[1];
9608       match[14] = tag1_val[0];
9609       if (proto)
9610         {
9611           match[17] = proto_val & 0xff;
9612           match[16] = proto_val >> 8;
9613         }
9614       if (cos1)
9615         match[14] |= (cos1_val & 0x7) << 5;
9616
9617       *matchp = match;
9618       return 1;
9619     }
9620   if (cos2)
9621     match[18] |= (cos2_val & 0x7) << 5;
9622   if (cos1)
9623     match[14] |= (cos1_val & 0x7) << 5;
9624   if (proto)
9625     {
9626       match[13] = proto_val & 0xff;
9627       match[12] = proto_val >> 8;
9628     }
9629
9630   *matchp = match;
9631   return 1;
9632 }
9633 #endif
9634
9635 uword
9636 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9637 {
9638   u8 **matchp = va_arg (*args, u8 **);
9639   u32 skip_n_vectors = va_arg (*args, u32);
9640   u32 match_n_vectors = va_arg (*args, u32);
9641
9642   u8 *match = 0;
9643   u8 *l2 = 0;
9644   u8 *l3 = 0;
9645   u8 *l4 = 0;
9646
9647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9648     {
9649       if (unformat (input, "hex %U", unformat_hex_string, &match))
9650         ;
9651       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9652         ;
9653       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9654         ;
9655       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9656         ;
9657       else
9658         break;
9659     }
9660
9661   if (l4 && !l3)
9662     {
9663       vec_free (match);
9664       vec_free (l2);
9665       vec_free (l4);
9666       return 0;
9667     }
9668
9669   if (match || l2 || l3 || l4)
9670     {
9671       if (l2 || l3 || l4)
9672         {
9673           /* "Win a free Ethernet header in every packet" */
9674           if (l2 == 0)
9675             vec_validate_aligned (l2, 13, sizeof (u32x4));
9676           match = l2;
9677           if (vec_len (l3))
9678             {
9679               vec_append_aligned (match, l3, sizeof (u32x4));
9680               vec_free (l3);
9681             }
9682           if (vec_len (l4))
9683             {
9684               vec_append_aligned (match, l4, sizeof (u32x4));
9685               vec_free (l4);
9686             }
9687         }
9688
9689       /* Make sure the vector is big enough even if key is all 0's */
9690       vec_validate_aligned
9691         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9692          sizeof (u32x4));
9693
9694       /* Set size, include skipped vectors */
9695       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9696
9697       *matchp = match;
9698
9699       return 1;
9700     }
9701
9702   return 0;
9703 }
9704
9705 static int
9706 api_classify_add_del_session (vat_main_t * vam)
9707 {
9708   unformat_input_t *i = vam->input;
9709   vl_api_classify_add_del_session_t *mp;
9710   int is_add = 1;
9711   u32 table_index = ~0;
9712   u32 hit_next_index = ~0;
9713   u32 opaque_index = ~0;
9714   u8 *match = 0;
9715   i32 advance = 0;
9716   u32 skip_n_vectors = 0;
9717   u32 match_n_vectors = 0;
9718   u32 action = 0;
9719   u32 metadata = 0;
9720   int ret;
9721
9722   /*
9723    * Warning: you have to supply skip_n and match_n
9724    * because the API client cant simply look at the classify
9725    * table object.
9726    */
9727
9728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9729     {
9730       if (unformat (i, "del"))
9731         is_add = 0;
9732       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9733                          &hit_next_index))
9734         ;
9735       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9736                          &hit_next_index))
9737         ;
9738       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9739                          &hit_next_index))
9740         ;
9741       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9742         ;
9743       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9744         ;
9745       else if (unformat (i, "opaque-index %d", &opaque_index))
9746         ;
9747       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9748         ;
9749       else if (unformat (i, "match_n %d", &match_n_vectors))
9750         ;
9751       else if (unformat (i, "match %U", api_unformat_classify_match,
9752                          &match, skip_n_vectors, match_n_vectors))
9753         ;
9754       else if (unformat (i, "advance %d", &advance))
9755         ;
9756       else if (unformat (i, "table-index %d", &table_index))
9757         ;
9758       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9759         action = 1;
9760       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9761         action = 2;
9762       else if (unformat (i, "action %d", &action))
9763         ;
9764       else if (unformat (i, "metadata %d", &metadata))
9765         ;
9766       else
9767         break;
9768     }
9769
9770   if (table_index == ~0)
9771     {
9772       errmsg ("Table index required");
9773       return -99;
9774     }
9775
9776   if (is_add && match == 0)
9777     {
9778       errmsg ("Match value required");
9779       return -99;
9780     }
9781
9782   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9783
9784   mp->is_add = is_add;
9785   mp->table_index = ntohl (table_index);
9786   mp->hit_next_index = ntohl (hit_next_index);
9787   mp->opaque_index = ntohl (opaque_index);
9788   mp->advance = ntohl (advance);
9789   mp->action = action;
9790   mp->metadata = ntohl (metadata);
9791   clib_memcpy (mp->match, match, vec_len (match));
9792   vec_free (match);
9793
9794   S (mp);
9795   W (ret);
9796   return ret;
9797 }
9798
9799 static int
9800 api_classify_set_interface_ip_table (vat_main_t * vam)
9801 {
9802   unformat_input_t *i = vam->input;
9803   vl_api_classify_set_interface_ip_table_t *mp;
9804   u32 sw_if_index;
9805   int sw_if_index_set;
9806   u32 table_index = ~0;
9807   u8 is_ipv6 = 0;
9808   int ret;
9809
9810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9813         sw_if_index_set = 1;
9814       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9815         sw_if_index_set = 1;
9816       else if (unformat (i, "table %d", &table_index))
9817         ;
9818       else
9819         {
9820           clib_warning ("parse error '%U'", format_unformat_error, i);
9821           return -99;
9822         }
9823     }
9824
9825   if (sw_if_index_set == 0)
9826     {
9827       errmsg ("missing interface name or sw_if_index");
9828       return -99;
9829     }
9830
9831
9832   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9833
9834   mp->sw_if_index = ntohl (sw_if_index);
9835   mp->table_index = ntohl (table_index);
9836   mp->is_ipv6 = is_ipv6;
9837
9838   S (mp);
9839   W (ret);
9840   return ret;
9841 }
9842
9843 static int
9844 api_classify_set_interface_l2_tables (vat_main_t * vam)
9845 {
9846   unformat_input_t *i = vam->input;
9847   vl_api_classify_set_interface_l2_tables_t *mp;
9848   u32 sw_if_index;
9849   int sw_if_index_set;
9850   u32 ip4_table_index = ~0;
9851   u32 ip6_table_index = ~0;
9852   u32 other_table_index = ~0;
9853   u32 is_input = 1;
9854   int ret;
9855
9856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9857     {
9858       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9859         sw_if_index_set = 1;
9860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9861         sw_if_index_set = 1;
9862       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9863         ;
9864       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9865         ;
9866       else if (unformat (i, "other-table %d", &other_table_index))
9867         ;
9868       else if (unformat (i, "is-input %d", &is_input))
9869         ;
9870       else
9871         {
9872           clib_warning ("parse error '%U'", format_unformat_error, i);
9873           return -99;
9874         }
9875     }
9876
9877   if (sw_if_index_set == 0)
9878     {
9879       errmsg ("missing interface name or sw_if_index");
9880       return -99;
9881     }
9882
9883
9884   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
9885
9886   mp->sw_if_index = ntohl (sw_if_index);
9887   mp->ip4_table_index = ntohl (ip4_table_index);
9888   mp->ip6_table_index = ntohl (ip6_table_index);
9889   mp->other_table_index = ntohl (other_table_index);
9890   mp->is_input = (u8) is_input;
9891
9892   S (mp);
9893   W (ret);
9894   return ret;
9895 }
9896
9897 static int
9898 api_set_ipfix_exporter (vat_main_t * vam)
9899 {
9900   unformat_input_t *i = vam->input;
9901   vl_api_set_ipfix_exporter_t *mp;
9902   ip4_address_t collector_address;
9903   u8 collector_address_set = 0;
9904   u32 collector_port = ~0;
9905   ip4_address_t src_address;
9906   u8 src_address_set = 0;
9907   u32 vrf_id = ~0;
9908   u32 path_mtu = ~0;
9909   u32 template_interval = ~0;
9910   u8 udp_checksum = 0;
9911   int ret;
9912
9913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9914     {
9915       if (unformat (i, "collector_address %U", unformat_ip4_address,
9916                     &collector_address))
9917         collector_address_set = 1;
9918       else if (unformat (i, "collector_port %d", &collector_port))
9919         ;
9920       else if (unformat (i, "src_address %U", unformat_ip4_address,
9921                          &src_address))
9922         src_address_set = 1;
9923       else if (unformat (i, "vrf_id %d", &vrf_id))
9924         ;
9925       else if (unformat (i, "path_mtu %d", &path_mtu))
9926         ;
9927       else if (unformat (i, "template_interval %d", &template_interval))
9928         ;
9929       else if (unformat (i, "udp_checksum"))
9930         udp_checksum = 1;
9931       else
9932         break;
9933     }
9934
9935   if (collector_address_set == 0)
9936     {
9937       errmsg ("collector_address required");
9938       return -99;
9939     }
9940
9941   if (src_address_set == 0)
9942     {
9943       errmsg ("src_address required");
9944       return -99;
9945     }
9946
9947   M (SET_IPFIX_EXPORTER, mp);
9948
9949   memcpy (mp->collector_address, collector_address.data,
9950           sizeof (collector_address.data));
9951   mp->collector_port = htons ((u16) collector_port);
9952   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9953   mp->vrf_id = htonl (vrf_id);
9954   mp->path_mtu = htonl (path_mtu);
9955   mp->template_interval = htonl (template_interval);
9956   mp->udp_checksum = udp_checksum;
9957
9958   S (mp);
9959   W (ret);
9960   return ret;
9961 }
9962
9963 static int
9964 api_set_ipfix_classify_stream (vat_main_t * vam)
9965 {
9966   unformat_input_t *i = vam->input;
9967   vl_api_set_ipfix_classify_stream_t *mp;
9968   u32 domain_id = 0;
9969   u32 src_port = UDP_DST_PORT_ipfix;
9970   int ret;
9971
9972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9973     {
9974       if (unformat (i, "domain %d", &domain_id))
9975         ;
9976       else if (unformat (i, "src_port %d", &src_port))
9977         ;
9978       else
9979         {
9980           errmsg ("unknown input `%U'", format_unformat_error, i);
9981           return -99;
9982         }
9983     }
9984
9985   M (SET_IPFIX_CLASSIFY_STREAM, mp);
9986
9987   mp->domain_id = htonl (domain_id);
9988   mp->src_port = htons ((u16) src_port);
9989
9990   S (mp);
9991   W (ret);
9992   return ret;
9993 }
9994
9995 static int
9996 api_ipfix_classify_table_add_del (vat_main_t * vam)
9997 {
9998   unformat_input_t *i = vam->input;
9999   vl_api_ipfix_classify_table_add_del_t *mp;
10000   int is_add = -1;
10001   u32 classify_table_index = ~0;
10002   u8 ip_version = 0;
10003   u8 transport_protocol = 255;
10004   int ret;
10005
10006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10007     {
10008       if (unformat (i, "add"))
10009         is_add = 1;
10010       else if (unformat (i, "del"))
10011         is_add = 0;
10012       else if (unformat (i, "table %d", &classify_table_index))
10013         ;
10014       else if (unformat (i, "ip4"))
10015         ip_version = 4;
10016       else if (unformat (i, "ip6"))
10017         ip_version = 6;
10018       else if (unformat (i, "tcp"))
10019         transport_protocol = 6;
10020       else if (unformat (i, "udp"))
10021         transport_protocol = 17;
10022       else
10023         {
10024           errmsg ("unknown input `%U'", format_unformat_error, i);
10025           return -99;
10026         }
10027     }
10028
10029   if (is_add == -1)
10030     {
10031       errmsg ("expecting: add|del");
10032       return -99;
10033     }
10034   if (classify_table_index == ~0)
10035     {
10036       errmsg ("classifier table not specified");
10037       return -99;
10038     }
10039   if (ip_version == 0)
10040     {
10041       errmsg ("IP version not specified");
10042       return -99;
10043     }
10044
10045   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10046
10047   mp->is_add = is_add;
10048   mp->table_id = htonl (classify_table_index);
10049   mp->ip_version = ip_version;
10050   mp->transport_protocol = transport_protocol;
10051
10052   S (mp);
10053   W (ret);
10054   return ret;
10055 }
10056
10057 static int
10058 api_get_node_index (vat_main_t * vam)
10059 {
10060   unformat_input_t *i = vam->input;
10061   vl_api_get_node_index_t *mp;
10062   u8 *name = 0;
10063   int ret;
10064
10065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10066     {
10067       if (unformat (i, "node %s", &name))
10068         ;
10069       else
10070         break;
10071     }
10072   if (name == 0)
10073     {
10074       errmsg ("node name required");
10075       return -99;
10076     }
10077   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10078     {
10079       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10080       return -99;
10081     }
10082
10083   M (GET_NODE_INDEX, mp);
10084   clib_memcpy (mp->node_name, name, vec_len (name));
10085   vec_free (name);
10086
10087   S (mp);
10088   W (ret);
10089   return ret;
10090 }
10091
10092 static int
10093 api_get_next_index (vat_main_t * vam)
10094 {
10095   unformat_input_t *i = vam->input;
10096   vl_api_get_next_index_t *mp;
10097   u8 *node_name = 0, *next_node_name = 0;
10098   int ret;
10099
10100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10101     {
10102       if (unformat (i, "node-name %s", &node_name))
10103         ;
10104       else if (unformat (i, "next-node-name %s", &next_node_name))
10105         break;
10106     }
10107
10108   if (node_name == 0)
10109     {
10110       errmsg ("node name required");
10111       return -99;
10112     }
10113   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10114     {
10115       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10116       return -99;
10117     }
10118
10119   if (next_node_name == 0)
10120     {
10121       errmsg ("next node name required");
10122       return -99;
10123     }
10124   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10125     {
10126       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10127       return -99;
10128     }
10129
10130   M (GET_NEXT_INDEX, mp);
10131   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10132   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10133   vec_free (node_name);
10134   vec_free (next_node_name);
10135
10136   S (mp);
10137   W (ret);
10138   return ret;
10139 }
10140
10141 static int
10142 api_add_node_next (vat_main_t * vam)
10143 {
10144   unformat_input_t *i = vam->input;
10145   vl_api_add_node_next_t *mp;
10146   u8 *name = 0;
10147   u8 *next = 0;
10148   int ret;
10149
10150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10151     {
10152       if (unformat (i, "node %s", &name))
10153         ;
10154       else if (unformat (i, "next %s", &next))
10155         ;
10156       else
10157         break;
10158     }
10159   if (name == 0)
10160     {
10161       errmsg ("node name required");
10162       return -99;
10163     }
10164   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10165     {
10166       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10167       return -99;
10168     }
10169   if (next == 0)
10170     {
10171       errmsg ("next node required");
10172       return -99;
10173     }
10174   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10175     {
10176       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10177       return -99;
10178     }
10179
10180   M (ADD_NODE_NEXT, mp);
10181   clib_memcpy (mp->node_name, name, vec_len (name));
10182   clib_memcpy (mp->next_name, next, vec_len (next));
10183   vec_free (name);
10184   vec_free (next);
10185
10186   S (mp);
10187   W (ret);
10188   return ret;
10189 }
10190
10191 static int
10192 api_l2tpv3_create_tunnel (vat_main_t * vam)
10193 {
10194   unformat_input_t *i = vam->input;
10195   ip6_address_t client_address, our_address;
10196   int client_address_set = 0;
10197   int our_address_set = 0;
10198   u32 local_session_id = 0;
10199   u32 remote_session_id = 0;
10200   u64 local_cookie = 0;
10201   u64 remote_cookie = 0;
10202   u8 l2_sublayer_present = 0;
10203   vl_api_l2tpv3_create_tunnel_t *mp;
10204   int ret;
10205
10206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10207     {
10208       if (unformat (i, "client_address %U", unformat_ip6_address,
10209                     &client_address))
10210         client_address_set = 1;
10211       else if (unformat (i, "our_address %U", unformat_ip6_address,
10212                          &our_address))
10213         our_address_set = 1;
10214       else if (unformat (i, "local_session_id %d", &local_session_id))
10215         ;
10216       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10217         ;
10218       else if (unformat (i, "local_cookie %lld", &local_cookie))
10219         ;
10220       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10221         ;
10222       else if (unformat (i, "l2-sublayer-present"))
10223         l2_sublayer_present = 1;
10224       else
10225         break;
10226     }
10227
10228   if (client_address_set == 0)
10229     {
10230       errmsg ("client_address required");
10231       return -99;
10232     }
10233
10234   if (our_address_set == 0)
10235     {
10236       errmsg ("our_address required");
10237       return -99;
10238     }
10239
10240   M (L2TPV3_CREATE_TUNNEL, mp);
10241
10242   clib_memcpy (mp->client_address, client_address.as_u8,
10243                sizeof (mp->client_address));
10244
10245   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10246
10247   mp->local_session_id = ntohl (local_session_id);
10248   mp->remote_session_id = ntohl (remote_session_id);
10249   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10250   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10251   mp->l2_sublayer_present = l2_sublayer_present;
10252   mp->is_ipv6 = 1;
10253
10254   S (mp);
10255   W (ret);
10256   return ret;
10257 }
10258
10259 static int
10260 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10261 {
10262   unformat_input_t *i = vam->input;
10263   u32 sw_if_index;
10264   u8 sw_if_index_set = 0;
10265   u64 new_local_cookie = 0;
10266   u64 new_remote_cookie = 0;
10267   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10268   int ret;
10269
10270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10271     {
10272       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10273         sw_if_index_set = 1;
10274       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10275         sw_if_index_set = 1;
10276       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10277         ;
10278       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10279         ;
10280       else
10281         break;
10282     }
10283
10284   if (sw_if_index_set == 0)
10285     {
10286       errmsg ("missing interface name or sw_if_index");
10287       return -99;
10288     }
10289
10290   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10291
10292   mp->sw_if_index = ntohl (sw_if_index);
10293   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10294   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10295
10296   S (mp);
10297   W (ret);
10298   return ret;
10299 }
10300
10301 static int
10302 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10303 {
10304   unformat_input_t *i = vam->input;
10305   vl_api_l2tpv3_interface_enable_disable_t *mp;
10306   u32 sw_if_index;
10307   u8 sw_if_index_set = 0;
10308   u8 enable_disable = 1;
10309   int ret;
10310
10311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10312     {
10313       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10314         sw_if_index_set = 1;
10315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10316         sw_if_index_set = 1;
10317       else if (unformat (i, "enable"))
10318         enable_disable = 1;
10319       else if (unformat (i, "disable"))
10320         enable_disable = 0;
10321       else
10322         break;
10323     }
10324
10325   if (sw_if_index_set == 0)
10326     {
10327       errmsg ("missing interface name or sw_if_index");
10328       return -99;
10329     }
10330
10331   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10332
10333   mp->sw_if_index = ntohl (sw_if_index);
10334   mp->enable_disable = enable_disable;
10335
10336   S (mp);
10337   W (ret);
10338   return ret;
10339 }
10340
10341 static int
10342 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10343 {
10344   unformat_input_t *i = vam->input;
10345   vl_api_l2tpv3_set_lookup_key_t *mp;
10346   u8 key = ~0;
10347   int ret;
10348
10349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10350     {
10351       if (unformat (i, "lookup_v6_src"))
10352         key = L2T_LOOKUP_SRC_ADDRESS;
10353       else if (unformat (i, "lookup_v6_dst"))
10354         key = L2T_LOOKUP_DST_ADDRESS;
10355       else if (unformat (i, "lookup_session_id"))
10356         key = L2T_LOOKUP_SESSION_ID;
10357       else
10358         break;
10359     }
10360
10361   if (key == (u8) ~ 0)
10362     {
10363       errmsg ("l2tp session lookup key unset");
10364       return -99;
10365     }
10366
10367   M (L2TPV3_SET_LOOKUP_KEY, mp);
10368
10369   mp->key = key;
10370
10371   S (mp);
10372   W (ret);
10373   return ret;
10374 }
10375
10376 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10377   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10378 {
10379   vat_main_t *vam = &vat_main;
10380
10381   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10382          format_ip6_address, mp->our_address,
10383          format_ip6_address, mp->client_address,
10384          clib_net_to_host_u32 (mp->sw_if_index));
10385
10386   print (vam->ofp,
10387          "   local cookies %016llx %016llx remote cookie %016llx",
10388          clib_net_to_host_u64 (mp->local_cookie[0]),
10389          clib_net_to_host_u64 (mp->local_cookie[1]),
10390          clib_net_to_host_u64 (mp->remote_cookie));
10391
10392   print (vam->ofp, "   local session-id %d remote session-id %d",
10393          clib_net_to_host_u32 (mp->local_session_id),
10394          clib_net_to_host_u32 (mp->remote_session_id));
10395
10396   print (vam->ofp, "   l2 specific sublayer %s\n",
10397          mp->l2_sublayer_present ? "preset" : "absent");
10398
10399 }
10400
10401 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10402   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10403 {
10404   vat_main_t *vam = &vat_main;
10405   vat_json_node_t *node = NULL;
10406   struct in6_addr addr;
10407
10408   if (VAT_JSON_ARRAY != vam->json_tree.type)
10409     {
10410       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10411       vat_json_init_array (&vam->json_tree);
10412     }
10413   node = vat_json_array_add (&vam->json_tree);
10414
10415   vat_json_init_object (node);
10416
10417   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10418   vat_json_object_add_ip6 (node, "our_address", addr);
10419   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10420   vat_json_object_add_ip6 (node, "client_address", addr);
10421
10422   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10423   vat_json_init_array (lc);
10424   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10425   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10426   vat_json_object_add_uint (node, "remote_cookie",
10427                             clib_net_to_host_u64 (mp->remote_cookie));
10428
10429   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10430   vat_json_object_add_uint (node, "local_session_id",
10431                             clib_net_to_host_u32 (mp->local_session_id));
10432   vat_json_object_add_uint (node, "remote_session_id",
10433                             clib_net_to_host_u32 (mp->remote_session_id));
10434   vat_json_object_add_string_copy (node, "l2_sublayer",
10435                                    mp->l2_sublayer_present ? (u8 *) "present"
10436                                    : (u8 *) "absent");
10437 }
10438
10439 static int
10440 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10441 {
10442   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10443   vl_api_control_ping_t *mp_ping;
10444   int ret;
10445
10446   /* Get list of l2tpv3-tunnel interfaces */
10447   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10448   S (mp);
10449
10450   /* Use a control ping for synchronization */
10451   M (CONTROL_PING, mp_ping);
10452   S (mp_ping);
10453
10454   W (ret);
10455   return ret;
10456 }
10457
10458
10459 static void vl_api_sw_interface_tap_details_t_handler
10460   (vl_api_sw_interface_tap_details_t * mp)
10461 {
10462   vat_main_t *vam = &vat_main;
10463
10464   print (vam->ofp, "%-16s %d",
10465          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10466 }
10467
10468 static void vl_api_sw_interface_tap_details_t_handler_json
10469   (vl_api_sw_interface_tap_details_t * mp)
10470 {
10471   vat_main_t *vam = &vat_main;
10472   vat_json_node_t *node = NULL;
10473
10474   if (VAT_JSON_ARRAY != vam->json_tree.type)
10475     {
10476       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10477       vat_json_init_array (&vam->json_tree);
10478     }
10479   node = vat_json_array_add (&vam->json_tree);
10480
10481   vat_json_init_object (node);
10482   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10483   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10484 }
10485
10486 static int
10487 api_sw_interface_tap_dump (vat_main_t * vam)
10488 {
10489   vl_api_sw_interface_tap_dump_t *mp;
10490   vl_api_control_ping_t *mp_ping;
10491   int ret;
10492
10493   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10494   /* Get list of tap interfaces */
10495   M (SW_INTERFACE_TAP_DUMP, mp);
10496   S (mp);
10497
10498   /* Use a control ping for synchronization */
10499   M (CONTROL_PING, mp_ping);
10500   S (mp_ping);
10501
10502   W (ret);
10503   return ret;
10504 }
10505
10506 static uword unformat_vxlan_decap_next
10507   (unformat_input_t * input, va_list * args)
10508 {
10509   u32 *result = va_arg (*args, u32 *);
10510   u32 tmp;
10511
10512   if (unformat (input, "l2"))
10513     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10514   else if (unformat (input, "%d", &tmp))
10515     *result = tmp;
10516   else
10517     return 0;
10518   return 1;
10519 }
10520
10521 static int
10522 api_vxlan_add_del_tunnel (vat_main_t * vam)
10523 {
10524   unformat_input_t *line_input = vam->input;
10525   vl_api_vxlan_add_del_tunnel_t *mp;
10526   ip46_address_t src, dst;
10527   u8 is_add = 1;
10528   u8 ipv4_set = 0, ipv6_set = 0;
10529   u8 src_set = 0;
10530   u8 dst_set = 0;
10531   u8 grp_set = 0;
10532   u32 mcast_sw_if_index = ~0;
10533   u32 encap_vrf_id = 0;
10534   u32 decap_next_index = ~0;
10535   u32 vni = 0;
10536   int ret;
10537
10538   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10539   memset (&src, 0, sizeof src);
10540   memset (&dst, 0, sizeof dst);
10541
10542   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10543     {
10544       if (unformat (line_input, "del"))
10545         is_add = 0;
10546       else
10547         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10548         {
10549           ipv4_set = 1;
10550           src_set = 1;
10551         }
10552       else
10553         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10554         {
10555           ipv4_set = 1;
10556           dst_set = 1;
10557         }
10558       else
10559         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10560         {
10561           ipv6_set = 1;
10562           src_set = 1;
10563         }
10564       else
10565         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10566         {
10567           ipv6_set = 1;
10568           dst_set = 1;
10569         }
10570       else if (unformat (line_input, "group %U %U",
10571                          unformat_ip4_address, &dst.ip4,
10572                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10573         {
10574           grp_set = dst_set = 1;
10575           ipv4_set = 1;
10576         }
10577       else if (unformat (line_input, "group %U",
10578                          unformat_ip4_address, &dst.ip4))
10579         {
10580           grp_set = dst_set = 1;
10581           ipv4_set = 1;
10582         }
10583       else if (unformat (line_input, "group %U %U",
10584                          unformat_ip6_address, &dst.ip6,
10585                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10586         {
10587           grp_set = dst_set = 1;
10588           ipv6_set = 1;
10589         }
10590       else if (unformat (line_input, "group %U",
10591                          unformat_ip6_address, &dst.ip6))
10592         {
10593           grp_set = dst_set = 1;
10594           ipv6_set = 1;
10595         }
10596       else
10597         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10598         ;
10599       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10600         ;
10601       else if (unformat (line_input, "decap-next %U",
10602                          unformat_vxlan_decap_next, &decap_next_index))
10603         ;
10604       else if (unformat (line_input, "vni %d", &vni))
10605         ;
10606       else
10607         {
10608           errmsg ("parse error '%U'", format_unformat_error, line_input);
10609           return -99;
10610         }
10611     }
10612
10613   if (src_set == 0)
10614     {
10615       errmsg ("tunnel src address not specified");
10616       return -99;
10617     }
10618   if (dst_set == 0)
10619     {
10620       errmsg ("tunnel dst address not specified");
10621       return -99;
10622     }
10623
10624   if (grp_set && !ip46_address_is_multicast (&dst))
10625     {
10626       errmsg ("tunnel group address not multicast");
10627       return -99;
10628     }
10629   if (grp_set && mcast_sw_if_index == ~0)
10630     {
10631       errmsg ("tunnel nonexistent multicast device");
10632       return -99;
10633     }
10634   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10635     {
10636       errmsg ("tunnel dst address must be unicast");
10637       return -99;
10638     }
10639
10640
10641   if (ipv4_set && ipv6_set)
10642     {
10643       errmsg ("both IPv4 and IPv6 addresses specified");
10644       return -99;
10645     }
10646
10647   if ((vni == 0) || (vni >> 24))
10648     {
10649       errmsg ("vni not specified or out of range");
10650       return -99;
10651     }
10652
10653   M (VXLAN_ADD_DEL_TUNNEL, mp);
10654
10655   if (ipv6_set)
10656     {
10657       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10658       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10659     }
10660   else
10661     {
10662       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10663       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10664     }
10665   mp->encap_vrf_id = ntohl (encap_vrf_id);
10666   mp->decap_next_index = ntohl (decap_next_index);
10667   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10668   mp->vni = ntohl (vni);
10669   mp->is_add = is_add;
10670   mp->is_ipv6 = ipv6_set;
10671
10672   S (mp);
10673   W (ret);
10674   return ret;
10675 }
10676
10677 static void vl_api_vxlan_tunnel_details_t_handler
10678   (vl_api_vxlan_tunnel_details_t * mp)
10679 {
10680   vat_main_t *vam = &vat_main;
10681   ip46_address_t src, dst;
10682
10683   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10684   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10685
10686   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10687          ntohl (mp->sw_if_index),
10688          format_ip46_address, &src, IP46_TYPE_ANY,
10689          format_ip46_address, &dst, IP46_TYPE_ANY,
10690          ntohl (mp->encap_vrf_id),
10691          ntohl (mp->decap_next_index), ntohl (mp->vni),
10692          ntohl (mp->mcast_sw_if_index));
10693 }
10694
10695 static void vl_api_vxlan_tunnel_details_t_handler_json
10696   (vl_api_vxlan_tunnel_details_t * mp)
10697 {
10698   vat_main_t *vam = &vat_main;
10699   vat_json_node_t *node = NULL;
10700
10701   if (VAT_JSON_ARRAY != vam->json_tree.type)
10702     {
10703       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10704       vat_json_init_array (&vam->json_tree);
10705     }
10706   node = vat_json_array_add (&vam->json_tree);
10707
10708   vat_json_init_object (node);
10709   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10710   if (mp->is_ipv6)
10711     {
10712       struct in6_addr ip6;
10713
10714       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10715       vat_json_object_add_ip6 (node, "src_address", ip6);
10716       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10717       vat_json_object_add_ip6 (node, "dst_address", ip6);
10718     }
10719   else
10720     {
10721       struct in_addr ip4;
10722
10723       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10724       vat_json_object_add_ip4 (node, "src_address", ip4);
10725       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10726       vat_json_object_add_ip4 (node, "dst_address", ip4);
10727     }
10728   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10729   vat_json_object_add_uint (node, "decap_next_index",
10730                             ntohl (mp->decap_next_index));
10731   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10732   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10733   vat_json_object_add_uint (node, "mcast_sw_if_index",
10734                             ntohl (mp->mcast_sw_if_index));
10735 }
10736
10737 static int
10738 api_vxlan_tunnel_dump (vat_main_t * vam)
10739 {
10740   unformat_input_t *i = vam->input;
10741   vl_api_vxlan_tunnel_dump_t *mp;
10742   vl_api_control_ping_t *mp_ping;
10743   u32 sw_if_index;
10744   u8 sw_if_index_set = 0;
10745   int ret;
10746
10747   /* Parse args required to build the message */
10748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10749     {
10750       if (unformat (i, "sw_if_index %d", &sw_if_index))
10751         sw_if_index_set = 1;
10752       else
10753         break;
10754     }
10755
10756   if (sw_if_index_set == 0)
10757     {
10758       sw_if_index = ~0;
10759     }
10760
10761   if (!vam->json_output)
10762     {
10763       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10764              "sw_if_index", "src_address", "dst_address",
10765              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10766     }
10767
10768   /* Get list of vxlan-tunnel interfaces */
10769   M (VXLAN_TUNNEL_DUMP, mp);
10770
10771   mp->sw_if_index = htonl (sw_if_index);
10772
10773   S (mp);
10774
10775   /* Use a control ping for synchronization */
10776   M (CONTROL_PING, mp_ping);
10777   S (mp_ping);
10778
10779   W (ret);
10780   return ret;
10781 }
10782
10783 static int
10784 api_gre_add_del_tunnel (vat_main_t * vam)
10785 {
10786   unformat_input_t *line_input = vam->input;
10787   vl_api_gre_add_del_tunnel_t *mp;
10788   ip4_address_t src4, dst4;
10789   u8 is_add = 1;
10790   u8 teb = 0;
10791   u8 src_set = 0;
10792   u8 dst_set = 0;
10793   u32 outer_fib_id = 0;
10794   int ret;
10795
10796   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10797     {
10798       if (unformat (line_input, "del"))
10799         is_add = 0;
10800       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10801         src_set = 1;
10802       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10803         dst_set = 1;
10804       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10805         ;
10806       else if (unformat (line_input, "teb"))
10807         teb = 1;
10808       else
10809         {
10810           errmsg ("parse error '%U'", format_unformat_error, line_input);
10811           return -99;
10812         }
10813     }
10814
10815   if (src_set == 0)
10816     {
10817       errmsg ("tunnel src address not specified");
10818       return -99;
10819     }
10820   if (dst_set == 0)
10821     {
10822       errmsg ("tunnel dst address not specified");
10823       return -99;
10824     }
10825
10826
10827   M (GRE_ADD_DEL_TUNNEL, mp);
10828
10829   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10830   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10831   mp->outer_fib_id = ntohl (outer_fib_id);
10832   mp->is_add = is_add;
10833   mp->teb = teb;
10834
10835   S (mp);
10836   W (ret);
10837   return ret;
10838 }
10839
10840 static void vl_api_gre_tunnel_details_t_handler
10841   (vl_api_gre_tunnel_details_t * mp)
10842 {
10843   vat_main_t *vam = &vat_main;
10844
10845   print (vam->ofp, "%11d%15U%15U%6d%14d",
10846          ntohl (mp->sw_if_index),
10847          format_ip4_address, &mp->src_address,
10848          format_ip4_address, &mp->dst_address,
10849          mp->teb, ntohl (mp->outer_fib_id));
10850 }
10851
10852 static void vl_api_gre_tunnel_details_t_handler_json
10853   (vl_api_gre_tunnel_details_t * mp)
10854 {
10855   vat_main_t *vam = &vat_main;
10856   vat_json_node_t *node = NULL;
10857   struct in_addr ip4;
10858
10859   if (VAT_JSON_ARRAY != vam->json_tree.type)
10860     {
10861       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10862       vat_json_init_array (&vam->json_tree);
10863     }
10864   node = vat_json_array_add (&vam->json_tree);
10865
10866   vat_json_init_object (node);
10867   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10868   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10869   vat_json_object_add_ip4 (node, "src_address", ip4);
10870   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10871   vat_json_object_add_ip4 (node, "dst_address", ip4);
10872   vat_json_object_add_uint (node, "teb", mp->teb);
10873   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10874 }
10875
10876 static int
10877 api_gre_tunnel_dump (vat_main_t * vam)
10878 {
10879   unformat_input_t *i = vam->input;
10880   vl_api_gre_tunnel_dump_t *mp;
10881   vl_api_control_ping_t *mp_ping;
10882   u32 sw_if_index;
10883   u8 sw_if_index_set = 0;
10884   int ret;
10885
10886   /* Parse args required to build the message */
10887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10888     {
10889       if (unformat (i, "sw_if_index %d", &sw_if_index))
10890         sw_if_index_set = 1;
10891       else
10892         break;
10893     }
10894
10895   if (sw_if_index_set == 0)
10896     {
10897       sw_if_index = ~0;
10898     }
10899
10900   if (!vam->json_output)
10901     {
10902       print (vam->ofp, "%11s%15s%15s%6s%14s",
10903              "sw_if_index", "src_address", "dst_address", "teb",
10904              "outer_fib_id");
10905     }
10906
10907   /* Get list of gre-tunnel interfaces */
10908   M (GRE_TUNNEL_DUMP, mp);
10909
10910   mp->sw_if_index = htonl (sw_if_index);
10911
10912   S (mp);
10913
10914   /* Use a control ping for synchronization */
10915   M (CONTROL_PING, mp_ping);
10916   S (mp_ping);
10917
10918   W (ret);
10919   return ret;
10920 }
10921
10922 static int
10923 api_l2_fib_clear_table (vat_main_t * vam)
10924 {
10925 //  unformat_input_t * i = vam->input;
10926   vl_api_l2_fib_clear_table_t *mp;
10927   int ret;
10928
10929   M (L2_FIB_CLEAR_TABLE, mp);
10930
10931   S (mp);
10932   W (ret);
10933   return ret;
10934 }
10935
10936 static int
10937 api_l2_interface_efp_filter (vat_main_t * vam)
10938 {
10939   unformat_input_t *i = vam->input;
10940   vl_api_l2_interface_efp_filter_t *mp;
10941   u32 sw_if_index;
10942   u8 enable = 1;
10943   u8 sw_if_index_set = 0;
10944   int ret;
10945
10946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10947     {
10948       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10949         sw_if_index_set = 1;
10950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10951         sw_if_index_set = 1;
10952       else if (unformat (i, "enable"))
10953         enable = 1;
10954       else if (unformat (i, "disable"))
10955         enable = 0;
10956       else
10957         {
10958           clib_warning ("parse error '%U'", format_unformat_error, i);
10959           return -99;
10960         }
10961     }
10962
10963   if (sw_if_index_set == 0)
10964     {
10965       errmsg ("missing sw_if_index");
10966       return -99;
10967     }
10968
10969   M (L2_INTERFACE_EFP_FILTER, mp);
10970
10971   mp->sw_if_index = ntohl (sw_if_index);
10972   mp->enable_disable = enable;
10973
10974   S (mp);
10975   W (ret);
10976   return ret;
10977 }
10978
10979 #define foreach_vtr_op                          \
10980 _("disable",  L2_VTR_DISABLED)                  \
10981 _("push-1",  L2_VTR_PUSH_1)                     \
10982 _("push-2",  L2_VTR_PUSH_2)                     \
10983 _("pop-1",  L2_VTR_POP_1)                       \
10984 _("pop-2",  L2_VTR_POP_2)                       \
10985 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10986 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10987 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10988 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10989
10990 static int
10991 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10992 {
10993   unformat_input_t *i = vam->input;
10994   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10995   u32 sw_if_index;
10996   u8 sw_if_index_set = 0;
10997   u8 vtr_op_set = 0;
10998   u32 vtr_op = 0;
10999   u32 push_dot1q = 1;
11000   u32 tag1 = ~0;
11001   u32 tag2 = ~0;
11002   int ret;
11003
11004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11005     {
11006       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11007         sw_if_index_set = 1;
11008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11009         sw_if_index_set = 1;
11010       else if (unformat (i, "vtr_op %d", &vtr_op))
11011         vtr_op_set = 1;
11012 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11013       foreach_vtr_op
11014 #undef _
11015         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11016         ;
11017       else if (unformat (i, "tag1 %d", &tag1))
11018         ;
11019       else if (unformat (i, "tag2 %d", &tag2))
11020         ;
11021       else
11022         {
11023           clib_warning ("parse error '%U'", format_unformat_error, i);
11024           return -99;
11025         }
11026     }
11027
11028   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11029     {
11030       errmsg ("missing vtr operation or sw_if_index");
11031       return -99;
11032     }
11033
11034   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11035   mp->sw_if_index = ntohl (sw_if_index);
11036   mp->vtr_op = ntohl (vtr_op);
11037   mp->push_dot1q = ntohl (push_dot1q);
11038   mp->tag1 = ntohl (tag1);
11039   mp->tag2 = ntohl (tag2);
11040
11041   S (mp);
11042   W (ret);
11043   return ret;
11044 }
11045
11046 static int
11047 api_create_vhost_user_if (vat_main_t * vam)
11048 {
11049   unformat_input_t *i = vam->input;
11050   vl_api_create_vhost_user_if_t *mp;
11051   u8 *file_name;
11052   u8 is_server = 0;
11053   u8 file_name_set = 0;
11054   u32 custom_dev_instance = ~0;
11055   u8 hwaddr[6];
11056   u8 use_custom_mac = 0;
11057   u8 *tag = 0;
11058   int ret;
11059
11060   /* Shut up coverity */
11061   memset (hwaddr, 0, sizeof (hwaddr));
11062
11063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11064     {
11065       if (unformat (i, "socket %s", &file_name))
11066         {
11067           file_name_set = 1;
11068         }
11069       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11070         ;
11071       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11072         use_custom_mac = 1;
11073       else if (unformat (i, "server"))
11074         is_server = 1;
11075       else if (unformat (i, "tag %s", &tag))
11076         ;
11077       else
11078         break;
11079     }
11080
11081   if (file_name_set == 0)
11082     {
11083       errmsg ("missing socket file name");
11084       return -99;
11085     }
11086
11087   if (vec_len (file_name) > 255)
11088     {
11089       errmsg ("socket file name too long");
11090       return -99;
11091     }
11092   vec_add1 (file_name, 0);
11093
11094   M (CREATE_VHOST_USER_IF, mp);
11095
11096   mp->is_server = is_server;
11097   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11098   vec_free (file_name);
11099   if (custom_dev_instance != ~0)
11100     {
11101       mp->renumber = 1;
11102       mp->custom_dev_instance = ntohl (custom_dev_instance);
11103     }
11104   mp->use_custom_mac = use_custom_mac;
11105   clib_memcpy (mp->mac_address, hwaddr, 6);
11106   if (tag)
11107     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11108   vec_free (tag);
11109
11110   S (mp);
11111   W (ret);
11112   return ret;
11113 }
11114
11115 static int
11116 api_modify_vhost_user_if (vat_main_t * vam)
11117 {
11118   unformat_input_t *i = vam->input;
11119   vl_api_modify_vhost_user_if_t *mp;
11120   u8 *file_name;
11121   u8 is_server = 0;
11122   u8 file_name_set = 0;
11123   u32 custom_dev_instance = ~0;
11124   u8 sw_if_index_set = 0;
11125   u32 sw_if_index = (u32) ~ 0;
11126   int ret;
11127
11128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11129     {
11130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11131         sw_if_index_set = 1;
11132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11133         sw_if_index_set = 1;
11134       else if (unformat (i, "socket %s", &file_name))
11135         {
11136           file_name_set = 1;
11137         }
11138       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11139         ;
11140       else if (unformat (i, "server"))
11141         is_server = 1;
11142       else
11143         break;
11144     }
11145
11146   if (sw_if_index_set == 0)
11147     {
11148       errmsg ("missing sw_if_index or interface name");
11149       return -99;
11150     }
11151
11152   if (file_name_set == 0)
11153     {
11154       errmsg ("missing socket file name");
11155       return -99;
11156     }
11157
11158   if (vec_len (file_name) > 255)
11159     {
11160       errmsg ("socket file name too long");
11161       return -99;
11162     }
11163   vec_add1 (file_name, 0);
11164
11165   M (MODIFY_VHOST_USER_IF, mp);
11166
11167   mp->sw_if_index = ntohl (sw_if_index);
11168   mp->is_server = is_server;
11169   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11170   vec_free (file_name);
11171   if (custom_dev_instance != ~0)
11172     {
11173       mp->renumber = 1;
11174       mp->custom_dev_instance = ntohl (custom_dev_instance);
11175     }
11176
11177   S (mp);
11178   W (ret);
11179   return ret;
11180 }
11181
11182 static int
11183 api_delete_vhost_user_if (vat_main_t * vam)
11184 {
11185   unformat_input_t *i = vam->input;
11186   vl_api_delete_vhost_user_if_t *mp;
11187   u32 sw_if_index = ~0;
11188   u8 sw_if_index_set = 0;
11189   int ret;
11190
11191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11192     {
11193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11194         sw_if_index_set = 1;
11195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11196         sw_if_index_set = 1;
11197       else
11198         break;
11199     }
11200
11201   if (sw_if_index_set == 0)
11202     {
11203       errmsg ("missing sw_if_index or interface name");
11204       return -99;
11205     }
11206
11207
11208   M (DELETE_VHOST_USER_IF, mp);
11209
11210   mp->sw_if_index = ntohl (sw_if_index);
11211
11212   S (mp);
11213   W (ret);
11214   return ret;
11215 }
11216
11217 static void vl_api_sw_interface_vhost_user_details_t_handler
11218   (vl_api_sw_interface_vhost_user_details_t * mp)
11219 {
11220   vat_main_t *vam = &vat_main;
11221
11222   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11223          (char *) mp->interface_name,
11224          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11225          clib_net_to_host_u64 (mp->features), mp->is_server,
11226          ntohl (mp->num_regions), (char *) mp->sock_filename);
11227   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11228 }
11229
11230 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11231   (vl_api_sw_interface_vhost_user_details_t * mp)
11232 {
11233   vat_main_t *vam = &vat_main;
11234   vat_json_node_t *node = NULL;
11235
11236   if (VAT_JSON_ARRAY != vam->json_tree.type)
11237     {
11238       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11239       vat_json_init_array (&vam->json_tree);
11240     }
11241   node = vat_json_array_add (&vam->json_tree);
11242
11243   vat_json_init_object (node);
11244   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11245   vat_json_object_add_string_copy (node, "interface_name",
11246                                    mp->interface_name);
11247   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11248                             ntohl (mp->virtio_net_hdr_sz));
11249   vat_json_object_add_uint (node, "features",
11250                             clib_net_to_host_u64 (mp->features));
11251   vat_json_object_add_uint (node, "is_server", mp->is_server);
11252   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11253   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11254   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11255 }
11256
11257 static int
11258 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11259 {
11260   vl_api_sw_interface_vhost_user_dump_t *mp;
11261   vl_api_control_ping_t *mp_ping;
11262   int ret;
11263   print (vam->ofp,
11264          "Interface name           idx hdr_sz features server regions filename");
11265
11266   /* Get list of vhost-user interfaces */
11267   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11268   S (mp);
11269
11270   /* Use a control ping for synchronization */
11271   M (CONTROL_PING, mp_ping);
11272   S (mp_ping);
11273
11274   W (ret);
11275   return ret;
11276 }
11277
11278 static int
11279 api_show_version (vat_main_t * vam)
11280 {
11281   vl_api_show_version_t *mp;
11282   int ret;
11283
11284   M (SHOW_VERSION, mp);
11285
11286   S (mp);
11287   W (ret);
11288   return ret;
11289 }
11290
11291
11292 static int
11293 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11294 {
11295   unformat_input_t *line_input = vam->input;
11296   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11297   ip4_address_t local4, remote4;
11298   ip6_address_t local6, remote6;
11299   u8 is_add = 1;
11300   u8 ipv4_set = 0, ipv6_set = 0;
11301   u8 local_set = 0;
11302   u8 remote_set = 0;
11303   u32 encap_vrf_id = 0;
11304   u32 decap_vrf_id = 0;
11305   u8 protocol = ~0;
11306   u32 vni;
11307   u8 vni_set = 0;
11308   int ret;
11309
11310   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11311     {
11312       if (unformat (line_input, "del"))
11313         is_add = 0;
11314       else if (unformat (line_input, "local %U",
11315                          unformat_ip4_address, &local4))
11316         {
11317           local_set = 1;
11318           ipv4_set = 1;
11319         }
11320       else if (unformat (line_input, "remote %U",
11321                          unformat_ip4_address, &remote4))
11322         {
11323           remote_set = 1;
11324           ipv4_set = 1;
11325         }
11326       else if (unformat (line_input, "local %U",
11327                          unformat_ip6_address, &local6))
11328         {
11329           local_set = 1;
11330           ipv6_set = 1;
11331         }
11332       else if (unformat (line_input, "remote %U",
11333                          unformat_ip6_address, &remote6))
11334         {
11335           remote_set = 1;
11336           ipv6_set = 1;
11337         }
11338       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11339         ;
11340       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11341         ;
11342       else if (unformat (line_input, "vni %d", &vni))
11343         vni_set = 1;
11344       else if (unformat (line_input, "next-ip4"))
11345         protocol = 1;
11346       else if (unformat (line_input, "next-ip6"))
11347         protocol = 2;
11348       else if (unformat (line_input, "next-ethernet"))
11349         protocol = 3;
11350       else if (unformat (line_input, "next-nsh"))
11351         protocol = 4;
11352       else
11353         {
11354           errmsg ("parse error '%U'", format_unformat_error, line_input);
11355           return -99;
11356         }
11357     }
11358
11359   if (local_set == 0)
11360     {
11361       errmsg ("tunnel local address not specified");
11362       return -99;
11363     }
11364   if (remote_set == 0)
11365     {
11366       errmsg ("tunnel remote address not specified");
11367       return -99;
11368     }
11369   if (ipv4_set && ipv6_set)
11370     {
11371       errmsg ("both IPv4 and IPv6 addresses specified");
11372       return -99;
11373     }
11374
11375   if (vni_set == 0)
11376     {
11377       errmsg ("vni not specified");
11378       return -99;
11379     }
11380
11381   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11382
11383
11384   if (ipv6_set)
11385     {
11386       clib_memcpy (&mp->local, &local6, sizeof (local6));
11387       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11388     }
11389   else
11390     {
11391       clib_memcpy (&mp->local, &local4, sizeof (local4));
11392       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11393     }
11394
11395   mp->encap_vrf_id = ntohl (encap_vrf_id);
11396   mp->decap_vrf_id = ntohl (decap_vrf_id);
11397   mp->protocol = protocol;
11398   mp->vni = ntohl (vni);
11399   mp->is_add = is_add;
11400   mp->is_ipv6 = ipv6_set;
11401
11402   S (mp);
11403   W (ret);
11404   return ret;
11405 }
11406
11407 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11408   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11409 {
11410   vat_main_t *vam = &vat_main;
11411
11412   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11413          ntohl (mp->sw_if_index),
11414          format_ip46_address, &(mp->local[0]),
11415          format_ip46_address, &(mp->remote[0]),
11416          ntohl (mp->vni),
11417          ntohl (mp->protocol),
11418          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11419 }
11420
11421 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11422   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11423 {
11424   vat_main_t *vam = &vat_main;
11425   vat_json_node_t *node = NULL;
11426   struct in_addr ip4;
11427   struct in6_addr ip6;
11428
11429   if (VAT_JSON_ARRAY != vam->json_tree.type)
11430     {
11431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11432       vat_json_init_array (&vam->json_tree);
11433     }
11434   node = vat_json_array_add (&vam->json_tree);
11435
11436   vat_json_init_object (node);
11437   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11438   if (mp->is_ipv6)
11439     {
11440       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11441       vat_json_object_add_ip6 (node, "local", ip6);
11442       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11443       vat_json_object_add_ip6 (node, "remote", ip6);
11444     }
11445   else
11446     {
11447       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11448       vat_json_object_add_ip4 (node, "local", ip4);
11449       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11450       vat_json_object_add_ip4 (node, "remote", ip4);
11451     }
11452   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11453   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11454   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11455   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11456   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11457 }
11458
11459 static int
11460 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11461 {
11462   unformat_input_t *i = vam->input;
11463   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11464   vl_api_control_ping_t *mp_ping;
11465   u32 sw_if_index;
11466   u8 sw_if_index_set = 0;
11467   int ret;
11468
11469   /* Parse args required to build the message */
11470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11471     {
11472       if (unformat (i, "sw_if_index %d", &sw_if_index))
11473         sw_if_index_set = 1;
11474       else
11475         break;
11476     }
11477
11478   if (sw_if_index_set == 0)
11479     {
11480       sw_if_index = ~0;
11481     }
11482
11483   if (!vam->json_output)
11484     {
11485       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11486              "sw_if_index", "local", "remote", "vni",
11487              "protocol", "encap_vrf_id", "decap_vrf_id");
11488     }
11489
11490   /* Get list of vxlan-tunnel interfaces */
11491   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11492
11493   mp->sw_if_index = htonl (sw_if_index);
11494
11495   S (mp);
11496
11497   /* Use a control ping for synchronization */
11498   M (CONTROL_PING, mp_ping);
11499   S (mp_ping);
11500
11501   W (ret);
11502   return ret;
11503 }
11504
11505 u8 *
11506 format_l2_fib_mac_address (u8 * s, va_list * args)
11507 {
11508   u8 *a = va_arg (*args, u8 *);
11509
11510   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11511                  a[2], a[3], a[4], a[5], a[6], a[7]);
11512 }
11513
11514 static void vl_api_l2_fib_table_entry_t_handler
11515   (vl_api_l2_fib_table_entry_t * mp)
11516 {
11517   vat_main_t *vam = &vat_main;
11518
11519   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11520          "       %d       %d     %d",
11521          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11522          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11523          mp->bvi_mac);
11524 }
11525
11526 static void vl_api_l2_fib_table_entry_t_handler_json
11527   (vl_api_l2_fib_table_entry_t * mp)
11528 {
11529   vat_main_t *vam = &vat_main;
11530   vat_json_node_t *node = NULL;
11531
11532   if (VAT_JSON_ARRAY != vam->json_tree.type)
11533     {
11534       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11535       vat_json_init_array (&vam->json_tree);
11536     }
11537   node = vat_json_array_add (&vam->json_tree);
11538
11539   vat_json_init_object (node);
11540   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11541   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11542   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11543   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11544   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11545   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11546 }
11547
11548 static int
11549 api_l2_fib_table_dump (vat_main_t * vam)
11550 {
11551   unformat_input_t *i = vam->input;
11552   vl_api_l2_fib_table_dump_t *mp;
11553   vl_api_control_ping_t *mp_ping;
11554   u32 bd_id;
11555   u8 bd_id_set = 0;
11556   int ret;
11557
11558   /* Parse args required to build the message */
11559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11560     {
11561       if (unformat (i, "bd_id %d", &bd_id))
11562         bd_id_set = 1;
11563       else
11564         break;
11565     }
11566
11567   if (bd_id_set == 0)
11568     {
11569       errmsg ("missing bridge domain");
11570       return -99;
11571     }
11572
11573   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11574
11575   /* Get list of l2 fib entries */
11576   M (L2_FIB_TABLE_DUMP, mp);
11577
11578   mp->bd_id = ntohl (bd_id);
11579   S (mp);
11580
11581   /* Use a control ping for synchronization */
11582   M (CONTROL_PING, mp_ping);
11583   S (mp_ping);
11584
11585   W (ret);
11586   return ret;
11587 }
11588
11589
11590 static int
11591 api_interface_name_renumber (vat_main_t * vam)
11592 {
11593   unformat_input_t *line_input = vam->input;
11594   vl_api_interface_name_renumber_t *mp;
11595   u32 sw_if_index = ~0;
11596   u32 new_show_dev_instance = ~0;
11597   int ret;
11598
11599   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11600     {
11601       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11602                     &sw_if_index))
11603         ;
11604       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11605         ;
11606       else if (unformat (line_input, "new_show_dev_instance %d",
11607                          &new_show_dev_instance))
11608         ;
11609       else
11610         break;
11611     }
11612
11613   if (sw_if_index == ~0)
11614     {
11615       errmsg ("missing interface name or sw_if_index");
11616       return -99;
11617     }
11618
11619   if (new_show_dev_instance == ~0)
11620     {
11621       errmsg ("missing new_show_dev_instance");
11622       return -99;
11623     }
11624
11625   M (INTERFACE_NAME_RENUMBER, mp);
11626
11627   mp->sw_if_index = ntohl (sw_if_index);
11628   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11629
11630   S (mp);
11631   W (ret);
11632   return ret;
11633 }
11634
11635 static int
11636 api_want_ip4_arp_events (vat_main_t * vam)
11637 {
11638   unformat_input_t *line_input = vam->input;
11639   vl_api_want_ip4_arp_events_t *mp;
11640   ip4_address_t address;
11641   int address_set = 0;
11642   u32 enable_disable = 1;
11643   int ret;
11644
11645   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11646     {
11647       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11648         address_set = 1;
11649       else if (unformat (line_input, "del"))
11650         enable_disable = 0;
11651       else
11652         break;
11653     }
11654
11655   if (address_set == 0)
11656     {
11657       errmsg ("missing addresses");
11658       return -99;
11659     }
11660
11661   M (WANT_IP4_ARP_EVENTS, mp);
11662   mp->enable_disable = enable_disable;
11663   mp->pid = getpid ();
11664   mp->address = address.as_u32;
11665
11666   S (mp);
11667   W (ret);
11668   return ret;
11669 }
11670
11671 static int
11672 api_want_ip6_nd_events (vat_main_t * vam)
11673 {
11674   unformat_input_t *line_input = vam->input;
11675   vl_api_want_ip6_nd_events_t *mp;
11676   ip6_address_t address;
11677   int address_set = 0;
11678   u32 enable_disable = 1;
11679   int ret;
11680
11681   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11682     {
11683       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11684         address_set = 1;
11685       else if (unformat (line_input, "del"))
11686         enable_disable = 0;
11687       else
11688         break;
11689     }
11690
11691   if (address_set == 0)
11692     {
11693       errmsg ("missing addresses");
11694       return -99;
11695     }
11696
11697   M (WANT_IP6_ND_EVENTS, mp);
11698   mp->enable_disable = enable_disable;
11699   mp->pid = getpid ();
11700   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11701
11702   S (mp);
11703   W (ret);
11704   return ret;
11705 }
11706
11707 static int
11708 api_input_acl_set_interface (vat_main_t * vam)
11709 {
11710   unformat_input_t *i = vam->input;
11711   vl_api_input_acl_set_interface_t *mp;
11712   u32 sw_if_index;
11713   int sw_if_index_set;
11714   u32 ip4_table_index = ~0;
11715   u32 ip6_table_index = ~0;
11716   u32 l2_table_index = ~0;
11717   u8 is_add = 1;
11718   int ret;
11719
11720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11721     {
11722       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11723         sw_if_index_set = 1;
11724       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11725         sw_if_index_set = 1;
11726       else if (unformat (i, "del"))
11727         is_add = 0;
11728       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11729         ;
11730       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11731         ;
11732       else if (unformat (i, "l2-table %d", &l2_table_index))
11733         ;
11734       else
11735         {
11736           clib_warning ("parse error '%U'", format_unformat_error, i);
11737           return -99;
11738         }
11739     }
11740
11741   if (sw_if_index_set == 0)
11742     {
11743       errmsg ("missing interface name or sw_if_index");
11744       return -99;
11745     }
11746
11747   M (INPUT_ACL_SET_INTERFACE, mp);
11748
11749   mp->sw_if_index = ntohl (sw_if_index);
11750   mp->ip4_table_index = ntohl (ip4_table_index);
11751   mp->ip6_table_index = ntohl (ip6_table_index);
11752   mp->l2_table_index = ntohl (l2_table_index);
11753   mp->is_add = is_add;
11754
11755   S (mp);
11756   W (ret);
11757   return ret;
11758 }
11759
11760 static int
11761 api_ip_address_dump (vat_main_t * vam)
11762 {
11763   unformat_input_t *i = vam->input;
11764   vl_api_ip_address_dump_t *mp;
11765   vl_api_control_ping_t *mp_ping;
11766   u32 sw_if_index = ~0;
11767   u8 sw_if_index_set = 0;
11768   u8 ipv4_set = 0;
11769   u8 ipv6_set = 0;
11770   int ret;
11771
11772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11773     {
11774       if (unformat (i, "sw_if_index %d", &sw_if_index))
11775         sw_if_index_set = 1;
11776       else
11777         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11778         sw_if_index_set = 1;
11779       else if (unformat (i, "ipv4"))
11780         ipv4_set = 1;
11781       else if (unformat (i, "ipv6"))
11782         ipv6_set = 1;
11783       else
11784         break;
11785     }
11786
11787   if (ipv4_set && ipv6_set)
11788     {
11789       errmsg ("ipv4 and ipv6 flags cannot be both set");
11790       return -99;
11791     }
11792
11793   if ((!ipv4_set) && (!ipv6_set))
11794     {
11795       errmsg ("no ipv4 nor ipv6 flag set");
11796       return -99;
11797     }
11798
11799   if (sw_if_index_set == 0)
11800     {
11801       errmsg ("missing interface name or sw_if_index");
11802       return -99;
11803     }
11804
11805   vam->current_sw_if_index = sw_if_index;
11806   vam->is_ipv6 = ipv6_set;
11807
11808   M (IP_ADDRESS_DUMP, mp);
11809   mp->sw_if_index = ntohl (sw_if_index);
11810   mp->is_ipv6 = ipv6_set;
11811   S (mp);
11812
11813   /* Use a control ping for synchronization */
11814   M (CONTROL_PING, mp_ping);
11815   S (mp_ping);
11816
11817   W (ret);
11818   return ret;
11819 }
11820
11821 static int
11822 api_ip_dump (vat_main_t * vam)
11823 {
11824   vl_api_ip_dump_t *mp;
11825   vl_api_control_ping_t *mp_ping;
11826   unformat_input_t *in = vam->input;
11827   int ipv4_set = 0;
11828   int ipv6_set = 0;
11829   int is_ipv6;
11830   int i;
11831   int ret;
11832
11833   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11834     {
11835       if (unformat (in, "ipv4"))
11836         ipv4_set = 1;
11837       else if (unformat (in, "ipv6"))
11838         ipv6_set = 1;
11839       else
11840         break;
11841     }
11842
11843   if (ipv4_set && ipv6_set)
11844     {
11845       errmsg ("ipv4 and ipv6 flags cannot be both set");
11846       return -99;
11847     }
11848
11849   if ((!ipv4_set) && (!ipv6_set))
11850     {
11851       errmsg ("no ipv4 nor ipv6 flag set");
11852       return -99;
11853     }
11854
11855   is_ipv6 = ipv6_set;
11856   vam->is_ipv6 = is_ipv6;
11857
11858   /* free old data */
11859   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11860     {
11861       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11862     }
11863   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11864
11865   M (IP_DUMP, mp);
11866   mp->is_ipv6 = ipv6_set;
11867   S (mp);
11868
11869   /* Use a control ping for synchronization */
11870   M (CONTROL_PING, mp_ping);
11871   S (mp_ping);
11872
11873   W (ret);
11874   return ret;
11875 }
11876
11877 static int
11878 api_ipsec_spd_add_del (vat_main_t * vam)
11879 {
11880   unformat_input_t *i = vam->input;
11881   vl_api_ipsec_spd_add_del_t *mp;
11882   u32 spd_id = ~0;
11883   u8 is_add = 1;
11884   int ret;
11885
11886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11887     {
11888       if (unformat (i, "spd_id %d", &spd_id))
11889         ;
11890       else if (unformat (i, "del"))
11891         is_add = 0;
11892       else
11893         {
11894           clib_warning ("parse error '%U'", format_unformat_error, i);
11895           return -99;
11896         }
11897     }
11898   if (spd_id == ~0)
11899     {
11900       errmsg ("spd_id must be set");
11901       return -99;
11902     }
11903
11904   M (IPSEC_SPD_ADD_DEL, mp);
11905
11906   mp->spd_id = ntohl (spd_id);
11907   mp->is_add = is_add;
11908
11909   S (mp);
11910   W (ret);
11911   return ret;
11912 }
11913
11914 static int
11915 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11916 {
11917   unformat_input_t *i = vam->input;
11918   vl_api_ipsec_interface_add_del_spd_t *mp;
11919   u32 sw_if_index;
11920   u8 sw_if_index_set = 0;
11921   u32 spd_id = (u32) ~ 0;
11922   u8 is_add = 1;
11923   int ret;
11924
11925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11926     {
11927       if (unformat (i, "del"))
11928         is_add = 0;
11929       else if (unformat (i, "spd_id %d", &spd_id))
11930         ;
11931       else
11932         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11933         sw_if_index_set = 1;
11934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11935         sw_if_index_set = 1;
11936       else
11937         {
11938           clib_warning ("parse error '%U'", format_unformat_error, i);
11939           return -99;
11940         }
11941
11942     }
11943
11944   if (spd_id == (u32) ~ 0)
11945     {
11946       errmsg ("spd_id must be set");
11947       return -99;
11948     }
11949
11950   if (sw_if_index_set == 0)
11951     {
11952       errmsg ("missing interface name or sw_if_index");
11953       return -99;
11954     }
11955
11956   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
11957
11958   mp->spd_id = ntohl (spd_id);
11959   mp->sw_if_index = ntohl (sw_if_index);
11960   mp->is_add = is_add;
11961
11962   S (mp);
11963   W (ret);
11964   return ret;
11965 }
11966
11967 static int
11968 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11969 {
11970   unformat_input_t *i = vam->input;
11971   vl_api_ipsec_spd_add_del_entry_t *mp;
11972   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11973   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11974   i32 priority = 0;
11975   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11976   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11977   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11978   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11979   int ret;
11980
11981   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11982   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11983   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11984   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11985   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11986   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11987
11988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11989     {
11990       if (unformat (i, "del"))
11991         is_add = 0;
11992       if (unformat (i, "outbound"))
11993         is_outbound = 1;
11994       if (unformat (i, "inbound"))
11995         is_outbound = 0;
11996       else if (unformat (i, "spd_id %d", &spd_id))
11997         ;
11998       else if (unformat (i, "sa_id %d", &sa_id))
11999         ;
12000       else if (unformat (i, "priority %d", &priority))
12001         ;
12002       else if (unformat (i, "protocol %d", &protocol))
12003         ;
12004       else if (unformat (i, "lport_start %d", &lport_start))
12005         ;
12006       else if (unformat (i, "lport_stop %d", &lport_stop))
12007         ;
12008       else if (unformat (i, "rport_start %d", &rport_start))
12009         ;
12010       else if (unformat (i, "rport_stop %d", &rport_stop))
12011         ;
12012       else
12013         if (unformat
12014             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12015         {
12016           is_ipv6 = 0;
12017           is_ip_any = 0;
12018         }
12019       else
12020         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12021         {
12022           is_ipv6 = 0;
12023           is_ip_any = 0;
12024         }
12025       else
12026         if (unformat
12027             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12028         {
12029           is_ipv6 = 0;
12030           is_ip_any = 0;
12031         }
12032       else
12033         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12034         {
12035           is_ipv6 = 0;
12036           is_ip_any = 0;
12037         }
12038       else
12039         if (unformat
12040             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12041         {
12042           is_ipv6 = 1;
12043           is_ip_any = 0;
12044         }
12045       else
12046         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12047         {
12048           is_ipv6 = 1;
12049           is_ip_any = 0;
12050         }
12051       else
12052         if (unformat
12053             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12054         {
12055           is_ipv6 = 1;
12056           is_ip_any = 0;
12057         }
12058       else
12059         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12060         {
12061           is_ipv6 = 1;
12062           is_ip_any = 0;
12063         }
12064       else
12065         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12066         {
12067           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12068             {
12069               clib_warning ("unsupported action: 'resolve'");
12070               return -99;
12071             }
12072         }
12073       else
12074         {
12075           clib_warning ("parse error '%U'", format_unformat_error, i);
12076           return -99;
12077         }
12078
12079     }
12080
12081   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12082
12083   mp->spd_id = ntohl (spd_id);
12084   mp->priority = ntohl (priority);
12085   mp->is_outbound = is_outbound;
12086
12087   mp->is_ipv6 = is_ipv6;
12088   if (is_ipv6 || is_ip_any)
12089     {
12090       clib_memcpy (mp->remote_address_start, &raddr6_start,
12091                    sizeof (ip6_address_t));
12092       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12093                    sizeof (ip6_address_t));
12094       clib_memcpy (mp->local_address_start, &laddr6_start,
12095                    sizeof (ip6_address_t));
12096       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12097                    sizeof (ip6_address_t));
12098     }
12099   else
12100     {
12101       clib_memcpy (mp->remote_address_start, &raddr4_start,
12102                    sizeof (ip4_address_t));
12103       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12104                    sizeof (ip4_address_t));
12105       clib_memcpy (mp->local_address_start, &laddr4_start,
12106                    sizeof (ip4_address_t));
12107       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12108                    sizeof (ip4_address_t));
12109     }
12110   mp->protocol = (u8) protocol;
12111   mp->local_port_start = ntohs ((u16) lport_start);
12112   mp->local_port_stop = ntohs ((u16) lport_stop);
12113   mp->remote_port_start = ntohs ((u16) rport_start);
12114   mp->remote_port_stop = ntohs ((u16) rport_stop);
12115   mp->policy = (u8) policy;
12116   mp->sa_id = ntohl (sa_id);
12117   mp->is_add = is_add;
12118   mp->is_ip_any = is_ip_any;
12119   S (mp);
12120   W (ret);
12121   return ret;
12122 }
12123
12124 static int
12125 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12126 {
12127   unformat_input_t *i = vam->input;
12128   vl_api_ipsec_sad_add_del_entry_t *mp;
12129   u32 sad_id = 0, spi = 0;
12130   u8 *ck = 0, *ik = 0;
12131   u8 is_add = 1;
12132
12133   u8 protocol = IPSEC_PROTOCOL_AH;
12134   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12135   u32 crypto_alg = 0, integ_alg = 0;
12136   ip4_address_t tun_src4;
12137   ip4_address_t tun_dst4;
12138   ip6_address_t tun_src6;
12139   ip6_address_t tun_dst6;
12140   int ret;
12141
12142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12143     {
12144       if (unformat (i, "del"))
12145         is_add = 0;
12146       else if (unformat (i, "sad_id %d", &sad_id))
12147         ;
12148       else if (unformat (i, "spi %d", &spi))
12149         ;
12150       else if (unformat (i, "esp"))
12151         protocol = IPSEC_PROTOCOL_ESP;
12152       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12153         {
12154           is_tunnel = 1;
12155           is_tunnel_ipv6 = 0;
12156         }
12157       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12158         {
12159           is_tunnel = 1;
12160           is_tunnel_ipv6 = 0;
12161         }
12162       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12163         {
12164           is_tunnel = 1;
12165           is_tunnel_ipv6 = 1;
12166         }
12167       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12168         {
12169           is_tunnel = 1;
12170           is_tunnel_ipv6 = 1;
12171         }
12172       else
12173         if (unformat
12174             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12175         {
12176           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12177               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12178             {
12179               clib_warning ("unsupported crypto-alg: '%U'",
12180                             format_ipsec_crypto_alg, crypto_alg);
12181               return -99;
12182             }
12183         }
12184       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12185         ;
12186       else
12187         if (unformat
12188             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12189         {
12190           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12191               integ_alg >= IPSEC_INTEG_N_ALG)
12192             {
12193               clib_warning ("unsupported integ-alg: '%U'",
12194                             format_ipsec_integ_alg, integ_alg);
12195               return -99;
12196             }
12197         }
12198       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12199         ;
12200       else
12201         {
12202           clib_warning ("parse error '%U'", format_unformat_error, i);
12203           return -99;
12204         }
12205
12206     }
12207
12208   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12209
12210   mp->sad_id = ntohl (sad_id);
12211   mp->is_add = is_add;
12212   mp->protocol = protocol;
12213   mp->spi = ntohl (spi);
12214   mp->is_tunnel = is_tunnel;
12215   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12216   mp->crypto_algorithm = crypto_alg;
12217   mp->integrity_algorithm = integ_alg;
12218   mp->crypto_key_length = vec_len (ck);
12219   mp->integrity_key_length = vec_len (ik);
12220
12221   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12222     mp->crypto_key_length = sizeof (mp->crypto_key);
12223
12224   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12225     mp->integrity_key_length = sizeof (mp->integrity_key);
12226
12227   if (ck)
12228     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12229   if (ik)
12230     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12231
12232   if (is_tunnel)
12233     {
12234       if (is_tunnel_ipv6)
12235         {
12236           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12237                        sizeof (ip6_address_t));
12238           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12239                        sizeof (ip6_address_t));
12240         }
12241       else
12242         {
12243           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12244                        sizeof (ip4_address_t));
12245           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12246                        sizeof (ip4_address_t));
12247         }
12248     }
12249
12250   S (mp);
12251   W (ret);
12252   return ret;
12253 }
12254
12255 static int
12256 api_ipsec_sa_set_key (vat_main_t * vam)
12257 {
12258   unformat_input_t *i = vam->input;
12259   vl_api_ipsec_sa_set_key_t *mp;
12260   u32 sa_id;
12261   u8 *ck = 0, *ik = 0;
12262   int ret;
12263
12264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12265     {
12266       if (unformat (i, "sa_id %d", &sa_id))
12267         ;
12268       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12269         ;
12270       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12271         ;
12272       else
12273         {
12274           clib_warning ("parse error '%U'", format_unformat_error, i);
12275           return -99;
12276         }
12277     }
12278
12279   M (IPSEC_SA_SET_KEY, mp);
12280
12281   mp->sa_id = ntohl (sa_id);
12282   mp->crypto_key_length = vec_len (ck);
12283   mp->integrity_key_length = vec_len (ik);
12284
12285   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12286     mp->crypto_key_length = sizeof (mp->crypto_key);
12287
12288   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12289     mp->integrity_key_length = sizeof (mp->integrity_key);
12290
12291   if (ck)
12292     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12293   if (ik)
12294     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12295
12296   S (mp);
12297   W (ret);
12298   return ret;
12299 }
12300
12301 static int
12302 api_ikev2_profile_add_del (vat_main_t * vam)
12303 {
12304   unformat_input_t *i = vam->input;
12305   vl_api_ikev2_profile_add_del_t *mp;
12306   u8 is_add = 1;
12307   u8 *name = 0;
12308   int ret;
12309
12310   const char *valid_chars = "a-zA-Z0-9_";
12311
12312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12313     {
12314       if (unformat (i, "del"))
12315         is_add = 0;
12316       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12317         vec_add1 (name, 0);
12318       else
12319         {
12320           errmsg ("parse error '%U'", format_unformat_error, i);
12321           return -99;
12322         }
12323     }
12324
12325   if (!vec_len (name))
12326     {
12327       errmsg ("profile name must be specified");
12328       return -99;
12329     }
12330
12331   if (vec_len (name) > 64)
12332     {
12333       errmsg ("profile name too long");
12334       return -99;
12335     }
12336
12337   M (IKEV2_PROFILE_ADD_DEL, mp);
12338
12339   clib_memcpy (mp->name, name, vec_len (name));
12340   mp->is_add = is_add;
12341   vec_free (name);
12342
12343   S (mp);
12344   W (ret);
12345   return ret;
12346 }
12347
12348 static int
12349 api_ikev2_profile_set_auth (vat_main_t * vam)
12350 {
12351   unformat_input_t *i = vam->input;
12352   vl_api_ikev2_profile_set_auth_t *mp;
12353   u8 *name = 0;
12354   u8 *data = 0;
12355   u32 auth_method = 0;
12356   u8 is_hex = 0;
12357   int ret;
12358
12359   const char *valid_chars = "a-zA-Z0-9_";
12360
12361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12362     {
12363       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12364         vec_add1 (name, 0);
12365       else if (unformat (i, "auth_method %U",
12366                          unformat_ikev2_auth_method, &auth_method))
12367         ;
12368       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12369         is_hex = 1;
12370       else if (unformat (i, "auth_data %v", &data))
12371         ;
12372       else
12373         {
12374           errmsg ("parse error '%U'", format_unformat_error, i);
12375           return -99;
12376         }
12377     }
12378
12379   if (!vec_len (name))
12380     {
12381       errmsg ("profile name must be specified");
12382       return -99;
12383     }
12384
12385   if (vec_len (name) > 64)
12386     {
12387       errmsg ("profile name too long");
12388       return -99;
12389     }
12390
12391   if (!vec_len (data))
12392     {
12393       errmsg ("auth_data must be specified");
12394       return -99;
12395     }
12396
12397   if (!auth_method)
12398     {
12399       errmsg ("auth_method must be specified");
12400       return -99;
12401     }
12402
12403   M (IKEV2_PROFILE_SET_AUTH, mp);
12404
12405   mp->is_hex = is_hex;
12406   mp->auth_method = (u8) auth_method;
12407   mp->data_len = vec_len (data);
12408   clib_memcpy (mp->name, name, vec_len (name));
12409   clib_memcpy (mp->data, data, vec_len (data));
12410   vec_free (name);
12411   vec_free (data);
12412
12413   S (mp);
12414   W (ret);
12415   return ret;
12416 }
12417
12418 static int
12419 api_ikev2_profile_set_id (vat_main_t * vam)
12420 {
12421   unformat_input_t *i = vam->input;
12422   vl_api_ikev2_profile_set_id_t *mp;
12423   u8 *name = 0;
12424   u8 *data = 0;
12425   u8 is_local = 0;
12426   u32 id_type = 0;
12427   ip4_address_t ip4;
12428   int ret;
12429
12430   const char *valid_chars = "a-zA-Z0-9_";
12431
12432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12433     {
12434       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12435         vec_add1 (name, 0);
12436       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12437         ;
12438       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12439         {
12440           data = vec_new (u8, 4);
12441           clib_memcpy (data, ip4.as_u8, 4);
12442         }
12443       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12444         ;
12445       else if (unformat (i, "id_data %v", &data))
12446         ;
12447       else if (unformat (i, "local"))
12448         is_local = 1;
12449       else if (unformat (i, "remote"))
12450         is_local = 0;
12451       else
12452         {
12453           errmsg ("parse error '%U'", format_unformat_error, i);
12454           return -99;
12455         }
12456     }
12457
12458   if (!vec_len (name))
12459     {
12460       errmsg ("profile name must be specified");
12461       return -99;
12462     }
12463
12464   if (vec_len (name) > 64)
12465     {
12466       errmsg ("profile name too long");
12467       return -99;
12468     }
12469
12470   if (!vec_len (data))
12471     {
12472       errmsg ("id_data must be specified");
12473       return -99;
12474     }
12475
12476   if (!id_type)
12477     {
12478       errmsg ("id_type must be specified");
12479       return -99;
12480     }
12481
12482   M (IKEV2_PROFILE_SET_ID, mp);
12483
12484   mp->is_local = is_local;
12485   mp->id_type = (u8) id_type;
12486   mp->data_len = vec_len (data);
12487   clib_memcpy (mp->name, name, vec_len (name));
12488   clib_memcpy (mp->data, data, vec_len (data));
12489   vec_free (name);
12490   vec_free (data);
12491
12492   S (mp);
12493   W (ret);
12494   return ret;
12495 }
12496
12497 static int
12498 api_ikev2_profile_set_ts (vat_main_t * vam)
12499 {
12500   unformat_input_t *i = vam->input;
12501   vl_api_ikev2_profile_set_ts_t *mp;
12502   u8 *name = 0;
12503   u8 is_local = 0;
12504   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12505   ip4_address_t start_addr, end_addr;
12506
12507   const char *valid_chars = "a-zA-Z0-9_";
12508   int ret;
12509
12510   start_addr.as_u32 = 0;
12511   end_addr.as_u32 = (u32) ~ 0;
12512
12513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12514     {
12515       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12516         vec_add1 (name, 0);
12517       else if (unformat (i, "protocol %d", &proto))
12518         ;
12519       else if (unformat (i, "start_port %d", &start_port))
12520         ;
12521       else if (unformat (i, "end_port %d", &end_port))
12522         ;
12523       else
12524         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12525         ;
12526       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12527         ;
12528       else if (unformat (i, "local"))
12529         is_local = 1;
12530       else if (unformat (i, "remote"))
12531         is_local = 0;
12532       else
12533         {
12534           errmsg ("parse error '%U'", format_unformat_error, i);
12535           return -99;
12536         }
12537     }
12538
12539   if (!vec_len (name))
12540     {
12541       errmsg ("profile name must be specified");
12542       return -99;
12543     }
12544
12545   if (vec_len (name) > 64)
12546     {
12547       errmsg ("profile name too long");
12548       return -99;
12549     }
12550
12551   M (IKEV2_PROFILE_SET_TS, mp);
12552
12553   mp->is_local = is_local;
12554   mp->proto = (u8) proto;
12555   mp->start_port = (u16) start_port;
12556   mp->end_port = (u16) end_port;
12557   mp->start_addr = start_addr.as_u32;
12558   mp->end_addr = end_addr.as_u32;
12559   clib_memcpy (mp->name, name, vec_len (name));
12560   vec_free (name);
12561
12562   S (mp);
12563   W (ret);
12564   return ret;
12565 }
12566
12567 static int
12568 api_ikev2_set_local_key (vat_main_t * vam)
12569 {
12570   unformat_input_t *i = vam->input;
12571   vl_api_ikev2_set_local_key_t *mp;
12572   u8 *file = 0;
12573   int ret;
12574
12575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12576     {
12577       if (unformat (i, "file %v", &file))
12578         vec_add1 (file, 0);
12579       else
12580         {
12581           errmsg ("parse error '%U'", format_unformat_error, i);
12582           return -99;
12583         }
12584     }
12585
12586   if (!vec_len (file))
12587     {
12588       errmsg ("RSA key file must be specified");
12589       return -99;
12590     }
12591
12592   if (vec_len (file) > 256)
12593     {
12594       errmsg ("file name too long");
12595       return -99;
12596     }
12597
12598   M (IKEV2_SET_LOCAL_KEY, mp);
12599
12600   clib_memcpy (mp->key_file, file, vec_len (file));
12601   vec_free (file);
12602
12603   S (mp);
12604   W (ret);
12605   return ret;
12606 }
12607
12608 static int
12609 api_ikev2_set_responder (vat_main_t * vam)
12610 {
12611   unformat_input_t *i = vam->input;
12612   vl_api_ikev2_set_responder_t *mp;
12613   int ret;
12614   u8 *name = 0;
12615   u32 sw_if_index = ~0;
12616   ip4_address_t address;
12617
12618   const char *valid_chars = "a-zA-Z0-9_";
12619
12620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12621     {
12622       if (unformat
12623           (i, "%U interface %d address %U", unformat_token, valid_chars,
12624            &name, &sw_if_index, unformat_ip4_address, &address))
12625         vec_add1 (name, 0);
12626       else
12627         {
12628           errmsg ("parse error '%U'", format_unformat_error, i);
12629           return -99;
12630         }
12631     }
12632
12633   if (!vec_len (name))
12634     {
12635       errmsg ("profile name must be specified");
12636       return -99;
12637     }
12638
12639   if (vec_len (name) > 64)
12640     {
12641       errmsg ("profile name too long");
12642       return -99;
12643     }
12644
12645   M (IKEV2_SET_RESPONDER, mp);
12646
12647   clib_memcpy (mp->name, name, vec_len (name));
12648   vec_free (name);
12649
12650   mp->sw_if_index = sw_if_index;
12651   clib_memcpy (mp->address, &address, sizeof (address));
12652
12653   S (mp);
12654   W (ret);
12655   return ret;
12656 }
12657
12658 static int
12659 api_ikev2_set_ike_transforms (vat_main_t * vam)
12660 {
12661   unformat_input_t *i = vam->input;
12662   vl_api_ikev2_set_ike_transforms_t *mp;
12663   int ret;
12664   u8 *name = 0;
12665   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12666
12667   const char *valid_chars = "a-zA-Z0-9_";
12668
12669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12670     {
12671       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12672                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12673         vec_add1 (name, 0);
12674       else
12675         {
12676           errmsg ("parse error '%U'", format_unformat_error, i);
12677           return -99;
12678         }
12679     }
12680
12681   if (!vec_len (name))
12682     {
12683       errmsg ("profile name must be specified");
12684       return -99;
12685     }
12686
12687   if (vec_len (name) > 64)
12688     {
12689       errmsg ("profile name too long");
12690       return -99;
12691     }
12692
12693   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12694
12695   clib_memcpy (mp->name, name, vec_len (name));
12696   vec_free (name);
12697   mp->crypto_alg = crypto_alg;
12698   mp->crypto_key_size = crypto_key_size;
12699   mp->integ_alg = integ_alg;
12700   mp->dh_group = dh_group;
12701
12702   S (mp);
12703   W (ret);
12704   return ret;
12705 }
12706
12707
12708 static int
12709 api_ikev2_set_esp_transforms (vat_main_t * vam)
12710 {
12711   unformat_input_t *i = vam->input;
12712   vl_api_ikev2_set_esp_transforms_t *mp;
12713   int ret;
12714   u8 *name = 0;
12715   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12716
12717   const char *valid_chars = "a-zA-Z0-9_";
12718
12719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12720     {
12721       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12722                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12723         vec_add1 (name, 0);
12724       else
12725         {
12726           errmsg ("parse error '%U'", format_unformat_error, i);
12727           return -99;
12728         }
12729     }
12730
12731   if (!vec_len (name))
12732     {
12733       errmsg ("profile name must be specified");
12734       return -99;
12735     }
12736
12737   if (vec_len (name) > 64)
12738     {
12739       errmsg ("profile name too long");
12740       return -99;
12741     }
12742
12743   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12744
12745   clib_memcpy (mp->name, name, vec_len (name));
12746   vec_free (name);
12747   mp->crypto_alg = crypto_alg;
12748   mp->crypto_key_size = crypto_key_size;
12749   mp->integ_alg = integ_alg;
12750   mp->dh_group = dh_group;
12751
12752   S (mp);
12753   W (ret);
12754   return ret;
12755 }
12756
12757 static int
12758 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12759 {
12760   unformat_input_t *i = vam->input;
12761   vl_api_ikev2_set_sa_lifetime_t *mp;
12762   int ret;
12763   u8 *name = 0;
12764   u64 lifetime, lifetime_maxdata;
12765   u32 lifetime_jitter, handover;
12766
12767   const char *valid_chars = "a-zA-Z0-9_";
12768
12769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12770     {
12771       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12772                     &lifetime, &lifetime_jitter, &handover,
12773                     &lifetime_maxdata))
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_SET_SA_LIFETIME, mp);
12795
12796   clib_memcpy (mp->name, name, vec_len (name));
12797   vec_free (name);
12798   mp->lifetime = lifetime;
12799   mp->lifetime_jitter = lifetime_jitter;
12800   mp->handover = handover;
12801   mp->lifetime_maxdata = lifetime_maxdata;
12802
12803   S (mp);
12804   W (ret);
12805   return ret;
12806 }
12807
12808 static int
12809 api_ikev2_initiate_sa_init (vat_main_t * vam)
12810 {
12811   unformat_input_t *i = vam->input;
12812   vl_api_ikev2_initiate_sa_init_t *mp;
12813   int ret;
12814   u8 *name = 0;
12815
12816   const char *valid_chars = "a-zA-Z0-9_";
12817
12818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12819     {
12820       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12821         vec_add1 (name, 0);
12822       else
12823         {
12824           errmsg ("parse error '%U'", format_unformat_error, i);
12825           return -99;
12826         }
12827     }
12828
12829   if (!vec_len (name))
12830     {
12831       errmsg ("profile name must be specified");
12832       return -99;
12833     }
12834
12835   if (vec_len (name) > 64)
12836     {
12837       errmsg ("profile name too long");
12838       return -99;
12839     }
12840
12841   M (IKEV2_INITIATE_SA_INIT, mp);
12842
12843   clib_memcpy (mp->name, name, vec_len (name));
12844   vec_free (name);
12845
12846   S (mp);
12847   W (ret);
12848   return ret;
12849 }
12850
12851 static int
12852 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12853 {
12854   unformat_input_t *i = vam->input;
12855   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12856   int ret;
12857   u64 ispi;
12858
12859
12860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12861     {
12862       if (unformat (i, "%lx", &ispi))
12863         ;
12864       else
12865         {
12866           errmsg ("parse error '%U'", format_unformat_error, i);
12867           return -99;
12868         }
12869     }
12870
12871   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12872
12873   mp->ispi = ispi;
12874
12875   S (mp);
12876   W (ret);
12877   return ret;
12878 }
12879
12880 static int
12881 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
12882 {
12883   unformat_input_t *i = vam->input;
12884   vl_api_ikev2_initiate_del_child_sa_t *mp;
12885   int ret;
12886   u32 ispi;
12887
12888
12889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12890     {
12891       if (unformat (i, "%x", &ispi))
12892         ;
12893       else
12894         {
12895           errmsg ("parse error '%U'", format_unformat_error, i);
12896           return -99;
12897         }
12898     }
12899
12900   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
12901
12902   mp->ispi = ispi;
12903
12904   S (mp);
12905   W (ret);
12906   return ret;
12907 }
12908
12909 static int
12910 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
12911 {
12912   unformat_input_t *i = vam->input;
12913   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
12914   int ret;
12915   u32 ispi;
12916
12917
12918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12919     {
12920       if (unformat (i, "%x", &ispi))
12921         ;
12922       else
12923         {
12924           errmsg ("parse error '%U'", format_unformat_error, i);
12925           return -99;
12926         }
12927     }
12928
12929   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
12930
12931   mp->ispi = ispi;
12932
12933   S (mp);
12934   W (ret);
12935   return ret;
12936 }
12937
12938 /*
12939  * MAP
12940  */
12941 static int
12942 api_map_add_domain (vat_main_t * vam)
12943 {
12944   unformat_input_t *i = vam->input;
12945   vl_api_map_add_domain_t *mp;
12946
12947   ip4_address_t ip4_prefix;
12948   ip6_address_t ip6_prefix;
12949   ip6_address_t ip6_src;
12950   u32 num_m_args = 0;
12951   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12952     0, psid_length = 0;
12953   u8 is_translation = 0;
12954   u32 mtu = 0;
12955   u32 ip6_src_len = 128;
12956   int ret;
12957
12958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12959     {
12960       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12961                     &ip4_prefix, &ip4_prefix_len))
12962         num_m_args++;
12963       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12964                          &ip6_prefix, &ip6_prefix_len))
12965         num_m_args++;
12966       else
12967         if (unformat
12968             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12969              &ip6_src_len))
12970         num_m_args++;
12971       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12972         num_m_args++;
12973       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12974         num_m_args++;
12975       else if (unformat (i, "psid-offset %d", &psid_offset))
12976         num_m_args++;
12977       else if (unformat (i, "psid-len %d", &psid_length))
12978         num_m_args++;
12979       else if (unformat (i, "mtu %d", &mtu))
12980         num_m_args++;
12981       else if (unformat (i, "map-t"))
12982         is_translation = 1;
12983       else
12984         {
12985           clib_warning ("parse error '%U'", format_unformat_error, i);
12986           return -99;
12987         }
12988     }
12989
12990   if (num_m_args < 3)
12991     {
12992       errmsg ("mandatory argument(s) missing");
12993       return -99;
12994     }
12995
12996   /* Construct the API message */
12997   M (MAP_ADD_DOMAIN, mp);
12998
12999   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13000   mp->ip4_prefix_len = ip4_prefix_len;
13001
13002   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13003   mp->ip6_prefix_len = ip6_prefix_len;
13004
13005   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13006   mp->ip6_src_prefix_len = ip6_src_len;
13007
13008   mp->ea_bits_len = ea_bits_len;
13009   mp->psid_offset = psid_offset;
13010   mp->psid_length = psid_length;
13011   mp->is_translation = is_translation;
13012   mp->mtu = htons (mtu);
13013
13014   /* send it... */
13015   S (mp);
13016
13017   /* Wait for a reply, return good/bad news  */
13018   W (ret);
13019   return ret;
13020 }
13021
13022 static int
13023 api_map_del_domain (vat_main_t * vam)
13024 {
13025   unformat_input_t *i = vam->input;
13026   vl_api_map_del_domain_t *mp;
13027
13028   u32 num_m_args = 0;
13029   u32 index;
13030   int ret;
13031
13032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13033     {
13034       if (unformat (i, "index %d", &index))
13035         num_m_args++;
13036       else
13037         {
13038           clib_warning ("parse error '%U'", format_unformat_error, i);
13039           return -99;
13040         }
13041     }
13042
13043   if (num_m_args != 1)
13044     {
13045       errmsg ("mandatory argument(s) missing");
13046       return -99;
13047     }
13048
13049   /* Construct the API message */
13050   M (MAP_DEL_DOMAIN, mp);
13051
13052   mp->index = ntohl (index);
13053
13054   /* send it... */
13055   S (mp);
13056
13057   /* Wait for a reply, return good/bad news  */
13058   W (ret);
13059   return ret;
13060 }
13061
13062 static int
13063 api_map_add_del_rule (vat_main_t * vam)
13064 {
13065   unformat_input_t *i = vam->input;
13066   vl_api_map_add_del_rule_t *mp;
13067   u8 is_add = 1;
13068   ip6_address_t ip6_dst;
13069   u32 num_m_args = 0, index, psid = 0;
13070   int ret;
13071
13072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13073     {
13074       if (unformat (i, "index %d", &index))
13075         num_m_args++;
13076       else if (unformat (i, "psid %d", &psid))
13077         num_m_args++;
13078       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13079         num_m_args++;
13080       else if (unformat (i, "del"))
13081         {
13082           is_add = 0;
13083         }
13084       else
13085         {
13086           clib_warning ("parse error '%U'", format_unformat_error, i);
13087           return -99;
13088         }
13089     }
13090
13091   /* Construct the API message */
13092   M (MAP_ADD_DEL_RULE, mp);
13093
13094   mp->index = ntohl (index);
13095   mp->is_add = is_add;
13096   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13097   mp->psid = ntohs (psid);
13098
13099   /* send it... */
13100   S (mp);
13101
13102   /* Wait for a reply, return good/bad news  */
13103   W (ret);
13104   return ret;
13105 }
13106
13107 static int
13108 api_map_domain_dump (vat_main_t * vam)
13109 {
13110   vl_api_map_domain_dump_t *mp;
13111   vl_api_control_ping_t *mp_ping;
13112   int ret;
13113
13114   /* Construct the API message */
13115   M (MAP_DOMAIN_DUMP, mp);
13116
13117   /* send it... */
13118   S (mp);
13119
13120   /* Use a control ping for synchronization */
13121   M (CONTROL_PING, mp_ping);
13122   S (mp_ping);
13123
13124   W (ret);
13125   return ret;
13126 }
13127
13128 static int
13129 api_map_rule_dump (vat_main_t * vam)
13130 {
13131   unformat_input_t *i = vam->input;
13132   vl_api_map_rule_dump_t *mp;
13133   vl_api_control_ping_t *mp_ping;
13134   u32 domain_index = ~0;
13135   int ret;
13136
13137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13138     {
13139       if (unformat (i, "index %u", &domain_index))
13140         ;
13141       else
13142         break;
13143     }
13144
13145   if (domain_index == ~0)
13146     {
13147       clib_warning ("parse error: domain index expected");
13148       return -99;
13149     }
13150
13151   /* Construct the API message */
13152   M (MAP_RULE_DUMP, mp);
13153
13154   mp->domain_index = htonl (domain_index);
13155
13156   /* send it... */
13157   S (mp);
13158
13159   /* Use a control ping for synchronization */
13160   M (CONTROL_PING, mp_ping);
13161   S (mp_ping);
13162
13163   W (ret);
13164   return ret;
13165 }
13166
13167 static void vl_api_map_add_domain_reply_t_handler
13168   (vl_api_map_add_domain_reply_t * mp)
13169 {
13170   vat_main_t *vam = &vat_main;
13171   i32 retval = ntohl (mp->retval);
13172
13173   if (vam->async_mode)
13174     {
13175       vam->async_errors += (retval < 0);
13176     }
13177   else
13178     {
13179       vam->retval = retval;
13180       vam->result_ready = 1;
13181     }
13182 }
13183
13184 static void vl_api_map_add_domain_reply_t_handler_json
13185   (vl_api_map_add_domain_reply_t * mp)
13186 {
13187   vat_main_t *vam = &vat_main;
13188   vat_json_node_t node;
13189
13190   vat_json_init_object (&node);
13191   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13192   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13193
13194   vat_json_print (vam->ofp, &node);
13195   vat_json_free (&node);
13196
13197   vam->retval = ntohl (mp->retval);
13198   vam->result_ready = 1;
13199 }
13200
13201 static int
13202 api_get_first_msg_id (vat_main_t * vam)
13203 {
13204   vl_api_get_first_msg_id_t *mp;
13205   unformat_input_t *i = vam->input;
13206   u8 *name;
13207   u8 name_set = 0;
13208   int ret;
13209
13210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13211     {
13212       if (unformat (i, "client %s", &name))
13213         name_set = 1;
13214       else
13215         break;
13216     }
13217
13218   if (name_set == 0)
13219     {
13220       errmsg ("missing client name");
13221       return -99;
13222     }
13223   vec_add1 (name, 0);
13224
13225   if (vec_len (name) > 63)
13226     {
13227       errmsg ("client name too long");
13228       return -99;
13229     }
13230
13231   M (GET_FIRST_MSG_ID, mp);
13232   clib_memcpy (mp->name, name, vec_len (name));
13233   S (mp);
13234   W (ret);
13235   return ret;
13236 }
13237
13238 static int
13239 api_cop_interface_enable_disable (vat_main_t * vam)
13240 {
13241   unformat_input_t *line_input = vam->input;
13242   vl_api_cop_interface_enable_disable_t *mp;
13243   u32 sw_if_index = ~0;
13244   u8 enable_disable = 1;
13245   int ret;
13246
13247   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13248     {
13249       if (unformat (line_input, "disable"))
13250         enable_disable = 0;
13251       if (unformat (line_input, "enable"))
13252         enable_disable = 1;
13253       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13254                          vam, &sw_if_index))
13255         ;
13256       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
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_INTERFACE_ENABLE_DISABLE, mp);
13270   mp->sw_if_index = ntohl (sw_if_index);
13271   mp->enable_disable = enable_disable;
13272
13273   /* send it... */
13274   S (mp);
13275   /* Wait for the reply */
13276   W (ret);
13277   return ret;
13278 }
13279
13280 static int
13281 api_cop_whitelist_enable_disable (vat_main_t * vam)
13282 {
13283   unformat_input_t *line_input = vam->input;
13284   vl_api_cop_whitelist_enable_disable_t *mp;
13285   u32 sw_if_index = ~0;
13286   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13287   u32 fib_id = 0;
13288   int ret;
13289
13290   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13291     {
13292       if (unformat (line_input, "ip4"))
13293         ip4 = 1;
13294       else if (unformat (line_input, "ip6"))
13295         ip6 = 1;
13296       else if (unformat (line_input, "default"))
13297         default_cop = 1;
13298       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13299                          vam, &sw_if_index))
13300         ;
13301       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13302         ;
13303       else if (unformat (line_input, "fib-id %d", &fib_id))
13304         ;
13305       else
13306         break;
13307     }
13308
13309   if (sw_if_index == ~0)
13310     {
13311       errmsg ("missing interface name or sw_if_index");
13312       return -99;
13313     }
13314
13315   /* Construct the API message */
13316   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13317   mp->sw_if_index = ntohl (sw_if_index);
13318   mp->fib_id = ntohl (fib_id);
13319   mp->ip4 = ip4;
13320   mp->ip6 = ip6;
13321   mp->default_cop = default_cop;
13322
13323   /* send it... */
13324   S (mp);
13325   /* Wait for the reply */
13326   W (ret);
13327   return ret;
13328 }
13329
13330 static int
13331 api_get_node_graph (vat_main_t * vam)
13332 {
13333   vl_api_get_node_graph_t *mp;
13334   int ret;
13335
13336   M (GET_NODE_GRAPH, mp);
13337
13338   /* send it... */
13339   S (mp);
13340   /* Wait for the reply */
13341   W (ret);
13342   return ret;
13343 }
13344
13345 /* *INDENT-OFF* */
13346 /** Used for parsing LISP eids */
13347 typedef CLIB_PACKED(struct{
13348   u8 addr[16];   /**< eid address */
13349   u32 len;       /**< prefix length if IP */
13350   u8 type;      /**< type of eid */
13351 }) lisp_eid_vat_t;
13352 /* *INDENT-ON* */
13353
13354 static uword
13355 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13356 {
13357   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13358
13359   memset (a, 0, sizeof (a[0]));
13360
13361   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13362     {
13363       a->type = 0;              /* ipv4 type */
13364     }
13365   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13366     {
13367       a->type = 1;              /* ipv6 type */
13368     }
13369   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13370     {
13371       a->type = 2;              /* mac type */
13372     }
13373   else
13374     {
13375       return 0;
13376     }
13377
13378   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13379     {
13380       return 0;
13381     }
13382
13383   return 1;
13384 }
13385
13386 static int
13387 lisp_eid_size_vat (u8 type)
13388 {
13389   switch (type)
13390     {
13391     case 0:
13392       return 4;
13393     case 1:
13394       return 16;
13395     case 2:
13396       return 6;
13397     }
13398   return 0;
13399 }
13400
13401 static void
13402 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13403 {
13404   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13405 }
13406
13407 static int
13408 api_one_add_del_locator_set (vat_main_t * vam)
13409 {
13410   unformat_input_t *input = vam->input;
13411   vl_api_one_add_del_locator_set_t *mp;
13412   u8 is_add = 1;
13413   u8 *locator_set_name = NULL;
13414   u8 locator_set_name_set = 0;
13415   vl_api_local_locator_t locator, *locators = 0;
13416   u32 sw_if_index, priority, weight;
13417   u32 data_len = 0;
13418
13419   int ret;
13420   /* Parse args required to build the message */
13421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13422     {
13423       if (unformat (input, "del"))
13424         {
13425           is_add = 0;
13426         }
13427       else if (unformat (input, "locator-set %s", &locator_set_name))
13428         {
13429           locator_set_name_set = 1;
13430         }
13431       else if (unformat (input, "sw_if_index %u p %u w %u",
13432                          &sw_if_index, &priority, &weight))
13433         {
13434           locator.sw_if_index = htonl (sw_if_index);
13435           locator.priority = priority;
13436           locator.weight = weight;
13437           vec_add1 (locators, locator);
13438         }
13439       else
13440         if (unformat
13441             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13442              &sw_if_index, &priority, &weight))
13443         {
13444           locator.sw_if_index = htonl (sw_if_index);
13445           locator.priority = priority;
13446           locator.weight = weight;
13447           vec_add1 (locators, locator);
13448         }
13449       else
13450         break;
13451     }
13452
13453   if (locator_set_name_set == 0)
13454     {
13455       errmsg ("missing locator-set name");
13456       vec_free (locators);
13457       return -99;
13458     }
13459
13460   if (vec_len (locator_set_name) > 64)
13461     {
13462       errmsg ("locator-set name too long");
13463       vec_free (locator_set_name);
13464       vec_free (locators);
13465       return -99;
13466     }
13467   vec_add1 (locator_set_name, 0);
13468
13469   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13470
13471   /* Construct the API message */
13472   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13473
13474   mp->is_add = is_add;
13475   clib_memcpy (mp->locator_set_name, locator_set_name,
13476                vec_len (locator_set_name));
13477   vec_free (locator_set_name);
13478
13479   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13480   if (locators)
13481     clib_memcpy (mp->locators, locators, data_len);
13482   vec_free (locators);
13483
13484   /* send it... */
13485   S (mp);
13486
13487   /* Wait for a reply... */
13488   W (ret);
13489   return ret;
13490 }
13491
13492 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13493
13494 static int
13495 api_one_add_del_locator (vat_main_t * vam)
13496 {
13497   unformat_input_t *input = vam->input;
13498   vl_api_one_add_del_locator_t *mp;
13499   u32 tmp_if_index = ~0;
13500   u32 sw_if_index = ~0;
13501   u8 sw_if_index_set = 0;
13502   u8 sw_if_index_if_name_set = 0;
13503   u32 priority = ~0;
13504   u8 priority_set = 0;
13505   u32 weight = ~0;
13506   u8 weight_set = 0;
13507   u8 is_add = 1;
13508   u8 *locator_set_name = NULL;
13509   u8 locator_set_name_set = 0;
13510   int ret;
13511
13512   /* Parse args required to build the message */
13513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13514     {
13515       if (unformat (input, "del"))
13516         {
13517           is_add = 0;
13518         }
13519       else if (unformat (input, "locator-set %s", &locator_set_name))
13520         {
13521           locator_set_name_set = 1;
13522         }
13523       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13524                          &tmp_if_index))
13525         {
13526           sw_if_index_if_name_set = 1;
13527           sw_if_index = tmp_if_index;
13528         }
13529       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13530         {
13531           sw_if_index_set = 1;
13532           sw_if_index = tmp_if_index;
13533         }
13534       else if (unformat (input, "p %d", &priority))
13535         {
13536           priority_set = 1;
13537         }
13538       else if (unformat (input, "w %d", &weight))
13539         {
13540           weight_set = 1;
13541         }
13542       else
13543         break;
13544     }
13545
13546   if (locator_set_name_set == 0)
13547     {
13548       errmsg ("missing locator-set name");
13549       return -99;
13550     }
13551
13552   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13553     {
13554       errmsg ("missing sw_if_index");
13555       vec_free (locator_set_name);
13556       return -99;
13557     }
13558
13559   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13560     {
13561       errmsg ("cannot use both params interface name and sw_if_index");
13562       vec_free (locator_set_name);
13563       return -99;
13564     }
13565
13566   if (priority_set == 0)
13567     {
13568       errmsg ("missing locator-set priority");
13569       vec_free (locator_set_name);
13570       return -99;
13571     }
13572
13573   if (weight_set == 0)
13574     {
13575       errmsg ("missing locator-set weight");
13576       vec_free (locator_set_name);
13577       return -99;
13578     }
13579
13580   if (vec_len (locator_set_name) > 64)
13581     {
13582       errmsg ("locator-set name too long");
13583       vec_free (locator_set_name);
13584       return -99;
13585     }
13586   vec_add1 (locator_set_name, 0);
13587
13588   /* Construct the API message */
13589   M (ONE_ADD_DEL_LOCATOR, mp);
13590
13591   mp->is_add = is_add;
13592   mp->sw_if_index = ntohl (sw_if_index);
13593   mp->priority = priority;
13594   mp->weight = weight;
13595   clib_memcpy (mp->locator_set_name, locator_set_name,
13596                vec_len (locator_set_name));
13597   vec_free (locator_set_name);
13598
13599   /* send it... */
13600   S (mp);
13601
13602   /* Wait for a reply... */
13603   W (ret);
13604   return ret;
13605 }
13606
13607 #define api_lisp_add_del_locator api_one_add_del_locator
13608
13609 uword
13610 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13611 {
13612   u32 *key_id = va_arg (*args, u32 *);
13613   u8 *s = 0;
13614
13615   if (unformat (input, "%s", &s))
13616     {
13617       if (!strcmp ((char *) s, "sha1"))
13618         key_id[0] = HMAC_SHA_1_96;
13619       else if (!strcmp ((char *) s, "sha256"))
13620         key_id[0] = HMAC_SHA_256_128;
13621       else
13622         {
13623           clib_warning ("invalid key_id: '%s'", s);
13624           key_id[0] = HMAC_NO_KEY;
13625         }
13626     }
13627   else
13628     return 0;
13629
13630   vec_free (s);
13631   return 1;
13632 }
13633
13634 static int
13635 api_one_add_del_local_eid (vat_main_t * vam)
13636 {
13637   unformat_input_t *input = vam->input;
13638   vl_api_one_add_del_local_eid_t *mp;
13639   u8 is_add = 1;
13640   u8 eid_set = 0;
13641   lisp_eid_vat_t _eid, *eid = &_eid;
13642   u8 *locator_set_name = 0;
13643   u8 locator_set_name_set = 0;
13644   u32 vni = 0;
13645   u16 key_id = 0;
13646   u8 *key = 0;
13647   int ret;
13648
13649   /* Parse args required to build the message */
13650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13651     {
13652       if (unformat (input, "del"))
13653         {
13654           is_add = 0;
13655         }
13656       else if (unformat (input, "vni %d", &vni))
13657         {
13658           ;
13659         }
13660       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13661         {
13662           eid_set = 1;
13663         }
13664       else if (unformat (input, "locator-set %s", &locator_set_name))
13665         {
13666           locator_set_name_set = 1;
13667         }
13668       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13669         ;
13670       else if (unformat (input, "secret-key %_%v%_", &key))
13671         ;
13672       else
13673         break;
13674     }
13675
13676   if (locator_set_name_set == 0)
13677     {
13678       errmsg ("missing locator-set name");
13679       return -99;
13680     }
13681
13682   if (0 == eid_set)
13683     {
13684       errmsg ("EID address not set!");
13685       vec_free (locator_set_name);
13686       return -99;
13687     }
13688
13689   if (key && (0 == key_id))
13690     {
13691       errmsg ("invalid key_id!");
13692       return -99;
13693     }
13694
13695   if (vec_len (key) > 64)
13696     {
13697       errmsg ("key too long");
13698       vec_free (key);
13699       return -99;
13700     }
13701
13702   if (vec_len (locator_set_name) > 64)
13703     {
13704       errmsg ("locator-set name too long");
13705       vec_free (locator_set_name);
13706       return -99;
13707     }
13708   vec_add1 (locator_set_name, 0);
13709
13710   /* Construct the API message */
13711   M (ONE_ADD_DEL_LOCAL_EID, mp);
13712
13713   mp->is_add = is_add;
13714   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13715   mp->eid_type = eid->type;
13716   mp->prefix_len = eid->len;
13717   mp->vni = clib_host_to_net_u32 (vni);
13718   mp->key_id = clib_host_to_net_u16 (key_id);
13719   clib_memcpy (mp->locator_set_name, locator_set_name,
13720                vec_len (locator_set_name));
13721   clib_memcpy (mp->key, key, vec_len (key));
13722
13723   vec_free (locator_set_name);
13724   vec_free (key);
13725
13726   /* send it... */
13727   S (mp);
13728
13729   /* Wait for a reply... */
13730   W (ret);
13731   return ret;
13732 }
13733
13734 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13735
13736 static int
13737 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13738 {
13739   u32 dp_table = 0, vni = 0;;
13740   unformat_input_t *input = vam->input;
13741   vl_api_gpe_add_del_fwd_entry_t *mp;
13742   u8 is_add = 1;
13743   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13744   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13745   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13746   u32 action = ~0, w;
13747   ip4_address_t rmt_rloc4, lcl_rloc4;
13748   ip6_address_t rmt_rloc6, lcl_rloc6;
13749   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13750   int ret;
13751
13752   memset (&rloc, 0, sizeof (rloc));
13753
13754   /* Parse args required to build the message */
13755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13756     {
13757       if (unformat (input, "del"))
13758         is_add = 0;
13759       else if (unformat (input, "add"))
13760         is_add = 1;
13761       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13762         {
13763           rmt_eid_set = 1;
13764         }
13765       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13766         {
13767           lcl_eid_set = 1;
13768         }
13769       else if (unformat (input, "vrf %d", &dp_table))
13770         ;
13771       else if (unformat (input, "bd %d", &dp_table))
13772         ;
13773       else if (unformat (input, "vni %d", &vni))
13774         ;
13775       else if (unformat (input, "w %d", &w))
13776         {
13777           if (!curr_rloc)
13778             {
13779               errmsg ("No RLOC configured for setting priority/weight!");
13780               return -99;
13781             }
13782           curr_rloc->weight = w;
13783         }
13784       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13785                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13786         {
13787           rloc.is_ip4 = 1;
13788
13789           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13790           rloc.weight = 0;
13791           vec_add1 (lcl_locs, rloc);
13792
13793           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13794           vec_add1 (rmt_locs, rloc);
13795           /* weight saved in rmt loc */
13796           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13797         }
13798       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13799                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13800         {
13801           rloc.is_ip4 = 0;
13802           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13803           rloc.weight = 0;
13804           vec_add1 (lcl_locs, rloc);
13805
13806           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13807           vec_add1 (rmt_locs, rloc);
13808           /* weight saved in rmt loc */
13809           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13810         }
13811       else if (unformat (input, "action %d", &action))
13812         {
13813           ;
13814         }
13815       else
13816         {
13817           clib_warning ("parse error '%U'", format_unformat_error, input);
13818           return -99;
13819         }
13820     }
13821
13822   if (!rmt_eid_set)
13823     {
13824       errmsg ("remote eid addresses not set");
13825       return -99;
13826     }
13827
13828   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13829     {
13830       errmsg ("eid types don't match");
13831       return -99;
13832     }
13833
13834   if (0 == rmt_locs && (u32) ~ 0 == action)
13835     {
13836       errmsg ("action not set for negative mapping");
13837       return -99;
13838     }
13839
13840   /* Construct the API message */
13841   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13842       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13843
13844   mp->is_add = is_add;
13845   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13846   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13847   mp->eid_type = rmt_eid->type;
13848   mp->dp_table = clib_host_to_net_u32 (dp_table);
13849   mp->vni = clib_host_to_net_u32 (vni);
13850   mp->rmt_len = rmt_eid->len;
13851   mp->lcl_len = lcl_eid->len;
13852   mp->action = action;
13853
13854   if (0 != rmt_locs && 0 != lcl_locs)
13855     {
13856       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13857       clib_memcpy (mp->locs, lcl_locs,
13858                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13859
13860       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13861       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13862                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13863     }
13864   vec_free (lcl_locs);
13865   vec_free (rmt_locs);
13866
13867   /* send it... */
13868   S (mp);
13869
13870   /* Wait for a reply... */
13871   W (ret);
13872   return ret;
13873 }
13874
13875 static int
13876 api_one_add_del_map_server (vat_main_t * vam)
13877 {
13878   unformat_input_t *input = vam->input;
13879   vl_api_one_add_del_map_server_t *mp;
13880   u8 is_add = 1;
13881   u8 ipv4_set = 0;
13882   u8 ipv6_set = 0;
13883   ip4_address_t ipv4;
13884   ip6_address_t ipv6;
13885   int ret;
13886
13887   /* Parse args required to build the message */
13888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13889     {
13890       if (unformat (input, "del"))
13891         {
13892           is_add = 0;
13893         }
13894       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13895         {
13896           ipv4_set = 1;
13897         }
13898       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13899         {
13900           ipv6_set = 1;
13901         }
13902       else
13903         break;
13904     }
13905
13906   if (ipv4_set && ipv6_set)
13907     {
13908       errmsg ("both eid v4 and v6 addresses set");
13909       return -99;
13910     }
13911
13912   if (!ipv4_set && !ipv6_set)
13913     {
13914       errmsg ("eid addresses not set");
13915       return -99;
13916     }
13917
13918   /* Construct the API message */
13919   M (ONE_ADD_DEL_MAP_SERVER, mp);
13920
13921   mp->is_add = is_add;
13922   if (ipv6_set)
13923     {
13924       mp->is_ipv6 = 1;
13925       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13926     }
13927   else
13928     {
13929       mp->is_ipv6 = 0;
13930       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13931     }
13932
13933   /* send it... */
13934   S (mp);
13935
13936   /* Wait for a reply... */
13937   W (ret);
13938   return ret;
13939 }
13940
13941 #define api_lisp_add_del_map_server api_one_add_del_map_server
13942
13943 static int
13944 api_one_add_del_map_resolver (vat_main_t * vam)
13945 {
13946   unformat_input_t *input = vam->input;
13947   vl_api_one_add_del_map_resolver_t *mp;
13948   u8 is_add = 1;
13949   u8 ipv4_set = 0;
13950   u8 ipv6_set = 0;
13951   ip4_address_t ipv4;
13952   ip6_address_t ipv6;
13953   int ret;
13954
13955   /* Parse args required to build the message */
13956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13957     {
13958       if (unformat (input, "del"))
13959         {
13960           is_add = 0;
13961         }
13962       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13963         {
13964           ipv4_set = 1;
13965         }
13966       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13967         {
13968           ipv6_set = 1;
13969         }
13970       else
13971         break;
13972     }
13973
13974   if (ipv4_set && ipv6_set)
13975     {
13976       errmsg ("both eid v4 and v6 addresses set");
13977       return -99;
13978     }
13979
13980   if (!ipv4_set && !ipv6_set)
13981     {
13982       errmsg ("eid addresses not set");
13983       return -99;
13984     }
13985
13986   /* Construct the API message */
13987   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
13988
13989   mp->is_add = is_add;
13990   if (ipv6_set)
13991     {
13992       mp->is_ipv6 = 1;
13993       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13994     }
13995   else
13996     {
13997       mp->is_ipv6 = 0;
13998       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13999     }
14000
14001   /* send it... */
14002   S (mp);
14003
14004   /* Wait for a reply... */
14005   W (ret);
14006   return ret;
14007 }
14008
14009 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14010
14011 static int
14012 api_lisp_gpe_enable_disable (vat_main_t * vam)
14013 {
14014   unformat_input_t *input = vam->input;
14015   vl_api_gpe_enable_disable_t *mp;
14016   u8 is_set = 0;
14017   u8 is_en = 1;
14018   int ret;
14019
14020   /* Parse args required to build the message */
14021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14022     {
14023       if (unformat (input, "enable"))
14024         {
14025           is_set = 1;
14026           is_en = 1;
14027         }
14028       else if (unformat (input, "disable"))
14029         {
14030           is_set = 1;
14031           is_en = 0;
14032         }
14033       else
14034         break;
14035     }
14036
14037   if (is_set == 0)
14038     {
14039       errmsg ("Value not set");
14040       return -99;
14041     }
14042
14043   /* Construct the API message */
14044   M (GPE_ENABLE_DISABLE, mp);
14045
14046   mp->is_en = is_en;
14047
14048   /* send it... */
14049   S (mp);
14050
14051   /* Wait for a reply... */
14052   W (ret);
14053   return ret;
14054 }
14055
14056 static int
14057 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14058 {
14059   unformat_input_t *input = vam->input;
14060   vl_api_one_rloc_probe_enable_disable_t *mp;
14061   u8 is_set = 0;
14062   u8 is_en = 0;
14063   int ret;
14064
14065   /* Parse args required to build the message */
14066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14067     {
14068       if (unformat (input, "enable"))
14069         {
14070           is_set = 1;
14071           is_en = 1;
14072         }
14073       else if (unformat (input, "disable"))
14074         is_set = 1;
14075       else
14076         break;
14077     }
14078
14079   if (!is_set)
14080     {
14081       errmsg ("Value not set");
14082       return -99;
14083     }
14084
14085   /* Construct the API message */
14086   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14087
14088   mp->is_enabled = is_en;
14089
14090   /* send it... */
14091   S (mp);
14092
14093   /* Wait for a reply... */
14094   W (ret);
14095   return ret;
14096 }
14097
14098 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14099
14100 static int
14101 api_one_map_register_enable_disable (vat_main_t * vam)
14102 {
14103   unformat_input_t *input = vam->input;
14104   vl_api_one_map_register_enable_disable_t *mp;
14105   u8 is_set = 0;
14106   u8 is_en = 0;
14107   int ret;
14108
14109   /* Parse args required to build the message */
14110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14111     {
14112       if (unformat (input, "enable"))
14113         {
14114           is_set = 1;
14115           is_en = 1;
14116         }
14117       else if (unformat (input, "disable"))
14118         is_set = 1;
14119       else
14120         break;
14121     }
14122
14123   if (!is_set)
14124     {
14125       errmsg ("Value not set");
14126       return -99;
14127     }
14128
14129   /* Construct the API message */
14130   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14131
14132   mp->is_enabled = is_en;
14133
14134   /* send it... */
14135   S (mp);
14136
14137   /* Wait for a reply... */
14138   W (ret);
14139   return ret;
14140 }
14141
14142 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14143
14144 static int
14145 api_one_enable_disable (vat_main_t * vam)
14146 {
14147   unformat_input_t *input = vam->input;
14148   vl_api_one_enable_disable_t *mp;
14149   u8 is_set = 0;
14150   u8 is_en = 0;
14151   int ret;
14152
14153   /* Parse args required to build the message */
14154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14155     {
14156       if (unformat (input, "enable"))
14157         {
14158           is_set = 1;
14159           is_en = 1;
14160         }
14161       else if (unformat (input, "disable"))
14162         {
14163           is_set = 1;
14164         }
14165       else
14166         break;
14167     }
14168
14169   if (!is_set)
14170     {
14171       errmsg ("Value not set");
14172       return -99;
14173     }
14174
14175   /* Construct the API message */
14176   M (ONE_ENABLE_DISABLE, mp);
14177
14178   mp->is_en = is_en;
14179
14180   /* send it... */
14181   S (mp);
14182
14183   /* Wait for a reply... */
14184   W (ret);
14185   return ret;
14186 }
14187
14188 #define api_lisp_enable_disable api_one_enable_disable
14189
14190 static int
14191 api_show_one_map_register_state (vat_main_t * vam)
14192 {
14193   vl_api_show_one_map_register_state_t *mp;
14194   int ret;
14195
14196   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14197
14198   /* send */
14199   S (mp);
14200
14201   /* wait for reply */
14202   W (ret);
14203   return ret;
14204 }
14205
14206 #define api_show_lisp_map_register_state api_show_one_map_register_state
14207
14208 static int
14209 api_show_one_rloc_probe_state (vat_main_t * vam)
14210 {
14211   vl_api_show_one_rloc_probe_state_t *mp;
14212   int ret;
14213
14214   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14215
14216   /* send */
14217   S (mp);
14218
14219   /* wait for reply */
14220   W (ret);
14221   return ret;
14222 }
14223
14224 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14225
14226 static int
14227 api_show_one_map_request_mode (vat_main_t * vam)
14228 {
14229   vl_api_show_one_map_request_mode_t *mp;
14230   int ret;
14231
14232   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14233
14234   /* send */
14235   S (mp);
14236
14237   /* wait for reply */
14238   W (ret);
14239   return ret;
14240 }
14241
14242 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14243
14244 static int
14245 api_one_map_request_mode (vat_main_t * vam)
14246 {
14247   unformat_input_t *input = vam->input;
14248   vl_api_one_map_request_mode_t *mp;
14249   u8 mode = 0;
14250   int ret;
14251
14252   /* Parse args required to build the message */
14253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14254     {
14255       if (unformat (input, "dst-only"))
14256         mode = 0;
14257       else if (unformat (input, "src-dst"))
14258         mode = 1;
14259       else
14260         {
14261           errmsg ("parse error '%U'", format_unformat_error, input);
14262           return -99;
14263         }
14264     }
14265
14266   M (ONE_MAP_REQUEST_MODE, mp);
14267
14268   mp->mode = mode;
14269
14270   /* send */
14271   S (mp);
14272
14273   /* wait for reply */
14274   W (ret);
14275   return ret;
14276 }
14277
14278 #define api_lisp_map_request_mode api_one_map_request_mode
14279
14280 /**
14281  * Enable/disable ONE proxy ITR.
14282  *
14283  * @param vam vpp API test context
14284  * @return return code
14285  */
14286 static int
14287 api_one_pitr_set_locator_set (vat_main_t * vam)
14288 {
14289   u8 ls_name_set = 0;
14290   unformat_input_t *input = vam->input;
14291   vl_api_one_pitr_set_locator_set_t *mp;
14292   u8 is_add = 1;
14293   u8 *ls_name = 0;
14294   int ret;
14295
14296   /* Parse args required to build the message */
14297   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14298     {
14299       if (unformat (input, "del"))
14300         is_add = 0;
14301       else if (unformat (input, "locator-set %s", &ls_name))
14302         ls_name_set = 1;
14303       else
14304         {
14305           errmsg ("parse error '%U'", format_unformat_error, input);
14306           return -99;
14307         }
14308     }
14309
14310   if (!ls_name_set)
14311     {
14312       errmsg ("locator-set name not set!");
14313       return -99;
14314     }
14315
14316   M (ONE_PITR_SET_LOCATOR_SET, mp);
14317
14318   mp->is_add = is_add;
14319   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14320   vec_free (ls_name);
14321
14322   /* send */
14323   S (mp);
14324
14325   /* wait for reply */
14326   W (ret);
14327   return ret;
14328 }
14329
14330 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14331
14332 static int
14333 api_show_one_pitr (vat_main_t * vam)
14334 {
14335   vl_api_show_one_pitr_t *mp;
14336   int ret;
14337
14338   if (!vam->json_output)
14339     {
14340       print (vam->ofp, "%=20s", "lisp status:");
14341     }
14342
14343   M (SHOW_ONE_PITR, mp);
14344   /* send it... */
14345   S (mp);
14346
14347   /* Wait for a reply... */
14348   W (ret);
14349   return ret;
14350 }
14351
14352 #define api_show_lisp_pitr api_show_one_pitr
14353
14354 /**
14355  * Add/delete mapping between vni and vrf
14356  */
14357 static int
14358 api_one_eid_table_add_del_map (vat_main_t * vam)
14359 {
14360   unformat_input_t *input = vam->input;
14361   vl_api_one_eid_table_add_del_map_t *mp;
14362   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14363   u32 vni, vrf, bd_index;
14364   int ret;
14365
14366   /* Parse args required to build the message */
14367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14368     {
14369       if (unformat (input, "del"))
14370         is_add = 0;
14371       else if (unformat (input, "vrf %d", &vrf))
14372         vrf_set = 1;
14373       else if (unformat (input, "bd_index %d", &bd_index))
14374         bd_index_set = 1;
14375       else if (unformat (input, "vni %d", &vni))
14376         vni_set = 1;
14377       else
14378         break;
14379     }
14380
14381   if (!vni_set || (!vrf_set && !bd_index_set))
14382     {
14383       errmsg ("missing arguments!");
14384       return -99;
14385     }
14386
14387   if (vrf_set && bd_index_set)
14388     {
14389       errmsg ("error: both vrf and bd entered!");
14390       return -99;
14391     }
14392
14393   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14394
14395   mp->is_add = is_add;
14396   mp->vni = htonl (vni);
14397   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14398   mp->is_l2 = bd_index_set;
14399
14400   /* send */
14401   S (mp);
14402
14403   /* wait for reply */
14404   W (ret);
14405   return ret;
14406 }
14407
14408 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14409
14410 uword
14411 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14412 {
14413   u32 *action = va_arg (*args, u32 *);
14414   u8 *s = 0;
14415
14416   if (unformat (input, "%s", &s))
14417     {
14418       if (!strcmp ((char *) s, "no-action"))
14419         action[0] = 0;
14420       else if (!strcmp ((char *) s, "natively-forward"))
14421         action[0] = 1;
14422       else if (!strcmp ((char *) s, "send-map-request"))
14423         action[0] = 2;
14424       else if (!strcmp ((char *) s, "drop"))
14425         action[0] = 3;
14426       else
14427         {
14428           clib_warning ("invalid action: '%s'", s);
14429           action[0] = 3;
14430         }
14431     }
14432   else
14433     return 0;
14434
14435   vec_free (s);
14436   return 1;
14437 }
14438
14439 /**
14440  * Add/del remote mapping to/from ONE control plane
14441  *
14442  * @param vam vpp API test context
14443  * @return return code
14444  */
14445 static int
14446 api_one_add_del_remote_mapping (vat_main_t * vam)
14447 {
14448   unformat_input_t *input = vam->input;
14449   vl_api_one_add_del_remote_mapping_t *mp;
14450   u32 vni = 0;
14451   lisp_eid_vat_t _eid, *eid = &_eid;
14452   lisp_eid_vat_t _seid, *seid = &_seid;
14453   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14454   u32 action = ~0, p, w, data_len;
14455   ip4_address_t rloc4;
14456   ip6_address_t rloc6;
14457   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14458   int ret;
14459
14460   memset (&rloc, 0, sizeof (rloc));
14461
14462   /* Parse args required to build the message */
14463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14464     {
14465       if (unformat (input, "del-all"))
14466         {
14467           del_all = 1;
14468         }
14469       else if (unformat (input, "del"))
14470         {
14471           is_add = 0;
14472         }
14473       else if (unformat (input, "add"))
14474         {
14475           is_add = 1;
14476         }
14477       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14478         {
14479           eid_set = 1;
14480         }
14481       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14482         {
14483           seid_set = 1;
14484         }
14485       else if (unformat (input, "vni %d", &vni))
14486         {
14487           ;
14488         }
14489       else if (unformat (input, "p %d w %d", &p, &w))
14490         {
14491           if (!curr_rloc)
14492             {
14493               errmsg ("No RLOC configured for setting priority/weight!");
14494               return -99;
14495             }
14496           curr_rloc->priority = p;
14497           curr_rloc->weight = w;
14498         }
14499       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14500         {
14501           rloc.is_ip4 = 1;
14502           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14503           vec_add1 (rlocs, rloc);
14504           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14505         }
14506       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14507         {
14508           rloc.is_ip4 = 0;
14509           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14510           vec_add1 (rlocs, rloc);
14511           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14512         }
14513       else if (unformat (input, "action %U",
14514                          unformat_negative_mapping_action, &action))
14515         {
14516           ;
14517         }
14518       else
14519         {
14520           clib_warning ("parse error '%U'", format_unformat_error, input);
14521           return -99;
14522         }
14523     }
14524
14525   if (0 == eid_set)
14526     {
14527       errmsg ("missing params!");
14528       return -99;
14529     }
14530
14531   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14532     {
14533       errmsg ("no action set for negative map-reply!");
14534       return -99;
14535     }
14536
14537   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14538
14539   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14540   mp->is_add = is_add;
14541   mp->vni = htonl (vni);
14542   mp->action = (u8) action;
14543   mp->is_src_dst = seid_set;
14544   mp->eid_len = eid->len;
14545   mp->seid_len = seid->len;
14546   mp->del_all = del_all;
14547   mp->eid_type = eid->type;
14548   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14549   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14550
14551   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14552   clib_memcpy (mp->rlocs, rlocs, data_len);
14553   vec_free (rlocs);
14554
14555   /* send it... */
14556   S (mp);
14557
14558   /* Wait for a reply... */
14559   W (ret);
14560   return ret;
14561 }
14562
14563 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14564
14565 /**
14566  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14567  * forwarding entries in data-plane accordingly.
14568  *
14569  * @param vam vpp API test context
14570  * @return return code
14571  */
14572 static int
14573 api_one_add_del_adjacency (vat_main_t * vam)
14574 {
14575   unformat_input_t *input = vam->input;
14576   vl_api_one_add_del_adjacency_t *mp;
14577   u32 vni = 0;
14578   ip4_address_t leid4, reid4;
14579   ip6_address_t leid6, reid6;
14580   u8 reid_mac[6] = { 0 };
14581   u8 leid_mac[6] = { 0 };
14582   u8 reid_type, leid_type;
14583   u32 leid_len = 0, reid_len = 0, len;
14584   u8 is_add = 1;
14585   int ret;
14586
14587   leid_type = reid_type = (u8) ~ 0;
14588
14589   /* Parse args required to build the message */
14590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14591     {
14592       if (unformat (input, "del"))
14593         {
14594           is_add = 0;
14595         }
14596       else if (unformat (input, "add"))
14597         {
14598           is_add = 1;
14599         }
14600       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14601                          &reid4, &len))
14602         {
14603           reid_type = 0;        /* ipv4 */
14604           reid_len = len;
14605         }
14606       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14607                          &reid6, &len))
14608         {
14609           reid_type = 1;        /* ipv6 */
14610           reid_len = len;
14611         }
14612       else if (unformat (input, "reid %U", unformat_ethernet_address,
14613                          reid_mac))
14614         {
14615           reid_type = 2;        /* mac */
14616         }
14617       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14618                          &leid4, &len))
14619         {
14620           leid_type = 0;        /* ipv4 */
14621           leid_len = len;
14622         }
14623       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14624                          &leid6, &len))
14625         {
14626           leid_type = 1;        /* ipv6 */
14627           leid_len = len;
14628         }
14629       else if (unformat (input, "leid %U", unformat_ethernet_address,
14630                          leid_mac))
14631         {
14632           leid_type = 2;        /* mac */
14633         }
14634       else if (unformat (input, "vni %d", &vni))
14635         {
14636           ;
14637         }
14638       else
14639         {
14640           errmsg ("parse error '%U'", format_unformat_error, input);
14641           return -99;
14642         }
14643     }
14644
14645   if ((u8) ~ 0 == reid_type)
14646     {
14647       errmsg ("missing params!");
14648       return -99;
14649     }
14650
14651   if (leid_type != reid_type)
14652     {
14653       errmsg ("remote and local EIDs are of different types!");
14654       return -99;
14655     }
14656
14657   M (ONE_ADD_DEL_ADJACENCY, mp);
14658   mp->is_add = is_add;
14659   mp->vni = htonl (vni);
14660   mp->leid_len = leid_len;
14661   mp->reid_len = reid_len;
14662   mp->eid_type = reid_type;
14663
14664   switch (mp->eid_type)
14665     {
14666     case 0:
14667       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14668       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14669       break;
14670     case 1:
14671       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14672       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14673       break;
14674     case 2:
14675       clib_memcpy (mp->leid, leid_mac, 6);
14676       clib_memcpy (mp->reid, reid_mac, 6);
14677       break;
14678     default:
14679       errmsg ("unknown EID type %d!", mp->eid_type);
14680       return 0;
14681     }
14682
14683   /* send it... */
14684   S (mp);
14685
14686   /* Wait for a reply... */
14687   W (ret);
14688   return ret;
14689 }
14690
14691 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14692
14693 uword
14694 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14695 {
14696   u32 *mode = va_arg (*args, u32 *);
14697
14698   if (unformat (input, "lisp"))
14699     *mode = 0;
14700   else if (unformat (input, "vxlan"))
14701     *mode = 1;
14702   else
14703     return 0;
14704
14705   return 1;
14706 }
14707
14708 static int
14709 api_gpe_get_encap_mode (vat_main_t * vam)
14710 {
14711   vl_api_gpe_get_encap_mode_t *mp;
14712   int ret;
14713
14714   /* Construct the API message */
14715   M (GPE_GET_ENCAP_MODE, mp);
14716
14717   /* send it... */
14718   S (mp);
14719
14720   /* Wait for a reply... */
14721   W (ret);
14722   return ret;
14723 }
14724
14725 static int
14726 api_gpe_set_encap_mode (vat_main_t * vam)
14727 {
14728   unformat_input_t *input = vam->input;
14729   vl_api_gpe_set_encap_mode_t *mp;
14730   int ret;
14731   u32 mode = 0;
14732
14733   /* Parse args required to build the message */
14734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14735     {
14736       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14737         ;
14738       else
14739         break;
14740     }
14741
14742   /* Construct the API message */
14743   M (GPE_SET_ENCAP_MODE, mp);
14744
14745   mp->mode = mode;
14746
14747   /* send it... */
14748   S (mp);
14749
14750   /* Wait for a reply... */
14751   W (ret);
14752   return ret;
14753 }
14754
14755 static int
14756 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14757 {
14758   unformat_input_t *input = vam->input;
14759   vl_api_gpe_add_del_iface_t *mp;
14760   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14761   u32 dp_table = 0, vni = 0;
14762   int ret;
14763
14764   /* Parse args required to build the message */
14765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14766     {
14767       if (unformat (input, "up"))
14768         {
14769           action_set = 1;
14770           is_add = 1;
14771         }
14772       else if (unformat (input, "down"))
14773         {
14774           action_set = 1;
14775           is_add = 0;
14776         }
14777       else if (unformat (input, "table_id %d", &dp_table))
14778         {
14779           dp_table_set = 1;
14780         }
14781       else if (unformat (input, "bd_id %d", &dp_table))
14782         {
14783           dp_table_set = 1;
14784           is_l2 = 1;
14785         }
14786       else if (unformat (input, "vni %d", &vni))
14787         {
14788           vni_set = 1;
14789         }
14790       else
14791         break;
14792     }
14793
14794   if (action_set == 0)
14795     {
14796       errmsg ("Action not set");
14797       return -99;
14798     }
14799   if (dp_table_set == 0 || vni_set == 0)
14800     {
14801       errmsg ("vni and dp_table must be set");
14802       return -99;
14803     }
14804
14805   /* Construct the API message */
14806   M (GPE_ADD_DEL_IFACE, mp);
14807
14808   mp->is_add = is_add;
14809   mp->dp_table = dp_table;
14810   mp->is_l2 = is_l2;
14811   mp->vni = vni;
14812
14813   /* send it... */
14814   S (mp);
14815
14816   /* Wait for a reply... */
14817   W (ret);
14818   return ret;
14819 }
14820
14821 /**
14822  * Add/del map request itr rlocs from ONE control plane and updates
14823  *
14824  * @param vam vpp API test context
14825  * @return return code
14826  */
14827 static int
14828 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14829 {
14830   unformat_input_t *input = vam->input;
14831   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14832   u8 *locator_set_name = 0;
14833   u8 locator_set_name_set = 0;
14834   u8 is_add = 1;
14835   int ret;
14836
14837   /* Parse args required to build the message */
14838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14839     {
14840       if (unformat (input, "del"))
14841         {
14842           is_add = 0;
14843         }
14844       else if (unformat (input, "%_%v%_", &locator_set_name))
14845         {
14846           locator_set_name_set = 1;
14847         }
14848       else
14849         {
14850           clib_warning ("parse error '%U'", format_unformat_error, input);
14851           return -99;
14852         }
14853     }
14854
14855   if (is_add && !locator_set_name_set)
14856     {
14857       errmsg ("itr-rloc is not set!");
14858       return -99;
14859     }
14860
14861   if (is_add && vec_len (locator_set_name) > 64)
14862     {
14863       errmsg ("itr-rloc locator-set name too long");
14864       vec_free (locator_set_name);
14865       return -99;
14866     }
14867
14868   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14869   mp->is_add = is_add;
14870   if (is_add)
14871     {
14872       clib_memcpy (mp->locator_set_name, locator_set_name,
14873                    vec_len (locator_set_name));
14874     }
14875   else
14876     {
14877       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14878     }
14879   vec_free (locator_set_name);
14880
14881   /* send it... */
14882   S (mp);
14883
14884   /* Wait for a reply... */
14885   W (ret);
14886   return ret;
14887 }
14888
14889 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14890
14891 static int
14892 api_one_locator_dump (vat_main_t * vam)
14893 {
14894   unformat_input_t *input = vam->input;
14895   vl_api_one_locator_dump_t *mp;
14896   vl_api_control_ping_t *mp_ping;
14897   u8 is_index_set = 0, is_name_set = 0;
14898   u8 *ls_name = 0;
14899   u32 ls_index = ~0;
14900   int ret;
14901
14902   /* Parse args required to build the message */
14903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14904     {
14905       if (unformat (input, "ls_name %_%v%_", &ls_name))
14906         {
14907           is_name_set = 1;
14908         }
14909       else if (unformat (input, "ls_index %d", &ls_index))
14910         {
14911           is_index_set = 1;
14912         }
14913       else
14914         {
14915           errmsg ("parse error '%U'", format_unformat_error, input);
14916           return -99;
14917         }
14918     }
14919
14920   if (!is_index_set && !is_name_set)
14921     {
14922       errmsg ("error: expected one of index or name!");
14923       return -99;
14924     }
14925
14926   if (is_index_set && is_name_set)
14927     {
14928       errmsg ("error: only one param expected!");
14929       return -99;
14930     }
14931
14932   if (vec_len (ls_name) > 62)
14933     {
14934       errmsg ("error: locator set name too long!");
14935       return -99;
14936     }
14937
14938   if (!vam->json_output)
14939     {
14940       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14941     }
14942
14943   M (ONE_LOCATOR_DUMP, mp);
14944   mp->is_index_set = is_index_set;
14945
14946   if (is_index_set)
14947     mp->ls_index = clib_host_to_net_u32 (ls_index);
14948   else
14949     {
14950       vec_add1 (ls_name, 0);
14951       strncpy ((char *) mp->ls_name, (char *) ls_name,
14952                sizeof (mp->ls_name) - 1);
14953     }
14954
14955   /* send it... */
14956   S (mp);
14957
14958   /* Use a control ping for synchronization */
14959   M (CONTROL_PING, mp_ping);
14960   S (mp_ping);
14961
14962   /* Wait for a reply... */
14963   W (ret);
14964   return ret;
14965 }
14966
14967 #define api_lisp_locator_dump api_one_locator_dump
14968
14969 static int
14970 api_one_locator_set_dump (vat_main_t * vam)
14971 {
14972   vl_api_one_locator_set_dump_t *mp;
14973   vl_api_control_ping_t *mp_ping;
14974   unformat_input_t *input = vam->input;
14975   u8 filter = 0;
14976   int ret;
14977
14978   /* Parse args required to build the message */
14979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14980     {
14981       if (unformat (input, "local"))
14982         {
14983           filter = 1;
14984         }
14985       else if (unformat (input, "remote"))
14986         {
14987           filter = 2;
14988         }
14989       else
14990         {
14991           errmsg ("parse error '%U'", format_unformat_error, input);
14992           return -99;
14993         }
14994     }
14995
14996   if (!vam->json_output)
14997     {
14998       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14999     }
15000
15001   M (ONE_LOCATOR_SET_DUMP, mp);
15002
15003   mp->filter = filter;
15004
15005   /* send it... */
15006   S (mp);
15007
15008   /* Use a control ping for synchronization */
15009   M (CONTROL_PING, mp_ping);
15010   S (mp_ping);
15011
15012   /* Wait for a reply... */
15013   W (ret);
15014   return ret;
15015 }
15016
15017 #define api_lisp_locator_set_dump api_one_locator_set_dump
15018
15019 static int
15020 api_one_eid_table_map_dump (vat_main_t * vam)
15021 {
15022   u8 is_l2 = 0;
15023   u8 mode_set = 0;
15024   unformat_input_t *input = vam->input;
15025   vl_api_one_eid_table_map_dump_t *mp;
15026   vl_api_control_ping_t *mp_ping;
15027   int ret;
15028
15029   /* Parse args required to build the message */
15030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15031     {
15032       if (unformat (input, "l2"))
15033         {
15034           is_l2 = 1;
15035           mode_set = 1;
15036         }
15037       else if (unformat (input, "l3"))
15038         {
15039           is_l2 = 0;
15040           mode_set = 1;
15041         }
15042       else
15043         {
15044           errmsg ("parse error '%U'", format_unformat_error, input);
15045           return -99;
15046         }
15047     }
15048
15049   if (!mode_set)
15050     {
15051       errmsg ("expected one of 'l2' or 'l3' parameter!");
15052       return -99;
15053     }
15054
15055   if (!vam->json_output)
15056     {
15057       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15058     }
15059
15060   M (ONE_EID_TABLE_MAP_DUMP, mp);
15061   mp->is_l2 = is_l2;
15062
15063   /* send it... */
15064   S (mp);
15065
15066   /* Use a control ping for synchronization */
15067   M (CONTROL_PING, mp_ping);
15068   S (mp_ping);
15069
15070   /* Wait for a reply... */
15071   W (ret);
15072   return ret;
15073 }
15074
15075 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15076
15077 static int
15078 api_one_eid_table_vni_dump (vat_main_t * vam)
15079 {
15080   vl_api_one_eid_table_vni_dump_t *mp;
15081   vl_api_control_ping_t *mp_ping;
15082   int ret;
15083
15084   if (!vam->json_output)
15085     {
15086       print (vam->ofp, "VNI");
15087     }
15088
15089   M (ONE_EID_TABLE_VNI_DUMP, mp);
15090
15091   /* send it... */
15092   S (mp);
15093
15094   /* Use a control ping for synchronization */
15095   M (CONTROL_PING, mp_ping);
15096   S (mp_ping);
15097
15098   /* Wait for a reply... */
15099   W (ret);
15100   return ret;
15101 }
15102
15103 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15104
15105 static int
15106 api_one_eid_table_dump (vat_main_t * vam)
15107 {
15108   unformat_input_t *i = vam->input;
15109   vl_api_one_eid_table_dump_t *mp;
15110   vl_api_control_ping_t *mp_ping;
15111   struct in_addr ip4;
15112   struct in6_addr ip6;
15113   u8 mac[6];
15114   u8 eid_type = ~0, eid_set = 0;
15115   u32 prefix_length = ~0, t, vni = 0;
15116   u8 filter = 0;
15117   int ret;
15118
15119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15120     {
15121       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15122         {
15123           eid_set = 1;
15124           eid_type = 0;
15125           prefix_length = t;
15126         }
15127       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15128         {
15129           eid_set = 1;
15130           eid_type = 1;
15131           prefix_length = t;
15132         }
15133       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15134         {
15135           eid_set = 1;
15136           eid_type = 2;
15137         }
15138       else if (unformat (i, "vni %d", &t))
15139         {
15140           vni = t;
15141         }
15142       else if (unformat (i, "local"))
15143         {
15144           filter = 1;
15145         }
15146       else if (unformat (i, "remote"))
15147         {
15148           filter = 2;
15149         }
15150       else
15151         {
15152           errmsg ("parse error '%U'", format_unformat_error, i);
15153           return -99;
15154         }
15155     }
15156
15157   if (!vam->json_output)
15158     {
15159       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15160              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15161     }
15162
15163   M (ONE_EID_TABLE_DUMP, mp);
15164
15165   mp->filter = filter;
15166   if (eid_set)
15167     {
15168       mp->eid_set = 1;
15169       mp->vni = htonl (vni);
15170       mp->eid_type = eid_type;
15171       switch (eid_type)
15172         {
15173         case 0:
15174           mp->prefix_length = prefix_length;
15175           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15176           break;
15177         case 1:
15178           mp->prefix_length = prefix_length;
15179           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15180           break;
15181         case 2:
15182           clib_memcpy (mp->eid, mac, sizeof (mac));
15183           break;
15184         default:
15185           errmsg ("unknown EID type %d!", eid_type);
15186           return -99;
15187         }
15188     }
15189
15190   /* send it... */
15191   S (mp);
15192
15193   /* Use a control ping for synchronization */
15194   M (CONTROL_PING, mp_ping);
15195   S (mp_ping);
15196
15197   /* Wait for a reply... */
15198   W (ret);
15199   return ret;
15200 }
15201
15202 #define api_lisp_eid_table_dump api_one_eid_table_dump
15203
15204 static int
15205 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15206 {
15207   unformat_input_t *i = vam->input;
15208   vl_api_gpe_fwd_entries_get_t *mp;
15209   u8 vni_set = 0;
15210   u32 vni = ~0;
15211   int ret;
15212
15213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15214     {
15215       if (unformat (i, "vni %d", &vni))
15216         {
15217           vni_set = 1;
15218         }
15219       else
15220         {
15221           errmsg ("parse error '%U'", format_unformat_error, i);
15222           return -99;
15223         }
15224     }
15225
15226   if (!vni_set)
15227     {
15228       errmsg ("vni not set!");
15229       return -99;
15230     }
15231
15232   if (!vam->json_output)
15233     {
15234       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15235              "leid", "reid");
15236     }
15237
15238   M (GPE_FWD_ENTRIES_GET, mp);
15239   mp->vni = clib_host_to_net_u32 (vni);
15240
15241   /* send it... */
15242   S (mp);
15243
15244   /* Wait for a reply... */
15245   W (ret);
15246   return ret;
15247 }
15248
15249 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15250 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15251 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15252 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15253
15254 static int
15255 api_one_adjacencies_get (vat_main_t * vam)
15256 {
15257   unformat_input_t *i = vam->input;
15258   vl_api_one_adjacencies_get_t *mp;
15259   u8 vni_set = 0;
15260   u32 vni = ~0;
15261   int ret;
15262
15263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15264     {
15265       if (unformat (i, "vni %d", &vni))
15266         {
15267           vni_set = 1;
15268         }
15269       else
15270         {
15271           errmsg ("parse error '%U'", format_unformat_error, i);
15272           return -99;
15273         }
15274     }
15275
15276   if (!vni_set)
15277     {
15278       errmsg ("vni not set!");
15279       return -99;
15280     }
15281
15282   if (!vam->json_output)
15283     {
15284       print (vam->ofp, "%s %40s", "leid", "reid");
15285     }
15286
15287   M (ONE_ADJACENCIES_GET, mp);
15288   mp->vni = clib_host_to_net_u32 (vni);
15289
15290   /* send it... */
15291   S (mp);
15292
15293   /* Wait for a reply... */
15294   W (ret);
15295   return ret;
15296 }
15297
15298 #define api_lisp_adjacencies_get api_one_adjacencies_get
15299
15300 static int
15301 api_one_map_server_dump (vat_main_t * vam)
15302 {
15303   vl_api_one_map_server_dump_t *mp;
15304   vl_api_control_ping_t *mp_ping;
15305   int ret;
15306
15307   if (!vam->json_output)
15308     {
15309       print (vam->ofp, "%=20s", "Map server");
15310     }
15311
15312   M (ONE_MAP_SERVER_DUMP, mp);
15313   /* send it... */
15314   S (mp);
15315
15316   /* Use a control ping for synchronization */
15317   M (CONTROL_PING, mp_ping);
15318   S (mp_ping);
15319
15320   /* Wait for a reply... */
15321   W (ret);
15322   return ret;
15323 }
15324
15325 #define api_lisp_map_server_dump api_one_map_server_dump
15326
15327 static int
15328 api_one_map_resolver_dump (vat_main_t * vam)
15329 {
15330   vl_api_one_map_resolver_dump_t *mp;
15331   vl_api_control_ping_t *mp_ping;
15332   int ret;
15333
15334   if (!vam->json_output)
15335     {
15336       print (vam->ofp, "%=20s", "Map resolver");
15337     }
15338
15339   M (ONE_MAP_RESOLVER_DUMP, mp);
15340   /* send it... */
15341   S (mp);
15342
15343   /* Use a control ping for synchronization */
15344   M (CONTROL_PING, mp_ping);
15345   S (mp_ping);
15346
15347   /* Wait for a reply... */
15348   W (ret);
15349   return ret;
15350 }
15351
15352 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15353
15354 static int
15355 api_show_one_status (vat_main_t * vam)
15356 {
15357   vl_api_show_one_status_t *mp;
15358   int ret;
15359
15360   if (!vam->json_output)
15361     {
15362       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15363     }
15364
15365   M (SHOW_ONE_STATUS, mp);
15366   /* send it... */
15367   S (mp);
15368   /* Wait for a reply... */
15369   W (ret);
15370   return ret;
15371 }
15372
15373 #define api_show_lisp_status api_show_one_status
15374
15375 static int
15376 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15377 {
15378   vl_api_gpe_fwd_entry_path_dump_t *mp;
15379   vl_api_control_ping_t *mp_ping;
15380   unformat_input_t *i = vam->input;
15381   u32 fwd_entry_index = ~0;
15382   int ret;
15383
15384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15385     {
15386       if (unformat (i, "index %d", &fwd_entry_index))
15387         ;
15388       else
15389         break;
15390     }
15391
15392   if (~0 == fwd_entry_index)
15393     {
15394       errmsg ("no index specified!");
15395       return -99;
15396     }
15397
15398   if (!vam->json_output)
15399     {
15400       print (vam->ofp, "first line");
15401     }
15402
15403   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15404
15405   /* send it... */
15406   S (mp);
15407   /* Use a control ping for synchronization */
15408   M (CONTROL_PING, mp_ping);
15409   S (mp_ping);
15410
15411   /* Wait for a reply... */
15412   W (ret);
15413   return ret;
15414 }
15415
15416 static int
15417 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15418 {
15419   vl_api_one_get_map_request_itr_rlocs_t *mp;
15420   int ret;
15421
15422   if (!vam->json_output)
15423     {
15424       print (vam->ofp, "%=20s", "itr-rlocs:");
15425     }
15426
15427   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15428   /* send it... */
15429   S (mp);
15430   /* Wait for a reply... */
15431   W (ret);
15432   return ret;
15433 }
15434
15435 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15436
15437 static int
15438 api_af_packet_create (vat_main_t * vam)
15439 {
15440   unformat_input_t *i = vam->input;
15441   vl_api_af_packet_create_t *mp;
15442   u8 *host_if_name = 0;
15443   u8 hw_addr[6];
15444   u8 random_hw_addr = 1;
15445   int ret;
15446
15447   memset (hw_addr, 0, sizeof (hw_addr));
15448
15449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15450     {
15451       if (unformat (i, "name %s", &host_if_name))
15452         vec_add1 (host_if_name, 0);
15453       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15454         random_hw_addr = 0;
15455       else
15456         break;
15457     }
15458
15459   if (!vec_len (host_if_name))
15460     {
15461       errmsg ("host-interface name must be specified");
15462       return -99;
15463     }
15464
15465   if (vec_len (host_if_name) > 64)
15466     {
15467       errmsg ("host-interface name too long");
15468       return -99;
15469     }
15470
15471   M (AF_PACKET_CREATE, mp);
15472
15473   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15474   clib_memcpy (mp->hw_addr, hw_addr, 6);
15475   mp->use_random_hw_addr = random_hw_addr;
15476   vec_free (host_if_name);
15477
15478   S (mp);
15479
15480   /* *INDENT-OFF* */
15481   W2 (ret,
15482       ({
15483         if (ret == 0)
15484           fprintf (vam->ofp ? vam->ofp : stderr,
15485                    " new sw_if_index = %d\n", vam->sw_if_index);
15486       }));
15487   /* *INDENT-ON* */
15488   return ret;
15489 }
15490
15491 static int
15492 api_af_packet_delete (vat_main_t * vam)
15493 {
15494   unformat_input_t *i = vam->input;
15495   vl_api_af_packet_delete_t *mp;
15496   u8 *host_if_name = 0;
15497   int ret;
15498
15499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15500     {
15501       if (unformat (i, "name %s", &host_if_name))
15502         vec_add1 (host_if_name, 0);
15503       else
15504         break;
15505     }
15506
15507   if (!vec_len (host_if_name))
15508     {
15509       errmsg ("host-interface name must be specified");
15510       return -99;
15511     }
15512
15513   if (vec_len (host_if_name) > 64)
15514     {
15515       errmsg ("host-interface name too long");
15516       return -99;
15517     }
15518
15519   M (AF_PACKET_DELETE, mp);
15520
15521   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15522   vec_free (host_if_name);
15523
15524   S (mp);
15525   W (ret);
15526   return ret;
15527 }
15528
15529 static int
15530 api_policer_add_del (vat_main_t * vam)
15531 {
15532   unformat_input_t *i = vam->input;
15533   vl_api_policer_add_del_t *mp;
15534   u8 is_add = 1;
15535   u8 *name = 0;
15536   u32 cir = 0;
15537   u32 eir = 0;
15538   u64 cb = 0;
15539   u64 eb = 0;
15540   u8 rate_type = 0;
15541   u8 round_type = 0;
15542   u8 type = 0;
15543   u8 color_aware = 0;
15544   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15545   int ret;
15546
15547   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15548   conform_action.dscp = 0;
15549   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15550   exceed_action.dscp = 0;
15551   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15552   violate_action.dscp = 0;
15553
15554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15555     {
15556       if (unformat (i, "del"))
15557         is_add = 0;
15558       else if (unformat (i, "name %s", &name))
15559         vec_add1 (name, 0);
15560       else if (unformat (i, "cir %u", &cir))
15561         ;
15562       else if (unformat (i, "eir %u", &eir))
15563         ;
15564       else if (unformat (i, "cb %u", &cb))
15565         ;
15566       else if (unformat (i, "eb %u", &eb))
15567         ;
15568       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15569                          &rate_type))
15570         ;
15571       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15572                          &round_type))
15573         ;
15574       else if (unformat (i, "type %U", unformat_policer_type, &type))
15575         ;
15576       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15577                          &conform_action))
15578         ;
15579       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15580                          &exceed_action))
15581         ;
15582       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15583                          &violate_action))
15584         ;
15585       else if (unformat (i, "color-aware"))
15586         color_aware = 1;
15587       else
15588         break;
15589     }
15590
15591   if (!vec_len (name))
15592     {
15593       errmsg ("policer name must be specified");
15594       return -99;
15595     }
15596
15597   if (vec_len (name) > 64)
15598     {
15599       errmsg ("policer name too long");
15600       return -99;
15601     }
15602
15603   M (POLICER_ADD_DEL, mp);
15604
15605   clib_memcpy (mp->name, name, vec_len (name));
15606   vec_free (name);
15607   mp->is_add = is_add;
15608   mp->cir = cir;
15609   mp->eir = eir;
15610   mp->cb = cb;
15611   mp->eb = eb;
15612   mp->rate_type = rate_type;
15613   mp->round_type = round_type;
15614   mp->type = type;
15615   mp->conform_action_type = conform_action.action_type;
15616   mp->conform_dscp = conform_action.dscp;
15617   mp->exceed_action_type = exceed_action.action_type;
15618   mp->exceed_dscp = exceed_action.dscp;
15619   mp->violate_action_type = violate_action.action_type;
15620   mp->violate_dscp = violate_action.dscp;
15621   mp->color_aware = color_aware;
15622
15623   S (mp);
15624   W (ret);
15625   return ret;
15626 }
15627
15628 static int
15629 api_policer_dump (vat_main_t * vam)
15630 {
15631   unformat_input_t *i = vam->input;
15632   vl_api_policer_dump_t *mp;
15633   vl_api_control_ping_t *mp_ping;
15634   u8 *match_name = 0;
15635   u8 match_name_valid = 0;
15636   int ret;
15637
15638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15639     {
15640       if (unformat (i, "name %s", &match_name))
15641         {
15642           vec_add1 (match_name, 0);
15643           match_name_valid = 1;
15644         }
15645       else
15646         break;
15647     }
15648
15649   M (POLICER_DUMP, mp);
15650   mp->match_name_valid = match_name_valid;
15651   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15652   vec_free (match_name);
15653   /* send it... */
15654   S (mp);
15655
15656   /* Use a control ping for synchronization */
15657   M (CONTROL_PING, mp_ping);
15658   S (mp_ping);
15659
15660   /* Wait for a reply... */
15661   W (ret);
15662   return ret;
15663 }
15664
15665 static int
15666 api_policer_classify_set_interface (vat_main_t * vam)
15667 {
15668   unformat_input_t *i = vam->input;
15669   vl_api_policer_classify_set_interface_t *mp;
15670   u32 sw_if_index;
15671   int sw_if_index_set;
15672   u32 ip4_table_index = ~0;
15673   u32 ip6_table_index = ~0;
15674   u32 l2_table_index = ~0;
15675   u8 is_add = 1;
15676   int ret;
15677
15678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15679     {
15680       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15681         sw_if_index_set = 1;
15682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15683         sw_if_index_set = 1;
15684       else if (unformat (i, "del"))
15685         is_add = 0;
15686       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15687         ;
15688       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15689         ;
15690       else if (unformat (i, "l2-table %d", &l2_table_index))
15691         ;
15692       else
15693         {
15694           clib_warning ("parse error '%U'", format_unformat_error, i);
15695           return -99;
15696         }
15697     }
15698
15699   if (sw_if_index_set == 0)
15700     {
15701       errmsg ("missing interface name or sw_if_index");
15702       return -99;
15703     }
15704
15705   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15706
15707   mp->sw_if_index = ntohl (sw_if_index);
15708   mp->ip4_table_index = ntohl (ip4_table_index);
15709   mp->ip6_table_index = ntohl (ip6_table_index);
15710   mp->l2_table_index = ntohl (l2_table_index);
15711   mp->is_add = is_add;
15712
15713   S (mp);
15714   W (ret);
15715   return ret;
15716 }
15717
15718 static int
15719 api_policer_classify_dump (vat_main_t * vam)
15720 {
15721   unformat_input_t *i = vam->input;
15722   vl_api_policer_classify_dump_t *mp;
15723   vl_api_control_ping_t *mp_ping;
15724   u8 type = POLICER_CLASSIFY_N_TABLES;
15725   int ret;
15726
15727   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15728     ;
15729   else
15730     {
15731       errmsg ("classify table type must be specified");
15732       return -99;
15733     }
15734
15735   if (!vam->json_output)
15736     {
15737       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15738     }
15739
15740   M (POLICER_CLASSIFY_DUMP, mp);
15741   mp->type = type;
15742   /* send it... */
15743   S (mp);
15744
15745   /* Use a control ping for synchronization */
15746   M (CONTROL_PING, mp_ping);
15747   S (mp_ping);
15748
15749   /* Wait for a reply... */
15750   W (ret);
15751   return ret;
15752 }
15753
15754 static int
15755 api_netmap_create (vat_main_t * vam)
15756 {
15757   unformat_input_t *i = vam->input;
15758   vl_api_netmap_create_t *mp;
15759   u8 *if_name = 0;
15760   u8 hw_addr[6];
15761   u8 random_hw_addr = 1;
15762   u8 is_pipe = 0;
15763   u8 is_master = 0;
15764   int ret;
15765
15766   memset (hw_addr, 0, sizeof (hw_addr));
15767
15768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15769     {
15770       if (unformat (i, "name %s", &if_name))
15771         vec_add1 (if_name, 0);
15772       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15773         random_hw_addr = 0;
15774       else if (unformat (i, "pipe"))
15775         is_pipe = 1;
15776       else if (unformat (i, "master"))
15777         is_master = 1;
15778       else if (unformat (i, "slave"))
15779         is_master = 0;
15780       else
15781         break;
15782     }
15783
15784   if (!vec_len (if_name))
15785     {
15786       errmsg ("interface name must be specified");
15787       return -99;
15788     }
15789
15790   if (vec_len (if_name) > 64)
15791     {
15792       errmsg ("interface name too long");
15793       return -99;
15794     }
15795
15796   M (NETMAP_CREATE, mp);
15797
15798   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15799   clib_memcpy (mp->hw_addr, hw_addr, 6);
15800   mp->use_random_hw_addr = random_hw_addr;
15801   mp->is_pipe = is_pipe;
15802   mp->is_master = is_master;
15803   vec_free (if_name);
15804
15805   S (mp);
15806   W (ret);
15807   return ret;
15808 }
15809
15810 static int
15811 api_netmap_delete (vat_main_t * vam)
15812 {
15813   unformat_input_t *i = vam->input;
15814   vl_api_netmap_delete_t *mp;
15815   u8 *if_name = 0;
15816   int ret;
15817
15818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15819     {
15820       if (unformat (i, "name %s", &if_name))
15821         vec_add1 (if_name, 0);
15822       else
15823         break;
15824     }
15825
15826   if (!vec_len (if_name))
15827     {
15828       errmsg ("interface name must be specified");
15829       return -99;
15830     }
15831
15832   if (vec_len (if_name) > 64)
15833     {
15834       errmsg ("interface name too long");
15835       return -99;
15836     }
15837
15838   M (NETMAP_DELETE, mp);
15839
15840   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15841   vec_free (if_name);
15842
15843   S (mp);
15844   W (ret);
15845   return ret;
15846 }
15847
15848 static void vl_api_mpls_tunnel_details_t_handler
15849   (vl_api_mpls_tunnel_details_t * mp)
15850 {
15851   vat_main_t *vam = &vat_main;
15852   i32 len = mp->mt_next_hop_n_labels;
15853   i32 i;
15854
15855   print (vam->ofp, "[%d]: via %U %d labels ",
15856          mp->tunnel_index,
15857          format_ip4_address, mp->mt_next_hop,
15858          ntohl (mp->mt_next_hop_sw_if_index));
15859   for (i = 0; i < len; i++)
15860     {
15861       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15862     }
15863   print (vam->ofp, "");
15864 }
15865
15866 static void vl_api_mpls_tunnel_details_t_handler_json
15867   (vl_api_mpls_tunnel_details_t * mp)
15868 {
15869   vat_main_t *vam = &vat_main;
15870   vat_json_node_t *node = NULL;
15871   struct in_addr ip4;
15872   i32 i;
15873   i32 len = mp->mt_next_hop_n_labels;
15874
15875   if (VAT_JSON_ARRAY != vam->json_tree.type)
15876     {
15877       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15878       vat_json_init_array (&vam->json_tree);
15879     }
15880   node = vat_json_array_add (&vam->json_tree);
15881
15882   vat_json_init_object (node);
15883   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15884   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15885   vat_json_object_add_ip4 (node, "next_hop", ip4);
15886   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15887                             ntohl (mp->mt_next_hop_sw_if_index));
15888   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15889   vat_json_object_add_uint (node, "label_count", len);
15890   for (i = 0; i < len; i++)
15891     {
15892       vat_json_object_add_uint (node, "label",
15893                                 ntohl (mp->mt_next_hop_out_labels[i]));
15894     }
15895 }
15896
15897 static int
15898 api_mpls_tunnel_dump (vat_main_t * vam)
15899 {
15900   vl_api_mpls_tunnel_dump_t *mp;
15901   vl_api_control_ping_t *mp_ping;
15902   i32 index = -1;
15903   int ret;
15904
15905   /* Parse args required to build the message */
15906   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15907     {
15908       if (!unformat (vam->input, "tunnel_index %d", &index))
15909         {
15910           index = -1;
15911           break;
15912         }
15913     }
15914
15915   print (vam->ofp, "  tunnel_index %d", index);
15916
15917   M (MPLS_TUNNEL_DUMP, mp);
15918   mp->tunnel_index = htonl (index);
15919   S (mp);
15920
15921   /* Use a control ping for synchronization */
15922   M (CONTROL_PING, mp_ping);
15923   S (mp_ping);
15924
15925   W (ret);
15926   return ret;
15927 }
15928
15929 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15930 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15931
15932 static void
15933 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15934 {
15935   vat_main_t *vam = &vat_main;
15936   int count = ntohl (mp->count);
15937   vl_api_fib_path2_t *fp;
15938   int i;
15939
15940   print (vam->ofp,
15941          "table-id %d, label %u, ess_bit %u",
15942          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15943   fp = mp->path;
15944   for (i = 0; i < count; i++)
15945     {
15946       if (fp->afi == IP46_TYPE_IP6)
15947         print (vam->ofp,
15948                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15949                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15950                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15951                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15952                format_ip6_address, fp->next_hop);
15953       else if (fp->afi == IP46_TYPE_IP4)
15954         print (vam->ofp,
15955                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15956                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15957                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15958                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15959                format_ip4_address, fp->next_hop);
15960       fp++;
15961     }
15962 }
15963
15964 static void vl_api_mpls_fib_details_t_handler_json
15965   (vl_api_mpls_fib_details_t * mp)
15966 {
15967   vat_main_t *vam = &vat_main;
15968   int count = ntohl (mp->count);
15969   vat_json_node_t *node = NULL;
15970   struct in_addr ip4;
15971   struct in6_addr ip6;
15972   vl_api_fib_path2_t *fp;
15973   int i;
15974
15975   if (VAT_JSON_ARRAY != vam->json_tree.type)
15976     {
15977       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15978       vat_json_init_array (&vam->json_tree);
15979     }
15980   node = vat_json_array_add (&vam->json_tree);
15981
15982   vat_json_init_object (node);
15983   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15984   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15985   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15986   vat_json_object_add_uint (node, "path_count", count);
15987   fp = mp->path;
15988   for (i = 0; i < count; i++)
15989     {
15990       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15991       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15992       vat_json_object_add_uint (node, "is_local", fp->is_local);
15993       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15994       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15995       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15996       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15997       if (fp->afi == IP46_TYPE_IP4)
15998         {
15999           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16000           vat_json_object_add_ip4 (node, "next_hop", ip4);
16001         }
16002       else if (fp->afi == IP46_TYPE_IP6)
16003         {
16004           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16005           vat_json_object_add_ip6 (node, "next_hop", ip6);
16006         }
16007     }
16008 }
16009
16010 static int
16011 api_mpls_fib_dump (vat_main_t * vam)
16012 {
16013   vl_api_mpls_fib_dump_t *mp;
16014   vl_api_control_ping_t *mp_ping;
16015   int ret;
16016
16017   M (MPLS_FIB_DUMP, mp);
16018   S (mp);
16019
16020   /* Use a control ping for synchronization */
16021   M (CONTROL_PING, mp_ping);
16022   S (mp_ping);
16023
16024   W (ret);
16025   return ret;
16026 }
16027
16028 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16029 #define vl_api_ip_fib_details_t_print vl_noop_handler
16030
16031 static void
16032 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16033 {
16034   vat_main_t *vam = &vat_main;
16035   int count = ntohl (mp->count);
16036   vl_api_fib_path_t *fp;
16037   int i;
16038
16039   print (vam->ofp,
16040          "table-id %d, prefix %U/%d",
16041          ntohl (mp->table_id), format_ip4_address, mp->address,
16042          mp->address_length);
16043   fp = mp->path;
16044   for (i = 0; i < count; i++)
16045     {
16046       if (fp->afi == IP46_TYPE_IP6)
16047         print (vam->ofp,
16048                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16049                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16050                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16051                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16052                format_ip6_address, fp->next_hop);
16053       else if (fp->afi == IP46_TYPE_IP4)
16054         print (vam->ofp,
16055                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16056                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16057                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16058                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16059                format_ip4_address, fp->next_hop);
16060       fp++;
16061     }
16062 }
16063
16064 static void vl_api_ip_fib_details_t_handler_json
16065   (vl_api_ip_fib_details_t * mp)
16066 {
16067   vat_main_t *vam = &vat_main;
16068   int count = ntohl (mp->count);
16069   vat_json_node_t *node = NULL;
16070   struct in_addr ip4;
16071   struct in6_addr ip6;
16072   vl_api_fib_path_t *fp;
16073   int i;
16074
16075   if (VAT_JSON_ARRAY != vam->json_tree.type)
16076     {
16077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16078       vat_json_init_array (&vam->json_tree);
16079     }
16080   node = vat_json_array_add (&vam->json_tree);
16081
16082   vat_json_init_object (node);
16083   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16084   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16085   vat_json_object_add_ip4 (node, "prefix", ip4);
16086   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16087   vat_json_object_add_uint (node, "path_count", count);
16088   fp = mp->path;
16089   for (i = 0; i < count; i++)
16090     {
16091       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16092       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16093       vat_json_object_add_uint (node, "is_local", fp->is_local);
16094       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16095       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16096       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16097       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16098       if (fp->afi == IP46_TYPE_IP4)
16099         {
16100           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16101           vat_json_object_add_ip4 (node, "next_hop", ip4);
16102         }
16103       else if (fp->afi == IP46_TYPE_IP6)
16104         {
16105           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16106           vat_json_object_add_ip6 (node, "next_hop", ip6);
16107         }
16108     }
16109 }
16110
16111 static int
16112 api_ip_fib_dump (vat_main_t * vam)
16113 {
16114   vl_api_ip_fib_dump_t *mp;
16115   vl_api_control_ping_t *mp_ping;
16116   int ret;
16117
16118   M (IP_FIB_DUMP, mp);
16119   S (mp);
16120
16121   /* Use a control ping for synchronization */
16122   M (CONTROL_PING, mp_ping);
16123   S (mp_ping);
16124
16125   W (ret);
16126   return ret;
16127 }
16128
16129 static int
16130 api_ip_mfib_dump (vat_main_t * vam)
16131 {
16132   vl_api_ip_mfib_dump_t *mp;
16133   vl_api_control_ping_t *mp_ping;
16134   int ret;
16135
16136   M (IP_MFIB_DUMP, mp);
16137   S (mp);
16138
16139   /* Use a control ping for synchronization */
16140   M (CONTROL_PING, mp_ping);
16141   S (mp_ping);
16142
16143   W (ret);
16144   return ret;
16145 }
16146
16147 static void vl_api_ip_neighbor_details_t_handler
16148   (vl_api_ip_neighbor_details_t * mp)
16149 {
16150   vat_main_t *vam = &vat_main;
16151
16152   print (vam->ofp, "%c %U %U",
16153          (mp->is_static) ? 'S' : 'D',
16154          format_ethernet_address, &mp->mac_address,
16155          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16156          &mp->ip_address);
16157 }
16158
16159 static void vl_api_ip_neighbor_details_t_handler_json
16160   (vl_api_ip_neighbor_details_t * mp)
16161 {
16162
16163   vat_main_t *vam = &vat_main;
16164   vat_json_node_t *node;
16165   struct in_addr ip4;
16166   struct in6_addr ip6;
16167
16168   if (VAT_JSON_ARRAY != vam->json_tree.type)
16169     {
16170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16171       vat_json_init_array (&vam->json_tree);
16172     }
16173   node = vat_json_array_add (&vam->json_tree);
16174
16175   vat_json_init_object (node);
16176   vat_json_object_add_string_copy (node, "flag",
16177                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16178                                    "dynamic");
16179
16180   vat_json_object_add_string_copy (node, "link_layer",
16181                                    format (0, "%U", format_ethernet_address,
16182                                            &mp->mac_address));
16183
16184   if (mp->is_ipv6)
16185     {
16186       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16187       vat_json_object_add_ip6 (node, "ip_address", ip6);
16188     }
16189   else
16190     {
16191       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16192       vat_json_object_add_ip4 (node, "ip_address", ip4);
16193     }
16194 }
16195
16196 static int
16197 api_ip_neighbor_dump (vat_main_t * vam)
16198 {
16199   unformat_input_t *i = vam->input;
16200   vl_api_ip_neighbor_dump_t *mp;
16201   vl_api_control_ping_t *mp_ping;
16202   u8 is_ipv6 = 0;
16203   u32 sw_if_index = ~0;
16204   int ret;
16205
16206   /* Parse args required to build the message */
16207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16208     {
16209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16210         ;
16211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16212         ;
16213       else if (unformat (i, "ip6"))
16214         is_ipv6 = 1;
16215       else
16216         break;
16217     }
16218
16219   if (sw_if_index == ~0)
16220     {
16221       errmsg ("missing interface name or sw_if_index");
16222       return -99;
16223     }
16224
16225   M (IP_NEIGHBOR_DUMP, mp);
16226   mp->is_ipv6 = (u8) is_ipv6;
16227   mp->sw_if_index = ntohl (sw_if_index);
16228   S (mp);
16229
16230   /* Use a control ping for synchronization */
16231   M (CONTROL_PING, mp_ping);
16232   S (mp_ping);
16233
16234   W (ret);
16235   return ret;
16236 }
16237
16238 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16239 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16240
16241 static void
16242 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16243 {
16244   vat_main_t *vam = &vat_main;
16245   int count = ntohl (mp->count);
16246   vl_api_fib_path_t *fp;
16247   int i;
16248
16249   print (vam->ofp,
16250          "table-id %d, prefix %U/%d",
16251          ntohl (mp->table_id), format_ip6_address, mp->address,
16252          mp->address_length);
16253   fp = mp->path;
16254   for (i = 0; i < count; i++)
16255     {
16256       if (fp->afi == IP46_TYPE_IP6)
16257         print (vam->ofp,
16258                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16259                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16260                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16261                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16262                format_ip6_address, fp->next_hop);
16263       else if (fp->afi == IP46_TYPE_IP4)
16264         print (vam->ofp,
16265                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16266                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16267                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16268                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16269                format_ip4_address, fp->next_hop);
16270       fp++;
16271     }
16272 }
16273
16274 static void vl_api_ip6_fib_details_t_handler_json
16275   (vl_api_ip6_fib_details_t * mp)
16276 {
16277   vat_main_t *vam = &vat_main;
16278   int count = ntohl (mp->count);
16279   vat_json_node_t *node = NULL;
16280   struct in_addr ip4;
16281   struct in6_addr ip6;
16282   vl_api_fib_path_t *fp;
16283   int i;
16284
16285   if (VAT_JSON_ARRAY != vam->json_tree.type)
16286     {
16287       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16288       vat_json_init_array (&vam->json_tree);
16289     }
16290   node = vat_json_array_add (&vam->json_tree);
16291
16292   vat_json_init_object (node);
16293   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16294   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16295   vat_json_object_add_ip6 (node, "prefix", ip6);
16296   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16297   vat_json_object_add_uint (node, "path_count", count);
16298   fp = mp->path;
16299   for (i = 0; i < count; i++)
16300     {
16301       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16302       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16303       vat_json_object_add_uint (node, "is_local", fp->is_local);
16304       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16305       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16306       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16307       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16308       if (fp->afi == IP46_TYPE_IP4)
16309         {
16310           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16311           vat_json_object_add_ip4 (node, "next_hop", ip4);
16312         }
16313       else if (fp->afi == IP46_TYPE_IP6)
16314         {
16315           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16316           vat_json_object_add_ip6 (node, "next_hop", ip6);
16317         }
16318     }
16319 }
16320
16321 static int
16322 api_ip6_fib_dump (vat_main_t * vam)
16323 {
16324   vl_api_ip6_fib_dump_t *mp;
16325   vl_api_control_ping_t *mp_ping;
16326   int ret;
16327
16328   M (IP6_FIB_DUMP, mp);
16329   S (mp);
16330
16331   /* Use a control ping for synchronization */
16332   M (CONTROL_PING, mp_ping);
16333   S (mp_ping);
16334
16335   W (ret);
16336   return ret;
16337 }
16338
16339 static int
16340 api_ip6_mfib_dump (vat_main_t * vam)
16341 {
16342   vl_api_ip6_mfib_dump_t *mp;
16343   vl_api_control_ping_t *mp_ping;
16344   int ret;
16345
16346   M (IP6_MFIB_DUMP, mp);
16347   S (mp);
16348
16349   /* Use a control ping for synchronization */
16350   M (CONTROL_PING, mp_ping);
16351   S (mp_ping);
16352
16353   W (ret);
16354   return ret;
16355 }
16356
16357 int
16358 api_classify_table_ids (vat_main_t * vam)
16359 {
16360   vl_api_classify_table_ids_t *mp;
16361   int ret;
16362
16363   /* Construct the API message */
16364   M (CLASSIFY_TABLE_IDS, mp);
16365   mp->context = 0;
16366
16367   S (mp);
16368   W (ret);
16369   return ret;
16370 }
16371
16372 int
16373 api_classify_table_by_interface (vat_main_t * vam)
16374 {
16375   unformat_input_t *input = vam->input;
16376   vl_api_classify_table_by_interface_t *mp;
16377
16378   u32 sw_if_index = ~0;
16379   int ret;
16380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16381     {
16382       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16383         ;
16384       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16385         ;
16386       else
16387         break;
16388     }
16389   if (sw_if_index == ~0)
16390     {
16391       errmsg ("missing interface name or sw_if_index");
16392       return -99;
16393     }
16394
16395   /* Construct the API message */
16396   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16397   mp->context = 0;
16398   mp->sw_if_index = ntohl (sw_if_index);
16399
16400   S (mp);
16401   W (ret);
16402   return ret;
16403 }
16404
16405 int
16406 api_classify_table_info (vat_main_t * vam)
16407 {
16408   unformat_input_t *input = vam->input;
16409   vl_api_classify_table_info_t *mp;
16410
16411   u32 table_id = ~0;
16412   int ret;
16413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16414     {
16415       if (unformat (input, "table_id %d", &table_id))
16416         ;
16417       else
16418         break;
16419     }
16420   if (table_id == ~0)
16421     {
16422       errmsg ("missing table id");
16423       return -99;
16424     }
16425
16426   /* Construct the API message */
16427   M (CLASSIFY_TABLE_INFO, mp);
16428   mp->context = 0;
16429   mp->table_id = ntohl (table_id);
16430
16431   S (mp);
16432   W (ret);
16433   return ret;
16434 }
16435
16436 int
16437 api_classify_session_dump (vat_main_t * vam)
16438 {
16439   unformat_input_t *input = vam->input;
16440   vl_api_classify_session_dump_t *mp;
16441   vl_api_control_ping_t *mp_ping;
16442
16443   u32 table_id = ~0;
16444   int ret;
16445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16446     {
16447       if (unformat (input, "table_id %d", &table_id))
16448         ;
16449       else
16450         break;
16451     }
16452   if (table_id == ~0)
16453     {
16454       errmsg ("missing table id");
16455       return -99;
16456     }
16457
16458   /* Construct the API message */
16459   M (CLASSIFY_SESSION_DUMP, mp);
16460   mp->context = 0;
16461   mp->table_id = ntohl (table_id);
16462   S (mp);
16463
16464   /* Use a control ping for synchronization */
16465   M (CONTROL_PING, mp_ping);
16466   S (mp_ping);
16467
16468   W (ret);
16469   return ret;
16470 }
16471
16472 static void
16473 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16474 {
16475   vat_main_t *vam = &vat_main;
16476
16477   print (vam->ofp, "collector_address %U, collector_port %d, "
16478          "src_address %U, vrf_id %d, path_mtu %u, "
16479          "template_interval %u, udp_checksum %d",
16480          format_ip4_address, mp->collector_address,
16481          ntohs (mp->collector_port),
16482          format_ip4_address, mp->src_address,
16483          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16484          ntohl (mp->template_interval), mp->udp_checksum);
16485
16486   vam->retval = 0;
16487   vam->result_ready = 1;
16488 }
16489
16490 static void
16491   vl_api_ipfix_exporter_details_t_handler_json
16492   (vl_api_ipfix_exporter_details_t * mp)
16493 {
16494   vat_main_t *vam = &vat_main;
16495   vat_json_node_t node;
16496   struct in_addr collector_address;
16497   struct in_addr src_address;
16498
16499   vat_json_init_object (&node);
16500   clib_memcpy (&collector_address, &mp->collector_address,
16501                sizeof (collector_address));
16502   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16503   vat_json_object_add_uint (&node, "collector_port",
16504                             ntohs (mp->collector_port));
16505   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16506   vat_json_object_add_ip4 (&node, "src_address", src_address);
16507   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16508   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16509   vat_json_object_add_uint (&node, "template_interval",
16510                             ntohl (mp->template_interval));
16511   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16512
16513   vat_json_print (vam->ofp, &node);
16514   vat_json_free (&node);
16515   vam->retval = 0;
16516   vam->result_ready = 1;
16517 }
16518
16519 int
16520 api_ipfix_exporter_dump (vat_main_t * vam)
16521 {
16522   vl_api_ipfix_exporter_dump_t *mp;
16523   int ret;
16524
16525   /* Construct the API message */
16526   M (IPFIX_EXPORTER_DUMP, mp);
16527   mp->context = 0;
16528
16529   S (mp);
16530   W (ret);
16531   return ret;
16532 }
16533
16534 static int
16535 api_ipfix_classify_stream_dump (vat_main_t * vam)
16536 {
16537   vl_api_ipfix_classify_stream_dump_t *mp;
16538   int ret;
16539
16540   /* Construct the API message */
16541   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16542   mp->context = 0;
16543
16544   S (mp);
16545   W (ret);
16546   return ret;
16547   /* NOTREACHED */
16548   return 0;
16549 }
16550
16551 static void
16552   vl_api_ipfix_classify_stream_details_t_handler
16553   (vl_api_ipfix_classify_stream_details_t * mp)
16554 {
16555   vat_main_t *vam = &vat_main;
16556   print (vam->ofp, "domain_id %d, src_port %d",
16557          ntohl (mp->domain_id), ntohs (mp->src_port));
16558   vam->retval = 0;
16559   vam->result_ready = 1;
16560 }
16561
16562 static void
16563   vl_api_ipfix_classify_stream_details_t_handler_json
16564   (vl_api_ipfix_classify_stream_details_t * mp)
16565 {
16566   vat_main_t *vam = &vat_main;
16567   vat_json_node_t node;
16568
16569   vat_json_init_object (&node);
16570   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16571   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16572
16573   vat_json_print (vam->ofp, &node);
16574   vat_json_free (&node);
16575   vam->retval = 0;
16576   vam->result_ready = 1;
16577 }
16578
16579 static int
16580 api_ipfix_classify_table_dump (vat_main_t * vam)
16581 {
16582   vl_api_ipfix_classify_table_dump_t *mp;
16583   vl_api_control_ping_t *mp_ping;
16584   int ret;
16585
16586   if (!vam->json_output)
16587     {
16588       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16589              "transport_protocol");
16590     }
16591
16592   /* Construct the API message */
16593   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16594
16595   /* send it... */
16596   S (mp);
16597
16598   /* Use a control ping for synchronization */
16599   M (CONTROL_PING, mp_ping);
16600   S (mp_ping);
16601
16602   W (ret);
16603   return ret;
16604 }
16605
16606 static void
16607   vl_api_ipfix_classify_table_details_t_handler
16608   (vl_api_ipfix_classify_table_details_t * mp)
16609 {
16610   vat_main_t *vam = &vat_main;
16611   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16612          mp->transport_protocol);
16613 }
16614
16615 static void
16616   vl_api_ipfix_classify_table_details_t_handler_json
16617   (vl_api_ipfix_classify_table_details_t * mp)
16618 {
16619   vat_json_node_t *node = NULL;
16620   vat_main_t *vam = &vat_main;
16621
16622   if (VAT_JSON_ARRAY != vam->json_tree.type)
16623     {
16624       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16625       vat_json_init_array (&vam->json_tree);
16626     }
16627
16628   node = vat_json_array_add (&vam->json_tree);
16629   vat_json_init_object (node);
16630
16631   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16632   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16633   vat_json_object_add_uint (node, "transport_protocol",
16634                             mp->transport_protocol);
16635 }
16636
16637 static int
16638 api_sw_interface_span_enable_disable (vat_main_t * vam)
16639 {
16640   unformat_input_t *i = vam->input;
16641   vl_api_sw_interface_span_enable_disable_t *mp;
16642   u32 src_sw_if_index = ~0;
16643   u32 dst_sw_if_index = ~0;
16644   u8 state = 3;
16645   int ret;
16646
16647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16648     {
16649       if (unformat
16650           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16651         ;
16652       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16653         ;
16654       else
16655         if (unformat
16656             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16657         ;
16658       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16659         ;
16660       else if (unformat (i, "disable"))
16661         state = 0;
16662       else if (unformat (i, "rx"))
16663         state = 1;
16664       else if (unformat (i, "tx"))
16665         state = 2;
16666       else if (unformat (i, "both"))
16667         state = 3;
16668       else
16669         break;
16670     }
16671
16672   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16673
16674   mp->sw_if_index_from = htonl (src_sw_if_index);
16675   mp->sw_if_index_to = htonl (dst_sw_if_index);
16676   mp->state = state;
16677
16678   S (mp);
16679   W (ret);
16680   return ret;
16681 }
16682
16683 static void
16684 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16685                                             * mp)
16686 {
16687   vat_main_t *vam = &vat_main;
16688   u8 *sw_if_from_name = 0;
16689   u8 *sw_if_to_name = 0;
16690   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16691   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16692   char *states[] = { "none", "rx", "tx", "both" };
16693   hash_pair_t *p;
16694
16695   /* *INDENT-OFF* */
16696   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16697   ({
16698     if ((u32) p->value[0] == sw_if_index_from)
16699       {
16700         sw_if_from_name = (u8 *)(p->key);
16701         if (sw_if_to_name)
16702           break;
16703       }
16704     if ((u32) p->value[0] == sw_if_index_to)
16705       {
16706         sw_if_to_name = (u8 *)(p->key);
16707         if (sw_if_from_name)
16708           break;
16709       }
16710   }));
16711   /* *INDENT-ON* */
16712   print (vam->ofp, "%20s => %20s (%s)",
16713          sw_if_from_name, sw_if_to_name, states[mp->state]);
16714 }
16715
16716 static void
16717   vl_api_sw_interface_span_details_t_handler_json
16718   (vl_api_sw_interface_span_details_t * mp)
16719 {
16720   vat_main_t *vam = &vat_main;
16721   vat_json_node_t *node = NULL;
16722   u8 *sw_if_from_name = 0;
16723   u8 *sw_if_to_name = 0;
16724   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16725   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16726   hash_pair_t *p;
16727
16728   /* *INDENT-OFF* */
16729   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16730   ({
16731     if ((u32) p->value[0] == sw_if_index_from)
16732       {
16733         sw_if_from_name = (u8 *)(p->key);
16734         if (sw_if_to_name)
16735           break;
16736       }
16737     if ((u32) p->value[0] == sw_if_index_to)
16738       {
16739         sw_if_to_name = (u8 *)(p->key);
16740         if (sw_if_from_name)
16741           break;
16742       }
16743   }));
16744   /* *INDENT-ON* */
16745
16746   if (VAT_JSON_ARRAY != vam->json_tree.type)
16747     {
16748       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16749       vat_json_init_array (&vam->json_tree);
16750     }
16751   node = vat_json_array_add (&vam->json_tree);
16752
16753   vat_json_init_object (node);
16754   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16755   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16756   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16757   if (0 != sw_if_to_name)
16758     {
16759       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16760     }
16761   vat_json_object_add_uint (node, "state", mp->state);
16762 }
16763
16764 static int
16765 api_sw_interface_span_dump (vat_main_t * vam)
16766 {
16767   vl_api_sw_interface_span_dump_t *mp;
16768   vl_api_control_ping_t *mp_ping;
16769   int ret;
16770
16771   M (SW_INTERFACE_SPAN_DUMP, mp);
16772   S (mp);
16773
16774   /* Use a control ping for synchronization */
16775   M (CONTROL_PING, mp_ping);
16776   S (mp_ping);
16777
16778   W (ret);
16779   return ret;
16780 }
16781
16782 int
16783 api_pg_create_interface (vat_main_t * vam)
16784 {
16785   unformat_input_t *input = vam->input;
16786   vl_api_pg_create_interface_t *mp;
16787
16788   u32 if_id = ~0;
16789   int ret;
16790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16791     {
16792       if (unformat (input, "if_id %d", &if_id))
16793         ;
16794       else
16795         break;
16796     }
16797   if (if_id == ~0)
16798     {
16799       errmsg ("missing pg interface index");
16800       return -99;
16801     }
16802
16803   /* Construct the API message */
16804   M (PG_CREATE_INTERFACE, mp);
16805   mp->context = 0;
16806   mp->interface_id = ntohl (if_id);
16807
16808   S (mp);
16809   W (ret);
16810   return ret;
16811 }
16812
16813 int
16814 api_pg_capture (vat_main_t * vam)
16815 {
16816   unformat_input_t *input = vam->input;
16817   vl_api_pg_capture_t *mp;
16818
16819   u32 if_id = ~0;
16820   u8 enable = 1;
16821   u32 count = 1;
16822   u8 pcap_file_set = 0;
16823   u8 *pcap_file = 0;
16824   int ret;
16825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16826     {
16827       if (unformat (input, "if_id %d", &if_id))
16828         ;
16829       else if (unformat (input, "pcap %s", &pcap_file))
16830         pcap_file_set = 1;
16831       else if (unformat (input, "count %d", &count))
16832         ;
16833       else if (unformat (input, "disable"))
16834         enable = 0;
16835       else
16836         break;
16837     }
16838   if (if_id == ~0)
16839     {
16840       errmsg ("missing pg interface index");
16841       return -99;
16842     }
16843   if (pcap_file_set > 0)
16844     {
16845       if (vec_len (pcap_file) > 255)
16846         {
16847           errmsg ("pcap file name is too long");
16848           return -99;
16849         }
16850     }
16851
16852   u32 name_len = vec_len (pcap_file);
16853   /* Construct the API message */
16854   M (PG_CAPTURE, mp);
16855   mp->context = 0;
16856   mp->interface_id = ntohl (if_id);
16857   mp->is_enabled = enable;
16858   mp->count = ntohl (count);
16859   mp->pcap_name_length = ntohl (name_len);
16860   if (pcap_file_set != 0)
16861     {
16862       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16863     }
16864   vec_free (pcap_file);
16865
16866   S (mp);
16867   W (ret);
16868   return ret;
16869 }
16870
16871 int
16872 api_pg_enable_disable (vat_main_t * vam)
16873 {
16874   unformat_input_t *input = vam->input;
16875   vl_api_pg_enable_disable_t *mp;
16876
16877   u8 enable = 1;
16878   u8 stream_name_set = 0;
16879   u8 *stream_name = 0;
16880   int ret;
16881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16882     {
16883       if (unformat (input, "stream %s", &stream_name))
16884         stream_name_set = 1;
16885       else if (unformat (input, "disable"))
16886         enable = 0;
16887       else
16888         break;
16889     }
16890
16891   if (stream_name_set > 0)
16892     {
16893       if (vec_len (stream_name) > 255)
16894         {
16895           errmsg ("stream name too long");
16896           return -99;
16897         }
16898     }
16899
16900   u32 name_len = vec_len (stream_name);
16901   /* Construct the API message */
16902   M (PG_ENABLE_DISABLE, mp);
16903   mp->context = 0;
16904   mp->is_enabled = enable;
16905   if (stream_name_set != 0)
16906     {
16907       mp->stream_name_length = ntohl (name_len);
16908       clib_memcpy (mp->stream_name, stream_name, name_len);
16909     }
16910   vec_free (stream_name);
16911
16912   S (mp);
16913   W (ret);
16914   return ret;
16915 }
16916
16917 int
16918 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16919 {
16920   unformat_input_t *input = vam->input;
16921   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16922
16923   u16 *low_ports = 0;
16924   u16 *high_ports = 0;
16925   u16 this_low;
16926   u16 this_hi;
16927   ip4_address_t ip4_addr;
16928   ip6_address_t ip6_addr;
16929   u32 length;
16930   u32 tmp, tmp2;
16931   u8 prefix_set = 0;
16932   u32 vrf_id = ~0;
16933   u8 is_add = 1;
16934   u8 is_ipv6 = 0;
16935   int ret;
16936
16937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16938     {
16939       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16940         {
16941           prefix_set = 1;
16942         }
16943       else
16944         if (unformat
16945             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16946         {
16947           prefix_set = 1;
16948           is_ipv6 = 1;
16949         }
16950       else if (unformat (input, "vrf %d", &vrf_id))
16951         ;
16952       else if (unformat (input, "del"))
16953         is_add = 0;
16954       else if (unformat (input, "port %d", &tmp))
16955         {
16956           if (tmp == 0 || tmp > 65535)
16957             {
16958               errmsg ("port %d out of range", tmp);
16959               return -99;
16960             }
16961           this_low = tmp;
16962           this_hi = this_low + 1;
16963           vec_add1 (low_ports, this_low);
16964           vec_add1 (high_ports, this_hi);
16965         }
16966       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16967         {
16968           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16969             {
16970               errmsg ("incorrect range parameters");
16971               return -99;
16972             }
16973           this_low = tmp;
16974           /* Note: in debug CLI +1 is added to high before
16975              passing to real fn that does "the work"
16976              (ip_source_and_port_range_check_add_del).
16977              This fn is a wrapper around the binary API fn a
16978              control plane will call, which expects this increment
16979              to have occurred. Hence letting the binary API control
16980              plane fn do the increment for consistency between VAT
16981              and other control planes.
16982            */
16983           this_hi = tmp2;
16984           vec_add1 (low_ports, this_low);
16985           vec_add1 (high_ports, this_hi);
16986         }
16987       else
16988         break;
16989     }
16990
16991   if (prefix_set == 0)
16992     {
16993       errmsg ("<address>/<mask> not specified");
16994       return -99;
16995     }
16996
16997   if (vrf_id == ~0)
16998     {
16999       errmsg ("VRF ID required, not specified");
17000       return -99;
17001     }
17002
17003   if (vrf_id == 0)
17004     {
17005       errmsg
17006         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17007       return -99;
17008     }
17009
17010   if (vec_len (low_ports) == 0)
17011     {
17012       errmsg ("At least one port or port range required");
17013       return -99;
17014     }
17015
17016   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17017
17018   mp->is_add = is_add;
17019
17020   if (is_ipv6)
17021     {
17022       mp->is_ipv6 = 1;
17023       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17024     }
17025   else
17026     {
17027       mp->is_ipv6 = 0;
17028       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17029     }
17030
17031   mp->mask_length = length;
17032   mp->number_of_ranges = vec_len (low_ports);
17033
17034   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17035   vec_free (low_ports);
17036
17037   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17038   vec_free (high_ports);
17039
17040   mp->vrf_id = ntohl (vrf_id);
17041
17042   S (mp);
17043   W (ret);
17044   return ret;
17045 }
17046
17047 int
17048 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17049 {
17050   unformat_input_t *input = vam->input;
17051   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17052   u32 sw_if_index = ~0;
17053   int vrf_set = 0;
17054   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17055   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17056   u8 is_add = 1;
17057   int ret;
17058
17059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17060     {
17061       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17062         ;
17063       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17064         ;
17065       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17066         vrf_set = 1;
17067       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17068         vrf_set = 1;
17069       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17070         vrf_set = 1;
17071       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17072         vrf_set = 1;
17073       else if (unformat (input, "del"))
17074         is_add = 0;
17075       else
17076         break;
17077     }
17078
17079   if (sw_if_index == ~0)
17080     {
17081       errmsg ("Interface required but not specified");
17082       return -99;
17083     }
17084
17085   if (vrf_set == 0)
17086     {
17087       errmsg ("VRF ID required but not specified");
17088       return -99;
17089     }
17090
17091   if (tcp_out_vrf_id == 0
17092       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17093     {
17094       errmsg
17095         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17096       return -99;
17097     }
17098
17099   /* Construct the API message */
17100   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17101
17102   mp->sw_if_index = ntohl (sw_if_index);
17103   mp->is_add = is_add;
17104   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17105   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17106   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17107   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17108
17109   /* send it... */
17110   S (mp);
17111
17112   /* Wait for a reply... */
17113   W (ret);
17114   return ret;
17115 }
17116
17117 static int
17118 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17119 {
17120   unformat_input_t *i = vam->input;
17121   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17122   u32 local_sa_id = 0;
17123   u32 remote_sa_id = 0;
17124   ip4_address_t src_address;
17125   ip4_address_t dst_address;
17126   u8 is_add = 1;
17127   int ret;
17128
17129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17130     {
17131       if (unformat (i, "local_sa %d", &local_sa_id))
17132         ;
17133       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17134         ;
17135       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17136         ;
17137       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17138         ;
17139       else if (unformat (i, "del"))
17140         is_add = 0;
17141       else
17142         {
17143           clib_warning ("parse error '%U'", format_unformat_error, i);
17144           return -99;
17145         }
17146     }
17147
17148   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17149
17150   mp->local_sa_id = ntohl (local_sa_id);
17151   mp->remote_sa_id = ntohl (remote_sa_id);
17152   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17153   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17154   mp->is_add = is_add;
17155
17156   S (mp);
17157   W (ret);
17158   return ret;
17159 }
17160
17161 static int
17162 api_punt (vat_main_t * vam)
17163 {
17164   unformat_input_t *i = vam->input;
17165   vl_api_punt_t *mp;
17166   u32 ipv = ~0;
17167   u32 protocol = ~0;
17168   u32 port = ~0;
17169   int is_add = 1;
17170   int ret;
17171
17172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17173     {
17174       if (unformat (i, "ip %d", &ipv))
17175         ;
17176       else if (unformat (i, "protocol %d", &protocol))
17177         ;
17178       else if (unformat (i, "port %d", &port))
17179         ;
17180       else if (unformat (i, "del"))
17181         is_add = 0;
17182       else
17183         {
17184           clib_warning ("parse error '%U'", format_unformat_error, i);
17185           return -99;
17186         }
17187     }
17188
17189   M (PUNT, mp);
17190
17191   mp->is_add = (u8) is_add;
17192   mp->ipv = (u8) ipv;
17193   mp->l4_protocol = (u8) protocol;
17194   mp->l4_port = htons ((u16) port);
17195
17196   S (mp);
17197   W (ret);
17198   return ret;
17199 }
17200
17201 static void vl_api_ipsec_gre_tunnel_details_t_handler
17202   (vl_api_ipsec_gre_tunnel_details_t * mp)
17203 {
17204   vat_main_t *vam = &vat_main;
17205
17206   print (vam->ofp, "%11d%15U%15U%14d%14d",
17207          ntohl (mp->sw_if_index),
17208          format_ip4_address, &mp->src_address,
17209          format_ip4_address, &mp->dst_address,
17210          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17211 }
17212
17213 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17214   (vl_api_ipsec_gre_tunnel_details_t * mp)
17215 {
17216   vat_main_t *vam = &vat_main;
17217   vat_json_node_t *node = NULL;
17218   struct in_addr ip4;
17219
17220   if (VAT_JSON_ARRAY != vam->json_tree.type)
17221     {
17222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17223       vat_json_init_array (&vam->json_tree);
17224     }
17225   node = vat_json_array_add (&vam->json_tree);
17226
17227   vat_json_init_object (node);
17228   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17229   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17230   vat_json_object_add_ip4 (node, "src_address", ip4);
17231   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17232   vat_json_object_add_ip4 (node, "dst_address", ip4);
17233   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17234   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17235 }
17236
17237 static int
17238 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17239 {
17240   unformat_input_t *i = vam->input;
17241   vl_api_ipsec_gre_tunnel_dump_t *mp;
17242   vl_api_control_ping_t *mp_ping;
17243   u32 sw_if_index;
17244   u8 sw_if_index_set = 0;
17245   int ret;
17246
17247   /* Parse args required to build the message */
17248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17249     {
17250       if (unformat (i, "sw_if_index %d", &sw_if_index))
17251         sw_if_index_set = 1;
17252       else
17253         break;
17254     }
17255
17256   if (sw_if_index_set == 0)
17257     {
17258       sw_if_index = ~0;
17259     }
17260
17261   if (!vam->json_output)
17262     {
17263       print (vam->ofp, "%11s%15s%15s%14s%14s",
17264              "sw_if_index", "src_address", "dst_address",
17265              "local_sa_id", "remote_sa_id");
17266     }
17267
17268   /* Get list of gre-tunnel interfaces */
17269   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17270
17271   mp->sw_if_index = htonl (sw_if_index);
17272
17273   S (mp);
17274
17275   /* Use a control ping for synchronization */
17276   M (CONTROL_PING, mp_ping);
17277   S (mp_ping);
17278
17279   W (ret);
17280   return ret;
17281 }
17282
17283 static int
17284 api_delete_subif (vat_main_t * vam)
17285 {
17286   unformat_input_t *i = vam->input;
17287   vl_api_delete_subif_t *mp;
17288   u32 sw_if_index = ~0;
17289   int ret;
17290
17291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17292     {
17293       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17294         ;
17295       if (unformat (i, "sw_if_index %d", &sw_if_index))
17296         ;
17297       else
17298         break;
17299     }
17300
17301   if (sw_if_index == ~0)
17302     {
17303       errmsg ("missing sw_if_index");
17304       return -99;
17305     }
17306
17307   /* Construct the API message */
17308   M (DELETE_SUBIF, mp);
17309   mp->sw_if_index = ntohl (sw_if_index);
17310
17311   S (mp);
17312   W (ret);
17313   return ret;
17314 }
17315
17316 #define foreach_pbb_vtr_op      \
17317 _("disable",  L2_VTR_DISABLED)  \
17318 _("pop",  L2_VTR_POP_2)         \
17319 _("push",  L2_VTR_PUSH_2)
17320
17321 static int
17322 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17323 {
17324   unformat_input_t *i = vam->input;
17325   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17326   u32 sw_if_index = ~0, vtr_op = ~0;
17327   u16 outer_tag = ~0;
17328   u8 dmac[6], smac[6];
17329   u8 dmac_set = 0, smac_set = 0;
17330   u16 vlanid = 0;
17331   u32 sid = ~0;
17332   u32 tmp;
17333   int ret;
17334
17335   /* Shut up coverity */
17336   memset (dmac, 0, sizeof (dmac));
17337   memset (smac, 0, sizeof (smac));
17338
17339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17340     {
17341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17342         ;
17343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17344         ;
17345       else if (unformat (i, "vtr_op %d", &vtr_op))
17346         ;
17347 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17348       foreach_pbb_vtr_op
17349 #undef _
17350         else if (unformat (i, "translate_pbb_stag"))
17351         {
17352           if (unformat (i, "%d", &tmp))
17353             {
17354               vtr_op = L2_VTR_TRANSLATE_2_1;
17355               outer_tag = tmp;
17356             }
17357           else
17358             {
17359               errmsg
17360                 ("translate_pbb_stag operation requires outer tag definition");
17361               return -99;
17362             }
17363         }
17364       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17365         dmac_set++;
17366       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17367         smac_set++;
17368       else if (unformat (i, "sid %d", &sid))
17369         ;
17370       else if (unformat (i, "vlanid %d", &tmp))
17371         vlanid = tmp;
17372       else
17373         {
17374           clib_warning ("parse error '%U'", format_unformat_error, i);
17375           return -99;
17376         }
17377     }
17378
17379   if ((sw_if_index == ~0) || (vtr_op == ~0))
17380     {
17381       errmsg ("missing sw_if_index or vtr operation");
17382       return -99;
17383     }
17384   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17385       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17386     {
17387       errmsg
17388         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17389       return -99;
17390     }
17391
17392   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17393   mp->sw_if_index = ntohl (sw_if_index);
17394   mp->vtr_op = ntohl (vtr_op);
17395   mp->outer_tag = ntohs (outer_tag);
17396   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17397   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17398   mp->b_vlanid = ntohs (vlanid);
17399   mp->i_sid = ntohl (sid);
17400
17401   S (mp);
17402   W (ret);
17403   return ret;
17404 }
17405
17406 static int
17407 api_flow_classify_set_interface (vat_main_t * vam)
17408 {
17409   unformat_input_t *i = vam->input;
17410   vl_api_flow_classify_set_interface_t *mp;
17411   u32 sw_if_index;
17412   int sw_if_index_set;
17413   u32 ip4_table_index = ~0;
17414   u32 ip6_table_index = ~0;
17415   u8 is_add = 1;
17416   int ret;
17417
17418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17419     {
17420       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17421         sw_if_index_set = 1;
17422       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17423         sw_if_index_set = 1;
17424       else if (unformat (i, "del"))
17425         is_add = 0;
17426       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17427         ;
17428       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17429         ;
17430       else
17431         {
17432           clib_warning ("parse error '%U'", format_unformat_error, i);
17433           return -99;
17434         }
17435     }
17436
17437   if (sw_if_index_set == 0)
17438     {
17439       errmsg ("missing interface name or sw_if_index");
17440       return -99;
17441     }
17442
17443   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17444
17445   mp->sw_if_index = ntohl (sw_if_index);
17446   mp->ip4_table_index = ntohl (ip4_table_index);
17447   mp->ip6_table_index = ntohl (ip6_table_index);
17448   mp->is_add = is_add;
17449
17450   S (mp);
17451   W (ret);
17452   return ret;
17453 }
17454
17455 static int
17456 api_flow_classify_dump (vat_main_t * vam)
17457 {
17458   unformat_input_t *i = vam->input;
17459   vl_api_flow_classify_dump_t *mp;
17460   vl_api_control_ping_t *mp_ping;
17461   u8 type = FLOW_CLASSIFY_N_TABLES;
17462   int ret;
17463
17464   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17465     ;
17466   else
17467     {
17468       errmsg ("classify table type must be specified");
17469       return -99;
17470     }
17471
17472   if (!vam->json_output)
17473     {
17474       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17475     }
17476
17477   M (FLOW_CLASSIFY_DUMP, mp);
17478   mp->type = type;
17479   /* send it... */
17480   S (mp);
17481
17482   /* Use a control ping for synchronization */
17483   M (CONTROL_PING, mp_ping);
17484   S (mp_ping);
17485
17486   /* Wait for a reply... */
17487   W (ret);
17488   return ret;
17489 }
17490
17491 static int
17492 api_feature_enable_disable (vat_main_t * vam)
17493 {
17494   unformat_input_t *i = vam->input;
17495   vl_api_feature_enable_disable_t *mp;
17496   u8 *arc_name = 0;
17497   u8 *feature_name = 0;
17498   u32 sw_if_index = ~0;
17499   u8 enable = 1;
17500   int ret;
17501
17502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17503     {
17504       if (unformat (i, "arc_name %s", &arc_name))
17505         ;
17506       else if (unformat (i, "feature_name %s", &feature_name))
17507         ;
17508       else
17509         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17510         ;
17511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17512         ;
17513       else if (unformat (i, "disable"))
17514         enable = 0;
17515       else
17516         break;
17517     }
17518
17519   if (arc_name == 0)
17520     {
17521       errmsg ("missing arc name");
17522       return -99;
17523     }
17524   if (vec_len (arc_name) > 63)
17525     {
17526       errmsg ("arc name too long");
17527     }
17528
17529   if (feature_name == 0)
17530     {
17531       errmsg ("missing feature name");
17532       return -99;
17533     }
17534   if (vec_len (feature_name) > 63)
17535     {
17536       errmsg ("feature name too long");
17537     }
17538
17539   if (sw_if_index == ~0)
17540     {
17541       errmsg ("missing interface name or sw_if_index");
17542       return -99;
17543     }
17544
17545   /* Construct the API message */
17546   M (FEATURE_ENABLE_DISABLE, mp);
17547   mp->sw_if_index = ntohl (sw_if_index);
17548   mp->enable = enable;
17549   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17550   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17551   vec_free (arc_name);
17552   vec_free (feature_name);
17553
17554   S (mp);
17555   W (ret);
17556   return ret;
17557 }
17558
17559 static int
17560 api_sw_interface_tag_add_del (vat_main_t * vam)
17561 {
17562   unformat_input_t *i = vam->input;
17563   vl_api_sw_interface_tag_add_del_t *mp;
17564   u32 sw_if_index = ~0;
17565   u8 *tag = 0;
17566   u8 enable = 1;
17567   int ret;
17568
17569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17570     {
17571       if (unformat (i, "tag %s", &tag))
17572         ;
17573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17574         ;
17575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17576         ;
17577       else if (unformat (i, "del"))
17578         enable = 0;
17579       else
17580         break;
17581     }
17582
17583   if (sw_if_index == ~0)
17584     {
17585       errmsg ("missing interface name or sw_if_index");
17586       return -99;
17587     }
17588
17589   if (enable && (tag == 0))
17590     {
17591       errmsg ("no tag specified");
17592       return -99;
17593     }
17594
17595   /* Construct the API message */
17596   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17597   mp->sw_if_index = ntohl (sw_if_index);
17598   mp->is_add = enable;
17599   if (enable)
17600     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17601   vec_free (tag);
17602
17603   S (mp);
17604   W (ret);
17605   return ret;
17606 }
17607
17608 static void vl_api_l2_xconnect_details_t_handler
17609   (vl_api_l2_xconnect_details_t * mp)
17610 {
17611   vat_main_t *vam = &vat_main;
17612
17613   print (vam->ofp, "%15d%15d",
17614          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17615 }
17616
17617 static void vl_api_l2_xconnect_details_t_handler_json
17618   (vl_api_l2_xconnect_details_t * mp)
17619 {
17620   vat_main_t *vam = &vat_main;
17621   vat_json_node_t *node = NULL;
17622
17623   if (VAT_JSON_ARRAY != vam->json_tree.type)
17624     {
17625       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17626       vat_json_init_array (&vam->json_tree);
17627     }
17628   node = vat_json_array_add (&vam->json_tree);
17629
17630   vat_json_init_object (node);
17631   vat_json_object_add_uint (node, "rx_sw_if_index",
17632                             ntohl (mp->rx_sw_if_index));
17633   vat_json_object_add_uint (node, "tx_sw_if_index",
17634                             ntohl (mp->tx_sw_if_index));
17635 }
17636
17637 static int
17638 api_l2_xconnect_dump (vat_main_t * vam)
17639 {
17640   vl_api_l2_xconnect_dump_t *mp;
17641   vl_api_control_ping_t *mp_ping;
17642   int ret;
17643
17644   if (!vam->json_output)
17645     {
17646       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17647     }
17648
17649   M (L2_XCONNECT_DUMP, mp);
17650
17651   S (mp);
17652
17653   /* Use a control ping for synchronization */
17654   M (CONTROL_PING, mp_ping);
17655   S (mp_ping);
17656
17657   W (ret);
17658   return ret;
17659 }
17660
17661 static int
17662 api_sw_interface_set_mtu (vat_main_t * vam)
17663 {
17664   unformat_input_t *i = vam->input;
17665   vl_api_sw_interface_set_mtu_t *mp;
17666   u32 sw_if_index = ~0;
17667   u32 mtu = 0;
17668   int ret;
17669
17670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17671     {
17672       if (unformat (i, "mtu %d", &mtu))
17673         ;
17674       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17675         ;
17676       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17677         ;
17678       else
17679         break;
17680     }
17681
17682   if (sw_if_index == ~0)
17683     {
17684       errmsg ("missing interface name or sw_if_index");
17685       return -99;
17686     }
17687
17688   if (mtu == 0)
17689     {
17690       errmsg ("no mtu specified");
17691       return -99;
17692     }
17693
17694   /* Construct the API message */
17695   M (SW_INTERFACE_SET_MTU, mp);
17696   mp->sw_if_index = ntohl (sw_if_index);
17697   mp->mtu = ntohs ((u16) mtu);
17698
17699   S (mp);
17700   W (ret);
17701   return ret;
17702 }
17703
17704
17705 static int
17706 q_or_quit (vat_main_t * vam)
17707 {
17708 #if VPP_API_TEST_BUILTIN == 0
17709   longjmp (vam->jump_buf, 1);
17710 #endif
17711   return 0;                     /* not so much */
17712 }
17713
17714 static int
17715 q (vat_main_t * vam)
17716 {
17717   return q_or_quit (vam);
17718 }
17719
17720 static int
17721 quit (vat_main_t * vam)
17722 {
17723   return q_or_quit (vam);
17724 }
17725
17726 static int
17727 comment (vat_main_t * vam)
17728 {
17729   return 0;
17730 }
17731
17732 static int
17733 cmd_cmp (void *a1, void *a2)
17734 {
17735   u8 **c1 = a1;
17736   u8 **c2 = a2;
17737
17738   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17739 }
17740
17741 static int
17742 help (vat_main_t * vam)
17743 {
17744   u8 **cmds = 0;
17745   u8 *name = 0;
17746   hash_pair_t *p;
17747   unformat_input_t *i = vam->input;
17748   int j;
17749
17750   if (unformat (i, "%s", &name))
17751     {
17752       uword *hs;
17753
17754       vec_add1 (name, 0);
17755
17756       hs = hash_get_mem (vam->help_by_name, name);
17757       if (hs)
17758         print (vam->ofp, "usage: %s %s", name, hs[0]);
17759       else
17760         print (vam->ofp, "No such msg / command '%s'", name);
17761       vec_free (name);
17762       return 0;
17763     }
17764
17765   print (vam->ofp, "Help is available for the following:");
17766
17767     /* *INDENT-OFF* */
17768     hash_foreach_pair (p, vam->function_by_name,
17769     ({
17770       vec_add1 (cmds, (u8 *)(p->key));
17771     }));
17772     /* *INDENT-ON* */
17773
17774   vec_sort_with_function (cmds, cmd_cmp);
17775
17776   for (j = 0; j < vec_len (cmds); j++)
17777     print (vam->ofp, "%s", cmds[j]);
17778
17779   vec_free (cmds);
17780   return 0;
17781 }
17782
17783 static int
17784 set (vat_main_t * vam)
17785 {
17786   u8 *name = 0, *value = 0;
17787   unformat_input_t *i = vam->input;
17788
17789   if (unformat (i, "%s", &name))
17790     {
17791       /* The input buffer is a vector, not a string. */
17792       value = vec_dup (i->buffer);
17793       vec_delete (value, i->index, 0);
17794       /* Almost certainly has a trailing newline */
17795       if (value[vec_len (value) - 1] == '\n')
17796         value[vec_len (value) - 1] = 0;
17797       /* Make sure it's a proper string, one way or the other */
17798       vec_add1 (value, 0);
17799       (void) clib_macro_set_value (&vam->macro_main,
17800                                    (char *) name, (char *) value);
17801     }
17802   else
17803     errmsg ("usage: set <name> <value>");
17804
17805   vec_free (name);
17806   vec_free (value);
17807   return 0;
17808 }
17809
17810 static int
17811 unset (vat_main_t * vam)
17812 {
17813   u8 *name = 0;
17814
17815   if (unformat (vam->input, "%s", &name))
17816     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17817       errmsg ("unset: %s wasn't set", name);
17818   vec_free (name);
17819   return 0;
17820 }
17821
17822 typedef struct
17823 {
17824   u8 *name;
17825   u8 *value;
17826 } macro_sort_t;
17827
17828
17829 static int
17830 macro_sort_cmp (void *a1, void *a2)
17831 {
17832   macro_sort_t *s1 = a1;
17833   macro_sort_t *s2 = a2;
17834
17835   return strcmp ((char *) (s1->name), (char *) (s2->name));
17836 }
17837
17838 static int
17839 dump_macro_table (vat_main_t * vam)
17840 {
17841   macro_sort_t *sort_me = 0, *sm;
17842   int i;
17843   hash_pair_t *p;
17844
17845     /* *INDENT-OFF* */
17846     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17847     ({
17848       vec_add2 (sort_me, sm, 1);
17849       sm->name = (u8 *)(p->key);
17850       sm->value = (u8 *) (p->value[0]);
17851     }));
17852     /* *INDENT-ON* */
17853
17854   vec_sort_with_function (sort_me, macro_sort_cmp);
17855
17856   if (vec_len (sort_me))
17857     print (vam->ofp, "%-15s%s", "Name", "Value");
17858   else
17859     print (vam->ofp, "The macro table is empty...");
17860
17861   for (i = 0; i < vec_len (sort_me); i++)
17862     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17863   return 0;
17864 }
17865
17866 static int
17867 dump_node_table (vat_main_t * vam)
17868 {
17869   int i, j;
17870   vlib_node_t *node, *next_node;
17871
17872   if (vec_len (vam->graph_nodes) == 0)
17873     {
17874       print (vam->ofp, "Node table empty, issue get_node_graph...");
17875       return 0;
17876     }
17877
17878   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17879     {
17880       node = vam->graph_nodes[i];
17881       print (vam->ofp, "[%d] %s", i, node->name);
17882       for (j = 0; j < vec_len (node->next_nodes); j++)
17883         {
17884           if (node->next_nodes[j] != ~0)
17885             {
17886               next_node = vam->graph_nodes[node->next_nodes[j]];
17887               print (vam->ofp, "  [%d] %s", j, next_node->name);
17888             }
17889         }
17890     }
17891   return 0;
17892 }
17893
17894 static int
17895 value_sort_cmp (void *a1, void *a2)
17896 {
17897   name_sort_t *n1 = a1;
17898   name_sort_t *n2 = a2;
17899
17900   if (n1->value < n2->value)
17901     return -1;
17902   if (n1->value > n2->value)
17903     return 1;
17904   return 0;
17905 }
17906
17907
17908 static int
17909 dump_msg_api_table (vat_main_t * vam)
17910 {
17911   api_main_t *am = &api_main;
17912   name_sort_t *nses = 0, *ns;
17913   hash_pair_t *hp;
17914   int i;
17915
17916   /* *INDENT-OFF* */
17917   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17918   ({
17919     vec_add2 (nses, ns, 1);
17920     ns->name = (u8 *)(hp->key);
17921     ns->value = (u32) hp->value[0];
17922   }));
17923   /* *INDENT-ON* */
17924
17925   vec_sort_with_function (nses, value_sort_cmp);
17926
17927   for (i = 0; i < vec_len (nses); i++)
17928     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17929   vec_free (nses);
17930   return 0;
17931 }
17932
17933 static int
17934 get_msg_id (vat_main_t * vam)
17935 {
17936   u8 *name_and_crc;
17937   u32 message_index;
17938
17939   if (unformat (vam->input, "%s", &name_and_crc))
17940     {
17941       message_index = vl_api_get_msg_index (name_and_crc);
17942       if (message_index == ~0)
17943         {
17944           print (vam->ofp, " '%s' not found", name_and_crc);
17945           return 0;
17946         }
17947       print (vam->ofp, " '%s' has message index %d",
17948              name_and_crc, message_index);
17949       return 0;
17950     }
17951   errmsg ("name_and_crc required...");
17952   return 0;
17953 }
17954
17955 static int
17956 search_node_table (vat_main_t * vam)
17957 {
17958   unformat_input_t *line_input = vam->input;
17959   u8 *node_to_find;
17960   int j;
17961   vlib_node_t *node, *next_node;
17962   uword *p;
17963
17964   if (vam->graph_node_index_by_name == 0)
17965     {
17966       print (vam->ofp, "Node table empty, issue get_node_graph...");
17967       return 0;
17968     }
17969
17970   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17971     {
17972       if (unformat (line_input, "%s", &node_to_find))
17973         {
17974           vec_add1 (node_to_find, 0);
17975           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17976           if (p == 0)
17977             {
17978               print (vam->ofp, "%s not found...", node_to_find);
17979               goto out;
17980             }
17981           node = vam->graph_nodes[p[0]];
17982           print (vam->ofp, "[%d] %s", p[0], node->name);
17983           for (j = 0; j < vec_len (node->next_nodes); j++)
17984             {
17985               if (node->next_nodes[j] != ~0)
17986                 {
17987                   next_node = vam->graph_nodes[node->next_nodes[j]];
17988                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17989                 }
17990             }
17991         }
17992
17993       else
17994         {
17995           clib_warning ("parse error '%U'", format_unformat_error,
17996                         line_input);
17997           return -99;
17998         }
17999
18000     out:
18001       vec_free (node_to_find);
18002
18003     }
18004
18005   return 0;
18006 }
18007
18008
18009 static int
18010 script (vat_main_t * vam)
18011 {
18012 #if (VPP_API_TEST_BUILTIN==0)
18013   u8 *s = 0;
18014   char *save_current_file;
18015   unformat_input_t save_input;
18016   jmp_buf save_jump_buf;
18017   u32 save_line_number;
18018
18019   FILE *new_fp, *save_ifp;
18020
18021   if (unformat (vam->input, "%s", &s))
18022     {
18023       new_fp = fopen ((char *) s, "r");
18024       if (new_fp == 0)
18025         {
18026           errmsg ("Couldn't open script file %s", s);
18027           vec_free (s);
18028           return -99;
18029         }
18030     }
18031   else
18032     {
18033       errmsg ("Missing script name");
18034       return -99;
18035     }
18036
18037   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18038   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18039   save_ifp = vam->ifp;
18040   save_line_number = vam->input_line_number;
18041   save_current_file = (char *) vam->current_file;
18042
18043   vam->input_line_number = 0;
18044   vam->ifp = new_fp;
18045   vam->current_file = s;
18046   do_one_file (vam);
18047
18048   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18049   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18050   vam->ifp = save_ifp;
18051   vam->input_line_number = save_line_number;
18052   vam->current_file = (u8 *) save_current_file;
18053   vec_free (s);
18054
18055   return 0;
18056 #else
18057   clib_warning ("use the exec command...");
18058   return -99;
18059 #endif
18060 }
18061
18062 static int
18063 echo (vat_main_t * vam)
18064 {
18065   print (vam->ofp, "%v", vam->input->buffer);
18066   return 0;
18067 }
18068
18069 /* List of API message constructors, CLI names map to api_xxx */
18070 #define foreach_vpe_api_msg                                             \
18071 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18072 _(sw_interface_dump,"")                                                 \
18073 _(sw_interface_set_flags,                                               \
18074   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18075 _(sw_interface_add_del_address,                                         \
18076   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18077 _(sw_interface_set_table,                                               \
18078   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18079 _(sw_interface_set_mpls_enable,                                         \
18080   "<intfc> | sw_if_index [disable | dis]")                              \
18081 _(sw_interface_set_vpath,                                               \
18082   "<intfc> | sw_if_index <id> enable | disable")                        \
18083 _(sw_interface_set_vxlan_bypass,                                        \
18084   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18085 _(sw_interface_set_l2_xconnect,                                         \
18086   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18087   "enable | disable")                                                   \
18088 _(sw_interface_set_l2_bridge,                                           \
18089   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18090   "[shg <split-horizon-group>] [bvi]\n"                                 \
18091   "enable | disable")                                                   \
18092 _(bridge_domain_add_del,                                                \
18093   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18094 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18095 _(l2fib_add_del,                                                        \
18096   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18097 _(l2_flags,                                                             \
18098   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18099 _(bridge_flags,                                                         \
18100   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18101 _(tap_connect,                                                          \
18102   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18103 _(tap_modify,                                                           \
18104   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18105 _(tap_delete,                                                           \
18106   "<vpp-if-name> | sw_if_index <id>")                                   \
18107 _(sw_interface_tap_dump, "")                                            \
18108 _(ip_add_del_route,                                                     \
18109   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18110   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18111   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18112   "[multipath] [count <n>]")                                            \
18113 _(ip_mroute_add_del,                                                    \
18114   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18115   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18116 _(mpls_route_add_del,                                                   \
18117   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18118   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18119   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18120   "[multipath] [count <n>]")                                            \
18121 _(mpls_ip_bind_unbind,                                                  \
18122   "<label> <addr/len>")                                                 \
18123 _(mpls_tunnel_add_del,                                                  \
18124   " via <addr> [table-id <n>]\n"                                        \
18125   "sw_if_index <id>] [l2]  [del]")                                      \
18126 _(proxy_arp_add_del,                                                    \
18127   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18128 _(proxy_arp_intfc_enable_disable,                                       \
18129   "<intfc> | sw_if_index <id> enable | disable")                        \
18130 _(sw_interface_set_unnumbered,                                          \
18131   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18132 _(ip_neighbor_add_del,                                                  \
18133   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18134   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18135 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18136 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18137 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18138   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18139   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18140   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18141 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18142 _(reset_fib, "vrf <n> [ipv6]")                                          \
18143 _(dhcp_proxy_config,                                                    \
18144   "svr <v46-address> src <v46-address>\n"                               \
18145    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18146 _(dhcp_proxy_set_vss,                                                   \
18147   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18148 _(dhcp_proxy_dump, "ip6")                                               \
18149 _(dhcp_client_config,                                                   \
18150   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18151 _(set_ip_flow_hash,                                                     \
18152   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18153 _(sw_interface_ip6_enable_disable,                                      \
18154   "<intfc> | sw_if_index <id> enable | disable")                        \
18155 _(sw_interface_ip6_set_link_local_address,                              \
18156   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18157 _(sw_interface_ip6nd_ra_prefix,                                         \
18158   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18159   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18160   "[nolink] [isno]")                                                    \
18161 _(sw_interface_ip6nd_ra_config,                                         \
18162   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18163   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18164   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18165 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18166 _(l2_patch_add_del,                                                     \
18167   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18168   "enable | disable")                                                   \
18169 _(sr_tunnel_add_del,                                                    \
18170   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
18171   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
18172   "[policy <policy_name>]")                                             \
18173 _(sr_policy_add_del,                                                    \
18174   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
18175 _(sr_multicast_map_add_del,                                             \
18176   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
18177 _(classify_add_del_table,                                               \
18178   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18179   " [del] [del-chain] mask <mask-value>\n"                              \
18180   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18181   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18182 _(classify_add_del_session,                                             \
18183   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18184   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18185   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18186   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18187 _(classify_set_interface_ip_table,                                      \
18188   "<intfc> | sw_if_index <nn> table <nn>")                              \
18189 _(classify_set_interface_l2_tables,                                     \
18190   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18191   "  [other-table <nn>]")                                               \
18192 _(get_node_index, "node <node-name")                                    \
18193 _(add_node_next, "node <node-name> next <next-node-name>")              \
18194 _(l2tpv3_create_tunnel,                                                 \
18195   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18196   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18197   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18198 _(l2tpv3_set_tunnel_cookies,                                            \
18199   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18200   "[new_remote_cookie <nn>]\n")                                         \
18201 _(l2tpv3_interface_enable_disable,                                      \
18202   "<intfc> | sw_if_index <nn> enable | disable")                        \
18203 _(l2tpv3_set_lookup_key,                                                \
18204   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18205 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18206 _(vxlan_add_del_tunnel,                                                 \
18207   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18208   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18209   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18210 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18211 _(gre_add_del_tunnel,                                                   \
18212   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18213 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18214 _(l2_fib_clear_table, "")                                               \
18215 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18216 _(l2_interface_vlan_tag_rewrite,                                        \
18217   "<intfc> | sw_if_index <nn> \n"                                       \
18218   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18219   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18220 _(create_vhost_user_if,                                                 \
18221         "socket <filename> [server] [renumber <dev_instance>] "         \
18222         "[mac <mac_address>]")                                          \
18223 _(modify_vhost_user_if,                                                 \
18224         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18225         "[server] [renumber <dev_instance>]")                           \
18226 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18227 _(sw_interface_vhost_user_dump, "")                                     \
18228 _(show_version, "")                                                     \
18229 _(vxlan_gpe_add_del_tunnel,                                             \
18230   "local <addr> remote <addr> vni <nn>\n"                               \
18231     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18232   "[next-ethernet] [next-nsh]\n")                                       \
18233 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18234 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18235 _(interface_name_renumber,                                              \
18236   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18237 _(input_acl_set_interface,                                              \
18238   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18239   "  [l2-table <nn>] [del]")                                            \
18240 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18241 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18242 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18243 _(ip_dump, "ipv4 | ipv6")                                               \
18244 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18245 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18246   "  spid_id <n> ")                                                     \
18247 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18248   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18249   "  integ_alg <alg> integ_key <hex>")                                  \
18250 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18251   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18252   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18253   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18254 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18255 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18256 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18257   "(auth_data 0x<data> | auth_data <data>)")                            \
18258 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18259   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18260 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18261   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18262   "(local|remote)")                                                     \
18263 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18264 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18265 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18266 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18267 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18268 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18269 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18270 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18271 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18272 _(delete_loopback,"sw_if_index <nn>")                                   \
18273 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18274 _(map_add_domain,                                                       \
18275   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18276   "ip6-src <ip6addr> "                                                  \
18277   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18278 _(map_del_domain, "index <n>")                                          \
18279 _(map_add_del_rule,                                                     \
18280   "index <n> psid <n> dst <ip6addr> [del]")                             \
18281 _(map_domain_dump, "")                                                  \
18282 _(map_rule_dump, "index <map-domain>")                                  \
18283 _(want_interface_events,  "enable|disable")                             \
18284 _(want_stats,"enable|disable")                                          \
18285 _(get_first_msg_id, "client <name>")                                    \
18286 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18287 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18288   "fib-id <nn> [ip4][ip6][default]")                                    \
18289 _(get_node_graph, " ")                                                  \
18290 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18291 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18292 _(ioam_disable, "")                                                     \
18293 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18294                             " sw_if_index <sw_if_index> p <priority> "  \
18295                             "w <weight>] [del]")                        \
18296 _(one_add_del_locator, "locator-set <locator_name> "                    \
18297                         "iface <intf> | sw_if_index <sw_if_index> "     \
18298                         "p <priority> w <weight> [del]")                \
18299 _(one_add_del_local_eid,"vni <vni> eid "                                \
18300                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18301                          "locator-set <locator_name> [del]"             \
18302                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18303 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18304 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18305 _(one_enable_disable, "enable|disable")                                 \
18306 _(one_map_register_enable_disable, "enable|disable")                    \
18307 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18308 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18309                                "[seid <seid>] "                         \
18310                                "rloc <locator> p <prio> "               \
18311                                "w <weight> [rloc <loc> ... ] "          \
18312                                "action <action> [del-all]")             \
18313 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18314                           "<local-eid>")                                \
18315 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18316 _(one_map_request_mode, "src-dst|dst-only")                             \
18317 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18318 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18319 _(one_locator_set_dump, "[local | remote]")                             \
18320 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18321 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18322                        "[local] | [remote]")                            \
18323 _(one_eid_table_vni_dump, "")                                           \
18324 _(one_eid_table_map_dump, "l2|l3")                                      \
18325 _(one_map_resolver_dump, "")                                            \
18326 _(one_map_server_dump, "")                                              \
18327 _(one_adjacencies_get, "vni <vni>")                                     \
18328 _(show_one_rloc_probe_state, "")                                        \
18329 _(show_one_map_register_state, "")                                      \
18330 _(show_one_status, "")                                                  \
18331 _(one_get_map_request_itr_rlocs, "")                                    \
18332 _(show_one_pitr, "")                                                    \
18333 _(show_one_map_request_mode, "")                                        \
18334 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18335                             " sw_if_index <sw_if_index> p <priority> "  \
18336                             "w <weight>] [del]")                        \
18337 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18338                         "iface <intf> | sw_if_index <sw_if_index> "     \
18339                         "p <priority> w <weight> [del]")                \
18340 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18341                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18342                          "locator-set <locator_name> [del]"             \
18343                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18344 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18345 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18346 _(lisp_enable_disable, "enable|disable")                                \
18347 _(lisp_map_register_enable_disable, "enable|disable")                   \
18348 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18349 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18350                                "[seid <seid>] "                         \
18351                                "rloc <locator> p <prio> "               \
18352                                "w <weight> [rloc <loc> ... ] "          \
18353                                "action <action> [del-all]")             \
18354 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18355                           "<local-eid>")                                \
18356 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18357 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18358 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18359 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18360 _(lisp_locator_set_dump, "[local | remote]")                            \
18361 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18362 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18363                        "[local] | [remote]")                            \
18364 _(lisp_eid_table_vni_dump, "")                                          \
18365 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18366 _(lisp_map_resolver_dump, "")                                           \
18367 _(lisp_map_server_dump, "")                                             \
18368 _(lisp_adjacencies_get, "vni <vni>")                                    \
18369 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18370 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18371 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18372 _(gpe_get_encap_mode, "")                                               \
18373 _(lisp_gpe_add_del_iface, "up|down")                                    \
18374 _(lisp_gpe_enable_disable, "enable|disable")                            \
18375 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18376   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18377 _(show_lisp_rloc_probe_state, "")                                       \
18378 _(show_lisp_map_register_state, "")                                     \
18379 _(show_lisp_status, "")                                                 \
18380 _(lisp_get_map_request_itr_rlocs, "")                                   \
18381 _(show_lisp_pitr, "")                                                   \
18382 _(show_lisp_map_request_mode, "")                                       \
18383 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18384 _(af_packet_delete, "name <host interface name>")                       \
18385 _(policer_add_del, "name <policer name> <params> [del]")                \
18386 _(policer_dump, "[name <policer name>]")                                \
18387 _(policer_classify_set_interface,                                       \
18388   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18389   "  [l2-table <nn>] [del]")                                            \
18390 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18391 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18392     "[master|slave]")                                                   \
18393 _(netmap_delete, "name <interface name>")                               \
18394 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18395 _(mpls_fib_dump, "")                                                    \
18396 _(classify_table_ids, "")                                               \
18397 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18398 _(classify_table_info, "table_id <nn>")                                 \
18399 _(classify_session_dump, "table_id <nn>")                               \
18400 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18401     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18402     "[template_interval <nn>] [udp_checksum]")                          \
18403 _(ipfix_exporter_dump, "")                                              \
18404 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18405 _(ipfix_classify_stream_dump, "")                                       \
18406 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18407 _(ipfix_classify_table_dump, "")                                        \
18408 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18409 _(sw_interface_span_dump, "")                                           \
18410 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18411 _(pg_create_interface, "if_id <nn>")                                    \
18412 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18413 _(pg_enable_disable, "[stream <id>] disable")                           \
18414 _(ip_source_and_port_range_check_add_del,                               \
18415   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18416 _(ip_source_and_port_range_check_interface_add_del,                     \
18417   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18418   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18419 _(ipsec_gre_add_del_tunnel,                                             \
18420   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18421 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18422 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18423 _(l2_interface_pbb_tag_rewrite,                                         \
18424   "<intfc> | sw_if_index <nn> \n"                                       \
18425   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18426   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18427 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18428 _(flow_classify_set_interface,                                          \
18429   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18430 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18431 _(ip_fib_dump, "")                                                      \
18432 _(ip_mfib_dump, "")                                                     \
18433 _(ip6_fib_dump, "")                                                     \
18434 _(ip6_mfib_dump, "")                                                    \
18435 _(feature_enable_disable, "arc_name <arc_name> "                        \
18436   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18437 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18438 "[disable]")                                                            \
18439 _(l2_xconnect_dump, "")                                                 \
18440 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18441 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18442 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18443
18444 /* List of command functions, CLI names map directly to functions */
18445 #define foreach_cli_function                                    \
18446 _(comment, "usage: comment <ignore-rest-of-line>")              \
18447 _(dump_interface_table, "usage: dump_interface_table")          \
18448 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18449 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18450 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18451 _(dump_stats_table, "usage: dump_stats_table")                  \
18452 _(dump_macro_table, "usage: dump_macro_table ")                 \
18453 _(dump_node_table, "usage: dump_node_table")                    \
18454 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18455 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18456 _(echo, "usage: echo <message>")                                \
18457 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18458 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18459 _(help, "usage: help")                                          \
18460 _(q, "usage: quit")                                             \
18461 _(quit, "usage: quit")                                          \
18462 _(search_node_table, "usage: search_node_table <name>...")      \
18463 _(set, "usage: set <variable-name> <value>")                    \
18464 _(script, "usage: script <file-name>")                          \
18465 _(unset, "usage: unset <variable-name>")
18466
18467 #define _(N,n)                                  \
18468     static void vl_api_##n##_t_handler_uni      \
18469     (vl_api_##n##_t * mp)                       \
18470     {                                           \
18471         vat_main_t * vam = &vat_main;           \
18472         if (vam->json_output) {                 \
18473             vl_api_##n##_t_handler_json(mp);    \
18474         } else {                                \
18475             vl_api_##n##_t_handler(mp);         \
18476         }                                       \
18477     }
18478 foreach_vpe_api_reply_msg;
18479 #if VPP_API_TEST_BUILTIN == 0
18480 foreach_standalone_reply_msg;
18481 #endif
18482 #undef _
18483
18484 void
18485 vat_api_hookup (vat_main_t * vam)
18486 {
18487 #define _(N,n)                                                  \
18488     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18489                            vl_api_##n##_t_handler_uni,          \
18490                            vl_noop_handler,                     \
18491                            vl_api_##n##_t_endian,               \
18492                            vl_api_##n##_t_print,                \
18493                            sizeof(vl_api_##n##_t), 1);
18494   foreach_vpe_api_reply_msg;
18495 #if VPP_API_TEST_BUILTIN == 0
18496   foreach_standalone_reply_msg;
18497 #endif
18498 #undef _
18499
18500 #if (VPP_API_TEST_BUILTIN==0)
18501   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18502 #endif
18503
18504   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18505
18506   vam->function_by_name = hash_create_string (0, sizeof (uword));
18507
18508   vam->help_by_name = hash_create_string (0, sizeof (uword));
18509
18510   /* API messages we can send */
18511 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18512   foreach_vpe_api_msg;
18513 #undef _
18514
18515   /* Help strings */
18516 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18517   foreach_vpe_api_msg;
18518 #undef _
18519
18520   /* CLI functions */
18521 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18522   foreach_cli_function;
18523 #undef _
18524
18525   /* Help strings */
18526 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18527   foreach_cli_function;
18528 #undef _
18529 }
18530
18531 #if VPP_API_TEST_BUILTIN
18532 static clib_error_t *
18533 vat_api_hookup_shim (vlib_main_t * vm)
18534 {
18535   vat_api_hookup (&vat_main);
18536   return 0;
18537 }
18538
18539 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18540 #endif
18541
18542 /*
18543  * fd.io coding-style-patch-verification: ON
18544  *
18545  * Local Variables:
18546  * eval: (c-set-style "gnu")
18547  * End:
18548  */